Files
HiveGrid-Wireframes/hivegrid-cloud/scripts/verify-audit-cascade-guard.test.mjs
T

74 lines
2.7 KiB
JavaScript

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import path from "node:path";
import { describe, it } from "vitest";
import {
formatAuditCascadeGuardResult,
migrationPath,
schemaPath,
verifyAuditCascadeGuard,
} from "./verify-audit-cascade-guard.mjs";
const hardenedSchema = readFileSync(schemaPath, "utf8");
const hardenedMigration = readFileSync(migrationPath, "utf8");
const packageJson = JSON.parse(readFileSync(path.resolve("package.json"), "utf8"));
function verifyWithOverrides({ schemaText = hardenedSchema, migrationSql = hardenedMigration } = {}) {
return verifyAuditCascadeGuard({ schemaText, migrationSql });
}
describe("verify-audit-cascade-guard", () => {
it("passes against the hardened Prisma schema and migration", () => {
const result = verifyWithOverrides();
assert.equal(result.ok, true);
assert.deepEqual(result.failures, []);
assert.match(formatAuditCascadeGuardResult(result), /^PASS impersonation audit cascade guard/);
});
it("fails when an audit relation reintroduces onDelete Cascade", () => {
const result = verifyWithOverrides({
schemaText: hardenedSchema.replace("onDelete: SetNull)", "onDelete: Cascade)"),
});
assert.equal(result.ok, false);
assert.deepEqual(
result.failures.map((failure) => failure.id),
["schema.actor.optional-set-null", "schema.relation.no-cascade"],
);
assert.match(formatAuditCascadeGuardResult(result), /onDelete: Cascade/);
});
it("fails when actor or target SQL columns are made NOT NULL", () => {
const result = verifyWithOverrides({
migrationSql: hardenedMigration
.replace('"actorUserId" TEXT,', '"actorUserId" TEXT NOT NULL,')
.replace('"targetUserId" TEXT,', '"targetUserId" TEXT NOT NULL,'),
});
assert.equal(result.ok, false);
assert.deepEqual(
result.failures.map((failure) => failure.id),
["migration.actorUserId.nullable", "migration.targetUserId.nullable"],
);
});
it("fails when actor, target, or tenant foreign keys are missing ON DELETE SET NULL", () => {
const result = verifyWithOverrides({
migrationSql: hardenedMigration.replaceAll("ON DELETE SET NULL", "ON DELETE CASCADE"),
});
assert.equal(result.ok, false);
assert.deepEqual(
result.failures.map((failure) => failure.id),
["migration.actorUserId.set-null", "migration.targetUserId.set-null", "migration.tenantId.set-null"],
);
assert.match(formatAuditCascadeGuardResult(result), /migration\.tenantId\.set-null/);
});
it("registers the package script for the guard command", () => {
assert.equal(packageJson.scripts["verify:audit-cascade-guard"], "node scripts/verify-audit-cascade-guard.mjs");
});
});