import { describe, it, expect, vi, beforeEach } from 'vitest'; import { render, screen, waitFor } from '@testing-library/react'; import { RollbackReadinessSection } from '../RollbackReadinessSection'; vi.mock('@/lib/api', () => ({ apiFetch: vi.fn() })); const nodesState = { activeNode: { id: 1, type: 'local', name: 'local' }, hasCapability: vi.fn().mockReturnValue(true), }; vi.mock('@/context/NodeContext', () => ({ useNodes: () => nodesState, })); import { apiFetch } from '@/lib/api'; type Overall = 'ready' | 'partial' | 'not_ready'; const report = (overall: Overall) => ({ stack: 'web', computedAt: Date.now(), overall, items: [ { id: 'compose_source', state: 'ready', label: 'Previous compose file', detail: 'A backup is available to restore.' }, { id: 'volume_data', state: 'not_covered', label: 'Application data', detail: 'Named volumes and bind-mounted data are not included in file backups.' }, ], }); describe('RollbackReadinessSection', () => { beforeEach(() => { vi.mocked(apiFetch).mockReset(); nodesState.hasCapability.mockReturnValue(true); }); it.each(['ready', 'partial', 'not_ready'] as const)('renders the %s overall chip', async (overall) => { vi.mocked(apiFetch).mockResolvedValue(new Response(JSON.stringify(report(overall)), { status: 200 })); render(); await waitFor(() => expect(screen.getByTestId('rollback-overall')).toHaveAttribute('data-overall', overall)); }); it('always shows the application-data non-coverage disclosure', async () => { vi.mocked(apiFetch).mockResolvedValue(new Response(JSON.stringify(report('ready')), { status: 200 })); render(); await waitFor(() => expect(screen.getByText('Application data')).toBeInTheDocument()); expect(screen.getByText(/not included in file backups/)).toBeInTheDocument(); }); it('renders nothing without the update-guard capability and never fetches', () => { nodesState.hasCapability.mockReturnValue(false); const { container } = render(); expect(container).toBeEmptyDOMElement(); expect(apiFetch).not.toHaveBeenCalled(); }); it('renders nothing when the fetch fails', async () => { vi.mocked(apiFetch).mockRejectedValue(new Error('down')); const { container } = render(); await waitFor(() => expect(apiFetch).toHaveBeenCalled()); expect(container).toBeEmptyDOMElement(); }); });