Files
wh40k-points-comparator/react-app/src/test/UnitTable.test.jsx

60 lines
2.9 KiB
JavaScript

import { describe, it, expect, vi } from 'vitest'
import { render, screen, within } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import fixture from './fixtures/data.json'
import { UnitTable } from '../components/UnitTable.jsx'
import { buildColumns } from '../utils/columns.jsx'
const columns = buildColumns({ isMobile: false, showFactionCol: true, onSelectSize: () => {} })
describe('UnitTable', () => {
it('renders the count header with the filtered count', () => {
render(<UnitTable rows={fixture.units} columns={columns} filteredCount={fixture.units.length} onCellClick={() => {}} />)
// "X units" is rendered (X being the filteredCount). The text is split across
// <b>{X}</b> and ' units' so a regex/getByText matcher can't find the combined
// text — instead find the <b>{X}</b> and check the parent for the "units" suffix.
const countEl = screen.getByText(`${fixture.units.length}`)
expect(countEl.parentElement).toHaveTextContent(new RegExp(`${fixture.units.length}\\s*units`))
})
it('renders all unit names in the grid', () => {
render(<UnitTable rows={fixture.units} columns={columns} filteredCount={fixture.units.length} onCellClick={() => {}} />)
for (const u of fixture.units) {
expect(screen.getByText(u.name)).toBeInTheDocument()
}
})
it('calls onCellClick with the clicked row when a non-size cell is clicked', async () => {
const user = userEvent.setup()
const onCellClick = vi.fn()
const palatine = fixture.units.find(u => u.name === 'Palatine')
render(<UnitTable rows={[palatine]} columns={columns} filteredCount={1} onCellClick={onCellClick} />)
// Click the Old cell for Palatine. Note: the brief said '60' but the fixture has
// Palatine.original = 50, so we use '50' (the actual Old value).
const oldCell = screen.getByText('50')
await user.click(oldCell)
expect(onCellClick).toHaveBeenCalledTimes(1)
expect(onCellClick).toHaveBeenCalledWith(expect.objectContaining({ name: 'Palatine' }))
})
it('does NOT call onCellClick when the size cell is clicked (size cell handles its own clicks)', async () => {
const user = userEvent.setup()
const onCellClick = vi.fn()
const arco = fixture.units.find(u => u.name === 'Arco-flagellants')
render(<UnitTable rows={[arco]} columns={columns} filteredCount={1} onCellClick={onCellClick} />)
// The size column shows a Select for multi-size units
const combobox = screen.getByRole('combobox')
await user.click(combobox)
// No onCellClick yet
expect(onCellClick).not.toHaveBeenCalled()
})
it('renders em-dash for new units (null original)', () => {
const newUnit = fixture.units.find(u => u.name === 'New Unit X')
render(<UnitTable rows={[newUnit]} columns={columns} filteredCount={1} onCellClick={() => {}} />)
// At least one em-dash should be in the document
const dashes = screen.getAllByText('—')
expect(dashes.length).toBeGreaterThan(0)
})
})