import assert from "node:assert/strict"; import { test } from "vitest"; import { STUDIO_ERROR_CODES, toStudioGatewayError, } from "../../../src/features/tech-log/adapters/http/studio-error-mapping.ts"; import { createCsrfTokenProvider } from "../../../src/features/tech-log/adapters/http/studio-session-csrf.ts"; import { isStudioGatewayError } from "../../../src/features/tech-log/application/ports/studio-gateway-error.ts"; test("covers every canonical error code exactly once", () => { assert.equal(STUDIO_ERROR_CODES.length, 23); assert.equal(new Set(STUDIO_ERROR_CODES).size, 23); for (const code of ["IDEMPOTENCY_KEY_REUSED", "WARNING_ACKNOWLEDGEMENT_REQUIRED", "ASSET_QUARANTINED"]) { assert.ok(STUDIO_ERROR_CODES.includes(code as never), `${code} is missing`); } }); test("maps a PROBLEM outcome onto the port error, preserving the code", () => { const error = toStudioGatewayError( { kind: "PROBLEM", problem: { type: "https://techlog.local/problems/version-conflict", title: "VERSION_CONFLICT", status: 409, detail: "Expected 3; current 4.", code: "VERSION_CONFLICT", }, metadata: { status: 409 }, effect: "NOT_APPLIED", } as never, "saveStudioDocument", ); assert.ok(isStudioGatewayError(error)); assert.equal(error.code, "VERSION_CONFLICT"); assert.equal(error.status, 409); }); test("maps a transport failure onto STUDIO_UNAVAILABLE without inventing a domain code", () => { const error = toStudioGatewayError( { kind: "TRANSPORT_FAILURE", failure: { kind: "TIMEOUT" }, effect: "MAYBE_APPLIED" } as never, "getStudioDashboard", ); assert.equal(error.code, "STUDIO_UNAVAILABLE"); assert.equal(error.retryable, true); }); test("maps UNAUTHENTICATED onto AUTHENTICATION_REQUIRED", () => { const error = toStudioGatewayError( { kind: "UNAUTHENTICATED", effect: "NOT_APPLIED" } as never, "getStudioDashboard", ); assert.equal(error.code, "AUTHENTICATION_REQUIRED"); assert.equal(error.status, 401); }); test("fetches the CSRF token once and reuses it until invalidated", async () => { let calls = 0; const provider = createCsrfTokenProvider({ async execute() { calls += 1; return { csrfToken: `token-${calls}`, csrfHeaderName: "X-CSRF-TOKEN" }; }, }); assert.equal(await provider.token(), "token-1"); assert.equal(await provider.token(), "token-1"); assert.equal(calls, 1); provider.invalidate(); assert.equal(await provider.token(), "token-2"); assert.equal(calls, 2); }); test("does not stampede concurrent CSRF requests", async () => { let calls = 0; const provider = createCsrfTokenProvider({ async execute() { calls += 1; await Promise.resolve(); return { csrfToken: "token", csrfHeaderName: "X-CSRF-TOKEN" }; }, }); await Promise.all([provider.token(), provider.token(), provider.token()]); assert.equal(calls, 1); });