Assessor_2.0/tests/reporting/client-report-domains.test.ts

33 lines
2.4 KiB
TypeScript

import { expect, it } from 'vitest';
import type { ImportedDataset } from '../../src/domain/dataset';
import type { UnifiedResultProjection } from '../../src/domain/unified-result';
import { makeSheet } from '../../src/importers/sheet-factory';
import { securityDomainCatalog } from '../../src/evaluation/security-domains';
import { clientReportInput } from '../../src/reporting/client-report-projection';
// Synthetic data only. Management report domain rows count Work records, as the headline and Client Info do.
it('counts report domain rows on the same Work records as the headline, so their sums reconcile', () => {
const sheet = makeSheet('Synthetic · All Records', [
['Title', 'Status', 'Category', 'Source Rule ID', 'Scope', 'Technical Identity', 'Policy type', 'Policy section', 'Source: Scan'],
['Audit on DCs', 'Matched', 'Anomalies', 'A-AuditDC', '', '', '', '', 'PingCastle · synthetic'],
['Synthetic user right', 'Deviation', 'GPOs', '', 'computer', 'gpo-policy-identity-synthetic', 'security-template', 'Privilege Rights', 'GPOs · synthetic']
], '', 'synthetic', { isProjectSheet: true });
// One rolled-up GPO setting backed by two per-member comparison results.
const results = ['eval-1', 'eval-2'].map((id, index) => ({
resultProjectionId: `r${index}`, sourceKind: 'policy-evaluation', sourceResultId: id, sourceTool: 'GPOs', categories: [],
isDeviation: true, policyScope: 'computer', policyIdentityKey: 'gpo-policy-identity-synthetic'
})) as unknown as UnifiedResultProjection[];
const input = clientReportInput({
project: { id: 'project-synthetic', name: 'Synthetic' } as never, generatedAt: '2026-10-04T00:00:00.000Z',
results, dataset: { sheets: [sheet] } as unknown as ImportedDataset
});
const domains = input.workspaceDomains!;
expect(domains.map(domain => domain.domainId)).toEqual(securityDomainCatalog.map(domain => domain.id));
expect(domains.reduce((sum, domain) => sum + domain.deviations, 0)).toBe(input.workspaceCounts!.deviations);
expect(domains.reduce((sum, domain) => sum + domain.assessed, 0)).toBe(input.workspaceCounts!.assessed);
// The result-row summary counts both comparison rows; the Work-level rows never do.
const resultRows = input.results.filter(result => result.isDeviation).length;
expect(resultRows).toBe(2);
expect(domains.reduce((sum, domain) => sum + domain.assessed, 0)).toBeLessThan(sheet.analysis.records.length + 1);
});