import { createElement } from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import { describe, expect, it } from 'vitest'; import type { FindingRecord } from '../../src/domain/finding'; import { policyFindingCategories } from '../../src/profiles/group-policy/categories'; import { FindingReader, selectFindingFields } from '../../src/features/finding-reader/FindingReader'; function fixture(values: Record, title = 'Synthetic setting'): FindingRecord { return { id: 'synthetic', index: 0, title, filled: [], meta: [], fields: Object.entries(values).map(([label, value], index) => ({ index, label, value })) }; } describe('GPO category badges', () => { it.each([ ['system access · lockoutbadcount', 'System Access', 'Account Lockout'], ['system access · passwordhistorysize', 'System Access', 'Password Policy'], ['privilege rights · senetworklogonright', 'Privilege Rights', 'Logon Rights'], ['privilege rights · sebackupprivilege', 'Privilege Rights', 'Security'], ['registry values · machine\\software\\synthetic', 'Registry Values', 'Security'], ['system services · synthetic', 'System Services', 'Security'], ])('uses native section evidence from legacy headings: %s', (title, section, detail) => { const badges = policyFindingCategories(fixture({}, title), 'group-policy'); expect(badges).toContain(section); expect(badges).toContain(detail); }); it('uses structural registry branches only when no more specific family is known', () => { expect(policyFindingCategories(fixture({ 'Registry path': 'SOFTWARE\\Synthetic' }), 'group-policy')).toEqual(['Registry', 'Software']); expect(policyFindingCategories(fixture({ 'Registry path': 'SYSTEM\\CurrentControlSet\\Synthetic' }), 'group-policy')).toEqual(['Registry', 'System']); expect(policyFindingCategories(fixture({ 'Registry path': 'SOFTWARE\\Policies\\Microsoft\\Office\\16.0' }), 'group-policy')).toEqual(['Office']); expect(policyFindingCategories(fixture({ Description: 'privilege rights · sebackupprivilege' }), 'group-policy')).toEqual([]); }); it.each(['computer', 'user'])('adds the %s scope badge and retains the report field', scope => { const record = fixture({ Category: 'GPOs', Scope: scope }); const html = renderToStaticMarkup(createElement(FindingReader, { record, title: record.title, linkedSheets: [], resultReferences: [], search: '', position: 0, recordCount: 1, toolId: 'group-policy', onPrevious() {}, onNext() {}, onReview() {} })); expect(html).toContain(`data-policy-scope="true">Scope: ${scope}`); expect(selectFindingFields(record, record.title, false, 'group-policy').summary).toContainEqual({ index: 1, label: 'Scope', value: scope }); expect(html).toContain('

Scope

'); }); it('does not invent a scope badge when scope is absent or blank', () => { const examples: Record[] = [{}, { Scope: ' ' }]; for (const values of examples) { const record = fixture(values); const html = renderToStaticMarkup(createElement(FindingReader, { record, title: record.title, linkedSheets: [], resultReferences: [], search: '', position: 0, recordCount: 1, toolId: 'group-policy', onPrevious() {}, onNext() {}, onReview() {} })); expect(html).not.toContain('data-policy-scope'); } }); it('labels audit settings even when the customer setting is absent', () => { const record = fixture({ Baseline: 'Windows Server 2022 Security Baseline', 'Policy type': 'advanced-audit-policy', 'Configured Value': 'Not configured' }); expect(policyFindingCategories(record, 'group-policy')).toEqual(['Windows', 'Audit']); expect(selectFindingFields(record, record.title, false, 'group-policy').summary.map(field => field.label)).not.toContain('Policy type'); }); it('supports the previous generated audit heading and legacy audit templates', () => { expect(policyFindingCategories(fixture({}, 'system audit subcategory · synthetic-id'), 'group-policy')).toEqual(['Audit']); expect(policyFindingCategories(fixture({ 'Policy type': 'security-template', 'Policy section': 'Event Audit' }), 'group-policy')).toEqual(['Audit']); }); it.each([ ['Microsoft 365 Apps for enterprise Security Baseline', 'Office'], ['Office 2016 Security Baseline', 'Office'], ['Microsoft Edge Security Baseline', 'Edge'] ])('identifies the product family of %s', (baseline, category) => { expect(policyFindingCategories(fixture({ Baseline: baseline }), 'group-policy')).toEqual([category]); }); it.each([ ['SOFTWARE\\Policies\\Microsoft\\Windows Defender', 'Defender'], ['SOFTWARE\\Policies\\Microsoft\\WindowsFirewall\\DomainProfile', 'Firewall'], ['SOFTWARE\\Policies\\Microsoft\\FVE', 'BitLocker'], ['SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\LAPS', 'LAPS'] ])('identifies a known registry family %s', (path, category) => { expect(policyFindingCategories(fixture({ 'Registry path': path, Baseline: 'Windows 11 Security Baseline' }), 'group-policy')).toEqual(['Windows', category]); }); it('prefers explicit Office or Edge paths over the package product', () => { for (const product of ['Office', 'Edge']) { expect(policyFindingCategories(fixture({ 'Registry path': `HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\${product}\\16.0`, Baseline: 'Windows 11 Security Baseline' }), 'group-policy')).toEqual([product]); } }); it('uses a conservative fallback and does not search arbitrary finding text', () => { expect(policyFindingCategories(fixture({ Baseline: 'Windows 11 Security Baseline' }), 'group-policy')).toEqual(['Windows', 'Security']); expect(policyFindingCategories(fixture({ Description: 'Office Audit Firewall' }), 'group-policy')).toEqual([]); expect(policyFindingCategories(fixture({ Baseline: 'Windows 11 Security Baseline' }), 'cis-cat')).toEqual([]); }); it('renders compact badges alongside GPOs without changing the outcome', () => { const record = fixture({ Category: 'GPOs', Status: 'Fail', Baseline: 'Windows Server 2022 Security Baseline', 'Policy type': 'advanced-audit-policy' }); const html = renderToStaticMarkup(createElement(FindingReader, { record, title: record.title, linkedSheets: [], resultReferences: [], search: '', position: 0, recordCount: 1, toolId: 'group-policy', onPrevious() {}, onNext() {}, onReview() {} })); expect(html).toContain('Category: GPOs'); expect(html).toContain('data-derived-category="gpo">Windows'); expect(html).toContain('data-derived-category="gpo">Audit'); expect(html).toContain('data-outcome="fail"'); }); });