Files
pikasTech-HWLAB/internal/cloud/openfga-authorization.test.ts
T
2026-06-05 17:23:56 +08:00

43 lines
1.8 KiB
TypeScript

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" } });
}