// frontend/src/shell/NewSessionDialog.test.tsx import { render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { http, HttpResponse } from "msw"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { server } from "../test/msw"; import { canonicalWorkspaceFixture, workspaceRevisionFixture, workspaceSummaryFixture } from "../test/workspace-fixtures"; import { NewSessionDialog } from "./NewSessionDialog"; import { workspacePreferences } from "../workspaces/preferences"; function renderDialog() { const onCreated = vi.fn(); const client = new QueryClient({ defaultOptions: { queries: { retry: false } } }); render( , ); return { onCreated }; } test("the form has only a question field (no workspace/model/provider/thinking)", async () => { renderDialog(); await userEvent.click(screen.getByRole("button", { name: /new/i })); expect(await screen.findByLabelText(/question/i)).toBeInTheDocument(); expect(screen.queryByLabelText(/workspace/i)).not.toBeInTheDocument(); expect(screen.queryByLabelText(/model/i)).not.toBeInTheDocument(); expect(screen.queryByLabelText(/provider/i)).not.toBeInTheDocument(); expect(screen.queryByLabelText(/thinking/i)).not.toBeInTheDocument(); }); test("submitting includes ephemeral migrated preferences and calls onCreated", async () => { localStorage.clear(); let body: unknown = null; server.use( http.get("/api/settings", () => HttpResponse.json({ workspace: "default", provider: "zai", model: "glm-5.2", thinking: "low", })), http.get("/api/workspaces", () => HttpResponse.json([{ ...workspaceSummaryFixture("default", { displayName: "Default", revision: workspaceRevisionFixture("default"), }), }])), http.get("/api/workspaces/default", () => HttpResponse.json({ workspace: canonicalWorkspaceFixture("default", ["zai/glm-5.2"], "zai/glm-5.2"), revision: workspaceRevisionFixture("default"), })), http.post("/api/sessions", async ({ request }) => { body = await request.json(); return HttpResponse.json({ id: "s1" }); }), ); const { onCreated } = renderDialog(); await userEvent.click(screen.getByRole("button", { name: /new/i })); await userEvent.type(await screen.findByLabelText(/question/i), "Quante vendite nel 2025?"); await userEvent.click(screen.getByRole("button", { name: /^create$/i })); await waitFor(() => expect(body).toEqual({ question: "Quante vendite nel 2025?", workspaceId: "default", provider: "zai", model: "glm-5.2", thinking: "low", })); await waitFor(() => expect(onCreated).toHaveBeenCalledWith("s1")); }); test("first-run direct dialog creation waits for registry policy without a mounted footer", async () => { let body: unknown; let releasePolicy!: () => void; let summaryRequestStarted = false; let policyRequestStarted = false; const policyMayFinish = new Promise((resolve) => { releasePolicy = resolve; }); const revision = { id: "psd-clinical", commit: "a".repeat(40), blob: "b".repeat(40), snapshotPath: "/snapshot", }; workspacePreferences.save({ workspaceId: "psd-clinical", provider: "deepseek", model: "deepseek-v4-pro", thinking: "medium", }); server.use( http.get("/api/workspaces", () => { summaryRequestStarted = true; return HttpResponse.json([{ ...workspaceSummaryFixture("psd-clinical", { displayName: "PSD Clinical", revision: revision as any }), }]); }), http.get("/api/workspaces/psd-clinical", async () => { policyRequestStarted = true; await policyMayFinish; return HttpResponse.json({ workspace: canonicalWorkspaceFixture("psd-clinical", ["zai/glm-5.2"], "zai/glm-5.2"), revision, }); }), http.post("/api/sessions", async ({ request }) => { body = await request.json(); return HttpResponse.json({ id: "s1" }); }), ); const { onCreated } = renderDialog(); await userEvent.click(screen.getByRole("button", { name: /new/i })); await userEvent.type(await screen.findByLabelText(/question/i), "q"); await userEvent.click(screen.getByRole("button", { name: /^create$/i })); await waitFor(() => expect(summaryRequestStarted).toBe(true)); await waitFor(() => expect(policyRequestStarted).toBe(true)); expect(body).toBeUndefined(); expect(screen.getByRole("button", { name: /creating/i })).toBeDisabled(); releasePolicy(); await waitFor(() => expect(body).toEqual({ question: "q", workspaceId: "psd-clinical", provider: "zai", model: "glm-5.2", thinking: "medium", })); await waitFor(() => expect(onCreated).toHaveBeenCalledWith("s1")); }); test("empty question shows a validation error and does not submit", async () => { renderDialog(); await userEvent.click(screen.getByRole("button", { name: /new/i })); await userEvent.click(screen.getByRole("button", { name: /^create$/i })); expect(await screen.findByRole("alert")).toHaveTextContent(/empty/i); });