import * as React from 'react'; import expect from 'expect'; import { screen, render, waitFor, fireEvent } from '@testing-library/react'; import { testDataProvider } from '../../dataProvider'; import { AccessControl, DefaultTitle, NoAuthProvider, WithAuthProviderNoAccessControl, WithRenderProp, } from './CreateBase.stories'; describe('CreateBase', () => { it('should give access to the save function', async () => { const dataProvider = testDataProvider({ // @ts-ignore create: jest.fn((_, { data }) => Promise.resolve({ data: { id: 1, ...data } }) ), }); render(); fireEvent.click(screen.getByText('save')); await waitFor(() => { expect(dataProvider.create).toHaveBeenCalledWith('posts', { data: { test: 'test' }, }); }); }); it('should allow to override the onSuccess function', async () => { const dataProvider = testDataProvider({ // @ts-ignore create: jest.fn((_, { data }) => Promise.resolve({ data: { id: 1, ...data } }) ), }); const onSuccess = jest.fn(); render( ); fireEvent.click(screen.getByText('save')); await waitFor(() => { expect(onSuccess).toHaveBeenCalledWith( { id: 1, test: 'test', }, { data: { test: 'test' }, resource: 'posts' }, { snapshot: [] }, expect.anything() ); }); }); it('should allow to override the onSuccess function at call time', async () => { const dataProvider = testDataProvider({ // @ts-ignore create: jest.fn((_, { data }) => Promise.resolve({ data: { id: 1, ...data } }) ), }); const onSuccess = jest.fn(); const onSuccessOverride = jest.fn(); const { getByText } = render( ); getByText('save').click(); await waitFor(() => { expect(onSuccessOverride).toHaveBeenCalledWith( { id: 1, test: 'test', }, { data: { test: 'test' }, resource: 'posts' }, { snapshot: [] }, expect.anything() ); }); expect(onSuccess).not.toHaveBeenCalled(); }); it('should allow to override the onError function', async () => { jest.spyOn(console, 'error').mockImplementation(() => {}); const dataProvider = testDataProvider({ // @ts-ignore create: jest.fn(() => Promise.reject({ message: 'test' })), }); const onError = jest.fn(); render( ); fireEvent.click(screen.getByText('save')); await waitFor(() => { expect(onError).toHaveBeenCalledWith( { message: 'test' }, { data: { test: 'test' }, resource: 'posts' }, { snapshot: [] }, expect.anything() ); }); }); it('should allow to override the onError function at call time', async () => { const dataProvider = testDataProvider({ // @ts-ignore create: jest.fn(() => Promise.reject({ message: 'test' })), }); const onError = jest.fn(); const onErrorOverride = jest.fn(); render( ); screen.getByText('save').click(); await waitFor(() => { expect(onErrorOverride).toHaveBeenCalledWith( { message: 'test' }, { data: { test: 'test' }, resource: 'posts' }, expect.anything(), expect.anything() ); }); expect(onError).not.toHaveBeenCalled(); }); it('should allow to override the transform function', async () => { const dataProvider = testDataProvider({ // @ts-ignore create: jest.fn((_, { data }) => Promise.resolve({ data: { id: 1, ...data } }) ), }); const transform = jest .fn() .mockReturnValueOnce({ test: 'test transformed' }); render( ); fireEvent.click(screen.getByText('save')); await waitFor(() => { expect(transform).toHaveBeenCalledWith({ test: 'test' }); }); await waitFor(() => { expect(dataProvider.create).toHaveBeenCalledWith('posts', { data: { test: 'test transformed' }, }); }); }); it('should allow to override the transform function at call time', async () => { const dataProvider = testDataProvider({ // @ts-ignore create: jest.fn((_, { data }) => Promise.resolve({ data: { id: 1, ...data } }) ), }); const transform = jest.fn(); const transformOverride = jest .fn() .mockReturnValueOnce({ test: 'test transformed' }); render( ); screen.getByText('save').click(); await waitFor(() => { expect(transformOverride).toHaveBeenCalledWith({ test: 'test' }); }); await waitFor(() => { expect(dataProvider.create).toHaveBeenCalledWith('posts', { data: { test: 'test transformed' }, }); }); expect(transform).not.toHaveBeenCalled(); }); it('should show the view immediately if authProvider is not provided', () => { const dataProvider = testDataProvider(); render(); screen.getByText('save'); }); it('should wait for the authentication resolution before showing the view', async () => { let resolveAuth: () => void; const authProvider = { login: () => Promise.resolve(), logout: () => Promise.resolve(), checkError: () => Promise.resolve(), checkAuth: () => new Promise(resolve => { resolveAuth = resolve; }), }; const dataProvider = testDataProvider(); render( ); await screen.findByText('Authentication loading...'); resolveAuth!(); await screen.findByText('save'); }); it('should wait for both the authentication and authorization resolution before showing the view', async () => { let resolveAuth: () => void; let resolveCanAccess: (value: boolean) => void; const authProvider = { login: () => Promise.resolve(), logout: () => Promise.resolve(), checkError: () => Promise.resolve(), checkAuth: () => new Promise(resolve => { resolveAuth = resolve; }), canAccess: jest.fn( () => new Promise(resolve => { resolveCanAccess = resolve; }) ), }; const dataProvider = testDataProvider(); render( ); await screen.findByText('Authentication loading...'); resolveAuth!(); await screen.findByText('Authentication loading...'); await waitFor(() => { expect(authProvider.canAccess).toHaveBeenCalled(); }); resolveCanAccess!(true); await screen.findByText('save'); }); it('should provide a default title', async () => { render(); await screen.findByText('Create Post (en)'); fireEvent.click(screen.getByText('FR')); await screen.findByText('Créer Article (fr)'); }); it('should allow resource specific default title', async () => { render(); await screen.findByText('Create an article (en)'); fireEvent.click(screen.getByText('FR')); await screen.findByText('Créer un article (fr)'); }); it('should allow render props', async () => { const dataProvider = testDataProvider({ // @ts-ignore create: jest.fn((_, { data }) => Promise.resolve({ data: { id: 1, ...data } }) ), }); render(); fireEvent.click(screen.getByText('save')); await waitFor(() => { expect(dataProvider.create).toHaveBeenCalledWith('posts', { data: { test: 'test' }, }); }); }); });