72 lines
2.6 KiB
TypeScript
72 lines
2.6 KiB
TypeScript
import { render, screen, fireEvent } from '@testing-library/react';
|
||
import { ThemeProvider } from '../../theme';
|
||
import AdminDataTable, { type AdminTableColumn } from './AdminDataTable';
|
||
|
||
interface Row {
|
||
id: number;
|
||
name: string;
|
||
}
|
||
|
||
const ROWS: Row[] = [
|
||
{ id: 1, name: 'Alpha' },
|
||
{ id: 2, name: 'Beta' },
|
||
];
|
||
const COLUMNS: AdminTableColumn<Row>[] = [
|
||
{ key: 'id', header: 'ID', render: (r) => r.id },
|
||
{ key: 'name', header: 'Name', render: (r) => r.name },
|
||
];
|
||
|
||
describe('<AdminDataTable/>', () => {
|
||
const wrap = (ui: React.ReactNode) => render(<ThemeProvider>{ui}</ThemeProvider>);
|
||
|
||
it('renders headers and every row cell', () => {
|
||
wrap(<AdminDataTable columns={COLUMNS} rows={ROWS} getRowKey={(r) => r.id} />);
|
||
expect(screen.getByText('ID')).toBeInTheDocument();
|
||
expect(screen.getByText('Name')).toBeInTheDocument();
|
||
expect(screen.getByText('Alpha')).toBeInTheDocument();
|
||
expect(screen.getByText('Beta')).toBeInTheDocument();
|
||
});
|
||
|
||
it('exposes a data-col attribute per column', () => {
|
||
const { container } = wrap(<AdminDataTable columns={COLUMNS} rows={ROWS} getRowKey={(r) => r.id} />);
|
||
expect(container.querySelectorAll('[data-col="name"]').length).toBe(2);
|
||
});
|
||
|
||
it('calls onRowClick with the clicked row', () => {
|
||
const onRowClick = jest.fn();
|
||
wrap(<AdminDataTable columns={COLUMNS} rows={ROWS} getRowKey={(r) => r.id} onRowClick={onRowClick} />);
|
||
fireEvent.click(screen.getByText('Beta'));
|
||
expect(onRowClick).toHaveBeenCalledWith(ROWS[1]);
|
||
});
|
||
|
||
it('renders the footer line only when passed', () => {
|
||
const { rerender, container } = wrap(<AdminDataTable columns={COLUMNS} rows={ROWS} getRowKey={(r) => r.id} />);
|
||
expect(container.querySelector('p')).not.toBeInTheDocument();
|
||
rerender(
|
||
<ThemeProvider>
|
||
<AdminDataTable columns={COLUMNS} rows={ROWS} getRowKey={(r) => r.id} footer="Showing 1–2 of 2" />
|
||
</ThemeProvider>,
|
||
);
|
||
expect(screen.getByText('Showing 1–2 of 2')).toBeInTheDocument();
|
||
});
|
||
|
||
it('fires onSortChange with the column key when a sortable header is clicked', () => {
|
||
const onSortChange = jest.fn();
|
||
const sortableColumns: AdminTableColumn<Row>[] = [
|
||
{ key: 'id', header: 'ID', render: (r) => r.id, sortable: true },
|
||
{ key: 'name', header: 'Name', render: (r) => r.name },
|
||
];
|
||
wrap(
|
||
<AdminDataTable
|
||
columns={sortableColumns}
|
||
rows={ROWS}
|
||
getRowKey={(r) => r.id}
|
||
sort={{ key: 'id', direction: 'asc' }}
|
||
onSortChange={onSortChange}
|
||
/>,
|
||
);
|
||
fireEvent.click(screen.getByRole('button', { name: /ID/ }));
|
||
expect(onSortChange).toHaveBeenCalledWith('id');
|
||
});
|
||
});
|