diff --git a/frontend/src/shell/AppShell.new-session.test.tsx b/frontend/src/shell/AppShell.new-session.test.tsx index d660b8a2..2ec69026 100644 --- a/frontend/src/shell/AppShell.new-session.test.tsx +++ b/frontend/src/shell/AppShell.new-session.test.tsx @@ -1,4 +1,4 @@ -import { render, screen, waitFor } from "@testing-library/react"; +import { render, screen, waitFor, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { http, HttpResponse, delay } from "msw"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; @@ -90,6 +90,37 @@ test("a failed create restores the landing view and preserves the question for r expect(FakeEventSource.instances).toHaveLength(0); }); +test("model selector shows the three Pi-enabled models and persists the selected provider", async () => { + let saved: unknown; + server.use( + http.get("http://localhost:8787/settings", () => HttpResponse.json({ + workspace: "default", provider: "zai", model: "glm-5.2", thinking: "low", + })), + http.get("http://localhost:8787/models", () => HttpResponse.json({ models: [ + { provider: "zai", id: "glm-5.2", name: "GLM-5.2", reasoning: true }, + { provider: "deepseek", id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", reasoning: true }, + { provider: "local-qwen", id: "qwen3.6-35b-a3b", name: "Qwen3.6 35B A3B Local", reasoning: false }, + ] })), + http.put("http://localhost:8787/settings", async ({ request }) => { + const body = await request.json() as Record; + saved = body; + return HttpResponse.json(body); + }), + ); + renderShell(); + + const select = await screen.findByRole("combobox", { name: "Model" }); + await waitFor(() => { + expect(within(select).getAllByRole("option").map((option) => option.textContent)).toEqual([ + "GLM-5.2", "DeepSeek V4 Flash", "Qwen3.6 35B A3B Local", + ]); + }); + await userEvent.selectOptions(select, "qwen3.6-35b-a3b"); + await waitFor(() => expect(saved).toMatchObject({ + provider: "local-qwen", model: "qwen3.6-35b-a3b", + })); +}); + test("marks the composer as awaiting input for a pending freetext gate", () => { useSessionStore.setState({