refactor: remove legacy workspace UI state
This commit is contained in:
@@ -2,7 +2,7 @@ import { expect, test } from "vitest";
|
||||
import { http, HttpResponse } from "msw";
|
||||
import { server } from "../test/msw";
|
||||
import {
|
||||
asWorkspaceConflict, getWorkspace, importWorkspace, publishWorkspace, validateWorkspace,
|
||||
asWorkspaceConflict, getWorkspace, importWorkspace, listWorkspaces, publishWorkspace, validateWorkspace,
|
||||
type CanonicalWorkspace,
|
||||
} from "./workspaces";
|
||||
|
||||
@@ -34,9 +34,74 @@ const revision = {
|
||||
commit: "a".repeat(40),
|
||||
blob: "b".repeat(40),
|
||||
snapshotPath: "workspaces/psd-clinical.yaml",
|
||||
state: "operational" as const,
|
||||
};
|
||||
|
||||
const summary = {
|
||||
id: "psd-clinical",
|
||||
name: "psd-clinical",
|
||||
file: "psd-clinical.yaml",
|
||||
displayName: "PSD Clinical",
|
||||
description: "Clinical workspace",
|
||||
language: "en" as const,
|
||||
revision,
|
||||
};
|
||||
|
||||
test("decodes and normalizes state-free workspace summaries without passing through backend-only fields", async () => {
|
||||
server.use(http.get("/api/workspaces", () => HttpResponse.json([{
|
||||
...summary, workspace, backendOnly: "ignored",
|
||||
}])));
|
||||
|
||||
await expect(listWorkspaces()).resolves.toEqual([summary]);
|
||||
});
|
||||
|
||||
test("accepts internally multiline display names and descriptions using backend trim semantics", async () => {
|
||||
const multiline = {
|
||||
...summary,
|
||||
displayName: "PSD\nClinical",
|
||||
description: "First line\n\tSecond line",
|
||||
};
|
||||
server.use(http.get("/api/workspaces", () => HttpResponse.json([multiline])));
|
||||
|
||||
await expect(listWorkspaces()).resolves.toEqual([multiline]);
|
||||
});
|
||||
|
||||
test.each([
|
||||
["an id/name alias", { ...summary, name: "other-workspace" }],
|
||||
["a non-canonical selector file", { ...summary, file: "workspaces/psd-clinical.yaml" }],
|
||||
])("rejects workspace summaries with %s", async (_case, malformedSummary) => {
|
||||
server.use(http.get("/api/workspaces", () => HttpResponse.json([malformedSummary])));
|
||||
|
||||
await expect(listWorkspaces()).rejects.toThrow("invalid workspace summary");
|
||||
});
|
||||
|
||||
test.each([
|
||||
["historical state", { ...revision, state: "operational" }],
|
||||
["unknown revision field", { ...revision, generation: 1 }],
|
||||
["malformed revision", { ...revision, commit: "not-a-commit" }],
|
||||
])("rejects workspace summaries with %s", async (_case, malformedRevision) => {
|
||||
server.use(http.get("/api/workspaces", () => HttpResponse.json([{
|
||||
...summary, revision: malformedRevision,
|
||||
}])));
|
||||
|
||||
await expect(listWorkspaces()).rejects.toThrow("invalid workspace summary");
|
||||
});
|
||||
|
||||
test.each([
|
||||
["a non-array response", { ...summary }],
|
||||
["a malformed selector field", [{ ...summary, language: "fr" }]],
|
||||
])("rejects %s from the workspace summary API", async (_case, response) => {
|
||||
server.use(http.get("/api/workspaces", () => HttpResponse.json(response)));
|
||||
|
||||
await expect(listWorkspaces()).rejects.toThrow("invalid workspace summary");
|
||||
});
|
||||
|
||||
test("preserves a present summary without revision so callers can distinguish it from an absent workspace", async () => {
|
||||
const { revision: _revision, ...incomplete } = summary;
|
||||
server.use(http.get("/api/workspaces", () => HttpResponse.json([incomplete])));
|
||||
|
||||
await expect(listWorkspaces()).resolves.toEqual([incomplete]);
|
||||
});
|
||||
|
||||
test("uploads a workspace bundle without JSON content type", async () => {
|
||||
let contentType: string | null = null;
|
||||
server.use(http.post("/api/workspaces/import", ({ request }) => {
|
||||
@@ -76,6 +141,35 @@ test("rejects imported Evidence with a secret-shaped field", async () => {
|
||||
.rejects.toThrow("invalid imported workspace draft");
|
||||
});
|
||||
|
||||
test("accepts the atomic schema-v3 workspace revision contract without historical state", async () => {
|
||||
const stateFreeRevision = {
|
||||
id: "psd-clinical",
|
||||
commit: "a".repeat(40),
|
||||
blob: "b".repeat(40),
|
||||
snapshotPath: "workspaces/psd-clinical.yaml",
|
||||
};
|
||||
server.use(http.get("/api/workspaces/psd-clinical", () => HttpResponse.json({
|
||||
workspace, revision: stateFreeRevision,
|
||||
})));
|
||||
|
||||
await expect(getWorkspace("psd-clinical")).resolves.toEqual({ workspace, revision: stateFreeRevision });
|
||||
});
|
||||
|
||||
test("rejects the removed historical workspace revision state as an extra API key", async () => {
|
||||
server.use(http.get("/api/workspaces/psd-clinical", () => HttpResponse.json({
|
||||
workspace,
|
||||
revision: {
|
||||
id: "psd-clinical",
|
||||
commit: "a".repeat(40),
|
||||
blob: "b".repeat(40),
|
||||
snapshotPath: "workspaces/psd-clinical.yaml",
|
||||
state: "operational",
|
||||
},
|
||||
})));
|
||||
|
||||
await expect(getWorkspace("psd-clinical")).rejects.toThrow("invalid workspace revision");
|
||||
});
|
||||
|
||||
test("rejects read responses with a missing or inconsistent revision", async () => {
|
||||
server.use(http.get("/api/workspaces/psd-clinical", () => HttpResponse.json({
|
||||
workspace: evidenceWorkspace,
|
||||
|
||||
Reference in New Issue
Block a user