Files
clean-architecture-frontend…/tests/unit/risk-coverage.test.ts
T

586 lines
18 KiB
TypeScript

import { constants } from "node:fs";
import {
mkdir,
mkdtemp,
open,
readFile,
rm,
symlink,
writeFile,
} from "node:fs/promises";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import {
buildProductionModuleInventory,
evaluateRiskCoverage,
normalizeCoverageProducerPath,
parseRepositoryRiskCoveragePolicy,
parseRiskCoveragePolicy,
type ProductionModuleInventory,
} from "../../scripts/lib/risk-coverage.ts";
const roots: string[] = [];
const now = Date.parse("2026-08-02T00:00:00.000Z");
function counter(total = 1, covered = total, skipped = 0) {
return {
total,
covered,
skipped,
pct: total === 0 ? 100 : Math.floor((covered / total) * 10_000) / 100,
};
}
function metrics(total = 1, covered = total) {
return {
lines: counter(total, covered),
statements: counter(total, covered),
functions: counter(total, covered),
branches: counter(total, covered),
};
}
const fullMetrics = metrics();
function inventory(
files: readonly string[],
generatedExclusions: readonly string[] = [],
): ProductionModuleInventory {
return {
files,
preExclusionTotal: files.length + generatedExclusions.length,
generatedExclusions,
};
}
async function repositoryFixture(): Promise<string> {
const root = await mkdtemp(path.join(tmpdir(), "risk-coverage-"));
roots.push(root);
await mkdir(path.join(root, "src/nested"), { recursive: true });
await Promise.all([
writeFile(path.join(root, "src/a.ts"), "export const a = 1;\n"),
writeFile(path.join(root, "src/nested/b.tsx"), "export const b = 2;\n"),
writeFile(path.join(root, "src/types.d.ts"), "declare const value: 1;\n"),
writeFile(path.join(root, "src/example.stories.tsx"), "export {};\n"),
writeFile(path.join(root, "src/generated.ts"), "export const generated = true;\n"),
writeFile(path.join(root, "src/ignored.js"), "export const ignored = true;\n"),
]);
return root;
}
function policy(overrides: Record<string, unknown> = {}) {
return {
schemaVersion: 2,
repositoryBaseline: 2,
generatedPaths: ["src/generated.ts"],
summary: {
lines: 80,
statements: 78,
functions: 85,
branches: 68,
},
criticalModules: [
{
path: "src/a.ts",
owner: "platform-runtime",
minimum: {
lines: 80,
statements: 78,
functions: 85,
branches: 68,
},
},
],
highRiskPaths: ["src/a.ts"],
waivers: [],
...overrides,
};
}
afterEach(async () => {
await Promise.all(
roots.splice(0).map((root) => rm(root, { recursive: true, force: true })),
);
});
describe("repository-aware risk coverage", () => {
it("rejects the historical 14-file summary against the full repository", async () => {
const repositoryRoot = process.cwd();
const rawPolicy = JSON.parse(
await readFile("config/testing/risk-coverage.json", "utf8"),
) as unknown;
const summary = JSON.parse(
await readFile("tests/fixtures/coverage/repository-omission.json", "utf8"),
) as unknown;
const parsedPolicy = parseRepositoryRiskCoveragePolicy(rawPolicy, { now });
const productionInventory = await buildProductionModuleInventory({
repositoryRoot,
generatedPaths: parsedPolicy.generatedPaths,
});
const result = evaluateRiskCoverage({
repositoryRoot,
inventory: productionInventory,
policy: parsedPolicy,
summary,
});
expect(result.selectedTotal).toBe(14);
expect(result.repositoryTotal).toBeGreaterThan(result.selectedTotal);
expect(result.uncoveredModules).toHaveLength(
result.repositoryTotal - result.selectedTotal,
);
expect(result.status).toBe("FAIL");
});
it("reports exact inventory and generated-exclusion provenance", async () => {
const repositoryRoot = await repositoryFixture();
const productionInventory = await buildProductionModuleInventory({
repositoryRoot,
generatedPaths: ["src/generated.ts"],
});
const result = evaluateRiskCoverage({
repositoryRoot,
inventory: productionInventory,
policy: parseRiskCoveragePolicy(policy(), { now }),
summary: {
total: fullMetrics,
[path.join(repositoryRoot, "src/a.ts")]: fullMetrics,
},
});
expect(productionInventory).toEqual({
files: ["src/a.ts", "src/nested/b.tsx"],
preExclusionTotal: 3,
generatedExclusions: ["src/generated.ts"],
});
expect(result).toMatchObject({
status: "FAIL",
selectedTotal: 1,
repositoryTotal: 2,
preExclusionTotal: 3,
generatedExclusionCount: 1,
generatedExclusions: ["src/generated.ts"],
uncoveredModules: ["src/nested/b.tsx"],
});
});
it("rejects arbitrary coverage paths instead of silently allowing inflation", () => {
const parsedPolicy = parseRiskCoveragePolicy(
policy({ repositoryBaseline: 1, generatedPaths: [] }),
{ now },
);
expect(() =>
evaluateRiskCoverage({
repositoryRoot: "/repository",
inventory: inventory(["src/a.ts"]),
policy: parsedPolicy,
summary: {
total: metrics(2),
"src/a.ts": fullMetrics,
"tests/unit/a.test.ts": fullMetrics,
},
}),
).toThrow(/unexpected coverage path.*tests\/unit\/a\.test\.ts/u);
});
it("rejects outside and duplicate normalized producer paths", () => {
const parsedPolicy = parseRiskCoveragePolicy(
policy({ repositoryBaseline: 1, generatedPaths: [] }),
{ now },
);
const base = {
repositoryRoot: "/repository",
inventory: inventory(["src/a.ts"]),
policy: parsedPolicy,
};
expect(() =>
evaluateRiskCoverage({
...base,
summary: { total: fullMetrics, "/outside/src/a.ts": fullMetrics },
}),
).toThrow(/outside repository/u);
expect(() =>
evaluateRiskCoverage({
...base,
summary: {
total: metrics(2),
"src/a.ts": fullMetrics,
"/repository/src/a.ts": fullMetrics,
},
}),
).toThrow(/duplicate coverage path/u);
});
it("accepts only explicitly configured generated coverage paths", () => {
const parsedPolicy = parseRiskCoveragePolicy(
policy({ repositoryBaseline: 1 }),
{ now },
);
expect(() =>
evaluateRiskCoverage({
repositoryRoot: "/repository",
inventory: inventory(["src/a.ts"], ["src/generated.ts"]),
policy: parsedPolicy,
summary: {
total: metrics(2, 1),
"src/a.ts": fullMetrics,
"src/generated.ts": metrics(1, 0),
},
}),
).not.toThrow();
const result = evaluateRiskCoverage({
repositoryRoot: "/repository",
inventory: inventory(["src/a.ts"], ["src/generated.ts"]),
policy: parsedPolicy,
summary: {
total: metrics(2, 1),
"src/a.ts": fullMetrics,
"src/generated.ts": metrics(1, 0),
},
});
expect(
result.results.find(
({ scope, metric }) => scope === "total" && metric === "lines",
),
).toMatchObject({ received: 100, passed: true });
});
it("requires complete internally consistent Istanbul counters", () => {
const parsedPolicy = parseRiskCoveragePolicy(
policy({ repositoryBaseline: 1, generatedPaths: [] }),
{ now },
);
const base = {
repositoryRoot: "/repository",
inventory: inventory(["src/a.ts"]),
policy: parsedPolicy,
};
expect(() =>
evaluateRiskCoverage({
...base,
summary: { total: fullMetrics, "src/a.ts": { ...fullMetrics, lines: { pct: 100 } } },
}),
).toThrow(/lines.*total.*covered.*skipped/u);
expect(() =>
evaluateRiskCoverage({
...base,
summary: {
total: fullMetrics,
"src/a.ts": {
...fullMetrics,
lines: { total: 2, covered: 1, skipped: 2, pct: 50 },
},
},
}),
).toThrow(/covered plus skipped.*total/u);
expect(() =>
evaluateRiskCoverage({
...base,
summary: {
total: fullMetrics,
"src/a.ts": {
...fullMetrics,
lines: { total: 3, covered: 2, skipped: 0, pct: 66.67 },
},
},
}),
).toThrow(/pct.*66\.66/u);
expect(() =>
evaluateRiskCoverage({
...base,
summary: {
total: metrics(0),
"src/a.ts": { ...fullMetrics, lines: counter(0, 0, 0) },
},
}),
).toThrow(/coverage total.*does not match/u);
});
it("recomputes all global counters and requires an exact producer total", () => {
const parsedPolicy = parseRiskCoveragePolicy(
policy({ repositoryBaseline: 1, generatedPaths: [] }),
{ now },
);
expect(() =>
evaluateRiskCoverage({
repositoryRoot: "/repository",
inventory: inventory(["src/a.ts"]),
policy: parsedPolicy,
summary: {
total: metrics(2),
"src/a.ts": fullMetrics,
},
}),
).toThrow(/coverage total\.lines does not match recomputed inventory total/u);
});
it("accepts and validates Vitest branchesTrue without evaluating it", () => {
const parsedPolicy = parseRiskCoveragePolicy(
policy({ repositoryBaseline: 1, generatedPaths: [] }),
{ now },
);
const branchesTrue = counter(0);
expect(
evaluateRiskCoverage({
repositoryRoot: "/repository",
inventory: inventory(["src/a.ts"]),
policy: parsedPolicy,
summary: {
total: { ...fullMetrics, branchesTrue },
"src/a.ts": fullMetrics,
},
}),
).toMatchObject({ status: "PASS" });
expect(() =>
evaluateRiskCoverage({
repositoryRoot: "/repository",
inventory: inventory(["src/a.ts"]),
policy: parsedPolicy,
summary: {
total: {
...fullMetrics,
branchesTrue: { ...branchesTrue, pct: 0 },
},
"src/a.ts": fullMetrics,
},
}),
).toThrow(/branchesTrue\.pct.*100/u);
});
it("opens regular files with O_NOFOLLOW and fails a deterministic symlink swap", async () => {
const repositoryRoot = await repositoryFixture();
let observedFlags = 0;
await expect(
buildProductionModuleInventory({
repositoryRoot,
openFile: async (target, flags) => {
observedFlags = flags;
if (target.endsWith("src/a.ts")) {
throw Object.assign(new Error("injected link swap"), { code: "ELOOP" });
}
return open(target, flags);
},
}),
).rejects.toThrow(/unreadable.*src\/a\.ts/u);
expect(observedFlags & constants.O_NOFOLLOW).toBe(constants.O_NOFOLLOW);
});
it("rejects a post-lstat file identity swap even without relying on O_NOFOLLOW", async () => {
const repositoryRoot = await repositoryFixture();
const outside = await mkdtemp(path.join(tmpdir(), "risk-coverage-race-"));
roots.push(outside);
const outsideFile = path.join(outside, "replacement.ts");
await writeFile(outsideFile, "export const replacement = true;\n");
await expect(
buildProductionModuleInventory({
repositoryRoot,
openFile: async (target, flags) =>
open(target.endsWith("src/a.ts") ? outsideFile : target, flags),
}),
).rejects.toThrow(/changed during validation/u);
});
it("fails closed on empty, traversing, symlinked, or stale generated inventory", async () => {
const repositoryRoot = await repositoryFixture();
const emptyRoot = await mkdtemp(path.join(tmpdir(), "risk-coverage-empty-"));
roots.push(emptyRoot);
await mkdir(path.join(emptyRoot, "src"));
await expect(buildProductionModuleInventory({ repositoryRoot: emptyRoot })).rejects.toThrow(
/inventory is empty/u,
);
await expect(
buildProductionModuleInventory({ repositoryRoot, generatedPaths: ["../escape.ts"] }),
).rejects.toThrow(/repository-relative POSIX/u);
await expect(
buildProductionModuleInventory({ repositoryRoot, generatedPaths: ["src/missing.ts"] }),
).rejects.toThrow(/stale or not a production module/u);
const outside = await mkdtemp(path.join(tmpdir(), "risk-coverage-outside-"));
roots.push(outside);
await writeFile(path.join(outside, "linked.ts"), "export {};\n");
await symlink(path.join(outside, "linked.ts"), path.join(repositoryRoot, "src/link.ts"));
await expect(buildProductionModuleInventory({ repositoryRoot })).rejects.toThrow(
/symlink.*src\/link\.ts/u,
);
});
it("normalizes native Windows absolute producer paths but rejects POSIX backslashes", () => {
expect(
normalizeCoverageProducerPath({
repositoryRoot: "C:\\repo",
rawPath: "C:\\repo\\src\\nested\\a.ts",
platform: "win32",
}),
).toBe("src/nested/a.ts");
expect(() =>
normalizeCoverageProducerPath({
repositoryRoot: "/repository",
rawPath: "/repository/src\\a.ts",
platform: "posix",
}),
).toThrow(/POSIX separators/u);
expect(() =>
normalizeCoverageProducerPath({
repositoryRoot: "C:\\repo",
rawPath: "D:\\outside\\a.ts",
platform: "win32",
}),
).toThrow(/outside repository/u);
});
it("requires four positive metrics and canonical team ownership", () => {
expect(() =>
parseRiskCoveragePolicy(policy({ summary: { lines: 80 } }), { now }),
).toThrow(/summary must define all/u);
expect(() =>
parseRiskCoveragePolicy(policy({ summary: { lines: 80, statements: 78, functions: 85, branches: 0 } }), { now }),
).toThrow(/greater than 0/u);
expect(() =>
parseRiskCoveragePolicy(
policy({
criticalModules: [
{ path: "src/a.ts", owner: "Platform Runtime", minimum: policy().summary },
],
}),
{ now },
),
).toThrow(/canonical team id/u);
expect(() =>
parseRiskCoveragePolicy(
policy({
criticalModules: [
{ path: "src/a.ts", owner: "platform-runtime", minimum: { lines: 80 } },
],
}),
{ now },
),
).toThrow(/minimum must define all/u);
});
it("enforces ALL_POLICY_HIGH_RISK ownership without changed-file input", () => {
expect(() =>
parseRiskCoveragePolicy(
policy({ highRiskPaths: ["src/a.ts", "src/nested/b.tsx"] }),
{ now },
),
).toThrow(/high-risk module has no owner or waiver.*nested\/b/u);
const parsed = parseRiskCoveragePolicy(
policy({
highRiskPaths: ["src/a.ts", "src/nested/b.tsx"],
waivers: [
{
path: "src/nested/b.tsx",
owner: "runtime-security",
reason: "Temporary instrumentation gap",
expiresAt: "2026-08-03T00:00:00.000Z",
},
],
}),
{ now },
);
const result = evaluateRiskCoverage({
repositoryRoot: "/repository",
inventory: inventory(
["src/a.ts", "src/nested/b.tsx"],
["src/generated.ts"],
),
policy: parsed,
summary: {
total: metrics(2),
"src/a.ts": fullMetrics,
"src/nested/b.tsx": fullMetrics,
},
});
expect(result).toMatchObject({
ownershipScope: "ALL_POLICY_HIGH_RISK",
ownedHighRiskPaths: ["src/a.ts"],
waivedHighRiskPaths: ["src/nested/b.tsx"],
status: "PASS",
});
});
it.each([
[
{ path: "src/a.ts", owner: "Runtime Team", reason: "Temporary instrumentation gap", expiresAt: "2026-08-03T00:00:00.000Z" },
/canonical team id/u,
],
[
{ path: "src/a.ts", owner: "runtime-team", reason: "too short", expiresAt: "2026-08-03T00:00:00.000Z" },
/12 to 240/u,
],
[
{ path: "src/a.ts", owner: "runtime-team", reason: "Temporary\ninstrumentation gap", expiresAt: "2026-08-03T00:00:00.000Z" },
/control characters/u,
],
[
{ path: "src/a.ts", owner: "runtime-team", reason: "Temporary instrumentation gap", expiresAt: "2026-08-03T00:00:00Z" },
/canonical UTC ISO/u,
],
[
{ path: "src/a.ts", owner: "runtime-team", reason: "Temporary instrumentation gap", expiresAt: "2026-11-01T00:00:00.000Z" },
/90 days/u,
],
] as const)("rejects invalid waiver controls %#", (waiver, message) => {
expect(() =>
parseRiskCoveragePolicy(
policy({
criticalModules: [
{
path: "src/owned.ts",
owner: "platform-runtime",
minimum: policy().summary,
},
],
highRiskPaths: ["src/owned.ts", "src/a.ts"],
waivers: [waiver],
}),
{ now },
),
).toThrow(message);
});
it("rejects simultaneous critical ownership and waiver", () => {
expect(() =>
parseRiskCoveragePolicy(
policy({
waivers: [
{
path: "src/a.ts",
owner: "runtime-team",
reason: "Temporary instrumentation gap",
expiresAt: "2026-08-03T00:00:00.000Z",
},
],
}),
{ now },
),
).toThrow(/both a critical owner and waiver/u);
});
it("does not let repository policy omit or generate-exclude a required high-risk path", async () => {
const rawPolicy = JSON.parse(
await readFile("config/testing/risk-coverage.json", "utf8"),
) as Record<string, unknown>;
const missingPolicy = structuredClone(rawPolicy);
missingPolicy.highRiskPaths = (missingPolicy.highRiskPaths as string[]).filter(
(modulePath) => modulePath !== "src/adapters/http/http-execution-v3.ts",
);
expect(() => parseRepositoryRiskCoveragePolicy(missingPolicy, { now })).toThrow(
/required high-risk path.*http-execution-v3/u,
);
const excludedPolicy = structuredClone(rawPolicy);
excludedPolicy.generatedPaths = ["src/adapters/http/http-execution-v3.ts"];
expect(() => parseRepositoryRiskCoveragePolicy(excludedPolicy, { now })).toThrow(
/required high-risk path cannot be generated-excluded/u,
);
});
});