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();
});
});
});