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' },
});
});
});
});