import { describe, expect, test } from "bun:test"; import { defineAuthz } from "../src/registry.ts"; describe("defineAuthz", () => { test("returns a frozen module", () => { const mod = defineAuthz({ permissions: { "post:read": { title: "View posts" } }, roles: { editor: ["post:*"] }, }); expect(Object.isFrozen(mod)).toBe(true); expect(mod.permissions!["post:read"]!.title).toBe("View posts"); expect(mod.roles!.editor).toEqual(["post:*"]); }); test("defaults missing sections to empty objects", () => { const mod = defineAuthz({}); expect(mod.permissions).toEqual({}); expect(mod.roles).toEqual({}); expect(mod.policies).toEqual({}); expect(mod.attributes).toEqual({}); expect(mod.bindings).toEqual({}); }); test("rejects a permission id that is not colon-namespaced lowercase", () => { expect(() => defineAuthz({ permissions: { "Post Read": {} } })).toThrow(/permission id/i); expect(() => defineAuthz({ permissions: { "post:*": {} } })).toThrow(/wildcard/i); }); test("rejects permission ids that collide with role inheritance", () => { expect(() => defineAuthz({ permissions: { "role:assign": {} } })).toThrow( /reserved 'role:' prefix/i, ); }); test("rejects a role granting an unknown-shaped entry", () => { expect(() => defineAuthz({ roles: { editor: [""] } })).toThrow(/role 'editor'/i); }); test("rejects a binding naming a policy that is not declared", () => { expect(() => defineAuthz({ permissions: { "post:write": {} }, bindings: { "post:write": ["missingPolicy"] }, }), ).toThrow(/missingPolicy/); }); });