import test, { afterEach } from "node:test"; import assert from "node:assert/strict"; import { AdminApiError, fetchAdminJson, getAdminAccessState, getAdminErrorMessage } from "./api"; type MockFetch = typeof fetch; const originalFetch = globalThis.fetch; function installFetchMock(mock: MockFetch) { Object.defineProperty(globalThis, "fetch", { configurable: true, value: mock, }); } afterEach(() => { installFetchMock(originalFetch); }); test("fetchAdminJson includes cookie credentials", async () => { let seenCredentials: RequestCredentials | undefined; installFetchMock(async (_input, init) => { seenCredentials = init?.credentials; return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { "Content-Type": "application/json" }, }); }); const response = await fetchAdminJson<{ ok: boolean }>("admin/access"); assert.equal(seenCredentials, "include"); assert.deepEqual(response, { ok: true }); }); test("fetchAdminJson classifies 401 as unauthorized", async () => { installFetchMock(async () => new Response(JSON.stringify({ detail: "Not authenticated" }), { status: 401, headers: { "Content-Type": "application/json" }, })); await assert.rejects( () => fetchAdminJson("admin/access"), (error: unknown) => error instanceof AdminApiError && error.kind === "unauthorized" && getAdminAccessState(error) === "unauthenticated" && getAdminErrorMessage(error) === "Session expired. Log in again.", ); }); test("fetchAdminJson classifies 403 as forbidden", async () => { installFetchMock(async () => new Response(JSON.stringify({ detail: "Admin access required" }), { status: 403, headers: { "Content-Type": "application/json" }, })); await assert.rejects( () => fetchAdminJson("admin/overview"), (error: unknown) => error instanceof AdminApiError && error.kind === "forbidden" && getAdminAccessState(error) === "forbidden" && getAdminErrorMessage(error) === "Admin access required.", ); }); test("fetchAdminJson classifies 5xx html as unavailable", async () => { installFetchMock(async () => new Response("bad gateway", { status: 502, headers: { "Content-Type": "text/html" }, })); await assert.rejects( () => fetchAdminJson("admin/overview"), (error: unknown) => error instanceof AdminApiError && error.kind === "unavailable" && getAdminErrorMessage(error) === "Admin service unavailable.", ); }); test("fetchAdminJson classifies network errors distinctly", async () => { installFetchMock(async () => { throw new TypeError("Failed to fetch"); }); await assert.rejects( () => fetchAdminJson("admin/overview"), (error: unknown) => error instanceof AdminApiError && error.kind === "network" && getAdminAccessState(error) === "unavailable" && getAdminErrorMessage(error) === "Cannot reach server.", ); });