Assessor_2.0/tests/compliance/regulatory-mapping-earlier-...

42 lines
2.7 KiB
TypeScript

// @vitest-environment jsdom
import { act } from 'react';
import { createRoot } from 'react-dom/client';
import { expect, it, vi } from 'vitest';
import type { RegulatoryMappingResponse } from '../../src/compliance/regulatory-mapping';
import { RegulatoryMappingPanel } from '../../src/compliance/ui/RegulatoryMappingPanel';
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
// Synthetic: A.8.3 was auto-accepted by an earlier run of the rule; the current run no longer retrieves it.
const response: RegulatoryMappingResponse = {
version: 1, projectId: 'project-1', resultProjectionId: 'policy-evaluation-comparison:one', generationEnabled: true, state: 'succeeded',
decisions: [{ version: 1, id: 'decision-1', ruleKey: 'GPOs:synthetic', sourceTool: 'GPOs', mappingId: 'regulatory-mapping-old',
controlId: '8.3', decision: 'accepted', createdAt: '2026-10-05T10:00:00.000Z' }],
earlierControls: [{ controlId: '8.3', annexAControlId: 'A.8.3', title: 'Synthetic earlier title' }],
run: {
version: 1, id: 'regulatory-mapping-new', ruleKey: 'GPOs:synthetic', sourceTool: 'GPOs', status: 'succeeded', queryHash: 'a'.repeat(64),
preparedQuery: { schemaVersion: 1, query: 'Synthetic public query.', specificity: 'topic', publicTopics: [] },
corpusId: 'iso-test', corpusVersion: 'v2', sourceHashes: [], embeddingModel: 'bge-m3', retrievalVersion: 'test', promptVersion: 'test',
outputSchemaVersion: 1, model: 'work-model', createdAt: '2026-10-06T10:00:00.000Z', updatedAt: '2026-10-06T10:00:00.000Z',
candidates: [{ controlId: '8.2', annexAControlId: 'A.8.2', title: 'Synthetic current title', score: 0.9, evidence: [] }],
result: { schemaVersion: 1, outcome: 'mapped', mappings: [{ controlId: '8.2', relationship: 'primary', confidence: 'high', rationale: 'Synthetic.', evidenceChunkIds: [] }] }
}
};
it('rejects a control accepted by an earlier run that the current run no longer retrieves', () => {
const onDecision = vi.fn();
const container = document.createElement('div');
const root = createRoot(container);
act(() => root.render(<RegulatoryMappingPanel response={response} loading={false} error="" onStart={() => {}} onDecision={onDecision}/>));
const earlier = container.querySelector('[aria-label="Earlier decisions"]')!;
expect(earlier.textContent).toContain('A.8.3 — Synthetic earlier title');
expect(earlier.textContent).toContain('accepted');
expect(earlier.textContent).not.toContain('A.8.2');
const reject = [...earlier.querySelectorAll('button')].find(button => button.textContent === 'Reject')!;
act(() => reject.click());
expect(onDecision).toHaveBeenCalledWith(expect.objectContaining({ controlId: '8.3' }), 'rejected', '');
act(() => root.unmount());
});