fe139332ee
10 route shells under /[slug]/, role-filtered Nav, backstage stub at /__backstage__, dashboard reads session.products to render tiles. src/lib/session.ts is the canonical role × surface matrix; canSee() is the only RBAC primitive in the portal (real enforcement remains at the API layer). 24 vitest tests; 100% src/lib coverage. Refs: M5.2
66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
import { describe, expect, test } from "vitest";
|
|
import { canSee, hasAnyOrgRole, hasOrgRole, hasProduct } from "./session";
|
|
import type { SessionWithExtras } from "./session";
|
|
|
|
function s(roles: SessionWithExtras["org_roles"], products: string[] = []): SessionWithExtras {
|
|
return {
|
|
user: { name: "Test", email: "t@x.test" },
|
|
expires: "2099-01-01T00:00:00Z",
|
|
org_roles: roles,
|
|
products,
|
|
};
|
|
}
|
|
|
|
describe("hasOrgRole", () => {
|
|
test("null session has no roles", () => {
|
|
expect(hasOrgRole(null, "IT_ADMIN")).toBe(false);
|
|
});
|
|
test("matches single role", () => {
|
|
expect(hasOrgRole(s(["CXO"]), "CXO")).toBe(true);
|
|
expect(hasOrgRole(s(["CXO"]), "IT_ADMIN")).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("hasAnyOrgRole", () => {
|
|
test("any match wins", () => {
|
|
expect(hasAnyOrgRole(s(["LEGAL"]), ["IT_ADMIN", "LEGAL"])).toBe(true);
|
|
expect(hasAnyOrgRole(s(["USER"]), ["IT_ADMIN", "CXO"])).toBe(false);
|
|
});
|
|
test("empty roles", () => {
|
|
expect(hasAnyOrgRole(s(undefined), ["IT_ADMIN"])).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("hasProduct", () => {
|
|
test("checks products array", () => {
|
|
expect(hasProduct(s(["USER"], ["certifai"]), "certifai")).toBe(true);
|
|
expect(hasProduct(s(["USER"], ["certifai"]), "compliance")).toBe(false);
|
|
expect(hasProduct(null, "certifai")).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("canSee", () => {
|
|
test("IT_ADMIN sees settings, USER does not", () => {
|
|
expect(canSee(s(["IT_ADMIN"]), "settings")).toBe(true);
|
|
expect(canSee(s(["USER"]), "settings")).toBe(false);
|
|
});
|
|
test("CXO can see billing", () => {
|
|
expect(canSee(s(["CXO"]), "billing")).toBe(true);
|
|
});
|
|
test("LEGAL can see audit but not settings", () => {
|
|
expect(canSee(s(["LEGAL"]), "audit")).toBe(true);
|
|
expect(canSee(s(["LEGAL"]), "settings")).toBe(false);
|
|
});
|
|
test("FINANCE sees billing but not settings", () => {
|
|
expect(canSee(s(["FINANCE"]), "billing")).toBe(true);
|
|
expect(canSee(s(["FINANCE"]), "settings")).toBe(false);
|
|
});
|
|
test("dashboard visible to everyone with any role", () => {
|
|
expect(canSee(s(["USER"]), "dashboard")).toBe(true);
|
|
expect(canSee(s(["LEGAL"]), "dashboard")).toBe(true);
|
|
});
|
|
test("null session sees nothing", () => {
|
|
expect(canSee(null, "dashboard")).toBe(false);
|
|
});
|
|
});
|