116 lines
3.5 KiB
TypeScript
116 lines
3.5 KiB
TypeScript
|
|
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<React.ComponentProps<typeof GameGrid>> = {}) {
|
||
|
|
const props = {
|
||
|
|
games: [RED, GOLD, RUBY],
|
||
|
|
selectedId: null,
|
||
|
|
onSelect: vi.fn(),
|
||
|
|
...overrides,
|
||
|
|
}
|
||
|
|
render(<GameGrid {...props} />)
|
||
|
|
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()
|
||
|
|
})
|
||
|
|
})
|