import * as React from 'react'; import expect from 'expect'; import { waitFor, render, screen } from '@testing-library/react'; import { QueryClient } from '@tanstack/react-query'; import { Basic } from './useCanAccess.stories'; describe('useCanAccess', () => { it('should return a loading state on mount', () => { render(); screen.getByText('LOADING'); }); it('should return isPending: true by default after a tick', async () => { render(); screen.getByText('LOADING'); await waitFor(() => { expect(screen.queryByText('LOADING')).toBeNull(); }); }); it('should allow access on mount when there is no authProvider', async () => { render(); expect(screen.queryByText('LOADING')).toBeNull(); screen.getByText('canAccess: YES'); await new Promise(resolve => setTimeout(resolve, 100)); screen.getByText('Renders: 1'); }); it('should return that the resource is accessible when canAccess return true', async () => { const authProvider = { login: () => Promise.reject('bad method'), logout: () => Promise.reject('bad method'), checkAuth: () => Promise.reject('bad method'), checkError: () => Promise.reject('bad method'), getPermissions: () => Promise.reject('bad method'), canAccess: () => Promise.resolve(true), }; render(); await waitFor(() => { expect(screen.queryByText('LOADING')).toBeNull(); expect(screen.queryByText('canAccess: YES')).not.toBeNull(); }); }); it('should return that the resource is accessible when auth provider does not have an canAccess method', async () => { const authProvider = { login: () => Promise.reject('bad method'), logout: () => Promise.reject('bad method'), checkAuth: () => Promise.reject('bad method'), checkError: () => Promise.reject('bad method'), getPermissions: () => Promise.reject('bad method'), canAccess: undefined, }; render(); await waitFor(() => { expect(screen.queryByText('LOADING')).toBeNull(); expect(screen.queryByText('canAccess: YES')).not.toBeNull(); }); await new Promise(resolve => setTimeout(resolve, 100)); screen.getByText('Renders: 1'); }); it('should return that the resource is not accessible when canAccess return false', async () => { const authProvider = { login: () => Promise.reject('bad method'), logout: () => Promise.reject('bad method'), checkAuth: () => Promise.reject('bad method'), checkError: () => Promise.reject('bad method'), getPermissions: () => Promise.reject('bad method'), canAccess: () => Promise.resolve(false), }; render(); await waitFor(() => { expect(screen.queryByText('LOADING')).toBeNull(); expect(screen.queryByText('canAccess: NO')).not.toBeNull(); expect(screen.queryByText('ERROR')).toBeNull(); }); }); it('should return the error when auth.canAccess call fails', async () => { const authProvider = { login: () => Promise.reject('bad method'), logout: () => Promise.reject('bad method'), checkAuth: () => Promise.reject('bad method'), getPermissions: () => Promise.reject('bad method'), checkError: () => Promise.reject('bad method'), canAccess: () => Promise.reject(new Error('not good')), }; render(); await screen.findByText('LOADING'); await screen.findByText('not good'); }); it('should abort the request if the query is canceled', async () => { const abort = jest.fn(); const authProvider = { canAccess: jest.fn( ({ signal }) => new Promise(() => { signal.addEventListener('abort', () => { abort(signal.reason); }); }) ) as any, checkError: () => Promise.resolve(), supportAbortSignal: true, } as any; const queryClient = new QueryClient(); render(); await waitFor(() => { expect(authProvider.canAccess).toHaveBeenCalled(); }); queryClient.cancelQueries({ queryKey: ['auth', 'canAccess'], }); await waitFor(() => { expect(abort).toHaveBeenCalled(); }); }); });