100 lines
6.5 KiB
TypeScript
100 lines
6.5 KiB
TypeScript
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<string, string>, 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}</span>`);
|
|
expect(selectFindingFields(record, record.title, false, 'group-policy').summary).toContainEqual({ index: 1, label: 'Scope', value: scope });
|
|
expect(html).toContain('<h4>Scope</h4>');
|
|
});
|
|
|
|
it('does not invent a scope badge when scope is absent or blank', () => {
|
|
const examples: Record<string, string>[] = [{}, { 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</span>');
|
|
expect(html).toContain('data-derived-category="gpo">Audit</span>');
|
|
expect(html).toContain('data-outcome="fail"');
|
|
});
|
|
});
|