import { describe, it, expect } from 'vitest'; import { screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { HttpResponse, http } from 'msw'; import { renderRoute } from './render'; import { server } from './mocks/server'; describe('Companies page', () => { it('renders page title', async () => { renderRoute('/companies'); await waitFor(() => { expect(screen.getByRole('heading', { name: 'Companies' })).toBeInTheDocument(); }); }); it('renders company list with tickers', async () => { renderRoute('/companies'); await waitFor(() => { expect(screen.getByText('AAPL')).toBeInTheDocument(); }); expect(screen.getByText('MSFT')).toBeInTheDocument(); }); it('shows company names', async () => { renderRoute('/companies'); await waitFor(() => { expect(screen.getByText('Apple Inc.')).toBeInTheDocument(); }); expect(screen.getByText('Microsoft Corporation')).toBeInTheDocument(); }); it('shows sector column', async () => { renderRoute('/companies'); await waitFor(() => { expect(screen.getByText('AAPL')).toBeInTheDocument(); }); const row = screen.getByText('AAPL').closest('tr')!; expect(row).toHaveTextContent('Technology'); }); it('shows active status badge', async () => { renderRoute('/companies'); await waitFor(() => { expect(screen.getByText('AAPL')).toBeInTheDocument(); }); const row = screen.getByText('AAPL').closest('tr')!; expect(row).toHaveTextContent('active'); }); it('shows source count', async () => { renderRoute('/companies'); await waitFor(() => { expect(screen.getByText('AAPL')).toBeInTheDocument(); }); const row = screen.getByText('AAPL').closest('tr')!; expect(row).toHaveTextContent('3'); }); it('renders Add Company button', async () => { renderRoute('/companies'); await waitFor(() => { expect(screen.getByText('Add Company')).toBeInTheDocument(); }); }); it('shows add company form on button click', async () => { const user = userEvent.setup(); renderRoute('/companies'); await waitFor(() => { expect(screen.getByText('Add Company')).toBeInTheDocument(); }); await user.click(screen.getByText('Add Company')); await waitFor(() => { expect(screen.getByLabelText('Ticker')).toBeInTheDocument(); }); expect(screen.getByLabelText('Legal Name')).toBeInTheDocument(); expect(screen.getByLabelText('Sector')).toBeInTheDocument(); expect(screen.getByLabelText('Exchange')).toBeInTheDocument(); }); it('submits new company form', async () => { const user = userEvent.setup(); renderRoute('/companies'); await waitFor(() => { expect(screen.getByText('Add Company')).toBeInTheDocument(); }); await user.click(screen.getByText('Add Company')); await waitFor(() => { expect(screen.getByLabelText('Ticker')).toBeInTheDocument(); }); await user.type(screen.getByLabelText('Ticker'), 'GOOG'); await user.type(screen.getByLabelText('Legal Name'), 'Alphabet Inc.'); await user.click(screen.getByText('Create')); // Form should close on success await waitFor(() => { expect(screen.queryByLabelText('Ticker')).not.toBeInTheDocument(); }); }); it('cancel closes the add form', async () => { const user = userEvent.setup(); renderRoute('/companies'); await waitFor(() => { expect(screen.getByText('Add Company')).toBeInTheDocument(); }); await user.click(screen.getByText('Add Company')); await waitFor(() => { expect(screen.getByText('Cancel')).toBeInTheDocument(); }); await user.click(screen.getByText('Cancel')); await waitFor(() => { expect(screen.queryByLabelText('Ticker')).not.toBeInTheDocument(); }); }); it('shows empty state when no companies', async () => { server.use( http.get('/api/companies', () => HttpResponse.json([])), ); renderRoute('/companies'); await waitFor(() => { expect(screen.getByText('No data')).toBeInTheDocument(); }); }); });