import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import type { Game } from '../types' import { GameGrid } from './GameGrid' const RED: Game = { id: 1, name: 'Pokemon Red', slug: 'red', generation: 1, region: 'kanto', category: null, boxArtUrl: null, color: null, releaseYear: null, versionGroupId: 1, } const GOLD: Game = { id: 2, name: 'Pokemon Gold', slug: 'gold', generation: 2, region: 'johto', category: null, boxArtUrl: null, color: null, releaseYear: null, versionGroupId: 2, } const RUBY: Game = { id: 3, name: 'Pokemon Ruby', slug: 'ruby', generation: 3, region: 'hoenn', category: null, boxArtUrl: null, color: null, releaseYear: null, versionGroupId: 3, } function setup(overrides: Partial> = {}) { const props = { games: [RED, GOLD, RUBY], selectedId: null, onSelect: vi.fn(), ...overrides, } render() return props } describe('GameGrid', () => { it('renders all game names', () => { setup() expect(screen.getByText('Pokemon Red')).toBeInTheDocument() expect(screen.getByText('Pokemon Gold')).toBeInTheDocument() expect(screen.getByText('Pokemon Ruby')).toBeInTheDocument() }) it('renders generation filter pills for each unique generation', () => { setup() expect(screen.getByRole('button', { name: 'Gen 1' })).toBeInTheDocument() expect(screen.getByRole('button', { name: 'Gen 2' })).toBeInTheDocument() expect(screen.getByRole('button', { name: 'Gen 3' })).toBeInTheDocument() }) it('filters games when a generation pill is clicked', async () => { setup() await userEvent.click(screen.getByRole('button', { name: 'Gen 1' })) expect(screen.getByText('Pokemon Red')).toBeInTheDocument() expect(screen.queryByText('Pokemon Gold')).not.toBeInTheDocument() expect(screen.queryByText('Pokemon Ruby')).not.toBeInTheDocument() }) it('restores all games when "All" generation pill is clicked', async () => { setup() await userEvent.click(screen.getByRole('button', { name: 'Gen 1' })) await userEvent.click(screen.getAllByRole('button', { name: 'All' })[0]!) expect(screen.getByText('Pokemon Red')).toBeInTheDocument() expect(screen.getByText('Pokemon Gold')).toBeInTheDocument() expect(screen.getByText('Pokemon Ruby')).toBeInTheDocument() }) it('filters games when a region pill is clicked', async () => { setup() await userEvent.click(screen.getByRole('button', { name: 'Johto' })) expect(screen.queryByText('Pokemon Red')).not.toBeInTheDocument() expect(screen.getByText('Pokemon Gold')).toBeInTheDocument() expect(screen.queryByText('Pokemon Ruby')).not.toBeInTheDocument() }) it('calls onSelect with the game when a game card is clicked', async () => { const { onSelect } = setup() await userEvent.click(screen.getByText('Pokemon Red')) expect(onSelect).toHaveBeenCalledWith(RED) }) it('hides games with active runs when the checkbox is ticked', async () => { setup({ runs: [{ id: 10, gameId: 1, status: 'active' } as never], }) await userEvent.click(screen.getByLabelText(/hide games with active run/i)) expect(screen.queryByText('Pokemon Red')).not.toBeInTheDocument() expect(screen.getByText('Pokemon Gold')).toBeInTheDocument() }) it('does not render run-based checkboxes when runs prop is omitted', () => { setup({ runs: undefined }) expect(screen.queryByLabelText(/hide games with active run/i)).not.toBeInTheDocument() }) })