import { render, screen, fireEvent } from '@testing-library/react'; import { vi } from 'vitest'; import { ContainerImageStatusValue } from '../../queries/useContainerImageStatus'; import { UpdateStatusBadge } from './UpdateStatusBadge'; describe('UpdateStatusBadge', () => { it('renders "Update available" when the image is outdated', () => { render(); expect(screen.getByText('Update available')).toBeInTheDocument(); }); it('renders an up-to-date indicator when the image is updated', () => { render(); expect(screen.getByText('Up to date')).toBeInTheDocument(); }); it('shows a spinner while loading', () => { render(); expect( screen.getByLabelText('Checking for image updates') ).toBeInTheDocument(); }); it.each([ 'skipped', 'error', 'processing', 'preparing', ])('renders nothing for the neutral status "%s"', (status) => { const { container } = render(); expect(container).toBeEmptyDOMElement(); }); it('renders nothing when status is undefined and not loading', () => { const { container } = render(); expect(container).toBeEmptyDOMElement(); }); describe('interactive behavior', () => { it('renders "Update available" as a plain span when no handler is passed', () => { render(); expect( screen.queryByRole('button', { name: /update available/i }) ).not.toBeInTheDocument(); }); it('renders "Update available" as a button and fires the handler on click', () => { const onUpdateClick = vi.fn(); render( ); const button = screen.getByRole('button', { name: /update available/i, }); fireEvent.click(button); expect(onUpdateClick).toHaveBeenCalledTimes(1); }); it('renders "Up to date" as a plain span when no handler is passed', () => { render(); expect( screen.queryByRole('button', { name: /up to date/i }) ).not.toBeInTheDocument(); }); it('renders "Up to date" as a button and fires the recheck handler on click', () => { const onRecheckClick = vi.fn(); render( ); const button = screen.getByRole('button', { name: /up to date/i }); fireEvent.click(button); expect(onRecheckClick).toHaveBeenCalledTimes(1); }); it('shows a pending affordance and disables the update button while updating', () => { const onUpdateClick = vi.fn(); render( ); const button = screen.getByRole('button', { name: /updating the image/i, }); expect(button).toBeDisabled(); expect(screen.getByText('Updating...')).toBeInTheDocument(); fireEvent.click(button); expect(onUpdateClick).not.toHaveBeenCalled(); }); it('shows a spinner and disables the recheck button while rechecking', () => { const onRecheckClick = vi.fn(); render( ); const button = screen.getByRole('button', { name: /up to date/i }); expect(button).toBeDisabled(); fireEvent.click(button); expect(onRecheckClick).not.toHaveBeenCalled(); }); }); });