42 lines
1.2 KiB
TypeScript
42 lines
1.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { authorizeHousekeeping } from "./authorization";
|
|
import { anyCapability, type HousekeepingCapabilityContext } from "./contracts";
|
|
|
|
function capabilityContext(
|
|
granted: readonly string[],
|
|
rank = 7,
|
|
): HousekeepingCapabilityContext {
|
|
return {
|
|
actor: { id: 42, username: "operator", rank },
|
|
isSuperAdmin: false,
|
|
has: (slug) => granted.includes(slug),
|
|
hasAny: (...slugs) => slugs.some((slug) => granted.includes(slug)),
|
|
hasAll: (...slugs) => slugs.every((slug) => granted.includes(slug)),
|
|
};
|
|
}
|
|
|
|
describe("authorizeHousekeeping", () => {
|
|
it("returns the authorized capability context", () => {
|
|
const context = capabilityContext(["admin.users.view"]);
|
|
|
|
expect(
|
|
authorizeHousekeeping(context, anyCapability("admin.users.view")),
|
|
).toMatchObject({ ok: true, data: context });
|
|
});
|
|
|
|
it("returns FORBIDDEN for a missing capability regardless of rank", () => {
|
|
const result = authorizeHousekeeping(
|
|
capabilityContext([], 999),
|
|
anyCapability("admin.users.view"),
|
|
);
|
|
|
|
expect(result).toMatchObject({
|
|
ok: false,
|
|
error: {
|
|
code: "FORBIDDEN",
|
|
messageKey: "errors.housekeeping.forbidden",
|
|
},
|
|
});
|
|
});
|
|
});
|