// @vitest-environment jsdom import { act } from 'react'; import { createRoot } from 'react-dom/client'; import { afterEach, expect, it, vi } from 'vitest'; import { useApp } from '../../src/app/AppProvider'; import { resetEnginePreferencesForTests, setEngineEnabled } from '../../src/app/engine-preferences'; import { AssessorApiClient } from '../../src/api/assessor-api-client'; import { DashboardPanel } from '../../src/features/dashboard/DashboardPanel'; import { makeSheet } from '../../src/importers/sheet-factory'; import { genericProfile } from '../../src/profiles/generic/generic-profile'; import type { EnvironmentSnapshot } from '../../src/domain/environment-context'; vi.mock('../../src/app/AppProvider', () => ({ useApp: vi.fn() })); vi.mock('../../src/features/search-filter/WorkTimeslotControl', () => ({ WorkTimeslotControl: () => Synthetic timeslot })); afterEach(() => { vi.restoreAllMocks(); vi.unstubAllGlobals(); document.body.replaceChildren(); }); it.each(['dark', 'light'])('integrates Directory and opens all Domain Information and native evidence in %s', async theme => { document.documentElement.dataset.theme = theme; vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true); vi.stubGlobal('ResizeObserver', class { observe() {} disconnect() {} }); localStorage.clear(); resetEnginePreferencesForTests(); setEngineEnabled('context', false); const sheet = makeSheet('Synthetic', [['Name', 'Status'], ['Control', 'Failed']], '', 'synthetic.csv', { isProjectSheet: true }); vi.mocked(useApp).mockReturnValue({ dataset: { fileName: 'Synthetic client', sheets: [sheet], scanTool: 'Generic' }, activeSheet: sheet, activeProfile: genericProfile, reviews: {}, targetProjectId: 'synthetic-client', activeAssessmentIds: ['slot'], activeScanRunIds: ['run'], facetFilters: {}, setStatusFilter: vi.fn(), setFacetFilter: vi.fn(), setPathFindingIds: vi.fn(), resetFilters: vi.fn(), setView: vi.fn(), setActionOnly: vi.fn(), setActiveSheet: vi.fn() } as unknown as ReturnType); const tool = { id: 'synthetic', name: 'Synthetic scanner' }; const facts: Array<[string, string | number]> = [ ['domain.fqdn', 'synthetic.example'], ['domain.netbios_name', 'SYNTHETIC'], ['forest.name', 'synthetic.forest'], ['domain.count', 2], ['domain.controller_count', 3], ['domain.functional_level', 'Domain level'], ['forest.functional_level', 'Forest level'], ['forest.schema_version', 'Windows Server 2019'], ['domain.created_at', '2001-03-08'], ['entra.tenant_name', 'Synthetic tenant'] ]; const snapshot: EnvironmentSnapshot = { version: 1, projectId: 'synthetic-client', scanRunIds: ['run'], generatedAt: '2026-10-02T12:00:00Z', coverage: { observed: 10, explicitlyAbsent: 0, empty: 0, restricted: 0, incomplete: 0 }, observations: facts.map(([property, value]) => ({ version: 1, id: property, scanRunId: 'run', importFileId: 'file', tool, subject: { type: 'domain' }, property, label: property, originalValue: value, normalizedValue: value, valueType: typeof value === 'number' ? 'number' : 'string', state: 'observed', source: { rowIndex: 0 }, mappingVersion: '1', attributes: {} })), sections: [{ version: 1, id: 'native-domain', scanRunId: 'run', importFileId: 'file', tool, sectionKey: 'sectionDomainInformation', label: 'Domain source', ordinal: 1, state: 'observed', tables: [{ name: 'Domain source', headers: ['Original evidence'], rows: [['Synthetic retained source']] }], source: { rowIndex: 0 }, extractorVersion: '1', attributes: {} }] }; vi.spyOn(AssessorApiClient.prototype, 'getEnvironmentSnapshot').mockResolvedValue(snapshot); vi.spyOn(AssessorApiClient.prototype, 'listProjectGpoBackupStatus').mockResolvedValue({ records: [] } as never); const host = document.createElement('div'); document.body.append(host); const root = createRoot(host); try { await act(async () => root.render()); const domain = host.querySelector('.client-domain-information')!; for (const value of ['SYNTHETIC', 'Windows Server 2019', '2001-03-08', 'Synthetic tenant']) expect(domain.textContent).toContain(value); expect([...host.querySelectorAll('h3')].some(heading => heading.textContent === 'Directory')).toBe(false); const button = domain.querySelector('[aria-label="Open Domain Information results"]')!; expect(button).not.toBeNull(); await act(async () => button.click()); const popup = document.querySelector('[role="dialog"]')!; expect(popup).not.toBeNull(); expect([...popup.querySelectorAll('.client-env-facts dt')].map(item => item.textContent)).toEqual([ 'Domain', 'NetBIOS name', 'Forest', 'Domains', 'Domain controllers', 'Domain functional level', 'Forest functional level', 'DC OS', 'Schema version', 'Domain created', 'Entra ID' ]); for (const [, value] of facts) expect(popup.textContent).toContain(String(value)); expect(popup.textContent).toContain('Synthetic retained source'); expect(useApp().setFacetFilter).not.toHaveBeenCalled(); } finally { act(() => root.unmount()); } });