import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import { useManagementTableHeader } from '../../../src/static/js/utils/hooks/useManagementTableHeader'; function HookConsumer(props: { order: 'asc' | 'desc'; selected: boolean; sort: string; type: 'comments' | 'media' | 'users'; onCheckAllRows?: (newSort: string, newOrder: 'asc' | 'desc') => void; onClickColumnSort?: (newSelected: boolean, newType: 'comments' | 'media' | 'users') => void; }) { const tuple = useManagementTableHeader(props) as [ string, 'asc' | 'desc', boolean, React.MouseEventHandler, () => void, ]; const [sort, order, isSelected, sortByColumn, checkAll] = tuple; return (
{sort}
{order}
{String(isSelected)}
); } describe('utils/hooks', () => { describe('useManagementTableHeader', () => { test('Returns a 5-tuple in expected order and reflects initial props', () => { let tuple: any; const Comp: React.FC = () => { tuple = useManagementTableHeader({ sort: 'title', order: 'asc', selected: false }); return null; }; render(); expect(Array.isArray(tuple)).toBe(true); expect(tuple).toHaveLength(5); const [sort, order, isSelected] = tuple; expect(sort).toBe('title'); expect(order).toBe('asc'); expect(isSelected).toBe(false); }); test('sortByColumn toggles order when clicking same column and updates sort when clicking different column', () => { const onClickColumnSort = jest.fn(); const { getByTestId, rerender } = render( ); // Initial state expect(getByTestId('sort').textContent).toBe('title'); expect(getByTestId('order').textContent).toBe('desc'); // Click same column -> toggle order to asc fireEvent.click(getByTestId('col-title')); expect(onClickColumnSort).toHaveBeenLastCalledWith('title', 'asc'); // Rerender to ensure state settled in testing DOM rerender( ); // Click same column -> toggle order to desc fireEvent.click(getByTestId('col-title')); expect(onClickColumnSort).toHaveBeenLastCalledWith('title', 'desc'); // Click different column -> set sort to that column and default order desc fireEvent.click(getByTestId('col-views')); expect(onClickColumnSort).toHaveBeenLastCalledWith('views', 'desc'); }); test('checkAll inverts current selection and invokes callback with newSelected and type', () => { const onCheckAllRows = jest.fn(); const { getByTestId } = render( ); expect(getByTestId('selected').textContent).toBe('false'); fireEvent.click(getByTestId('check-all')); // newSelected computed as !isSelected -> true expect(onCheckAllRows).toHaveBeenCalledWith(true, 'media'); }); test('Effects update internal state when props change', () => { const { getByTestId, rerender } = render( ); expect(getByTestId('sort').textContent).toBe('title'); expect(getByTestId('order').textContent).toBe('asc'); expect(getByTestId('selected').textContent).toBe('false'); rerender(); expect(getByTestId('sort').textContent).toBe('views'); expect(getByTestId('order').textContent).toBe('desc'); expect(getByTestId('selected').textContent).toBe('true'); }); test('Does not throw when optional callbacks are not provided', () => { const { getByTestId } = render(); expect(() => fireEvent.click(getByTestId('col-title'))).not.toThrow(); expect(() => fireEvent.click(getByTestId('check-all'))).not.toThrow(); }); }); });