import { act, Profiler, useState, type ReactNode } from 'react' import { createRoot } from 'react-dom/client' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import type { ExplainResponse } from '@evofw/shared' import { AgentPortRuleForm, AgentPortImportForm } from '@/components/agents/agent-port-acl-forms' import { portAclDraftSchema } from '@/components/agents/port-acl-validation' import { AgentExplainSheet } from '@/components/agents/agent-explain-sheet' import { AgentOverrideSheet } from '@/components/agents/agent-settings-sheets' import { StatsAgentSelect } from '@/components/stats/stats-agent-select' import '@evofw/ui/globals.css' if (!import.meta.env.DEV) throw new Error('Development checks only') ;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true const results = document.querySelector('#results')! const metrics = document.querySelector('#metrics')! const host = document.querySelector('#fixture')! const root = createRoot(host) const qc = new QueryClient({ defaultOptions: { queries: { retry: false }, mutations: { retry: false } } }) const originalFetch = window.fetch const checks: string[] = [] const measured = { scope: 'Current fixture harness only; no baseline comparison', commits: 0, actualDurationMs: 0, requestCounts: {} as Record } function reportMetrics() { metrics.textContent = JSON.stringify(measured, null, 2) } function check(condition: unknown, label: string) { if (!condition) throw new Error(label); checks.push(`PASS ${label}`); results.textContent = checks.join('\n') } const flush = () => new Promise((resolve) => setTimeout(resolve, 50)) async function render(node: ReactNode) { await act(async () => { root.render( { measured.commits++; measured.actualDurationMs += actualDuration; reportMetrics() }}>{node}); await flush() }) } async function input(id: string, value: string) { await act(async () => { const field = document.getElementById(id) as HTMLInputElement; Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')!.set!.call(field, value); field.dispatchEvent(new Event('input', { bubbles: true })); await flush() }) } async function submit() { await act(async () => { document.querySelector('[data-slot="sheet-content"] form')!.requestSubmit(); await flush() }) } async function choose(id: string, label: string) { await act(async () => { document.getElementById(id)!.click(); await flush() }); await act(async () => { const option = [...document.querySelectorAll('[role="option"]')].find((item) => item.textContent?.trim() === label); if (!option) throw new Error(`Option not found: ${label}`); option.click(); await flush() }) } const explain: ExplainResponse = { agent_id: 'fixture', query: { ip: '203.0.113.10', port: 443, protocol: 'tcp', chain: 'input', dnat: false, connection_state: 'new' }, desired: { revision: 8, hash: 'desired', decision: null, stage: 'external', match: null }, applied: { revision: null, hash: null, same_as_desired: null, status: 'unsupported' }, matches: [], matches_total: 0, truncated: false, limits: ['desired_policy_not_kernel_observation', 'external_firewall_may_override_accept'], external_firewall: { observed_at: null, rule_count: 0, complete: false } } let explainGets = 0 let overridePosts: Record[] = [] let failOverride = true window.fetch = async (request, init) => { const url = String(request) const path = url.split('?')[0] const key = `${init?.method ?? 'GET'} ${path}` measured.requestCounts[key] = (measured.requestCounts[key] ?? 0) + 1 reportMetrics() if (path.endsWith('/api/v1/agents')) return Response.json({ items: [{ id: 'fixture-office', name: 'Office network', hostname: 'office.example' }, { id: 'fixture-edge', name: 'Edge gateway', hostname: 'edge.example' }] }) if (path.endsWith('/explain')) { explainGets++; return Response.json(explain) } if (path.endsWith('/overrides')) { if (init?.method === 'POST') { overridePosts.push(JSON.parse(String(init.body))); return failOverride ? Response.json({ error: { message: 'Fixture write rejected' } }, { status: 503 }) : Response.json({ ok: true }) } return Response.json({ items: [{ id: 'expired', agent_id: 'fixture', cidr: '198.51.100.0/24', action: 'deny', created_at: '2026-10-23T00:00:00Z', created_by_name: 'Fixture author', reason: 'Fixture incident', expires_at: '2026-10-23T01:00:00Z', expired: true, expiration_enforcement: 'next_policy_sync' }] }) } throw new Error(`Unexpected fixture request: ${key}`) } try { const catalog = { items: [{ value: 'fixture-list', label: 'Office ranges' }], loading: false, ready: true, error: null, retry: () => {} } const initial = { action: 'open' as const, protocol: 'tcp' as const, port_start: '', port_end: '', src_kind: 'all' as const, src_cidr: '', list_id: '', enabled: true, comment: '' } let saves = 0 let savedPort: number | null = null const rule = (list = catalog) => {}} title="Fixture rule" description="Fixture only" canWrite pending={false} lists={list} initialValues={initial} onSubmit={(values) => { saves++; savedPort = portAclDraftSchema.parse(values).port_start }} /> await render(rule()) await input('acl-port_start', '1e3'); await submit() check(saves === 0 && document.getElementById('acl-port_start')?.getAttribute('aria-invalid') === 'true', 'RHF Port ACL blocks exponent notation before save') await input('acl-port_start', '443'); await input('acl-port_end', '80'); await submit() check(saves === 0 && document.getElementById('acl-port_end')?.getAttribute('aria-invalid') === 'true', 'RHF Port ACL rejects reversed range with an inline error') await input('acl-port_end', '') const portNode = document.getElementById('acl-port_start') await render(rule({ ...catalog, items: [...catalog.items] })) check(document.getElementById('acl-port_start') === portNode && (portNode as HTMLInputElement).value === '443', 'catalog refresh preserves the mounted dirty Port ACL draft') await submit() check(saves === 1 && savedPort === 443, 'form submit delivers one validated Port ACL save') let imports = 0 let imported = '' await render( {}} canWrite pending={false} lists={catalog} sets={catalog} onSubmit={(values) => { imports++; imported = `${values.listId}:${values.ports}` }} />) await input('acl-import-ports', '80-'); await submit() check(imports === 0 && document.getElementById('acl-import-ports')?.getAttribute('aria-invalid') === 'true', 'RHF import rejects malformed ports and missing source') await choose('acl-import-source', 'Office ranges'); await input('acl-import-ports', '22,8000-8001'); await submit() check(imports === 1 && imported === 'fixture-list:22,8000-8001', 'RHF import submits its selected source and valid ranges once') let selection: string[] = [] function Selection() { const [value, setValue] = useState([]); return { selection = next; setValue(next) }} /> } await render() await act(async () => { const field = document.getElementById('stats-agents')!; field.focus(); field.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })); await flush(); await flush() }) check(document.getElementById('stats-agents')?.getAttribute('aria-expanded') === 'true', 'agent combobox opens through keyboard interaction') await act(async () => { const option = [...document.querySelectorAll('[role="option"]')].find((item) => item.textContent?.includes('Office network')); if (!option) throw new Error('Office network option not found'); option.click(); await flush() }) check(selection[0] === 'fixture-office' && host.textContent?.includes('Office network') && !host.textContent?.includes('fixture-office'), 'agent filtering selects names without exposing raw identifiers') await render( {}} />) await input('explain-ip', '203.0.113.10'); await input('explain-port', '443'); await submit() check(explainGets === 0 && document.getElementById('explain-port')?.getAttribute('aria-invalid') === 'true', 'Explain blocks an unpaired transport input without a request') await choose('explain-protocol', 'TCP'); await submit(); await act(async () => { await flush() }) check(explainGets === 1 && document.body.textContent?.includes('Решение не определено') && document.body.textContent?.includes('Совпадение неизвестно'), 'Explain preserves external and unconfirmed decisions after a valid read') await input('explain-ip', '203.0.113.11') check(explainGets === 1 && document.body.textContent?.includes('Форма изменена — запустите проверку снова'), 'editing Explain retains a labeled previous result without issuing another query') await render( {}} />) await act(async () => { await flush() }) check(document.body.textContent?.includes('Fixture author') && document.body.textContent?.includes('Истёк'), 'override history shows server-owned author and expired state') await input('ov-cidr', '203.0.113.10'); await choose('ov-expiry-mode', 'На время'); await input('ov-ttl', '0'); await submit() check(overridePosts.length === 0 && document.getElementById('ov-ttl')?.getAttribute('aria-invalid') === 'true', 'override expiry validation blocks zero TTL') await input('ov-ttl', '15') await act(async () => { const reason = document.getElementById('ov-reason') as HTMLTextAreaElement; Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value')!.set!.call(reason, 'Fixture reason'); reason.dispatchEvent(new Event('input', { bubbles: true })); await flush() }) await submit(); await act(async () => { await flush() }) check(overridePosts.length === 1 && (document.getElementById('ov-cidr') as HTMLInputElement).value === '203.0.113.10', 'failed override write preserves the dirty draft') failOverride = false await submit(); await act(async () => { await flush() }) check(overridePosts.length === 2 && overridePosts[1].ttl_seconds === 900 && overridePosts[1].reason === 'Fixture reason' && !('expires_at' in overridePosts[1]) && !('created_by_name' in overridePosts[1]), 'temporary override sends validated TTL and reason without author spoofing') check((document.getElementById('ov-cidr') as HTMLInputElement).value === '' && document.body.textContent?.includes('следующей связи'), 'successful override resets the draft and retains next-sync expiry limits') results.dataset.status = 'passed' } catch (error) { results.textContent = `${checks.join('\n')}\nFAIL ${error instanceof Error ? error.stack : String(error)}` results.dataset.status = 'failed' } finally { await act(async () => root.unmount()) qc.clear() window.fetch = originalFetch reportMetrics() }