33 lines
2.4 KiB
TypeScript
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);
|
|
});
|