feat(web): 用户工作台 - 产品化壳层、内容库布局与积分入口
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,18 +1,16 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { getWorkspaceAntThemeConfig } from "../src/lib/app-theme";
|
||||
|
||||
describe("asset library header buttons", () => {
|
||||
test("only restyles header buttons in light mode and uses outline tokens", () => {
|
||||
test("user pages share control geometry without a light-only outline override", () => {
|
||||
const css = readFileSync(resolve(import.meta.dir, "../src/styles/globals.css"), "utf8");
|
||||
const headerButtonRule = css.match(/html:not\(\.dark\) \.library-page \.app-page-header \.ant-btn,[\s\S]*?transition: all 180ms ease-out !important;\s*}/)?.[0] || "";
|
||||
const headerButtonHoverRule = css.match(/html:not\(\.dark\) \.library-page \.app-page-header \.ant-btn:hover,[\s\S]*?transform: translateY\(-1px\);\s*}/)?.[0] || "";
|
||||
|
||||
expect(headerButtonRule).toContain("html:not(.dark) .canvas-library-page .app-page-header .ant-btn");
|
||||
expect(headerButtonRule).toContain("background: transparent !important;");
|
||||
expect(headerButtonRule).toContain("color: var(--foreground) !important;");
|
||||
expect(headerButtonHoverRule).toContain("background: var(--btn-outline-hover-bg) !important;");
|
||||
expect(headerButtonHoverRule).toContain("color: var(--foreground) !important;");
|
||||
expect(css).not.toContain("\n .library-page .app-page-header .ant-btn,\n");
|
||||
const theme = getWorkspaceAntThemeConfig();
|
||||
expect(theme.token?.controlHeight).toBe(38);
|
||||
expect(theme.components?.Button?.borderRadius).toBe(theme.token?.borderRadius);
|
||||
expect(theme.components?.Button?.defaultBorderColor).toBe("transparent");
|
||||
expect(css).not.toContain("html:not(.dark) .library-page .app-page-header .ant-btn");
|
||||
expect(css).not.toContain("html .assets-library-page .app-page-header .assets-header-action-buttons .ant-btn");
|
||||
});
|
||||
});
|
||||
|
||||
29
web/test/assets-collection-layout.test.ts
Normal file
29
web/test/assets-collection-layout.test.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
describe("asset library category sidebar", () => {
|
||||
test("keeps type, business and folder filters in a left-hand nav", () => {
|
||||
const page = readFileSync(resolve(import.meta.dir, "../src/pages/assets/index.tsx"), "utf8");
|
||||
const css = readFileSync(resolve(import.meta.dir, "../src/styles/workspace-product.css"), "utf8");
|
||||
expect(page).toContain('className="assets-collection-layout"');
|
||||
expect(page).toContain('aria-label="素材分类"');
|
||||
expect(page).toContain('title="素材类型"');
|
||||
expect(page).toContain('title="业务分类"');
|
||||
expect(page).toContain("我的分类");
|
||||
expect(page).not.toContain("全部自定义分类");
|
||||
expect(css).toMatch(/\.assets-collection-layout\s*\{[^}]*grid-template-columns:\s*220px minmax\(0, 1fr\)/s);
|
||||
});
|
||||
});
|
||||
|
||||
describe("wallet history pagination", () => {
|
||||
test("pins ledger pagination to the history panel footer", () => {
|
||||
const modal = readFileSync(resolve(import.meta.dir, "../src/components/layout/workspace-wallet-modal.tsx"), "utf8");
|
||||
const css = readFileSync(resolve(import.meta.dir, "../src/styles/globals.css"), "utf8");
|
||||
expect(modal).toContain("workspace-wallet-history-scroll");
|
||||
expect(modal).toContain("workspace-wallet-pagination");
|
||||
expect(modal).not.toContain("wallet.total > 20");
|
||||
expect(css).toMatch(/\.workspace-wallet-content\.is-history\s*\{[^}]*overflow:\s*hidden/s);
|
||||
expect(css).toMatch(/\.workspace-wallet-pagination\s*\{[^}]*margin-top:\s*auto/s);
|
||||
});
|
||||
});
|
||||
23
web/test/settings-preference-spacing.test.ts
Normal file
23
web/test/settings-preference-spacing.test.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
test("settings page drops the page header copy and audio preference blocks", () => {
|
||||
const source = readFileSync(resolve(import.meta.dir, "../src/pages/settings/index.tsx"), "utf8");
|
||||
expect(source).not.toContain("创作偏好");
|
||||
expect(source).not.toContain("配置默认模型、生成参数和素材存储。");
|
||||
expect(source).not.toContain("音频默认值");
|
||||
expect(source).not.toContain("音频指令");
|
||||
expect(source).not.toContain("默认音频指令");
|
||||
expect(source).toContain("默认生图张数");
|
||||
expect(source).toContain("settings-preference-heading");
|
||||
});
|
||||
|
||||
test("wallet tabs and preference blocks keep a visible gap from neighboring surfaces", () => {
|
||||
const css = readFileSync(resolve(import.meta.dir, "../src/styles/globals.css"), "utf8");
|
||||
expect(css).toContain(".workspace-wallet-tabs {");
|
||||
expect(css).toContain("margin: 12px 24px 0;");
|
||||
expect(css).toContain("margin: 16px 24px 24px;");
|
||||
expect(css).toContain(".settings-preference-heading { margin-bottom: var(--space-5); }");
|
||||
expect(css).toContain(".app-user-workspace.settings-page .settings-preference-block {\n padding: 20px 20px 12px;");
|
||||
});
|
||||
@@ -39,7 +39,7 @@ describe("workspace route loading", () => {
|
||||
expect(router).toContain('{ path: "/create", element: <RequireAuth>{deferred(<CreatePage />)}</RequireAuth> }');
|
||||
expect(router).not.toContain('path: "/home"');
|
||||
expect(router).not.toContain("HomePage");
|
||||
expect(navigation).toContain('{ id: "home", title: "首页", icon: Home, to: "/" }');
|
||||
expect(navigation).toContain('{ ...toolItem("create", "/"), id: "home", title: "创作" }');
|
||||
expect(navigation).not.toContain('to: "/create"');
|
||||
expect(navigation).not.toContain('to: "/home"');
|
||||
});
|
||||
@@ -69,6 +69,9 @@ describe("workspace route loading", () => {
|
||||
expect(layout).not.toContain("useCanvasUiStore");
|
||||
expect(layout).not.toContain("CanvasDeleteProjectsDialog");
|
||||
expect(canvas).toContain("deleteDialogOpen ? <Suspense");
|
||||
expect(detail).toContain("project-workspace-header");
|
||||
expect(detail).not.toContain("useWorkspaceTopBarExtension");
|
||||
expect(detail).toContain("新建画布");
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user