import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { fireEvent, render, screen, waitFor, within, } from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { SessionManagerPage } from "@/components/sessions/SessionManagerPage"; import type { SessionMessage, SessionMeta } from "@/types"; import { setSessionFixtures } from "../msw/state"; const toastSuccessMock = vi.fn(); const toastErrorMock = vi.fn(); vi.mock("sonner", () => ({ toast: { success: (...args: unknown[]) => toastSuccessMock(...args), error: (...args: unknown[]) => toastErrorMock(...args), }, })); vi.mock("@/components/sessions/SessionToc", () => ({ SessionTocSidebar: () => null, SessionTocDialog: () => null, })); vi.mock("@/components/ConfirmDialog", () => ({ ConfirmDialog: ({ isOpen, title, message, confirmText, cancelText, onConfirm, onCancel, }: { isOpen: boolean; title: string; message: string; confirmText: string; cancelText: string; onConfirm: () => void; onCancel: () => void; }) => isOpen ? (
{title}
{message}
) : null, })); const renderPage = () => { const client = new QueryClient({ defaultOptions: { queries: { retry: false }, mutations: { retry: false }, }, }); return render( , ); }; describe("SessionManagerPage", () => { beforeEach(() => { toastSuccessMock.mockReset(); toastErrorMock.mockReset(); const sessions: SessionMeta[] = [ { providerId: "codex", sessionId: "codex-session-1", title: "Alpha Session", summary: "Alpha summary", projectDir: "/mock/codex", createdAt: 2, lastActiveAt: 20, sourcePath: "/mock/codex/session-1.jsonl", resumeCommand: "codex resume codex-session-1", }, { providerId: "codex", sessionId: "codex-session-2", title: "Beta Session", summary: "Beta summary", projectDir: "/mock/codex", createdAt: 1, lastActiveAt: 10, sourcePath: "/mock/codex/session-2.jsonl", resumeCommand: "codex resume codex-session-2", }, ]; const messages: Record = { "codex:/mock/codex/session-1.jsonl": [ { role: "user", content: "alpha", ts: 20 }, ], "codex:/mock/codex/session-2.jsonl": [ { role: "user", content: "beta", ts: 10 }, ], }; setSessionFixtures(sessions, messages); }); it("deletes the selected session and selects the next visible session", async () => { renderPage(); await waitFor(() => expect( screen.getByRole("heading", { name: "Alpha Session" }), ).toBeInTheDocument(), ); fireEvent.click(screen.getByRole("button", { name: /删除会话/i })); const dialog = screen.getByTestId("confirm-dialog"); expect(dialog).toBeInTheDocument(); expect(within(dialog).getByText(/Alpha Session/)).toBeInTheDocument(); fireEvent.click(within(dialog).getByRole("button", { name: /删除会话/i })); await waitFor(() => expect( screen.getByRole("heading", { name: "Beta Session" }), ).toBeInTheDocument(), ); expect(screen.queryByText("Alpha Session")).not.toBeInTheDocument(); expect(toastErrorMock).not.toHaveBeenCalled(); expect(toastSuccessMock).toHaveBeenCalled(); }); });