70 lines
4.2 KiB
TypeScript
70 lines
4.2 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import type { EnvironmentSnapshot } from '../../src/domain/environment-context';
|
|
import { clientInfoOverview, cloudInformationTileFacts, operatingSystemOverview } from '../../src/features/dashboard/client-info-facts';
|
|
import { reportGpoBackupCount, reportHeaderFacts } from '../../src/reporting/report-header-facts';
|
|
|
|
const observation = (property: string, value: unknown, label = property) => ({
|
|
property, label, state: 'observed', normalizedValue: value, originalValue: value,
|
|
subject: { type: 'domain' }, tool: { id: 'synthetic' }, sectionKey: 'synthetic'
|
|
});
|
|
|
|
const snapshot = {
|
|
version: 1, projectId: 'synthetic-project', scanRunIds: ['synthetic-run'], generatedAt: '2026-10-08T00:00:00Z',
|
|
coverage: { observed: 0, explicitlyAbsent: 0, empty: 0, restricted: 0, incomplete: 0 },
|
|
observations: [
|
|
observation('domain.fqdn', 'synthetic.example', 'Domain'),
|
|
observation('forest.name', 'synthetic.example'),
|
|
observation('domain.controller_count', 2, 'DC count'),
|
|
observation('domain.recycle_bin_enabled', false, 'Recycle Bin enabled')
|
|
],
|
|
sections: [{
|
|
sectionKey: 'sectionUserInformation', label: 'Users', state: 'observed',
|
|
tables: [{ name: 'User information', headers: ['Nb User Accounts', 'Nb Enabled', 'Nb Disabled'], rows: [[12, 10, 2]] }]
|
|
}]
|
|
} as unknown as EnvironmentSnapshot;
|
|
|
|
describe('Technical Report Information facts', () => {
|
|
it('states exactly the Client Info overview facts of the same snapshot', () => {
|
|
const facts = reportHeaderFacts(snapshot, { gpoCount: 3 })!;
|
|
const overview = clientInfoOverview(snapshot, { gpoCount: 3 });
|
|
expect(facts.data).toEqual([
|
|
{ label: 'AD Domains', value: '1' }, { label: 'Entra Tenant', value: '—' }, { label: 'User Accounts', value: '12' },
|
|
{ label: 'Computer Objects', value: '—' }, { label: 'Domain Controllers', value: '2' }, { label: 'GPOs', value: '3' }]);
|
|
expect(facts.data.map(item => item.label)).toEqual(overview.data.map(item => item.label));
|
|
// Domain Information without the counts Data already shows, as in Client Info.
|
|
expect(facts.domainInformation).toEqual(overview.domainInformation);
|
|
expect(facts.domainInformation.some(item => item.label === 'Domain controllers')).toBe(false);
|
|
const group = (title: string) => facts.groups.find(item => item.title === title)!.facts;
|
|
expect(facts.groups.map(item => item.title)).toEqual(
|
|
['Resilience', 'Inventory', 'Password policy', 'Certificates & PKI', 'Operating systems', 'Cloud Information']);
|
|
expect(group('Resilience')).toEqual(overview.detail.resilience.slice(0, 4));
|
|
expect(group('Inventory')).toEqual(overview.inventory.slice(0, 4));
|
|
expect(group('Operating systems')).toEqual(operatingSystemOverview(overview.detail.operatingSystems));
|
|
expect(group('Cloud Information').map(item => item.label)).toEqual(cloudInformationTileFacts(snapshot).map(item => item.label));
|
|
// Unknown facts stay an em dash, never zero.
|
|
expect(group('Password policy').every(item => item.value === '—')).toBe(true);
|
|
});
|
|
|
|
it('infers one Entra tenant only from loaded Maester results, as Client Info does', () => {
|
|
expect(reportHeaderFacts(snapshot, { inferredEntraTenant: true })!.data[1]).toEqual({ label: 'Entra Tenant', value: '1' });
|
|
expect(reportHeaderFacts(undefined, {})).toBeUndefined();
|
|
});
|
|
|
|
it('counts GPOs like the GPO backup list: instances of the latest processed run per backup source', () => {
|
|
const artifacts = [
|
|
{ id: 'backup-a', kind: 'source-file', relativePath: 'gpo-backups/a.zip' },
|
|
{ id: 'backup-b', kind: 'source-file', relativePath: 'gpo-backups/b.zip' },
|
|
{ id: 'scan', kind: 'source-file', relativePath: 'scans/report.html' }
|
|
] as never;
|
|
const runs = [
|
|
{ id: 'run-a-old', artifactId: 'backup-a', status: 'complete', completedAt: '2026-10-01T00:00:00Z' },
|
|
{ id: 'run-a-new', artifactId: 'backup-a', status: 'complete', completedAt: '2026-10-02T00:00:00Z' }
|
|
] as never;
|
|
const instances = [
|
|
{ processingRunId: 'run-a-old' }, { processingRunId: 'run-a-new' }, { processingRunId: 'run-a-new' }
|
|
] as never;
|
|
expect(reportGpoBackupCount(artifacts, runs, instances)).toBe(2);
|
|
expect(reportGpoBackupCount(artifacts, [], instances)).toBeUndefined();
|
|
});
|
|
});
|