Files
Epicnabbo-Catalogus-Updated…/src/lib/admin-operations-contract.test.ts
T

61 lines
2.2 KiB
TypeScript

import { existsSync, readdirSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
const ACTION_GATES: Array<[string, string]> = [
["admin-bans.ts", "PERMS.USERS_BAN"],
["admin-wordfilter.ts", "PERMS.WORDFILTER_EDIT"],
["admin-articles.ts", "PERMS.NEWS_EDIT"],
["admin-radio-autodj.ts", "PERMS.RADIO_EDIT"],
["catalog.ts", "PERMS.CATALOG_EDIT"],
["rooms.ts", "PERMS.ROOMS_EDIT"],
["admin-vpn.ts", "PERMS.SETTINGS_EDIT"],
["admin-ads.ts", "PERMS.PAGES_EDIT"],
["admin-alerts.ts", "PERMS.NOTIFICATIONS_EDIT"],
["tickets.ts", "PERMS.TICKETS_EDIT"],
["admin-help-tickets.ts", "PERMS.TICKETS_EDIT"],
["permissions.ts", "PERMS.PERMISSIONS_MANAGE"],
["permissions.ts", "repairAdminNavAclGrants"],
["admin-guilds.ts", "PERMS.USERS_EDIT"],
["moderation.ts", "PERMS.MODERATION_EDIT"],
];
describe("administration backend contract", () => {
it.each([
["analytics/export", "PERMS.ANALYTICS_EXPORT"],
["devops/health", "PERMS.DEVOPS_VIEW"],
["users/actions", "PERMS.USERS_EDIT"],
])("provides and guards /api/admin/%s", (route, permission) => {
const path = `src/app/api/admin/${route}/route.ts`;
expect(existsSync(path), path).toBe(true);
expect(readFileSync(path, "utf8"), path).toContain(permission);
});
it.each(ACTION_GATES)("guards %s with %s", (file, permission) => {
const source = readFileSync(`src/actions/${file}`, "utf8");
expect(source).toContain(permission);
expect(source).not.toMatch(/await requireStaff\(\)/);
expect(source).not.toMatch(/await requireStaffRateLimited\(\)/);
});
it("requires explicit permissions for every administration action", () => {
const dir = "src/actions";
const offenders: string[] = [];
for (const name of readdirSync(dir)) {
if (!name.endsWith(".ts") || name.endsWith(".test.ts")) continue;
const source = readFileSync(join(dir, name), "utf8");
if (/await requireStaff(RateLimited)?\(\)/.test(source)) {
offenders.push(name);
}
}
expect(offenders).toEqual([]);
});
it("keeps the shared ops health probe behind the API", () => {
expect(existsSync("src/lib/admin/ops-health.ts")).toBe(true);
expect(
readFileSync("src/app/api/admin/devops/health/route.ts", "utf8"),
).toContain("fetchOpsHealth");
});
});