import * as React from 'react'; import { useState, useCallback, ReactElement } from 'react'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import expect from 'expect'; import { useReferenceInputController } from './useReferenceInputController'; import { CoreAdminContext } from '../../core'; import { Form, useInput } from '../../form'; import { testDataProvider } from '../../dataProvider'; const ReferenceInputController = props => { const { children, ...rest } = props; const inputProps = useInput({ ...rest, }); return children( useReferenceInputController({ ...rest, ...inputProps }) ) as ReactElement; }; describe('useReferenceInputController', () => { const defaultProps = { children: jest.fn(), onChange: jest.fn(), reference: 'posts', resource: 'comments', source: 'post_id', }; const dataProvider = testDataProvider({ getMany: jest .fn() .mockResolvedValue({ data: [{ id: 1, title: 'foo' }] }), getList: jest.fn().mockResolvedValue({ data: [ { id: 1, title: 'foo' }, { id: 2, title: 'bar' }, ], total: 2, }), }); afterEach(() => { // @ts-ignore dataProvider.getMany.mockClear(); // @ts-ignore dataProvider.getList.mockClear(); }); it('should fetch possible values using getList', async () => { const children = jest.fn().mockReturnValue(

child

); render(
{children}
); await waitFor(() => { expect(dataProvider.getList).toBeCalledTimes(1); }); expect(dataProvider.getList).toBeCalledWith('posts', { filter: {}, meta: undefined, pagination: { page: 1, perPage: 25, }, sort: { field: 'id', order: 'ASC', }, }); }); it('should allow getList pagination and sorting customization', async () => { const children = jest.fn().mockReturnValue(

child

); render(
{children}
); await waitFor(() => { expect(dataProvider.getList).toBeCalledTimes(1); expect(dataProvider.getList).toBeCalledWith('posts', { filter: {}, meta: undefined, pagination: { page: 5, perPage: 10, }, sort: { field: 'title', order: 'ASC', }, }); }); }); it('should fetch current value using getMany', async () => { const children = jest.fn().mockReturnValue(

child

); render(
{children}
); await waitFor(() => { expect(dataProvider.getList).toBeCalledTimes(1); expect(dataProvider.getMany).toBeCalledTimes(1); expect(dataProvider.getMany).toBeCalledWith('posts', { ids: [1] }); }); }); it('should not fetch current value using getMany if it is empty', async () => { const children = jest.fn().mockReturnValue(

child

); render(
{children}
); await waitFor(() => { expect(dataProvider.getList).toBeCalledTimes(1); }); await new Promise(resolve => setTimeout(resolve, 100)); expect(dataProvider.getMany).not.toHaveBeenCalled(); }); it('should pass possibleValues and record to child', async () => { const children = jest.fn().mockReturnValue(

child

); render(
{children}
); await waitFor(() => { expect(children.mock.calls.length).toBeGreaterThanOrEqual(4); }); expect(children).toHaveBeenCalledWith( expect.objectContaining({ allChoices: [ { id: 1, title: 'foo' }, { id: 2, title: 'bar' }, ], availableChoices: [ { id: 1, title: 'foo' }, { id: 2, title: 'bar' }, ], selectedChoices: [{ id: 1, title: 'foo' }], displayedFilters: {}, error: null, filter: {}, filterValues: {}, isFetching: false, isLoading: false, page: 1, perPage: 25, hasPreviousPage: false, hasNextPage: false, hideFilter: expect.any(Function), setFilters: expect.any(Function), setPage: expect.any(Function), setPerPage: expect.any(Function), setSort: expect.any(Function), showFilter: expect.any(Function), sort: { field: 'title', order: 'ASC' }, refetch: expect.any(Function), resource: 'posts', source: 'post_id', total: 2, }) ); }); it('should refetch reference getList when its props change', async () => { const children = jest.fn().mockReturnValue(

child

); const Component = () => { const [sort, setSort] = useState({ field: 'title', order: 'ASC' }); const handleClick = useCallback( () => setSort({ field: 'body', order: 'DESC' }), [setSort] ); return ( <>