diff --git a/frontend/src/api/sessions.test.ts b/frontend/src/api/sessions.test.ts index e7a8610a..60a20c78 100644 --- a/frontend/src/api/sessions.test.ts +++ b/frontend/src/api/sessions.test.ts @@ -1,5 +1,6 @@ import { http, HttpResponse } from "msw"; import { server } from "../test/msw"; +import { canonicalWorkspaceFixture } from "../test/workspace-fixtures"; import { createSession, getMe, listSessions, prewarmRuntime, resumeSession } from "./sessions"; import { renameSession, setSessionGroup, archiveSession, unarchiveSession, @@ -18,7 +19,7 @@ test("createSession migrates legacy selections and POSTs browser preferences", a revision: { id: "psd-clinical", commit: "a".repeat(40), blob: "b".repeat(40), snapshotPath: "/snapshot", state: "operational" }, }])), http.get("/api/workspaces/psd-clinical", () => HttpResponse.json({ - workspace: { llm_policy: { allowed: ["zai/glm-5.2"] } }, + workspace: canonicalWorkspaceFixture("psd-clinical"), revision: { id: "psd-clinical", commit: "a".repeat(40), blob: "b".repeat(40), snapshotPath: "/snapshot", state: "operational" }, })), http.post("/api/sessions", async ({ request }) => { diff --git a/frontend/src/shell/NewSessionDialog.test.tsx b/frontend/src/shell/NewSessionDialog.test.tsx index 0f4afb00..8b7dd617 100644 --- a/frontend/src/shell/NewSessionDialog.test.tsx +++ b/frontend/src/shell/NewSessionDialog.test.tsx @@ -4,6 +4,7 @@ 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 } from "../test/workspace-fixtures"; import { NewSessionDialog } from "./NewSessionDialog"; function renderDialog() { @@ -39,7 +40,8 @@ test("submitting includes browser-local migrated preferences and calls onCreated revision: { state: "operational" }, }])), http.get("/api/workspaces/default", () => HttpResponse.json({ - workspace: { llm_policy: { default: "zai/glm-5.2", allowed: ["zai/glm-5.2"] } }, + workspace: canonicalWorkspaceFixture("default", ["zai/glm-5.2"], "zai/glm-5.2"), + revision: workspaceRevisionFixture("default"), })), http.post("/api/sessions", async ({ request }) => { body = await request.json(); @@ -82,7 +84,7 @@ test("first-run direct dialog creation waits for registry policy without a mount policyRequestStarted = true; await policyMayFinish; return HttpResponse.json({ - workspace: { llm_policy: { default: "zai/glm-5.2", allowed: ["zai/glm-5.2"] } }, revision, + workspace: canonicalWorkspaceFixture("psd-clinical", ["zai/glm-5.2"], "zai/glm-5.2"), revision, }); }), http.post("/api/sessions", async ({ request }) => { diff --git a/frontend/src/shell/SteerInput.test.tsx b/frontend/src/shell/SteerInput.test.tsx index 099ec063..f7ad4d0e 100644 --- a/frontend/src/shell/SteerInput.test.tsx +++ b/frontend/src/shell/SteerInput.test.tsx @@ -4,6 +4,7 @@ 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 } from "../test/workspace-fixtures"; import { useSessionStore } from "../store/sessionStore"; import { ComposerFooter, ContextGauge, SteerInput } from "./SteerInput"; @@ -27,7 +28,7 @@ test("new sessions send the browser-selected workspace, model, provider, and thi revision: { id: "psd-clinical", commit: "a".repeat(40), blob: "b".repeat(40), snapshotPath: "/snapshot", state: "operational" }, }])), http.get("/api/workspaces/psd-clinical", () => HttpResponse.json({ - workspace: { llm_policy: { allowed: ["zai/glm-5.2"] } }, + workspace: canonicalWorkspaceFixture("psd-clinical"), revision: { id: "psd-clinical", commit: "a".repeat(40), blob: "b".repeat(40), snapshotPath: "/snapshot", state: "operational" }, })), http.post("/api/sessions", async ({ request }) => { @@ -136,7 +137,7 @@ test("footer shows cumulative k-token counters after workspace and context gauge })), http.get("/api/workspaces", () => HttpResponse.json([{ name: "psd" }])), http.get("/api/workspaces/psd", () => HttpResponse.json({ - workspace: { llm_policy: { allowed: ["zai/glm-5.2"] } }, + workspace: canonicalWorkspaceFixture("psd"), revision: { id: "psd", commit: "a".repeat(40), blob: "b".repeat(40), snapshotPath: "/snapshot", state: "operational" }, })), http.get("/api/models", () => HttpResponse.json({ @@ -175,7 +176,7 @@ test("footer limits model choices to the selected workspace policy", async () => revision: { id: "psd-clinical", commit: "a".repeat(40), blob: "b".repeat(40), snapshotPath: "/snapshot", state: "operational" }, }])), http.get("/api/workspaces/psd-clinical", () => HttpResponse.json({ - workspace: { llm_policy: { allowed: ["zai/glm-5.2"] } }, + workspace: canonicalWorkspaceFixture("psd-clinical"), revision: { id: "psd-clinical", commit: "a".repeat(40), blob: "b".repeat(40), snapshotPath: "/snapshot", state: "operational" }, })), http.get("/api/models", () => HttpResponse.json({ models: [ @@ -208,11 +209,11 @@ test("switching workspaces replaces an out-of-policy model before session creati { id: "psd-clinical", name: "psd-clinical", file: "psd-clinical.yaml", displayName: "PSD Clinical", revision: revision("psd-clinical") }, ])), http.get("/api/workspaces/research", () => HttpResponse.json({ - workspace: { workspace: { id: "research" }, llm_policy: { allowed: ["deepseek/deepseek-v4-pro"] } }, + workspace: canonicalWorkspaceFixture("research", ["deepseek/deepseek-v4-pro"]), revision: revision("research"), })), http.get("/api/workspaces/psd-clinical", () => HttpResponse.json({ - workspace: { workspace: { id: "psd-clinical" }, llm_policy: { default: "zai/glm-5.2", allowed: ["zai/glm-5.2"] } }, + workspace: canonicalWorkspaceFixture("psd-clinical", ["zai/glm-5.2"], "zai/glm-5.2"), revision: revision("psd-clinical"), })), http.get("/api/models", () => HttpResponse.json({ models: [ @@ -259,13 +260,13 @@ test("immediate submit waits for a switched workspace policy before creating a s { id: "psd-clinical", name: "psd-clinical", file: "psd-clinical.yaml", displayName: "PSD Clinical", revision: revision("psd-clinical") }, ])), http.get("/api/workspaces/research", () => HttpResponse.json({ - workspace: { llm_policy: { allowed: ["deepseek/deepseek-v4-pro"] } }, revision: revision("research"), + workspace: canonicalWorkspaceFixture("research", ["deepseek/deepseek-v4-pro"]), revision: revision("research"), })), http.get("/api/workspaces/psd-clinical", async () => { policyRequestStarted = true; await policyMayFinish; return HttpResponse.json({ - workspace: { llm_policy: { default: "zai/glm-5.2", allowed: ["zai/glm-5.2"] } }, + workspace: canonicalWorkspaceFixture("psd-clinical", ["zai/glm-5.2"], "zai/glm-5.2"), revision: revision("psd-clinical"), }); }), @@ -317,7 +318,7 @@ test("initial restored workspace waits for its delayed policy before creating a policyRequestStarted = true; await policyMayFinish; return HttpResponse.json({ - workspace: { llm_policy: { default: "zai/glm-5.2", allowed: ["zai/glm-5.2"] } }, + workspace: canonicalWorkspaceFixture("psd-clinical", ["zai/glm-5.2"], "zai/glm-5.2"), revision: revision("psd-clinical"), }); }), @@ -476,7 +477,7 @@ test("submit follows a rapid workspace switch instead of waiting for an abandone { id: "workspace-c", name: "workspace-c", file: "workspace-c.yaml", displayName: "Workspace C", revision: revision("workspace-c") }, ])), http.get("/api/workspaces/research", () => HttpResponse.json({ - workspace: { llm_policy: { allowed: ["deepseek/deepseek-v4-pro"] } }, revision: revision("research"), + workspace: canonicalWorkspaceFixture("research", ["deepseek/deepseek-v4-pro"]), revision: revision("research"), })), http.get("/api/workspaces/workspace-b", async () => { bPolicyRequestStarted = true; @@ -487,7 +488,7 @@ test("submit follows a rapid workspace switch instead of waiting for an abandone cPolicyRequestStarted = true; await cPolicyMayFinish; return HttpResponse.json({ - workspace: { llm_policy: { default: "zai/glm-5.2", allowed: ["zai/glm-5.2"] } }, + workspace: canonicalWorkspaceFixture("workspace-c", ["zai/glm-5.2"], "zai/glm-5.2"), revision: revision("workspace-c"), }); }), diff --git a/frontend/src/test/workspace-fixtures.ts b/frontend/src/test/workspace-fixtures.ts new file mode 100644 index 00000000..cc6f9ecd --- /dev/null +++ b/frontend/src/test/workspace-fixtures.ts @@ -0,0 +1,34 @@ +import type { CanonicalWorkspace, WorkspaceRevision } from "../api/workspaces"; + +export function canonicalWorkspaceFixture( + id: string, + allowed: `${string}/${string}`[] = ["zai/glm-5.2"], + defaultModel?: `${string}/${string}`, +): CanonicalWorkspace { + return { + workspace: { schema_version: 3, id, name: id, language: "en" }, + dwh: { + engine: "postgres", database: "database", schema: "public", + supported_transports: ["postgres_direct"], + }, + semantic_index: { + vector_store: { + engine: "qdrant", collection: id.replaceAll("-", "_"), dimensions: 1024, distance: "cosine", + }, + embedding: { + provider: "ollama_internal", model: "qwen3-embedding:0.6b", dimensions: 1024, + }, + }, + llm_policy: { ...(defaultModel ? { default: defaultModel } : {}), allowed }, + }; +} + +export function workspaceRevisionFixture( + id: string, + state: WorkspaceRevision["state"] = "operational", +): WorkspaceRevision { + return { + id, commit: "a".repeat(40), blob: "b".repeat(40), + snapshotPath: `/snapshots/${"a".repeat(40)}/${id}.yaml`, state, + }; +}