import { describe, expect, it } from 'vitest'; import type { UnifiedResultProjection } from '../../src/domain/unified-result'; import { resultsToPrivacySafeExportJson } from '../../src/exports/result-db-copy'; function result(overrides: Partial): UnifiedResultProjection { return { sourceKind: 'scanner-finding', title: 'Synthetic result', severityNormalized: 'medium', outcomeNormalized: 'pass', resultType: 'exposure_finding', isIoe: false, isDeviation: false, sourceTool: 'synthetic-tool', ...overrides } as UnifiedResultProjection; } describe('Result DB compact privacy-safe JSON export', () => { it('uses source rule IDs and includes every available actionable narrative', () => { const text = resultsToPrivacySafeExportJson([ result({ sourceRuleId: 'PK-CRITICAL-1', title: 'Critical deviation', description: 'Important evidence', recommendation: 'Urgent remediation', severityNormalized: 'critical', outcomeNormalized: 'fail', isIoe: true, isDeviation: true, affectedAsset: 'PRIVATE ASSET', reviewOwner: 'PRIVATE OWNER', processingStatus: 'current', reviewStatus: 'open' }), result({ sourceRuleId: 'PK-MEDIUM-1', title: 'Medium deviation', description: 'Medium evidence', recommendation: 'Medium remediation', outcomeNormalized: 'warning', isDeviation: true }), result({ title: 'Passed control' }), result({ sourceRuleId: 'PK-NOT-RUN-1', title: 'Unavailable control for alex@example.test', outcomeNormalized: 'not_run', severityNormalized: 'unknown' }) ]); const copied = JSON.parse(text); expect(copied.schemaVersion).toBe(1); expect(copied.summary).toMatchObject({ totalResults: 4, findingResults: 4, environmentResults: 0, actionableFindings: 2, notRunChecks: 1, findingOutcomes: { fail: 1, warning: 1, pass: 1, not_run: 1 } }); expect(copied.findings).toEqual([{ id: 'PK-CRITICAL-1', title: 'Critical deviation', description: 'Important evidence', recommendation: 'Urgent remediation', severity: 'critical', outcome: 'fail', resultType: 'exposure_finding', isIoe: true, deviation: true, tool: 'synthetic-tool' }, { id: 'PK-MEDIUM-1', title: 'Medium deviation', description: 'Medium evidence', recommendation: 'Medium remediation', severity: 'medium', outcome: 'warning', resultType: 'exposure_finding', isIoe: false, deviation: true, tool: 'synthetic-tool' }]); expect(copied.notRunChecks).toEqual([{ id: 'PK-NOT-RUN-1', title: 'Unavailable control for [redacted-email]', severity: 'unknown', resultType: 'exposure_finding', tool: 'synthetic-tool' }]); expect(text).not.toMatch(/Passed control|PRIVATE|alex@example\.test/); }); it('uses null when the source has no rule ID instead of inventing one', () => { const copied = JSON.parse(resultsToPrivacySafeExportJson([ result({ title: 'Unidentified deviation', outcomeNormalized: 'fail', isDeviation: true }) ])); expect(copied.findings[0].id).toBeNull(); }); it('groups approved environment facts and excludes identities and arbitrary values', () => { const os = result({ sourceKind: 'environment-observation', title: 'Operating System', environmentState: 'observed', environmentProperty: 'operating_system.name', environmentValueType: 'string', environmentSubjectIdentity: 'PRIVATE COMPUTER', environmentNormalizedValue: 'Windows Server 2022' }); const privateDomain = result({ sourceKind: 'environment-observation', title: 'Domain', environmentState: 'observed', environmentProperty: 'domain.fqdn', environmentValueType: 'string', environmentNormalizedValue: 'PRIVATE.EXAMPLE' }); const copied = JSON.parse(resultsToPrivacySafeExportJson([os, os, privateDomain])); expect(copied.summary).toMatchObject({ totalResults: 3, findingResults: 0, environmentResults: 3 }); expect(copied.environmentFacts).toEqual([{ title: 'Operating System', property: 'operating_system.name', value: 'Windows Server 2022', tool: 'synthetic-tool' }]); expect(JSON.stringify(copied)).not.toMatch(/PRIVATE/); }); it('includes non-identifying environment aggregates and configuration state in the AI export', () => { const facts: UnifiedResultProjection[] = [ ['user.account_count', 'number', 16], ['computer.account_count', 'number', 1], ['user.password_never_expires_count', 'number', 15], ['admin_group.count', 'number', 14], ['pki.certificate_template_count', 'number', 12], ['password_policy.minimum_length', 'number', 5], ['password_policy.complexity_enabled', 'boolean', false], ['laps.windows.present', 'boolean', false] ].map(([property, valueType, value]) => result({ sourceKind: 'environment-observation', title: `Fact ${property}`, environmentState: 'observed', environmentSubjectType: 'active-directory-environment', environmentProperty: property as string, environmentValueType: valueType as 'number' | 'boolean', environmentNormalizedValue: value as number | boolean })); const excludedIdentifier = result({ sourceKind: 'environment-observation', title: 'Domain', environmentState: 'observed', environmentProperty: 'domain.fqdn', environmentValueType: 'string', environmentNormalizedValue: 'PRIVATE.EXAMPLE' }); const copied = JSON.parse(resultsToPrivacySafeExportJson([...facts, excludedIdentifier])); const byProperty = new Map(copied.environmentFacts.map((fact: { property: string; value: unknown }) => [fact.property, fact.value])); expect(byProperty.get('user.account_count')).toBe(16); expect(byProperty.get('computer.account_count')).toBe(1); expect(byProperty.get('user.password_never_expires_count')).toBe(15); expect(byProperty.get('admin_group.count')).toBe(14); expect(byProperty.get('pki.certificate_template_count')).toBe(12); expect(byProperty.get('password_policy.minimum_length')).toBe(5); expect(byProperty.get('password_policy.complexity_enabled')).toBe(false); expect(byProperty.get('laps.windows.present')).toBe(false); expect(byProperty.has('domain.fqdn')).toBe(false); expect(JSON.stringify(copied)).not.toMatch(/PRIVATE/); }); });