import { test, beforeEach, afterEach } from "node:test";
import assert from "node:assert/strict";
import { ApiError, ControlPlaneClient } from "../src/api.js";
const originalFetch = globalThis.fetch;
beforeEach(() => {
globalThis.fetch = originalFetch;
});
afterEach(() => {
globalThis.fetch = originalFetch;
});
test("ControlPlaneClient reports non-JSON error bodies without rereading them", async () => {
globalThis.fetch = (async () =>
new Response("
upstream unavailable
", {
status: 502,
statusText: "Bad Gateway",
headers: { "content-type": "text/html" },
})) as typeof fetch;
await assert.rejects(
() => new ControlPlaneClient("https://api.example.test", "token").me(),
(err) => {
assert.ok(err instanceof ApiError);
assert.equal(err.status, 502);
assert.match(err.message, /upstream unavailable/);
assert.doesNotMatch(err.message, /Body is unusable/);
return true;
},
);
});
test("ControlPlaneClient forwards bearer tokens and extracts JSON error detail", async () => {
globalThis.fetch = (async (_input: RequestInfo | URL, init?: RequestInit) => {
const headers = init?.headers as Record;
assert.equal(headers.authorization, "Bearer access-token");
return new Response(JSON.stringify({ detail: "keycloak email is not verified" }), {
status: 403,
headers: { "content-type": "application/json" },
});
}) as typeof fetch;
await assert.rejects(
() => new ControlPlaneClient("https://api.example.test", "access-token").me(),
/API 403: keycloak email is not verified/,
);
});