From 667ec9af4cff7c4a27f4f4a775c722d4c1e3360e Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sun, 12 Jul 2026 19:01:28 +0200 Subject: [PATCH] test: define acl and import backend contracts --- src/lib/admin/acl-management-contract.test.ts | 21 ++++++++++++++++ src/lib/import-backend-contract.test.ts | 24 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/lib/admin/acl-management-contract.test.ts create mode 100644 src/lib/import-backend-contract.test.ts diff --git a/src/lib/admin/acl-management-contract.test.ts b/src/lib/admin/acl-management-contract.test.ts new file mode 100644 index 00000000..48fefd25 --- /dev/null +++ b/src/lib/admin/acl-management-contract.test.ts @@ -0,0 +1,21 @@ +import { readFileSync } from "node:fs"; +import { describe, expect, it } from "vitest"; + +describe("ACL management contract", () => { + it("uses normalized ACL persistence and the permissions.manage guard", () => { + const source = readFileSync("src/actions/permissions.ts", "utf8"); + expect(source).toContain("PERMS.PERMISSIONS_MANAGE"); + expect(source).toContain("adminAction"); + expect(source).toContain("aclModelPermission"); + expect(source).not.toContain("websiteHousekeepingPermissions"); + expect(source).not.toContain("websiteTeams"); + }); + + it("ships an idempotent ACL completion migration", () => { + const sql = readFileSync("prisma/migrations/0014_complete_acl_and_import_permissions.sql", "utf8"); + expect(sql).toContain("admin.assets.import"); + expect(sql).toContain("rank_"); + expect(sql).toContain("'Role'"); + expect(sql).toContain("'User'"); + }); +}); diff --git a/src/lib/import-backend-contract.test.ts b/src/lib/import-backend-contract.test.ts new file mode 100644 index 00000000..00b19361 --- /dev/null +++ b/src/lib/import-backend-contract.test.ts @@ -0,0 +1,24 @@ +import { existsSync, readFileSync } from "node:fs"; +import { describe, expect, it } from "vitest"; + +const ROUTES = [ + "badges", "badges/edit", "clone", "clone/batch", "clone/icon", + "clothing", "clothing/batch", "clothing/sets", "clothing/sets/batch", + "effects", "effects/batch", "furni", "furni/batch", "furni/batch-regen", + "furni/nitro-editor", "furni/resync", "pets", "pets/batch", "pets/icon", + "repair", "repair/audit", +]; + +describe("admin import backend contract", () => { + it.each(ROUTES)("provides and guards /api/admin/import/%s", (route) => { + const path = `src/app/api/admin/import/${route}/route.ts`; + expect(existsSync(path), path).toBe(true); + const source = readFileSync(path, "utf8"); + expect(source, path).toContain("PERMS.ASSETS_IMPORT"); + }); + + it("does not leave import actions as successful no-op stubs", () => { + const source = readFileSync("src/actions/import-furni.ts", "utf8"); + expect(source).not.toContain("deleted: 0, remaining: 0"); + }); +});