60 lines
2.9 KiB
JavaScript
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)
|
|
})
|
|
})
|