diff --git a/frontend/src/shell/NavSessions.tsx b/frontend/src/shell/NavSessions.tsx index 40c18075..ac413d91 100644 --- a/frontend/src/shell/NavSessions.tsx +++ b/frontend/src/shell/NavSessions.tsx @@ -1,5 +1,5 @@ // frontend/src/shell/NavSessions.tsx -import { useQuery } from "@tanstack/react-query"; +import { useQuery, useQueryClient } from "@tanstack/react-query"; import { listSessions } from "../api/sessions"; import { resumeSession } from "../api/sessions"; import type { SessionSummary } from "../api/types"; @@ -10,6 +10,7 @@ interface Props { } export function NavSessions({ activeSessionId, onSessionSelect }: Props) { + const queryClient = useQueryClient(); const { data: sessions = [] } = useQuery({ queryKey: ["sessions"], queryFn: listSessions, @@ -18,6 +19,7 @@ export function NavSessions({ activeSessionId, onSessionSelect }: Props) { async function handleClick(id: string) { await resumeSession(id); + queryClient.invalidateQueries({ queryKey: ["sessions"] }); onSessionSelect(id); } diff --git a/frontend/src/shell/NewSessionDialog.test.tsx b/frontend/src/shell/NewSessionDialog.test.tsx new file mode 100644 index 00000000..161b1f98 --- /dev/null +++ b/frontend/src/shell/NewSessionDialog.test.tsx @@ -0,0 +1,82 @@ +// 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 { NewSessionDialog } from "./NewSessionDialog"; + +function renderDialog() { + const onCreated = vi.fn(); + const client = new QueryClient({ defaultOptions: { queries: { retry: false } } }); + render( + + + , + ); + return { onCreated }; +} + +beforeEach(() => { + server.use( + http.get("http://localhost:8787/workspaces", () => + HttpResponse.json([{ name: "default", file: "default.db" }]), + ), + http.post("http://localhost:8787/sessions", () => + HttpResponse.json({ id: "s1" }), + ), + ); +}); + +test("§9 degradation: empty models -> model field is a FREE-TEXT input, not a select", async () => { + server.use( + http.get("http://localhost:8787/models", () => HttpResponse.json({ models: [] })), + ); + renderDialog(); + await userEvent.click(screen.getByRole("button", { name: /nuova/i })); + + // Free-text model input present; no model dropdown. + const freetext = await screen.findByTestId("model-freetext"); + expect(freetext.tagName).toBe("INPUT"); + // The only