import assert from "node:assert/strict"; import { test } from "bun:test"; import { createOpenFgaAuthorizer } from "./openfga-authorization.ts"; test("OpenFGA shadow mode is normalized to enforce and denies without a tuple", async () => { const calls: Array<{ path: string; method: string }> = []; const authorizer = createOpenFgaAuthorizer({ env: { HWLAB_OPENFGA_MODE: "shadow", HWLAB_OPENFGA_API_URL: "http://openfga.test" }, fetchImpl: async (url: string | URL, init: RequestInit = {}) => { const parsed = new URL(String(url)); calls.push({ path: parsed.pathname, method: init.method ?? "GET" }); if (parsed.pathname === "/healthz") return jsonResponse({}, 200); if (parsed.pathname === "/stores") return jsonResponse({ id: "store-shadow" }, 201); if (parsed.pathname === "/stores/store-shadow/authorization-models") return jsonResponse({ authorization_model_id: "model-shadow" }, 201); if (parsed.pathname === "/stores/store-shadow/check") return jsonResponse({ allowed: false }, 200); return jsonResponse({ error: "unexpected path" }, 404); } }); const decision = await authorizer.check({ actor: { id: "usr_shadow", role: "user" }, relation: "can_use", object: "tool:hwpod" }); assert.equal(decision.mode, "enforce"); assert.equal(decision.allowed, false); assert.equal(decision.fgaAllowed, false); assert.equal(decision.decisionSource, "openfga"); assert.deepEqual(calls.map((call) => call.path), [ "/healthz", "/stores", "/stores/store-shadow/authorization-models", "/stores/store-shadow/check", "/stores/store-shadow/check" ]); }); function jsonResponse(body: unknown, status: number) { return new Response(JSON.stringify(body), { status, headers: { "content-type": "application/json" } }); }