import * as React from 'react'; import { ReactElement } from 'react'; import expect from 'expect'; import { render, screen, waitFor, fireEvent } from '@testing-library/react'; import { useReferenceArrayInputController, UseReferenceArrayInputParams, } from './useReferenceArrayInputController'; import { CoreAdminContext } from '../../core'; import { testDataProvider } from '../../dataProvider'; import { ChoicesContextValue, Form } from '../../form'; import { SORT_ASC } from '../list/queryReducer'; const ReferenceArrayInputController = ( props: UseReferenceArrayInputParams & { children: (params: ChoicesContextValue) => ReactElement; } ) => { const { children, ...rest } = props; return children(useReferenceArrayInputController(rest)) as ReactElement; }; describe('useReferenceArrayInputController', () => { const defaultProps = { field: { value: undefined }, record: undefined, reference: 'tags', resource: 'posts', source: 'tag_ids', }; afterEach(async () => { // wait for the getManyAggregate batch to resolve await waitFor(() => new Promise(resolve => setTimeout(resolve, 0))); }); describe('isLoading', () => { it('should set isLoading to true as long as there are no references fetched and no selected references', () => { const children = jest.fn(({ isLoading }) => (
{isLoading.toString()}
)); render(
{children}
); expect(screen.queryByText('true')).not.toBeNull(); }); it('should set isLoading to false once the dataProvider returns', async () => { const children = jest.fn(({ isLoading }) => (
{isLoading.toString()}
)); const dataProvider = testDataProvider({ getMany: jest.fn().mockResolvedValue({ data: [] }), getList: jest.fn().mockResolvedValue({ data: [], total: 0 }), }); render(
{children}
); await waitFor(() => { expect(dataProvider.getList).toHaveBeenCalledTimes(1); }); await waitFor(() => { expect(dataProvider.getMany).toHaveBeenCalledTimes(1); }); expect(screen.queryByText('false')).not.toBeNull(); }); }); describe('error', () => { it('should set error in case of references fetch error and there are no selected reference in the input value', async () => { jest.spyOn(console, 'error').mockImplementation(() => {}); const children = jest.fn(({ error }) => (
{error?.message}
)); render( Promise.reject(new Error('boom')), getMany: () => Promise.resolve({ data: [] }), })} >
{children}
); await waitFor(() => { expect(screen.getByText('boom')).not.toBeNull(); }); }); it('should set error in case of references fetch error and there are no data found for the references already selected', async () => { jest.spyOn(console, 'error').mockImplementation(() => {}); const children = jest.fn(({ error }) => (
{error?.message}
)); render( Promise.reject(new Error('boom')), getMany: () => Promise.resolve({ data: [] }), })} >
{children}
); await waitFor(() => { expect(screen.queryByText('boom')).not.toBeNull(); }); }); it.skip('should not display an error in case of references fetch error but data from at least one selected reference was found', async () => { const children = jest.fn(({ error }) => (
{error?.message}
)); render( Promise.reject(new Error('boom')), // @ts-ignore getMany: () => Promise.resolve({ data: [{ id: 1, title: 'foo' }], }), })} >
{children}
); await waitFor( () => new Promise(resolve => setTimeout(resolve, 100)) ); expect(screen.queryByText('boom')).toBeNull(); }); }); it('should call getList on mount with default params', async () => { const children = jest.fn(() =>
); const dataProvider = testDataProvider({ // @ts-ignore getList: jest .fn() .mockResolvedValue(Promise.resolve({ data: [], total: 0 })), }); render(
{children}
); expect(dataProvider.getList).toHaveBeenCalledWith('tags', { pagination: { page: 1, perPage: 25, }, sort: { field: 'id', order: 'DESC', }, filter: {}, meta: undefined, }); }); it('should call getList with meta when provided', async () => { const children = jest.fn(() =>
); const dataProvider = testDataProvider({ // @ts-ignore getList: jest .fn() .mockResolvedValue(Promise.resolve({ data: [], total: 0 })), }); render(
{children}
); expect(dataProvider.getList).toHaveBeenCalledWith('tags', { pagination: { page: 1, perPage: 25, }, sort: { field: 'id', order: 'DESC', }, filter: {}, meta: { value: 'a' }, }); }); it('should allow to customize getList arguments with perPage, sort, and filter props', () => { const children = jest.fn(() =>
); const dataProvider = testDataProvider({ getList: jest .fn() .mockResolvedValue(Promise.resolve({ data: [], total: 0 })), }); render(
{children}
); expect(dataProvider.getList).toHaveBeenCalledWith('tags', { pagination: { page: 2, perPage: 5, }, sort: { field: 'foo', order: 'ASC', }, filter: { permanentFilter: 'foo' }, meta: undefined, }); }); it('should call getList when setFilters is called', async () => { const children = jest.fn(({ setFilters }) => (