import { describe, expect, test } from "bun:test"; import { screen, waitFor } from "@testing-library/react"; import { createElement } from "react"; import { App } from "../../../src/web/app"; import { renderWithProviders } from "../test-utils"; const MOCK_PROJECT = { createdAt: "2024-01-01T00:00:00.000Z", description: "测试项目", id: "test-project-id", name: "测试项目", status: "active" as const, updatedAt: "2024-01-01T00:00:00.000Z", }; function createMockHandler(overrides?: { status?: "active" | "archived" }) { const project = { ...MOCK_PROJECT, ...overrides }; const handler = (input: RequestInfo | URL) => { const url = input instanceof Request ? input.url : typeof input === "string" ? input : input.toString(); if (url.includes("/api/settings")) { return new Response(JSON.stringify({ theme: "system" }), { headers: { "Content-Type": "application/json" }, status: 200, }); } if (url.includes("/api/meta")) { return new Response( JSON.stringify({ ok: true, service: "test-app", timestamp: new Date().toISOString(), version: "0.1.0" }), { headers: { "Content-Type": "application/json" }, status: 200 }, ); } if (url.includes(`/api/projects/${project.id}`)) { return new Response(JSON.stringify({ project }), { headers: { "Content-Type": "application/json" }, status: 200, }); } if (url.includes("/api/projects/") && url.includes("/conversations")) { return new Response(JSON.stringify({ items: [], page: 1, pageSize: 100, total: 0 }), { headers: { "Content-Type": "application/json" }, status: 200, }); } return new Response(JSON.stringify({ error: "Not Found" }), { status: 404 }); }; const mocked = ((input: RequestInfo | URL, _init?: RequestInit) => Promise.resolve(handler(input))) as unknown as typeof fetch; globalThis.fetch = mocked; window.fetch = mocked; } describe("Workbench 路由", () => { test("active 项目可进入 Workbench", async () => { createMockHandler(); renderWithProviders(createElement(App), { initialRoute: `/workbench/${MOCK_PROJECT.id}`, }); await waitFor( () => { const body = document.body.textContent ?? ""; expect(body).toContain("工作台"); }, { timeout: 10000 }, ); }); test("Workbench 显示返回管理台按钮", async () => { createMockHandler(); renderWithProviders(createElement(App), { initialRoute: `/workbench/${MOCK_PROJECT.id}`, }); await screen.findByText("返回管理台", {}, { timeout: 10000 }); }); test("不存在项目显示不可访问", async () => { createMockHandler(); renderWithProviders(createElement(App), { initialRoute: "/workbench/nonexistent-id", }); await screen.findByText("项目不存在或不可访问", {}, { timeout: 10000 }); }); test("archived 项目显示不可访问", async () => { createMockHandler({ status: "archived" }); renderWithProviders(createElement(App), { initialRoute: `/workbench/${MOCK_PROJECT.id}`, }); await screen.findByText("项目不存在或不可访问", {}, { timeout: 10000 }); }); test("Workbench 显示聊天室菜单", async () => { createMockHandler(); renderWithProviders(createElement(App), { initialRoute: `/workbench/${MOCK_PROJECT.id}`, }); await screen.findByText("聊天室", {}, { timeout: 10000 }); }); test("Workbench 收集箱路由可达", async () => { createMockHandler(); renderWithProviders(createElement(App), { initialRoute: `/workbench/${MOCK_PROJECT.id}/inbox`, }); await screen.findByText("新增素材", {}, { timeout: 10000 }); }); test("Workbench 显示收集箱菜单", async () => { createMockHandler(); renderWithProviders(createElement(App), { initialRoute: `/workbench/${MOCK_PROJECT.id}`, }); await screen.findByText("收集箱", {}, { timeout: 10000 }); }); });