Assessor_2.0/tests/server/regulatory-mapping-comparis...

58 lines
2.4 KiB
TypeScript

import { describe, expect, it } from 'vitest';
// The reusable evaluation command is plain ESM so it can run directly with Node.
// @ts-expect-error The script intentionally has no separate declaration file.
import { changeFor, evaluateRun, validateBaseline } from '../../scripts/compare-regulatory-mappings.mjs';
function run(candidates: string[], mappings: Array<{ controlId: string; relationship: 'primary' | 'supporting' }>, status = 'succeeded') {
return {
run_status: status,
data: {
candidates: candidates.map((controlId, index) => ({ controlId, score: 1 / (61 + index) })),
result: { mappings: mappings.map(mapping => ({ ...mapping, confidence: 'high' })) }
}
};
}
const finding = { sourceRuleId: 'RULE-1', primary: '1.1', supporting: ['1.2'] };
describe('regulatory mapping comparison script', () => {
it('allows a manual baseline with no primary and rejects duplicate relationships', () => {
expect(() => validateBaseline({
schemaVersion: 1,
scanners: [{ sourceTool: 'scanner', label: 'Scanner', findings: [{ sourceRuleId: 'RULE-1', primary: null, supporting: ['1.1'] }] }]
})).not.toThrow();
expect(() => validateBaseline({
schemaVersion: 1,
scanners: [{ sourceTool: 'scanner', label: 'Scanner', findings: [{ sourceRuleId: 'RULE-1', primary: '1.1', supporting: ['1.1'] }] }]
})).toThrow(/duplicate controls/i);
});
it('separates retrieval, selection, role and extra-control results', () => {
const evaluation = evaluateRun(run(
['1.1', '1.2', '2.1'],
[{ controlId: '1.1', relationship: 'supporting' }, { controlId: '2.1', relationship: 'primary' }]
), finding);
expect(evaluation.retrievalGaps).toEqual([]);
expect(evaluation.selectionGaps).toEqual(['1.2']);
expect(evaluation.roleMismatches).toEqual(['1.1']);
expect(evaluation.extras).toEqual(['2.1']);
expect(evaluation.verdict).toBe('Incomplete + extras');
});
it('classifies opposing recall and extra-control changes as mixed', () => {
const previous = evaluateRun(run(['1.1'], [{ controlId: '1.1', relationship: 'primary' }]), finding);
const current = evaluateRun(run(
['1.1', '1.2', '2.1'],
[
{ controlId: '1.1', relationship: 'primary' },
{ controlId: '1.2', relationship: 'supporting' },
{ controlId: '2.1', relationship: 'supporting' }
]
), finding);
expect(changeFor(previous, current)).toBe('Mixed');
});
});