import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { cleanup, render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import type { ReactNode } from "react"; import { MemoryRouter, Route, Routes } from "react-router-dom"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; vi.mock("./lib/api", () => ({ clearPlatformSession: vi.fn(), confirmTask: vi.fn(), createTask: vi.fn(), deleteTask: vi.fn(), getHistoryTasks: vi.fn(), getPlatformReadiness: vi.fn(), getPlatformSession: vi.fn(), getTask: vi.fn(), getTaskCandidates: vi.fn(), getTaskReport: vi.fn(), preparePlatform: vi.fn(), retryTaskPlatform: vi.fn() })); import { NewTaskPage, SessionPreparePage } from "./App"; import { clearPlatformSession, getHistoryTasks, getPlatformReadiness, getPlatformSession, preparePlatform } from "./lib/api"; function renderWithProviders(node: ReactNode, initialEntries?: string[]) { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } }); return render( {initialEntries ? ( {node} ) : ( {node} )} ); } describe("task composer and session console", () => { beforeEach(() => { vi.mocked(getPlatformReadiness).mockResolvedValue({ platforms: [ { platform: "tmall", ready: true, status: "ready", searchRequirement: "recommended", reason: "当前工作区存在可复用会话,创建任务时会再次校验。", lastPreparedAt: "2026-04-02T12:00:00.000Z", expiresAt: "2026-04-03T12:00:00.000Z" }, { platform: "jd", ready: false, status: "missing", searchRequirement: "required", reason: "需要先完成会话准备,否则系统会标记为 SearchBlocked。" } ] } as any); vi.mocked(getHistoryTasks).mockResolvedValue({ tasks: [ { taskId: "task-1", query: "Nintendo Switch 2", taskStatus: "Completed", updatedAt: "2026-04-02T12:00:00.000Z", hasReport: true, defaultReportVersion: 2, failedPlatforms: [], blockedPlatforms: [] }, { taskId: "task-2", query: "DJI Pocket 3", taskStatus: "AwaitingConfirmation", updatedAt: "2026-04-02T11:30:00.000Z", hasReport: false, failedPlatforms: [], blockedPlatforms: ["jd"] } ] } as any); vi.mocked(getPlatformSession).mockResolvedValue({ session: { platform: "jd", ready: true, status: "ready", searchRequirement: "required", scope: "workspace", ttlHours: 24, lastPreparedAt: "2026-04-02T10:00:00.000Z", expiresAt: "2026-04-03T10:00:00.000Z", encryptedSnapshotAvailable: true, cipherLabel: "mock-aes-gcm-v1" } } as any); vi.mocked(clearPlatformSession).mockResolvedValue(undefined); vi.mocked(preparePlatform).mockResolvedValue({ platform: "jd", session_ready: true, status: "ready", last_prepared_at: "2026-04-02T10:00:00.000Z", expires_at: "2026-04-03T10:00:00.000Z", encrypted_snapshot_available: true } as any); }); afterEach(() => { cleanup(); vi.clearAllMocks(); }); it("shows readiness details and recent task shortcuts on the new task page", async () => { renderWithProviders(); expect(await screen.findByText("最近任务捷径")).toBeInTheDocument(); expect(await screen.findByText("Nintendo Switch 2")).toBeInTheDocument(); expect(await screen.findByText("DJI Pocket 3")).toBeInTheDocument(); expect(await screen.findByText("搜索要求:建议预热")).toBeInTheDocument(); expect( await screen.findByText(/当前工作区已有可复用会话,有效至/) ).toBeInTheDocument(); }); it("shows session details and allows clearing the current session", async () => { const user = userEvent.setup(); renderWithProviders( } path="/sessions/:platform/prepare" /> , ["/sessions/jd/prepare?from=/tasks/new"] ); expect(await screen.findByText("已加密保存")).toBeInTheDocument(); expect(screen.getByText(/完成后将返回:\/tasks\/new/)).toBeInTheDocument(); await user.click(screen.getByRole("button", { name: "清理当前会话" })); await waitFor(() => { expect(clearPlatformSession).toHaveBeenCalledWith("jd"); }); }); });