import { render, screen, within } from '@testing-library/react'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { ContainerPage } from '../../src/ContainerPage'; afterEach(() => vi.unstubAllGlobals()); describe('container status projection', () => { it('normalizes presentation and never fabricates missing health or metrics', async () => { vi.stubGlobal('fetch', vi.fn().mockResolvedValue(new Response(JSON.stringify({ source: { id: 'unraid', state: 'healthy', freshness: 'fresh' }, total: 2, containers: [ { id: 'a', name: 'alpha', state: 'RUNNING', health: 'unknown', intentionalStop: false, metricsAvailable: false, lifecycleAvailable: false, uptimeSeconds: 0, restartCount: 0, exitCode: 0, cpuPercent: 0, memoryBytes: 0, memoryLimitBytes: 0, networkRxBytes: 0, networkTxBytes: 0, blockReadBytes: 0, blockWriteBytes: 0 }, { id: 'b', name: 'beta', state: 'restarting', health: 'unhealthy', intentionalStop: false, metricsAvailable: true, lifecycleAvailable: true, uptimeSeconds: 60, restartCount: 4, exitCode: 137, cpuPercent: 12.5, memoryBytes: 1024, memoryLimitBytes: 2048, networkRxBytes: 0, networkTxBytes: 0, blockReadBytes: 0, blockWriteBytes: 0 }, ], }), { status: 200, headers: { 'Content-Type': 'application/json' } }))); render(); const alpha = (await screen.findAllByRole('link', { name: 'alpha' })).map((item) => item.closest('tr')).find(Boolean); const beta = screen.getAllByText('beta').map((item) => item.closest('tr')).find(Boolean); expect(alpha).not.toBeNull(); expect(beta).not.toBeNull(); expect(within(alpha!).getByText('Actief').closest('.status-badge')).toHaveClass('status-badge--ready'); expect(within(alpha!).getAllByText('Onbekend').length).toBeGreaterThanOrEqual(2); expect(within(alpha!).getByText(/metingen niet beschikbaar/)).toBeVisible(); expect(within(beta!).getByText('Wordt herstart').closest('.status-badge')).toHaveClass('status-badge--attention'); expect(within(beta!).getByText('Ongezond').closest('.status-badge')).toHaveClass('status-badge--attention'); expect(within(beta!).getByText('12,5%')).toBeVisible(); }); it('does not render stale item states as ready', async () => { vi.stubGlobal('fetch', vi.fn().mockResolvedValue(new Response(JSON.stringify({ source: { id: 'unraid', state: 'unknown', freshness: 'stale', reason: 'stale_source' }, total: 1, containers: [{ id: 'a', name: 'stale-alpha', state: 'running', health: 'healthy', intentionalStop: false, metricsAvailable: true, lifecycleAvailable: true, uptimeSeconds: 60, restartCount: 0, exitCode: 0, cpuPercent: 10, memoryBytes: 1024, memoryLimitBytes: 2048, networkRxBytes: 0, networkTxBytes: 0, blockReadBytes: 0, blockWriteBytes: 0 }], }), { status: 200, headers: { 'Content-Type': 'application/json' } }))); render(); const row = (await screen.findAllByRole('link', { name: 'stale-alpha' })).map((item) => item.closest('tr')).find(Boolean); expect(row).not.toBeNull(); expect(row!.querySelectorAll('.status-badge--unknown')).toHaveLength(2); expect(within(row!).queryByText('running')).not.toBeInTheDocument(); expect(within(row!).queryByText('healthy')).not.toBeInTheDocument(); }); });