Assessor_2.0/tests/reporting/report-input-assembler.test.ts

70 lines
3.9 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest';
import type { AssessorRepository } from '../../src/persistence/assessor-repository';
import type { UnifiedResultProjection } from '../../src/domain/unified-result';
import { makeSheet } from '../../src/importers/sheet-factory';
import { loadCanonicalProjectWorkspace } from '../../src/features/project-import/load-canonical-project-workspace';
import { assembleReportProjectionInput } from '../../src/reporting/report-input-assembler';
vi.mock('../../src/features/project-import/load-canonical-project-workspace', () => ({
loadCanonicalProjectWorkspace: vi.fn()
}));
describe('report input assembly', () => {
it('freezes only selected Dummy source facts on export without inventing environment facts or a policy verdict', async () => {
const sheet = makeSheet('Dummy', [['Title', 'Source: Scan'], ['Synthetic check', 'PingCastle']],
'', 'dummy.csv', { isProjectSheet: true });
vi.mocked(loadCanonicalProjectWorkspace).mockResolvedValue({
models: [], assessmentIds: ['dummy-assessment'],
dataset: { fileName: 'Dummy', sheets: [sheet], scanTool: 'PingCastle' } as never
});
const result = {
resultProjectionId: 'dummy-result', sourceKind: 'scanner-finding', sourceResultId: 'dummy-source',
projectId: 'dummy-project', assessmentId: 'dummy-assessment', scanRunId: 'dummy-run',
collectionRunId: 'dummy-run', title: 'Print Spooler hardening', sourceTool: 'PingCastle', sourceRuleId: 'A-DC-Spooler',
severityNormalized: 'medium', outcomeNormalized: 'fail', isDeviation: true,
categories: [], frameworkReferences: [], policyActualValue: 0, policyBaselineValue: 1
} as unknown as UnifiedResultProjection;
const queryUnifiedResults = vi.fn(async (query: { sourceKind?: string[] }) => ({
items: query.sourceKind?.includes('scanner-finding') ? [result] : [],
total: query.sourceKind?.includes('scanner-finding') ? 1 : 0,
offset: 0, limit: 500
}));
const repository = {
getProject: vi.fn(async () => ({ id: 'dummy-project', name: 'Dummy Customer', attributes: {}, createdAt: '', updatedAt: '' })),
queryUnifiedResults,
getEnvironmentSnapshot: vi.fn(async () => ({ observations: [] })),
listReviews: vi.fn(async () => []),
listProjectProcessingRuns: vi.fn(async () => [{
id: 'other-timeslot-processing', artifactId: 'other-artifact', diagnosticCodes: ['other-diagnostic'],
status: 'complete', processors: [], completedAt: '2026-09-01T00:00:00Z'
}]),
listGpoPolicyAnalyses: vi.fn(async () => []),
listPolicySnapshotAggregations: vi.fn(async () => []),
listPolicyEvaluations: vi.fn(async () => []),
listImportArtifacts: vi.fn(async () => []),
listGpoBackupInstances: vi.fn(async () => [])
} as unknown as AssessorRepository;
const input = await assembleReportProjectionInput(repository, {
projectId: 'dummy-project', assessmentIds: ['dummy-assessment'], scanRunIds: ['dummy-run'],
generatedAt: '2026-09-23T10:00:00Z'
});
expect(input.results).toEqual([result]);
expect(input.domainOf(result)).toBe('hardening');
expect(input.environment).toEqual([
{ key: 'Domain', value: undefined }, { key: 'Forest', value: undefined },
{ key: 'Domain Controller', value: undefined }
]);
expect(input.policyEntries).toEqual([]);
expect(input.delta).toBeUndefined();
expect(input.diagnostics).toEqual([]);
expect(input.provenance?.some(entry => entry.id === 'other-timeslot-processing')).toBe(false);
expect(queryUnifiedResults).toHaveBeenCalledWith(expect.objectContaining({
audience: 'internal-analysis', projectId: 'dummy-project', assessmentIds: ['dummy-assessment'],
scanRunIds: ['dummy-run']
}));
expect(repository.getEnvironmentSnapshot).toHaveBeenCalledWith(expect.objectContaining({
projectId: 'dummy-project', scanRunIds: ['dummy-run']
}));
});
});