Files
ForgeFlow/tests/git-validator-policy.test.mjs
T

54 lines
3.2 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
const {
normalizePolicy,
validateSuppression,
applyPolicy,
buildTrend,
exportReport,
} = require("../src/main/git-validator-policy.cjs");
test("Git Validator policies enforce score, blockers and enabled checks", () => {
const policy = normalizePolicy({ id: "organization", label: "ITWorx", requiredScore: 88, enabledChecks: ["security", "readme"], blockingChecks: ["security"] });
const governed = applyPolicy([
{ id: "security", status: "warning", category: "Security", weight: 10 },
{ id: "readme", status: "pass", category: "Collaboration", weight: 5 },
{ id: "ignored", status: "error", category: "Other", weight: 5 },
], policy, []);
assert.equal(governed.policy.requiredScore, 88);
assert.deepEqual(governed.checks.map((check) => check.id), ["security", "readme"]);
assert.equal(governed.checks[0].blocking, true);
});
test("suppressions require accountable evidence and reactivate after expiry", () => {
const now = new Date("2026-07-01T00:00:00.000Z");
const suppression = validateSuppression({ checkId: "signed-tags", reason: "Tracked under release hardening", author: "Jens", ticket: "FF-42", expiresAt: "2026-07-08T00:00:00.000Z", scope: "repository", evidence: "sha:abc" }, normalizePolicy({ id: "standard" }), now);
let governed = applyPolicy([{ id: "signed-tags", status: "warning", category: "Governance", weight: 5 }], { id: "standard" }, [suppression], now);
assert.equal(governed.checks[0].suppressed, true);
governed = applyPolicy(governed.checks, { id: "standard" }, [suppression], new Date("2026-07-09T00:00:00.000Z"));
assert.equal(governed.checks[0].suppressed, false);
assert.equal(governed.checks[0].expiredSuppression.id, suppression.id);
assert.throws(() => validateSuppression({ checkId: "x", reason: "short", author: "a", expiresAt: "2026-07-02", evidence: "x" }, normalizePolicy(), now), /requires/);
});
test("trends report new, resolved and regressed findings without false precision", () => {
const previous = { checks: [{ id: "a", status: "warning" }, { id: "b", status: "error" }, { id: "c", status: "pass" }] };
const report = { score: 74, categories: { Security: 50 }, checkedAt: "2026-07-02T00:00:00Z", commitSha: "abc", checks: [{ id: "a", status: "error" }, { id: "b", status: "pass" }, { id: "c", status: "warning", suppressed: true }] };
const trend = buildTrend(previous, report);
assert.deepEqual(trend.regressions, ["a"]);
assert.deepEqual(trend.resolved.sort(), ["b"]);
assert.deepEqual(trend.suppressions, ["c"]);
});
test("reports export as JSON, Markdown and standalone escaped HTML", () => {
const report = { repository: "jens/<app>", score: 80, commitSha: "abc", policy: { label: "Production" }, checks: [{ id: "readme", category: "Collaboration", status: "pass", detail: "Safe & ready" }] };
assert.doesNotThrow(() => JSON.parse(exportReport(report, "json").content));
assert.match(exportReport(report, "markdown").content, /\| readme \|/);
const html = exportReport(report, "html").content;
assert.match(html, /<!doctype html>/);
assert.match(html, /jens\/&lt;app&gt;/);
});