import * as React from 'react'; import { ReactNode } from 'react'; import expect from 'expect'; import { useList, UseListOptions, UseListValue } from './useList'; import { fireEvent, render, waitFor } from '@testing-library/react'; import { ListContextProvider } from './ListContextProvider'; import { useListContext } from './useListContext'; const UseList = ({ children, callback, ...props }: UseListOptions & { children?: ReactNode; callback: (value: UseListValue) => void; }) => { const value = useList(props); callback(value); return {children}; }; describe('', () => { it('should filter string data based on the filter props', () => { const callback = jest.fn(); const data = [ { id: 1, title: 'hello' }, { id: 2, title: 'world' }, ]; render( ); expect(callback).toHaveBeenCalledWith( expect.objectContaining({ sort: { field: 'id', order: 'ASC' }, isFetching: false, isLoading: false, data: [{ id: 2, title: 'world' }], error: undefined, total: 1, }) ); }); it('should filter array data based on the filter props', async () => { const callback = jest.fn(); const data = [ { id: 1, items: ['one', 'two'] }, { id: 2, items: ['three'] }, { id: 3, items: 'four' }, { id: 4, items: ['five'] }, ]; render( ); await waitFor(() => { expect(callback).toHaveBeenCalledWith( expect.objectContaining({ sort: { field: 'id', order: 'ASC' }, isFetching: false, isLoading: false, data: [ { id: 1, items: ['one', 'two'] }, { id: 3, items: 'four' }, { id: 4, items: ['five'] }, ], error: undefined, total: 3, }) ); }); }); it('should apply sorting correctly', async () => { const callback = jest.fn(); const data = [ { id: 1, title: 'hello' }, { id: 2, title: 'world' }, ]; const SortButton = () => { const listContext = useListContext(); return ( ); }; const { getByText } = render( ); await waitFor(() => { expect(callback).toHaveBeenCalledWith( expect.objectContaining({ sort: { field: 'title', order: 'DESC' }, isFetching: false, isLoading: false, data: [ { id: 2, title: 'world' }, { id: 1, title: 'hello' }, ], error: undefined, total: 2, }) ); }); fireEvent.click(getByText('Sort by title ASC')); await waitFor(() => { expect(callback).toHaveBeenCalledWith( expect.objectContaining({ sort: { field: 'title', order: 'ASC' }, isFetching: false, isLoading: false, data: [ { id: 1, title: 'hello' }, { id: 2, title: 'world' }, ], error: undefined, total: 2, }) ); }); }); it('should apply pagination correctly', async () => { const callback = jest.fn(); const data = [ { id: 1, title: 'hello' }, { id: 2, title: 'world' }, { id: 3, title: 'baz' }, { id: 4, title: 'bar' }, { id: 5, title: 'foo' }, { id: 6, title: 'plop' }, { id: 7, title: 'bazinga' }, ]; render( ); await waitFor(() => { expect(callback).toHaveBeenCalledWith( expect.objectContaining({ sort: { field: 'id', order: 'ASC' }, isFetching: false, isLoading: false, data: [ { id: 6, title: 'plop' }, { id: 7, title: 'bazinga' }, ], page: 2, perPage: 5, error: undefined, total: 7, }) ); }); }); it('should be usable with asynchronously fetched data', () => { const callback = jest.fn(); const data = [ { id: 1, title: 'hello' }, { id: 2, title: 'world' }, ]; const { rerender } = render( ); rerender( ); expect(callback).toHaveBeenCalledWith( expect.objectContaining({ sort: { field: 'id', order: 'ASC' }, isFetching: true, isLoading: false, data: [{ id: 2, title: 'world' }], error: undefined, total: 1, }) ); }); it('should filter array data based on the custom filter', async () => { const callback = jest.fn(); const data = [ { id: 1, items: ['one', 'two'] }, { id: 2, items: ['three'] }, { id: 3, items: 'four' }, { id: 4, items: ['five'] }, ]; render( record.id > 2} callback={callback} /> ); await waitFor(() => { expect(callback).toHaveBeenCalledWith( expect.objectContaining({ sort: { field: 'id', order: 'ASC' }, isFetching: false, isLoading: false, data: [ { id: 3, items: 'four' }, { id: 4, items: ['five'] }, ], error: undefined, total: 2, }) ); }); }); it('should filter data based on a custom filter with nested objects', () => { const callback = jest.fn(); const data = [ { id: 1, title: { name: 'hello' } }, { id: 2, title: { name: 'world' } }, ]; render( ); expect(callback).toHaveBeenCalledWith( expect.objectContaining({ sort: { field: 'id', order: 'ASC' }, isFetching: false, isLoading: false, data: [{ id: 2, title: { name: 'world' } }], error: undefined, total: 1, }) ); }); });