import * as React from 'react' import * as Redux from 'react-redux' import * as RA from 'react-admin' import { useResourceRefresh } from './useResourceRefresh' jest.mock('react', () => ({ ...jest.requireActual('react'), useState: jest.fn(), })) jest.mock('react-redux', () => ({ ...jest.requireActual('react-redux'), useSelector: jest.fn(), })) jest.mock('react-admin', () => ({ ...jest.requireActual('react-admin'), useRefresh: jest.fn(), useDataProvider: jest.fn(), })) describe('useResourceRefresh', () => { const setState = jest.fn() const useStateMock = (initState) => [initState, setState] const refresh = jest.fn() const useRefreshMock = () => refresh const getMany = jest.fn() const useDataProviderMock = () => ({ getMany }) let lastTime beforeEach(() => { jest.spyOn(React, 'useState').mockImplementation(useStateMock) jest.spyOn(RA, 'useRefresh').mockImplementation(useRefreshMock) jest.spyOn(RA, 'useDataProvider').mockImplementation(useDataProviderMock) lastTime = new Date(new Date().valueOf() + 1000) }) afterEach(() => { jest.clearAllMocks() }) it('stores last time checked, to avoid redundant runs', () => { const useSelectorMock = () => ({ lastReceived: lastTime }) jest.spyOn(Redux, 'useSelector').mockImplementation(useSelectorMock) useResourceRefresh() expect(setState).toHaveBeenCalledWith(lastTime) }) it("does not run again if lastTime didn't change", () => { jest.spyOn(React, 'useState').mockImplementation(() => [lastTime, setState]) const useSelectorMock = () => ({ lastReceived: lastTime }) jest.spyOn(Redux, 'useSelector').mockImplementation(useSelectorMock) useResourceRefresh() expect(setState).not.toHaveBeenCalled() }) describe('No visible resources specified', () => { it('triggers a UI refresh when received a "any" resource refresh', () => { const useSelectorMock = () => ({ lastReceived: lastTime, resources: { '*': '*' }, }) jest.spyOn(Redux, 'useSelector').mockImplementation(useSelectorMock) useResourceRefresh() expect(refresh).toHaveBeenCalledTimes(1) expect(getMany).not.toHaveBeenCalled() }) it('triggers a UI refresh when received an "any" id', () => { const useSelectorMock = () => ({ lastReceived: lastTime, resources: { album: ['*'] }, }) jest.spyOn(Redux, 'useSelector').mockImplementation(useSelectorMock) useResourceRefresh() expect(refresh).toHaveBeenCalledTimes(1) expect(getMany).not.toHaveBeenCalled() }) it('triggers a refetch of the resources received', () => { const useSelectorMock = () => ({ lastReceived: lastTime, resources: { album: ['al-1', 'al-2'], song: ['sg-1', 'sg-2'] }, }) jest.spyOn(Redux, 'useSelector').mockImplementation(useSelectorMock) useResourceRefresh() expect(refresh).not.toHaveBeenCalled() expect(getMany).toHaveBeenCalledTimes(2) expect(getMany).toHaveBeenCalledWith('album', { ids: ['al-1', 'al-2'] }) expect(getMany).toHaveBeenCalledWith('song', { ids: ['sg-1', 'sg-2'] }) }) }) describe('Visible resources specified', () => { it('triggers a UI refresh when received a "any" resource refresh', () => { const useSelectorMock = () => ({ lastReceived: lastTime, resources: { '*': '*' }, }) jest.spyOn(Redux, 'useSelector').mockImplementation(useSelectorMock) useResourceRefresh('album') expect(refresh).toHaveBeenCalledTimes(1) expect(getMany).not.toHaveBeenCalled() }) it('triggers a refetch of the resources received if they are visible', () => { const useSelectorMock = () => ({ lastReceived: lastTime, resources: { album: ['al-1', 'al-2'], song: ['sg-1', 'sg-2'] }, }) jest.spyOn(Redux, 'useSelector').mockImplementation(useSelectorMock) useResourceRefresh('song') expect(refresh).not.toHaveBeenCalled() expect(getMany).toHaveBeenCalledTimes(1) expect(getMany).toHaveBeenCalledWith('song', { ids: ['sg-1', 'sg-2'] }) }) }) })