1import { describe, expect, it } from "vitest"; 2 3import { 4 LEVELS, 5 ROLES, 6 levelAtLeast, 7 levelFromPrisma, 8 levelRank, 9 levelToPrisma, 10 maxLevel, 11 minLevel, 12 roleFromPrisma, 13 roleToPrisma, 14 type PermissionLevel, 15} from "./levels.js"; 16 17describe("LEVELS ordering", () => { 18 it("orders none < view < comment < edit < full_access", () => { 19 expect(LEVELS).toEqual(["none", "view", "comment", "edit", "full_access"]); 20 expect(levelRank("none")).toBe(0); 21 expect(levelRank("view")).toBe(1); 22 expect(levelRank("comment")).toBe(2); 23 expect(levelRank("edit")).toBe(3); 24 expect(levelRank("full_access")).toBe(4); 25 }); 26}); 27 28describe("maxLevel / minLevel", () => { 29 it("takes the higher / lower of two levels", () => { 30 expect(maxLevel("edit", "view")).toBe("edit"); 31 expect(maxLevel("view", "full_access")).toBe("full_access"); 32 expect(maxLevel("comment", "comment")).toBe("comment"); 33 expect(minLevel("edit", "view")).toBe("view"); 34 expect(minLevel("full_access", "comment")).toBe("comment"); 35 expect(minLevel("none", "none")).toBe("none"); 36 }); 37}); 38 39describe("levelAtLeast", () => { 40 const cases: [PermissionLevel, PermissionLevel, boolean][] = [ 41 ["edit", "comment", true], 42 ["view", "edit", false], 43 ["full_access", "full_access", true], 44 ["full_access", "view", true], 45 ["none", "view", false], 46 ["view", "view", true], 47 ["comment", "edit", false], 48 ]; 49 it.each(cases)("levelAtLeast(%s, %s) === %s", (level, required, expected) => { 50 expect(levelAtLeast(level, required)).toBe(expected); 51 }); 52}); 53 54describe("prisma mapping (levels)", () => { 55 const pairs: [PermissionLevel, string][] = [ 56 ["none", "NONE"], 57 ["view", "VIEW"], 58 ["comment", "COMMENT"], 59 ["edit", "EDIT"], 60 ["full_access", "FULL_ACCESS"], 61 ]; 62 63 it("maps wire → prisma", () => { 64 for (const [wire, prisma] of pairs) { 65 expect(levelToPrisma(wire)).toBe(prisma); 66 } 67 }); 68 69 it("maps prisma → wire (round-trips)", () => { 70 for (const [wire, prisma] of pairs) { 71 expect(levelFromPrisma(prisma)).toBe(wire); 72 } 73 }); 74 75 it("throws on unknown prisma values", () => { 76 expect(() => levelFromPrisma("ADMIN")).toThrow(/unknown PermissionLevel/); 77 expect(() => levelFromPrisma("view")).toThrow(/unknown PermissionLevel/); 78 }); 79}); 80 81describe("prisma mapping (roles)", () => { 82 it("maps wire → prisma and back", () => { 83 expect(roleToPrisma("owner")).toBe("OWNER"); 84 expect(roleToPrisma("admin")).toBe("ADMIN"); 85 expect(roleToPrisma("member")).toBe("MEMBER"); 86 expect(roleToPrisma("guest")).toBe("GUEST"); 87 expect(roleFromPrisma("OWNER")).toBe("owner"); 88 expect(roleFromPrisma("GUEST")).toBe("guest"); 89 }); 90 91 it("throws on unknown role values", () => { 92 expect(() => roleFromPrisma("FULL_ACCESS")).toThrow(/unknown WorkspaceRole/); 93 }); 94 95 it("ROLES is ascending in authority", () => { 96 expect(ROLES).toEqual(["guest", "member", "admin", "owner"]); 97 }); 98}); 99