import { describe, it, expect, vi } from 'vitest'; import { render, screen, fireEvent } from '@testing-library/react'; import type { ComponentProps } from 'react'; import { StackRow } from '../StackRow'; import type { Label } from '@/components/label-types'; function base(overrides: Partial> = {}) { return { file: 'web.yml', displayName: 'web', status: 'running' as const, isBusy: false, isActive: false, isPaid: true, labels: [] as Label[], hasUpdate: false, hasGitPending: false, onSelect: vi.fn(), kebabSlot: null, ...overrides, }; } describe('StackRow', () => { it('renders UP for running', () => { render(); expect(screen.getByText('UP')).toBeInTheDocument(); }); it('renders DN for exited', () => { render(); expect(screen.getByText('DN')).toBeInTheDocument(); }); it('renders -- for unknown', () => { render(); expect(screen.getByText('--')).toBeInTheDocument(); }); it('renders cyan rail only when active', () => { const { rerender } = render(); expect(screen.getByTestId('stack-row')).not.toHaveClass('bg-accent/[0.07]'); rerender(); expect(screen.getByTestId('stack-row')).toHaveClass('bg-accent/[0.07]'); }); it('fires onSelect on click', () => { const onSelect = vi.fn(); render(); screen.getByTestId('stack-row').click(); expect(onSelect).toHaveBeenCalledWith('web.yml'); }); it('fires onSelect on Enter and Space', () => { const onSelect = vi.fn(); render(); const row = screen.getByTestId('stack-row'); row.focus(); fireEvent.keyDown(row, { key: 'Enter' }); fireEvent.keyDown(row, { key: ' ' }); expect(onSelect).toHaveBeenCalledTimes(2); }); it('kebab click does not trigger onSelect', () => { const onSelect = vi.fn(); render(k })} />); screen.getByTestId('kebab').click(); expect(onSelect).not.toHaveBeenCalled(); }); it('renders loader when isBusy', () => { const { container } = render(); expect(container.querySelector('.animate-spin')).not.toBeNull(); expect(screen.queryByText('UP')).not.toBeInTheDocument(); }); });