Files
ThothII/frontend/src/api/workspaces.test.ts
T

101 lines
3.5 KiB
TypeScript

import { expect, test } from "vitest";
import { http, HttpResponse } from "msw";
import { server } from "../test/msw";
import { canonicalWorkspaceFixture, workspaceRevisionFixture, workspaceSummaryFixture } from "../test/workspace-fixtures";
import {
forgetWorkspaceSecret,
getWorkspace,
getWorkspaceRuntimeConfiguration,
listWorkspaces,
saveWorkspaceSecrets,
} from "./workspaces";
const workspace = canonicalWorkspaceFixture("psd-clinical");
const revision = workspaceRevisionFixture("psd-clinical");
const runtimeConfiguration = {
workspaceId: "psd-clinical",
revision,
configurationState: "configuration_required",
requirements: [{
id: "dwh.password",
connector: "dwh",
label: "Data warehouse password",
description: "Password used by the selected data warehouse connection.",
input: "password",
required: true,
configured: false,
}],
} as const;
test("decodes read-only workspace summaries with a revision in every readiness state", async () => {
const ready = workspaceSummaryFixture("psd-clinical", {
displayName: "PSD Clinical",
revision,
});
const needsSecrets = {
...ready,
configurationState: "configuration_required" as const,
};
server.use(http.get("/api/workspaces", () => HttpResponse.json([ready, needsSecrets])));
await expect(listWorkspaces()).resolves.toEqual([ready, needsSecrets]);
});
test("accepts the immutable workspace revision contract", async () => {
server.use(http.get("/api/workspaces/psd-clinical", () => HttpResponse.json({ workspace, revision })));
await expect(getWorkspace("psd-clinical")).resolves.toEqual({ workspace, revision });
});
test("decodes runtime requirements but rejects any secret value returned by the server", async () => {
server.use(http.get(
"/api/workspaces/psd-clinical/runtime-configuration",
() => HttpResponse.json(runtimeConfiguration),
));
await expect(getWorkspaceRuntimeConfiguration("psd-clinical"))
.resolves.toEqual(runtimeConfiguration);
server.use(http.get(
"/api/workspaces/psd-clinical/runtime-configuration",
() => HttpResponse.json({
...runtimeConfiguration,
requirements: [{ ...runtimeConfiguration.requirements[0], value: "leaked-secret" }],
}),
));
await expect(getWorkspaceRuntimeConfiguration("psd-clinical"))
.rejects.toThrow("invalid runtime configuration");
});
test("blind secret replacement sends values once and returns status only", async () => {
let requestBody: unknown;
server.use(http.put("/api/workspaces/psd-clinical/secrets", async ({ request }) => {
requestBody = await request.json();
return HttpResponse.json({
...runtimeConfiguration,
configurationState: "ready",
requirements: [{ ...runtimeConfiguration.requirements[0], configured: true }],
});
}));
const response = await saveWorkspaceSecrets("psd-clinical", {
"dwh.password": "one-time-value",
});
expect(requestBody).toEqual({ values: { "dwh.password": "one-time-value" } });
expect(response.configurationState).toBe("ready");
expect(JSON.stringify(response)).not.toContain("one-time-value");
});
test("forget targets one declared requirement", async () => {
let called = false;
server.use(http.delete("/api/workspaces/psd-clinical/secrets/dwh.password", () => {
called = true;
return HttpResponse.json(runtimeConfiguration);
}));
await expect(forgetWorkspaceSecret("psd-clinical", "dwh.password"))
.resolves.toEqual(runtimeConfiguration);
expect(called).toBe(true);
});