Assessor_2.0/tests/features/gpo-duplicate-results.test.tsx

138 lines
8.7 KiB
TypeScript

import { createElement } from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import { describe, expect, it } from 'vitest';
import type { UnifiedResultProjection } from '../../src/domain/unified-result';
import { appendPolicyObservationsToDataset } from '../../src/features/project-import/policy-observations-to-dataset';
import { inlineResultTableSheets } from '../../src/features/linked-results/inline-result-tables';
import { buildPolicyDuplicatePresentation, policyEvidenceResultSheets, POLICY_DUPLICATE_DETAILS, POLICY_CONFLICT_DETAILS } from '../../src/profiles/group-policy/conflict-presentation';
import { buildPolicyWorkResults } from '../../src/evaluation/policy-work-results';
import { LinkedResults } from '../../src/features/linked-results/LinkedResults';
import { FindingReader, selectFindingFields } from '../../src/features/finding-reader/FindingReader';
function source(id: string, value = 'A B'): UnifiedResultProjection {
return { sourceKind: 'policy-observation', sourceResultId: id, projectId: 'synthetic', assessmentId: 'slot', title: 'Mode',
importedAt: '2026-09-06T00:00:00Z', policyScope: 'computer', policyDeliveryMechanism: 'registry-policy',
policyIdentityStatus: 'resolved', policyIdentityKey: 'mode', policyBackupInstanceId: `backup-${id}`,
sourceLocator: { objectPath: `C:/Private/GPO_Backup/${id}/{A40C8C9D-D16A-42E0-9E18-E490BA2E8867}/DomainSysvol/GPO/Machine/registry.pol#records=${id}` },
policyValues: [{ kind: 'registry-policy', key: 'Software\\Policies\\Synthetic', valueName: 'Mode', operation: 'set-value',
typeCode: 1, data: { kind: 'string', value } }] } as unknown as UnifiedResultProjection;
}
function fixture(sources = [source('a'), source('b'), source('c')]) {
const dataset = appendPolicyObservationsToDataset(null, 'Synthetic', sources)!;
const record = dataset.sheets[0].analysis.records[0];
return { record, sheets: inlineResultTableSheets(record) };
}
describe('GPO duplicate Results', () => {
it('shows one shared typed value and every source, without conflict variants', () => {
const { record, sheets } = fixture();
expect(sheets).toHaveLength(2);
expect(sheets[0].name).toBe('Duplicate setting');
expect(sheets[0].rows).toEqual([['Value', 'Type', 'Sources'], ['A B', 'REG_SZ (1)', '3']]);
expect(sheets[0].resultEmphasisColumns).toEqual([]);
expect(sheets[1].rows[0]).toEqual(['Source', 'Source path', 'Backup', 'Record']);
expect(sheets[1].rows[3]).toEqual(['Source 3', '{A40C8C9D-D16A-42E0-9E18-E490BA2E8867}/DomainSysvol/GPO/Machine/registry.pol#records=c', 'backup-c', 'c']);
expect(sheets[0].resultPreamble).toContain('Value name: Mode');
expect(sheets[0].resultPreamble).toContain('Scope: computer');
expect(record.fields.find(f => f.label === 'Duplicates')?.value).toBe('1 setting · 3 sources. Identical value and type.');
// The duplicate diagnostic marks the setting; it does not replace its verdict.
expect(record.fields.find(f => f.label === 'Status')?.value).toBe('No baseline rule');
});
it('enables the existing Results button and hides redundant evidence in the reader', () => {
const { record, sheets } = fixture();
const fields = selectFindingFields(record, record.title, true, 'group-policy');
expect(fields.summary.some(f => f.label === 'Duplicates')).toBe(true);
expect(fields.policyComparisonFields).toEqual([]);
expect([...fields.summary, ...fields.remainingFields].some(f => ['Sources', POLICY_DUPLICATE_DETAILS].includes(f.label))).toBe(false);
const html = renderToStaticMarkup(createElement(FindingReader, { record, title: record.title, linkedSheets: sheets,
resultReferences: [], search: '', position: 0, recordCount: 1, toolId: 'group-policy', onPrevious() {}, onNext() {}, onReview() {}, onResults() {} }));
const button = html.match(/<button[^>]*results-detail-btn[^>]*>/)?.[0];
expect(button).toBeDefined();
expect(button).not.toContain('disabled');
expect(html).toContain('Identical value and type.');
expect(html).toContain('backup-a');
expect(html).toContain('3 GPO backup sources');
});
it('uses the explanatory duplicate pipeline and inert value rendering without conflict warnings', () => {
const { sheets } = fixture([source('a', '<script>synthetic</script>'), source('b', '<script>synthetic</script>')]);
const html = renderToStaticMarkup(<LinkedResults sheets={sheets} resizableTables />);
expect(html).toContain('Duplicate setting');
expect(html).toContain('Duplicate detected');
expect(html).toContain('A duplicate alone is not a baseline deviation.');
expect(html).toContain('Setting details');
expect(html).toContain('Observed value');
expect(html).toContain('Technical source details');
expect(html).toContain('<table class="variant-comparison__table">');
expect(html).toContain('technical-path');
expect(html).toContain('&lt;script&gt;');
expect(html).not.toContain('<script>');
expect(html).not.toContain('result-evidence-difference');
expect(html).not.toContain('Conflicting variants');
expect(html).not.toMatch(/C:|Private|GPO_Backup/);
expect(html).not.toContain('Show source');
expect(html).toMatch(/2 sources<\/span><div class="variant-comparison__sources"[^>]*><code class="technical-path">/);
});
it('follows duplicate, setting, observed-value and technical-details reading order', () => {
const { sheets } = fixture();
const html = renderToStaticMarkup(<LinkedResults sheets={sheets} />);
const duplicate = html.indexOf('Duplicate detected');
const setting = html.indexOf('Setting details');
const observed = html.indexOf('Observed value');
const technical = html.indexOf('Technical source details');
expect(duplicate).toBeGreaterThan(-1);
expect(setting).toBeGreaterThan(duplicate);
expect(observed).toBeGreaterThan(setting);
expect(technical).toBeGreaterThan(observed);
});
it('labels empty duplicate values explicitly without changing the evidence', () => {
const { sheets } = fixture([source('a', ''), source('b', '')]);
const html = renderToStaticMarkup(<LinkedResults sheets={sheets} />);
expect(html).toContain('&quot;&quot;');
expect(html).toContain('Empty string');
expect(sheets[0].rows[1][0]).toBe('');
});
it('preserves original values, whitespace, source provenance and cached sheets', () => {
const sources = [source('a'), source('b')];
const before = JSON.stringify(sources);
const { record, sheets } = fixture(sources);
expect(sheets[0].analysis.records[0].fields.find(f => f.label === 'Value')?.value).toBe('A B');
expect(JSON.stringify(sources)).toBe(before);
expect(inlineResultTableSheets(record)).toBe(sheets);
});
it('retains 2300 duplicate source references without repeating the shared value', () => {
const { sheets } = fixture(Array.from({ length: 2300 }, (_, i) => source(String(i))));
expect(sheets[0].analysis.records).toHaveLength(1);
expect(sheets[0].rows[1][2]).toBe('2300');
expect(sheets[1].analysis.records).toHaveLength(2300);
expect(sheets[1].rows.at(-1)?.[0]).toBe('Source 2300');
});
it('does not manufacture duplicate evidence for conflicts, one source or absent values', () => {
const entry = buildPolicyWorkResults([source('a'), source('b')], [])[0];
expect(buildPolicyDuplicatePresentation({ ...entry, sources: [source('a')] })).toBeUndefined();
expect(buildPolicyDuplicatePresentation({ ...entry, sources: [source('a'), source('b', 'different')] })).toBeUndefined();
expect(buildPolicyDuplicatePresentation({ ...entry, status: 'Conflicts', duplicate: false, conflict: true })).toBeUndefined();
expect(buildPolicyDuplicatePresentation({ ...entry, sources: [source('a'), { ...source('b'), policyValues: [] }] })).toBeUndefined();
});
it('falls back to existing evidence on malformed, oversized or ambiguous envelopes', () => {
for (const value of ['{', JSON.stringify({ version: 2 }), 'x'.repeat(10 * 1024 * 1024 + 1)]) {
const { record } = fixture();
const changed = { ...record, fields: record.fields.map(f => f.label === POLICY_DUPLICATE_DETAILS ? { ...f, value } : f) };
expect(policyEvidenceResultSheets(changed)).toEqual([]);
expect(selectFindingFields(changed, changed.title, false, 'group-policy').policyComparisonFields).toHaveLength(0);
expect(changed.policySourceEvidence).toHaveLength(3);
expect(selectFindingFields({ ...changed, policySourceEvidence: undefined }, changed.title, false, 'group-policy').policyComparisonFields).toHaveLength(1);
}
const { record } = fixture();
const extra = record.fields.find(f => f.label === POLICY_DUPLICATE_DETAILS)!;
expect(policyEvidenceResultSheets({ ...record, fields: [...record.fields, { ...extra, label: POLICY_CONFLICT_DETAILS }] })).toEqual([]);
});
});