53 lines
3.1 KiB
TypeScript
53 lines
3.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { groundRegulatoryMappingResult, regulatoryMappingResultValidationErrors } from '../../src/compliance/regulatory-mapping';
|
|
|
|
const grounded = new Map([['5.1', new Set(['semantic-5.1', 'reference-5.1'])]]);
|
|
|
|
describe('regulatory mapping output validation', () => {
|
|
it('accepts a grounded proposal and rejects unknown controls, duplicate controls, and foreign evidence', () => {
|
|
const valid = {
|
|
schemaVersion: 1, outcome: 'mapped', mappings: [{
|
|
controlId: '5.1', relationship: 'primary', confidence: 'high', rationale: 'Synthetic rationale.',
|
|
evidenceChunkIds: ['semantic-5.1', 'reference-5.1']
|
|
}]
|
|
};
|
|
expect(regulatoryMappingResultValidationErrors(valid, grounded)).toEqual([]);
|
|
expect(regulatoryMappingResultValidationErrors({ ...valid, mappings: [
|
|
...valid.mappings, { ...valid.mappings[0], evidenceChunkIds: ['other'] }
|
|
] }, grounded)).toEqual(expect.arrayContaining([
|
|
expect.stringContaining('duplicates control 5.1'),
|
|
expect.stringContaining('not grounded')
|
|
]));
|
|
expect(regulatoryMappingResultValidationErrors({ ...valid, mappings: [{ ...valid.mappings[0], controlId: '9.9' }] }, grounded))
|
|
.toEqual(expect.arrayContaining([expect.stringContaining('unknown candidate control')]));
|
|
});
|
|
|
|
it('trims ungrounded evidence ids, drops fully ungrounded known-control mappings, and leaves unknown controls for validation', () => {
|
|
const result = groundRegulatoryMappingResult({
|
|
schemaVersion: 1, outcome: 'mapped', mappings: [
|
|
{ controlId: '5.1', relationship: 'primary', confidence: 'high', rationale: 'One good id kept.', evidenceChunkIds: ['semantic-5.1', 'foreign'] },
|
|
{ controlId: '5.1', relationship: 'supporting', confidence: 'low', rationale: 'No real evidence.', evidenceChunkIds: ['foreign', 'other'] }
|
|
]
|
|
}, grounded) as { mappings: Array<{ evidenceChunkIds: string[] }> };
|
|
expect(result.mappings).toHaveLength(1);
|
|
expect(result.mappings[0].evidenceChunkIds).toEqual(['semantic-5.1']);
|
|
|
|
const unknown = groundRegulatoryMappingResult({
|
|
schemaVersion: 1, outcome: 'mapped', mappings: [{ controlId: '9.9', relationship: 'primary', confidence: 'high', rationale: 'x', evidenceChunkIds: ['semantic-5.1'] }]
|
|
}, grounded) as { mappings: unknown[] };
|
|
expect(unknown.mappings).toHaveLength(1);
|
|
expect(regulatoryMappingResultValidationErrors(unknown, grounded)).toEqual(expect.arrayContaining([expect.stringContaining('unknown candidate control')]));
|
|
});
|
|
|
|
it('requires refusal outcomes to contain no mappings and a bounded reason', () => {
|
|
expect(regulatoryMappingResultValidationErrors({
|
|
schemaVersion: 1, outcome: 'no_relevant_control', reason: 'No direct relationship.', mappings: []
|
|
}, grounded)).toEqual([]);
|
|
expect(regulatoryMappingResultValidationErrors({
|
|
schemaVersion: 1, outcome: 'insufficient_context', reason: 'Unknown.', mappings: [{
|
|
controlId: '5.1', relationship: 'supporting', confidence: 'low', rationale: 'Synthetic.', evidenceChunkIds: ['semantic-5.1']
|
|
}]
|
|
}, grounded)).toContain('A refusal outcome must not include mappings.');
|
|
});
|
|
});
|