UNPKG

@kadconsulting/dry

Version:
241 lines 10.9 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { useEffect, useRef, useState } from 'react'; import { render, screen, waitFor, fireEvent, within, } from '@testing-library/react'; import DataTable from './DataTable'; import { FilterType } from './DataTableTypes'; describe('DataTable', () => { const sampleColumns = [ { Header: 'Order #', accessor: 'orderNumber', filterType: FilterType.Text }, { Header: 'Project', accessor: 'projectId', filterType: FilterType.Text }, { Header: 'Status', accessor: 'orderState', filterType: FilterType.Text }, { Header: 'Date Created', accessor: 'dateCreated', filterType: FilterType.DateRange, }, { Header: 'Amount', accessor: 'amount', filterType: FilterType.Number }, ]; const sampleData = [ { id: 1, orderNumber: '123', projectId: '456', orderState: 'Purchase Order', dateCreated: '2021-01-01', amount: 1000, }, { id: 2, orderNumber: '124', projectId: '457', orderState: 'Completed', dateCreated: '2021-01-02', amount: 2000, }, { id: 3, orderNumber: '125', projectId: '458', orderState: 'In Progress', dateCreated: '2021-01-03', amount: 3000, }, ]; const defaultProps = { columns: sampleColumns, data: sampleData, pageIndex: 0, pageSize: 10, onPageChange: jest.fn(), filters: {}, columnOrder: sampleColumns.map((col) => col.accessor), columnWidths: {}, visibleColumns: sampleColumns.map((col) => col.accessor), pinnedColumns: [], setColumnOrder: jest.fn(), setColumnWidths: jest.fn(), loading: false, setPageIndex: jest.fn(), handleRowClick: jest.fn(), }; beforeEach(() => { jest.clearAllMocks(); }); it('renders with given data and columns', () => { render(_jsx(DataTable, { ...defaultProps })); sampleColumns.forEach((column) => { expect(screen.getByText(column.Header)).toBeInTheDocument(); }); sampleData.forEach((row) => { expect(screen.getByText(row.orderNumber)).toBeInTheDocument(); }); }); it('renders loading state', () => { render(_jsx(DataTable, { ...defaultProps, loading: true, loadingRowCount: 3 })); expect(screen.getAllByRole('row')).toHaveLength(4); // Header + 3 loading rows }); it('handles row click', () => { render(_jsx(DataTable, { ...defaultProps })); fireEvent.click(screen.getByText('123')); expect(defaultProps.handleRowClick).toHaveBeenCalledWith(sampleData[0]); }); it('handles sorting when column header is clicked', async () => { render(_jsx(DataTable, { ...defaultProps })); const orderHeader = screen.getByText('Order #'); fireEvent.click(orderHeader); await waitFor(() => { expect(screen.getAllByRole('row')[1]).toHaveTextContent('123'); expect(screen.getAllByRole('row')[3]).toHaveTextContent('125'); }); fireEvent.click(orderHeader); await waitFor(() => { expect(screen.getAllByRole('row')[1]).toHaveTextContent('125'); expect(screen.getAllByRole('row')[3]).toHaveTextContent('123'); }); }); it('handles default sorting', () => { const columnsWithDefaultSort = [ ...sampleColumns, { Header: 'Default Sort', accessor: 'defaultSort', defaultSort: true }, ]; const dataWithDefaultSort = sampleData.map((item, index) => ({ ...item, defaultSort: index, })); render(_jsx(DataTable, { ...defaultProps, columns: columnsWithDefaultSort, data: dataWithDefaultSort })); const rows = screen.getAllByRole('row'); expect(within(rows[1]).getByText('0')).toBeInTheDocument(); expect(within(rows[3]).getByText('2')).toBeInTheDocument(); }); it('handles text filtering', async () => { const { rerender } = render(_jsx(DataTable, { ...defaultProps })); rerender(_jsx(DataTable, { ...defaultProps, filters: { orderNumber: ['123'] } })); await waitFor(() => { expect(screen.getAllByRole('row')).toHaveLength(2); // Header + 1 data row expect(screen.getByText('123')).toBeInTheDocument(); expect(screen.queryByText('124')).not.toBeInTheDocument(); }); }); it('handles number filtering', async () => { const { rerender } = render(_jsx(DataTable, { ...defaultProps })); rerender(_jsx(DataTable, { ...defaultProps, filters: { amount: 2000 } })); await waitFor(() => { expect(screen.getAllByRole('row')).toHaveLength(2); // Header + 1 data row expect(screen.getByText('124')).toBeInTheDocument(); expect(screen.queryByText('123')).not.toBeInTheDocument(); }); }); it('handles date range filtering', async () => { const { rerender } = render(_jsx(DataTable, { ...defaultProps })); rerender(_jsx(DataTable, { ...defaultProps, filters: { dateCreated: { startDate: '2021-01-02', endDate: '2021-01-03' }, } })); await waitFor(() => { expect(screen.getAllByRole('row')).toHaveLength(3); // Header + 2 data rows expect(screen.getByText('124')).toBeInTheDocument(); expect(screen.getByText('125')).toBeInTheDocument(); expect(screen.queryByText('123')).not.toBeInTheDocument(); }); }); it('handles column reordering', async () => { render(_jsx(DataTable, { ...defaultProps, isDraggable: true })); const headers = screen.getAllByRole('columnheader'); fireEvent.dragStart(headers[0]); fireEvent.dragOver(headers[1]); fireEvent.drop(headers[1]); expect(defaultProps.setColumnOrder).toHaveBeenCalled(); }); it('handles column resizing', async () => { render(_jsx(DataTable, { ...defaultProps, hasResize: true })); const resizeHandle = screen.getAllByText('─')[0]; fireEvent.mouseDown(resizeHandle, { clientX: 0 }); fireEvent.mouseMove(document, { clientX: 100 }); fireEvent.mouseUp(document); expect(defaultProps.setColumnWidths).toHaveBeenCalled(); }); it('renders with accordion when hasAccordion is true', () => { render(_jsx(DataTable, { ...defaultProps, hasAccordion: true })); expect(screen.getAllByText('Purchase Order')).toHaveLength(sampleData.length); }); it('handles pagination correctly', async () => { const onPageChange = jest.fn(); render(_jsx(DataTable, { ...defaultProps, pageSize: 2, onPageChange: onPageChange })); const nextButton = screen.getByText('Next'); fireEvent.click(nextButton); expect(onPageChange).toHaveBeenCalledWith(1, 2); const previousButton = screen.getByText('Previous'); fireEvent.click(previousButton); expect(onPageChange).toHaveBeenCalledWith(0, 2); }); it('renders custom cell content when provided', () => { const customColumns = [ ...sampleColumns, { Header: 'Custom', accessor: 'custom', Cell: ({ value }) => _jsx("span", { children: `Custom: ${value}` }), }, ]; const customData = sampleData.map((item) => ({ ...item, custom: 'test' })); render(_jsx(DataTable, { ...defaultProps, columns: customColumns, data: customData })); expect(screen.getAllByText('Custom: test')).toHaveLength(customData.length); expect(screen.getByText('Custom: test')).toBeInTheDocument(); }); it('handles empty data set', () => { render(_jsx(DataTable, { ...defaultProps, data: [] })); expect(screen.getByText('No data available')).toBeInTheDocument(); }); it('applies badge styling when badgeColumnConfig is provided', () => { const badgeColumnConfig = { orderState: { 'Purchase Order': { color: 'blue', variant: 'solid' }, Completed: { color: 'green', variant: 'outline' }, }, }; render(_jsx(DataTable, { ...defaultProps, badgeColumnConfig: badgeColumnConfig })); expect(screen.getByText('Purchase Order').parentElement).toHaveClass('badge-blue-solid'); expect(screen.getByText('Completed').parentElement).toHaveClass('badge-green-outline'); }); it('renders with a dry-prepended className', () => { const { container } = render(_jsx(DataTable, { ...defaultProps })); expect(container.firstChild).toHaveClass('dry-data-table'); }); it('passes a ref to its outermost element', async () => { const Wrapper = () => { const ref = useRef(null); const [refWasPassed, setRefWasPassed] = useState(false); useEffect(() => { setRefWasPassed(!!ref.current); }, []); return (_jsxs(_Fragment, { children: [_jsx(DataTable, { ref: ref, ...defaultProps }), refWasPassed && _jsx("div", { children: "Ref was passed!" })] })); }; render(_jsx(Wrapper, {})); await waitFor(() => screen.getByText('Ref was passed!')); }); it('passes a downstream id', () => { const id = 'test-id'; render(_jsx(DataTable, { ...defaultProps, id: id })); expect(document.getElementById(id)).toBeInTheDocument(); }); it('passes any downstream className(s)', () => { const className = 'first second third'; render(_jsx(DataTable, { ...defaultProps, className: className })); const parentElement = screen.getByRole('table').parentElement; expect(parentElement).toHaveClass('first'); expect(parentElement).toHaveClass('second'); expect(parentElement).toHaveClass('third'); }); it('passes any downstream data-* attribute(s)', () => { const testValue = 'product-1234-abcd-5678-efgh'; render(_jsx(DataTable, { ...defaultProps, "data-product": testValue })); const parentElement = screen.getByRole('table').parentElement; expect(parentElement).toHaveAttribute('data-product', testValue); }); it('supports downstream @testing-library `screen.getByTestId`', () => { const testId = 'test-subject'; render(_jsx(DataTable, { ...defaultProps, "data-testid": testId })); const parentElement = screen.getByRole('table').parentElement; expect(parentElement).toHaveAttribute('data-testid', testId); }); }); //# sourceMappingURL=DataTable.test.js.map