import { test } from 'node:test'; import assert from 'node:assert/strict'; import { deriveVerdict, isBlockingFinding, normalizeReview } from '../src/lib/verdict.js'; const F = (over = {}) => ({ title: 't', file: 'f.js', line: 1, severity: 'low', confidence: 'plausible', axis: 'style', detail: 'd', ...over }); test('confirmed critical correctness blocks', () => { assert.equal(isBlockingFinding(F({ severity: 'critical', confidence: 'confirmed', axis: 'correctness' })), true); }); test('confirmed high security blocks', () => { assert.equal(isBlockingFinding(F({ severity: 'high', confidence: 'confirmed', axis: 'security' })), true); }); test('plausible critical does NOT block', () => { assert.equal(isBlockingFinding(F({ severity: 'critical', confidence: 'plausible', axis: 'correctness' })), false); }); test('confirmed critical style does NOT block', () => { assert.equal(isBlockingFinding(F({ severity: 'critical', confidence: 'confirmed', axis: 'style' })), false); }); test('confirmed medium does NOT block', () => { assert.equal(isBlockingFinding(F({ severity: 'medium', confidence: 'confirmed', axis: 'security' })), false); }); test('untagged axis + confirmed critical blocks (conservative)', () => { assert.equal(isBlockingFinding(F({ severity: 'critical', confidence: 'confirmed', axis: null })), true); }); test('verdict fail on blocking finding', () => { const v = deriveVerdict({ findings: [F({ severity: 'high', confidence: 'confirmed', axis: 'correctness' })] }); assert.equal(v, 'fail'); }); test('verdict warn on plausible high', () => { const v = deriveVerdict({ findings: [F({ severity: 'high', confidence: 'plausible', axis: 'correctness' })] }); assert.equal(v, 'warn'); }); test('verdict warn on confirmed medium', () => { const v = deriveVerdict({ findings: [F({ severity: 'medium', confidence: 'confirmed', axis: 'security' })] }); assert.equal(v, 'warn'); }); test('verdict pass with only low findings', () => { const v = deriveVerdict({ findings: [F({ severity: 'low' })] }); assert.equal(v, 'pass'); }); test('verdict pass with no findings', () => { assert.equal(deriveVerdict({ findings: [] }), 'pass'); assert.equal(deriveVerdict({}), 'pass'); }); test('normalizeReview clamps scores and overrides model verdict', () => { const r = normalizeReview({ axes: { correctness: { score: 250, rationale: 'x' } }, overall: -5, grade: 'z', findings: [{ title: 'boom', severity: 'CRITICAL', confidence: 'Confirmed', axis: 'Correctness', file: 'a.js', line: '7' }], verdict: 'pass' // model says pass, but blocking finding exists }); assert.equal(r.axes.correctness.score, 100); assert.equal(r.axes.security.score, 0); // missing axis defaults assert.equal(r.overall, 0); assert.equal(r.grade, 'C'); assert.equal(r.findings[0].severity, 'critical'); assert.equal(r.findings[0].line, 7); assert.equal(r.verdict, 'fail'); // service-side derivation is authoritative }); test('normalizeReview tolerates junk', () => { assert.equal(normalizeReview(null), null); const r = normalizeReview({}); assert.equal(r.verdict, 'pass'); assert.equal(r.findings.length, 0); }); // --- applyTruncationCap --- import { applyTruncationCap } from '../src/lib/verdict.js'; test('truncation caps pass at warn', () => { const r = { verdict: 'pass' }; applyTruncationCap(r, true); assert.equal(r.verdict, 'warn'); }); test('truncation leaves warn as warn', () => { const r = { verdict: 'warn' }; applyTruncationCap(r, true); assert.equal(r.verdict, 'warn'); }); test('truncation does not downgrade fail', () => { const r = { verdict: 'fail' }; applyTruncationCap(r, true); assert.equal(r.verdict, 'fail'); }); test('no truncation leaves pass untouched', () => { const r = { verdict: 'pass' }; applyTruncationCap(r, false); assert.equal(r.verdict, 'pass'); });