import * as React from 'react';
import { render, act, cleanup } from '@testing-library/react';
import expect from 'expect';
import usePermissionsOptimized from './usePermissionsOptimized';
import AuthContext from './AuthContext';
describe('usePermissionsOptimized', () => {
afterEach(cleanup);
const CallPermissionsOnMount = ({ number, authParams }: any) => {
const { permissions } = usePermissionsOptimized(authParams);
return (
permissions {number}: {permissions}
);
};
it('returns undefined on mount', () => {
const getPermissions = jest.fn(() => Promise.resolve('admin'));
const { queryByText } = render(
);
expect(queryByText('permissions :')).not.toBeNull();
expect(queryByText('permissions : admin')).toBeNull();
});
it('returns permissions from authProvider after resolve', async () => {
const getPermissions = jest.fn(() => Promise.resolve('admin'));
const { queryByText } = render(
);
await act(async () => await new Promise(r => setTimeout(r)));
expect(queryByText('permissions :')).toBeNull();
expect(queryByText('permissions : admin')).not.toBeNull();
});
it('does not rerender once the permissions have already been fetched', async () => {
let renders = 0;
const ComponentToTest = () => {
const { permissions } = usePermissionsOptimized({ test: 3 });
renders++;
return {permissions}
;
};
const getPermissions = jest.fn(() => Promise.resolve('admin'));
// first usage
const { queryByText } = render(
);
expect(renders).toBe(1); // renders on mount
expect(getPermissions).toBeCalledTimes(1);
expect(queryByText('admin')).toBeNull();
await act(async () => await new Promise(r => setTimeout(r)));
expect(renders).toBe(2); // re-renders when the getPermissions returns
expect(queryByText('admin')).not.toBeNull();
// second usage
cleanup();
renders = 0;
const { queryByText: queryByText2 } = render(
);
expect(renders).toBe(1); // renders on mount
expect(getPermissions).toBeCalledTimes(2);
expect(queryByText2('admin')).not.toBeNull(); // answer from the cache
await act(async () => await new Promise(r => setTimeout(r)));
expect(renders).toBe(1); // does not rerender when the getPermissions returns the same permissions
});
it('can be called by two independent components', async () => {
const getPermissions = jest.fn(() => Promise.resolve('admin'));
const { queryByText } = render(
);
expect(queryByText('permissions 1:')).not.toBeNull();
expect(queryByText('permissions 2:')).not.toBeNull();
expect(queryByText('permissions 1: admin')).toBeNull();
expect(queryByText('permissions 2: admin')).toBeNull();
expect(getPermissions).toBeCalledTimes(2);
await act(async () => await new Promise(r => setTimeout(r)));
expect(queryByText('permissions 1:')).toBeNull();
expect(queryByText('permissions 2:')).toBeNull();
expect(queryByText('permissions 1: admin')).not.toBeNull();
expect(queryByText('permissions 2: admin')).not.toBeNull();
expect(getPermissions).toBeCalledTimes(2);
});
});