import { describe, expect, it } from "vitest"; import { isDenyEligible } from "./emit-gate.js"; import type { Finding } from "./types.js"; // isDenyEligible reads only ruleId / severity / fix / attributes, so a minimal // cast keeps the fixtures focused on the deny criteria under test. const base = { ruleId: "components/prefer-library", severity: "serious", fix: { deterministic: true }, } as unknown as Finding; describe("isDenyEligible", () => { it("denies a confident, allowlisted, CI-gating, deterministic finding", () => { expect(isDenyEligible(base, false)).toBe(true); }); it("never denies an advisory-flagged finding, even at error severity", () => { const advisory = { ...base, attributes: { advisory: true } } as unknown as Finding; expect(isDenyEligible(advisory, false)).toBe(false); // failOnWarnings must not resurrect it either. expect(isDenyEligible(advisory, true)).toBe(false); }); it("does not deny a rule outside the blocking allowlist", () => { expect(isDenyEligible({ ...base, ruleId: "composition/x" } as unknown as Finding, false)).toBe( false ); }); it("only denies a warn-level finding under failOnWarnings", () => { const warn = { ...base, severity: "moderate" } as unknown as Finding; expect(isDenyEligible(warn, false)).toBe(false); expect(isDenyEligible(warn, true)).toBe(true); }); it("does not deny an explicitly non-deterministic (heuristic) fix", () => { const heuristic = { ...base, fix: { deterministic: false } } as unknown as Finding; expect(isDenyEligible(heuristic, false)).toBe(false); }); });