/** * @vitest-environment happy-dom */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { cleanup, render, screen, waitFor, fireEvent } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { MemoryRouter } from 'react-router-dom'; import { type ReactNode } from 'react'; import { routerFuture } from '../routerFuture'; import { mockAgent, mockServerInfo, mockServerConfig } from '../test/fixtures'; import { api } from '../api/client'; import { downloadApiFile, downloadAuthedFile } from '../api/download'; import { getStoredAuth } from '../api/auth'; import { useWebSocket } from '../hooks/useWebSocket'; import { DEFAULT_FLEET_FILTERS } from '../help/fleetFilters'; import { generateSampleSeries, validateChartSeries } from '../help/chartSampleData'; import NeonCard from './NeonCard/NeonCard'; import { HelpTip, FieldHint } from './HelpTip'; import DownloadButton from './DownloadButton'; import AuthDownloadButton from './AuthDownloadButton'; import ErrorBoundary from './ErrorBoundary'; import SessionGate from './SessionGate'; import GaugeRing from './Charts/GaugeRing'; import HashrateChart from './Charts/HashrateChart'; import AgentRemoteActions from './Fleet/AgentRemoteActions'; import AgentListItem from './Fleet/AgentListItem'; import FleetToolbar from './Fleet/FleetToolbar'; import { LanDownloadQR } from './Fleet/LanDownloadQR'; import { AlertBanner, PoolStatusPanel, AIActivityPanel, EarningsEstimator, FleetHealthCard, ContributionBars, UnderperformerList, OSArchBreakdown, LANGroupView, } from './Fleet/FleetPanels'; import { ForgeLockedHint, ForgeFieldBadge, ForgeSectionHeader } from './Forge/ForgeFieldHints'; import { PipelineFlow, FleetPipelineStatus, ActivityPulse, ForgeCalibrateCompare, RoadmapGrid, } from './Visual/VisualComponents'; import MatrixStreamOverlay from './Visual/MatrixStreamOverlay'; import SystemStatusBar from './Visual/SystemStatusBar'; import FleetTopologyMap from './Visual/3D/FleetTopologyMap'; import Layout from './Layout/Layout'; import AmbientBackground from './Ambient/AmbientBackground'; import CursorFire from './Visual/CursorFire'; import MatrixRain from './Layout/MatrixRain'; vi.mock('./Fleet/ProtocolTunnelPanel', () => ({ default: () => null })); vi.mock('./Fleet/FullSysCheckPanel', () => ({ default: () => null })); vi.mock('../hooks/useWebSocket', () => ({ useWebSocket: vi.fn(), })); vi.mock('../context/ForgeContext', () => ({ useForge: vi.fn(() => ({ forging: false, stage: '' })), })); vi.mock('../api/download', () => { const downloadAuthedFile = vi.fn(); return { downloadAuthedFile, downloadApiFile: downloadAuthedFile, }; }); vi.mock('../api/auth', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, getStoredAuth: vi.fn(), setStoredAuth: vi.fn(), }; }); vi.mock('qrcode', () => ({ default: { toCanvas: vi.fn().mockResolvedValue(undefined), }, })); vi.mock('recharts', async () => { const actual = await vi.importActual('recharts'); return { ...actual, ResponsiveContainer: ({ children }: { children: ReactNode }) => (
{children}
), }; }); vi.mock('@react-three/fiber', () => ({ Canvas: ({ children }: { children: ReactNode }) =>
{children}
, useFrame: () => {}, })); vi.mock('@react-three/drei', () => ({ OrbitControls: () => null, Stars: () => null, Line: () => null, Sphere: () => null, })); const useWebSocketMock = vi.mocked(useWebSocket); const downloadApiFileMock = vi.mocked(downloadApiFile); const downloadAuthedFileMock = vi.mocked(downloadAuthedFile); const getStoredAuthMock = vi.mocked(getStoredAuth); function ThrowOnce({ shouldThrow }: { shouldThrow: boolean }) { if (shouldThrow) throw new Error('render boom'); return child ok; } describe('NeonCard', () => { afterEach(() => cleanup()); it('renders children with default brass accent and 3d class', () => { render(Inner); const card = screen.getByText('Inner').closest('.neon-card'); expect(card).toHaveClass('neon-card-brass', 'neon-card-3d'); expect(card?.querySelector('.neon-card-rim')).toBeTruthy(); }); it('applies accent, hud, tilt3d off, and custom className', () => { render( X ); const card = screen.getByText('X').closest('.neon-card'); expect(card).toHaveClass('neon-card-cyan', 'hud-corners', 'extra'); expect(card).not.toHaveClass('neon-card-3d'); }); }); describe('HelpTip', () => { afterEach(() => cleanup()); it('returns null for unknown field', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('shows help popup on hover for known field', async () => { render(); expect(screen.getByRole('button', { name: /Help: calibrate_wallet/ })).toBeInTheDocument(); await userEvent.setup().hover(screen.getByRole('button')); await waitFor(() => { expect(screen.getByRole('tooltip')).toHaveTextContent(/Monero payout address/i); }); }); it('FieldHint export is deprecated no-op', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); }); describe('DownloadButton', () => { afterEach(() => cleanup()); beforeEach(() => { downloadApiFileMock.mockReset(); }); it('downloads on click and shows busy label', async () => { downloadApiFileMock.mockImplementation(() => new Promise((r) => setTimeout(r, 50))); render( Save ); const btn = screen.getByRole('button', { name: 'Save' }); await userEvent.setup().click(btn); expect(screen.getByRole('button', { name: 'Downloading…' })).toBeDisabled(); await waitFor(() => expect(downloadApiFileMock).toHaveBeenCalledWith('/api/x', 'a.bin')); }); it('alerts on download failure', async () => { downloadApiFileMock.mockRejectedValue(new Error('network down')); const alertSpy = vi.spyOn(window, 'alert').mockImplementation(() => {}); render( Save ); await userEvent.setup().click(screen.getByRole('button')); await waitFor(() => expect(alertSpy).toHaveBeenCalledWith('network down')); alertSpy.mockRestore(); }); }); describe('AuthDownloadButton', () => { afterEach(() => cleanup()); beforeEach(() => { downloadAuthedFileMock.mockReset(); }); it('calls downloadAuthedFile and shows ellipsis while busy', async () => { downloadAuthedFileMock.mockImplementation(() => new Promise((r) => setTimeout(r, 30))); render( DL ); await userEvent.setup().click(screen.getByRole('button', { name: 'DL' })); expect(screen.getByRole('button', { name: '…' })).toBeDisabled(); await waitFor(() => expect(downloadAuthedFileMock).toHaveBeenCalledWith('/api/build/1', 'b.exe') ); }); }); describe('ErrorBoundary', () => { afterEach(() => cleanup()); it('renders children when no error', () => { render( ); expect(screen.getByText('child ok')).toBeInTheDocument(); }); it('shows fallback UI and clears error on retry', async () => { let throwNow = true; function MaybeThrow() { if (throwNow) throw new Error('render boom'); return child ok; } render( ); expect(screen.getByRole('heading', { name: 'Something failed to render' })).toBeInTheDocument(); throwNow = false; await userEvent.setup().click(screen.getByRole('button', { name: 'Retry' })); expect(screen.getByText('child ok')).toBeInTheDocument(); }); it('uses custom fallback when provided', () => { render( Custom fail

}>
); expect(screen.getByText('Custom fail')).toBeInTheDocument(); }); }); describe('SessionGate', () => { afterEach(() => { cleanup(); vi.unstubAllGlobals(); }); beforeEach(() => { getStoredAuthMock.mockReturnValue(null); }); it('shows login form when unauthenticated', async () => { vi.stubGlobal( 'fetch', vi.fn().mockResolvedValue({ ok: false }) ); render(
protected
); await waitFor(() => { expect(screen.getByRole('heading', { name: 'AetherForge' })).toBeInTheDocument(); }); expect(screen.queryByText('protected')).not.toBeInTheDocument(); }); it('renders children when stored auth validates', async () => { getStoredAuthMock.mockReturnValue('dGVzdA=='); vi.stubGlobal('fetch', vi.fn().mockResolvedValue({ ok: true, status: 200 })); render(
protected
); await waitFor(() => expect(screen.getByText('protected')).toBeInTheDocument()); }); it('keeps session on network blip during startup validation', async () => { getStoredAuthMock.mockReturnValue('dGVzdA=='); vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new Error('ECONNREFUSED'))); render(
protected
); await waitFor(() => expect(screen.getByText('protected')).toBeInTheDocument()); expect(screen.getByRole('status')).toHaveTextContent(/Cannot reach server/i); }); }); describe('GaugeRing', () => { afterEach(() => cleanup()); it('renders label and percentage for percent-scale max', () => { render(); expect(screen.getByText('42%')).toBeInTheDocument(); expect(screen.getByText('CPU')).toBeInTheDocument(); expect(screen.getByText('load')).toBeInTheDocument(); }); it('shows raw value in center while ring arc clamps to 0–100%', () => { const { rerender, container } = render(); expect(screen.getByText('0%')).toBeInTheDocument(); const fill = container.querySelector('.gauge-ring-fill') as SVGCircleElement; expect(fill.getAttribute('stroke-dashoffset')).toBe(String(2 * Math.PI * 42)); rerender(); expect(screen.getByText('100%')).toBeInTheDocument(); expect((container.querySelector('.gauge-ring-fill') as SVGCircleElement).getAttribute('stroke-dashoffset')).toBe('0'); }); }); describe('HashrateChart', () => { afterEach(() => cleanup()); it('shows empty state when data is empty', () => { render(); expect(screen.getByText('Fleet Hash')).toBeInTheDocument(); expect(screen.getByText(/No live data yet/i)).toBeInTheDocument(); }); it('renders chart with validated sample series', () => { const sample = generateSampleSeries('hashrate', 24); expect(validateChartSeries(sample).ok).toBe(true); render( ); expect(screen.getByText(/PEAK/)).toBeInTheDocument(); expect(screen.getByText(/LIVE/)).toBeInTheDocument(); }); it('renders chart with data points', () => { render( ); expect(screen.getByText('Live')).toBeInTheDocument(); expect(screen.getByText('● LIVE')).toBeInTheDocument(); expect(screen.getByTestId('recharts-responsive')).toBeInTheDocument(); }); }); describe('AgentRemoteActions', () => { afterEach(() => cleanup()); beforeEach(() => { vi.spyOn(api, 'listBuilds').mockResolvedValue([]); vi.spyOn(api, 'sendAgentCommand').mockResolvedValue({ success: true }); vi.spyOn(api, 'getConfig').mockResolvedValue(mockServerConfig()); }); it('compact mode disables actions when offline', () => { render( ); expect(screen.getByRole('button', { name: 'Pause' })).toBeDisabled(); expect(screen.getByRole('button', { name: 'Resume' })).toBeDisabled(); }); it('compact dispatches pause when online', async () => { const cmd = vi.spyOn(api, 'sendAgentCommand').mockResolvedValue({ success: true }); render( ); await userEvent.setup().click(screen.getByRole('button', { name: 'Pause' })); await waitFor(() => expect(cmd).toHaveBeenCalledWith('a1', 'pause', {})); }); it('full panel shows Target heading and recon section', async () => { render( ); await waitFor(() => { expect(screen.getByRole('heading', { name: 'Target: Node A' })).toBeInTheDocument(); }); expect(screen.getByRole('heading', { name: 'Recon & Intel' })).toBeInTheDocument(); expect(screen.getByText(/Terminal ready/i)).toBeInTheDocument(); }); it('disables recon buttons when agent offline', async () => { render( ); await waitFor(() => { expect(screen.getByRole('heading', { name: /Target:/i })).toBeInTheDocument(); }); expect(screen.getByRole('button', { name: 'Screenshot' })).toBeDisabled(); }); }); describe('AgentListItem', () => { afterEach(() => cleanup()); const baseProps = { agent: mockAgent({ name: 'List Node', tags: ['rack'], notes: 'a'.repeat(90) }), selected: false, expanded: false, onToggleExpand: vi.fn(), onSelect: vi.fn(), }; it('renders name, status, and click hint when collapsed', () => { render(); expect(screen.getByText('List Node')).toBeInTheDocument(); expect(screen.getByText('online')).toBeInTheDocument(); expect(screen.getByText('click for details')).toBeInTheDocument(); expect(screen.getByText('rack')).toBeInTheDocument(); }); it('truncates long notes preview when collapsed', () => { render(); const preview = screen.getByText(/…$/); expect(preview.textContent!.length).toBeLessThanOrEqual(81); }); it('expands meta and remote actions', async () => { vi.spyOn(api, 'listBuilds').mockResolvedValue([]); render(); expect(screen.getByText(/Shares:/)).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Pause' })).toBeInTheDocument(); }); it('checkbox stops row navigation', async () => { const onCheck = vi.fn(); render(); await userEvent.setup().click(screen.getByRole('checkbox')); expect(onCheck).toHaveBeenCalledWith(true); expect(baseProps.onSelect).not.toHaveBeenCalled(); }); }); describe('FleetToolbar', () => { afterEach(() => cleanup()); const filters = { ...DEFAULT_FLEET_FILTERS }; const agents = [ mockAgent({ tags: ['prod'], ip: '10.0.0.5' }), mockAgent({ id: 'a2', name: 'B', tags: ['dev'], ip: '10.0.1.2' }), ]; it('renders search and filter controls', () => { render( ); expect(screen.getByPlaceholderText('Search name, IP, notes, tags…')).toBeInTheDocument(); expect(screen.getByText('All tags')).toBeInTheDocument(); }); it('shows bulk bar when agents selected', async () => { const onBulk = vi.fn(); render( ); expect(screen.getByText('2 selected')).toBeInTheDocument(); await userEvent.setup().click(screen.getByRole('button', { name: 'Pause' })); expect(onBulk).toHaveBeenCalledWith('pause'); }); it('shows select-all filtered when props provided', () => { const onSelectAll = vi.fn(); render( ); fireEvent.click(screen.getByRole('button', { name: 'Select all filtered (3)' })); expect(onSelectAll).toHaveBeenCalled(); }); }); describe('LanDownloadQR', () => { afterEach(() => cleanup()); it('returns null without url', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('renders canvas when url provided', () => { const { container } = render(); expect(container.querySelector('canvas')).toBeTruthy(); }); }); describe('FleetPanels', () => { afterEach(() => cleanup()); it('AlertBanner returns null when empty', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('AlertBanner shows up to five alerts', () => { const alerts = [ { id: '1', level: 'warning', type: 'offline', message: 'Node down', timestamp: '2026-05-30T12:00:00Z' }, ]; render(); expect(screen.getByText('OFFLINE')).toBeInTheDocument(); expect(screen.getByText('Node down')).toBeInTheDocument(); }); it('PoolStatusPanel empty hint', () => { render(); expect(screen.getByRole('heading', { name: /Pool Stratum Status/i })).toBeInTheDocument(); expect(screen.getByText(/No forged pool connections yet/i)).toBeInTheDocument(); }); it('AIActivityPanel maps agent names', () => { render( ); expect(screen.getByText('Friendly')).toBeInTheDocument(); }); it('FleetHealthCard shows score and label', () => { render( ); expect(screen.getByText('NOMINAL')).toBeInTheDocument(); expect(screen.getByText('88')).toBeInTheDocument(); expect(screen.getByText('All good')).toBeInTheDocument(); }); it('ContributionBars returns null when empty', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('ContributionBars renders rows', () => { render( ); expect(screen.getByRole('heading', { name: /Contribution Map/i })).toBeInTheDocument(); expect(screen.getByText('A')).toBeInTheDocument(); }); it('OSArchBreakdown returns null when empty', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('LANGroupView needs at least two groups', () => { const { container } = render( ); expect(container.firstChild).toBeNull(); }); it('EarningsEstimator returns null when hashrate zero', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('UnderperformerList restart calls bulk API', async () => { const agents = [mockAgent({ id: 'u1', name: 'Slow' })]; const bulk = vi.spyOn(api, 'sendBulkCommand').mockResolvedValue({ success: true, sent: 1, failed: 0, action: 'restart' }); render(); await userEvent.setup().click(screen.getByRole('button', { name: /Restart All/i })); await waitFor(() => expect(bulk).toHaveBeenCalledWith(['u1'], 'restart')); expect(await screen.findByText(/Restart sent to 1/i)).toBeInTheDocument(); }); }); describe('ForgeFieldHints', () => { afterEach(() => cleanup()); it('ForgeLockedHint null without meta', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('ForgeFieldBadge shows baked label', () => { render(); expect(screen.getByText('⛏ baked')).toBeInTheDocument(); }); it('ForgeSectionHeader renders title and badge', () => { render( ); expect(screen.getByRole('heading', { name: 'Pool' })).toBeInTheDocument(); expect(screen.getByText(/server/i)).toBeInTheDocument(); }); }); describe('VisualComponents', () => { afterEach(() => cleanup()); it('PipelineFlow highlights active step', () => { render(); expect(document.querySelector('.pipeline-active')).toBeTruthy(); }); it('FleetPipelineStatus shows step labels', () => { render( ); expect(screen.getByText('Forged')).toBeInTheDocument(); expect(screen.getByText('Shares')).toBeInTheDocument(); }); it('ActivityPulse empty message', () => { render(); expect(screen.getByText(/Awaiting fleet activity/i)).toBeInTheDocument(); }); it('ForgeCalibrateCompare links to routes', () => { render( ); expect(screen.getByText(/Forge — baked into each binary/i)).toBeInTheDocument(); }); it('RoadmapGrid lists features', () => { render(); expect(document.querySelectorAll('.roadmap-card').length).toBeGreaterThan(0); }); }); describe('MatrixStreamOverlay', () => { afterEach(() => cleanup()); beforeEach(() => { useWebSocketMock.mockReturnValue({ isConnected: true, agents: [], recentShares: [], fleetAlerts: [], poolStatus: [], aiActivity: [], agentLogs: {}, commandResults: [], latestMessage: null, }); }); it('returns null when inactive', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('shows overlay heading when active', () => { render(); expect(screen.getByText('RAW_SOCKET_STREAM [ACTIVE]')).toBeInTheDocument(); }); }); describe('SystemStatusBar', () => { afterEach(() => cleanup()); beforeEach(() => { vi.spyOn(api, 'healthCheck').mockResolvedValue(undefined); vi.spyOn(api, 'listAgents').mockResolvedValue([mockAgent(), mockAgent({ id: 'a2', status: 'offline' })]); vi.spyOn(api, 'listBuilds').mockResolvedValue([{ id: 'b1' } as never]); }); it('shows server and fleet pills after poll', async () => { render( ); await waitFor(() => { expect(screen.getByText(/SERVER UP/i)).toBeInTheDocument(); }); expect(screen.getByText(/FLEET 1\/2 ONLINE/i)).toBeInTheDocument(); expect(screen.getByText(/1 BUILD/i)).toBeInTheDocument(); }); }); describe('FleetTopologyMap', () => { afterEach(() => cleanup()); it('renders canvas wrapper for agents', () => { render(); expect(screen.getByTestId('three-canvas')).toBeInTheDocument(); }); }); describe('AmbientBackground', () => { afterEach(() => cleanup()); it('renders ambient layers and sacred geometry svg', () => { const { container } = render(); expect(container.querySelector('.ambient-bg')).toBeTruthy(); expect(container.querySelector('.ambient-sacred-geo')).toBeTruthy(); expect(container.querySelector('.ambient-geo-hex-veil')).toBeTruthy(); expect(container.querySelectorAll('.ambient-geo-corner').length).toBeGreaterThanOrEqual(2); }); }); describe('CursorFire', () => { afterEach(() => cleanup()); it('mounts fullscreen canvas', () => { const { container } = render(); expect(container.querySelector('canvas')).toBeTruthy(); }); }); describe('MatrixRain', () => { afterEach(() => cleanup()); beforeEach(() => { useWebSocketMock.mockReturnValue({ isConnected: true, agents: [], recentShares: [], fleetAlerts: [], poolStatus: [], aiActivity: [], agentLogs: {}, commandResults: [], latestMessage: null, }); }); it('renders matrix rain canvas wrapper', () => { const { container } = render(); expect(container.querySelector('canvas')).toBeTruthy(); }); }); describe('Layout', () => { afterEach(() => cleanup()); beforeEach(() => { useWebSocketMock.mockReturnValue({ isConnected: true, agents: [mockAgent()], recentShares: [], fleetAlerts: [], poolStatus: [], aiActivity: [], agentLogs: {}, commandResults: [], latestMessage: null, }); vi.spyOn(api, 'getServerInfo').mockResolvedValue(mockServerInfo); }); it('renders nav links and children', async () => { render(
page body
); await waitFor(() => { expect(screen.getByText('page body')).toBeInTheDocument(); }); expect(screen.getByRole('link', { name: /Command Deck/i })).toBeInTheDocument(); expect(screen.getByRole('link', { name: /Fleet Roster/i })).toBeInTheDocument(); }); });