Skip to content

Commit

Permalink
Merge pull request #4446 from m4theushw/migrate-tests
Browse files Browse the repository at this point in the history
[RFR] Migrate tests to react-testing-library
  • Loading branch information
fzaninotto authored Mar 3, 2020
2 parents ef3a685 + eb572f8 commit a282acd
Show file tree
Hide file tree
Showing 13 changed files with 407 additions and 412 deletions.
25 changes: 14 additions & 11 deletions packages/ra-core/src/core/RoutesWithLayout.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import React from 'react';
import { Route, MemoryRouter } from 'react-router-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import { mount } from 'enzyme';
import assert from 'assert';
import { render, cleanup } from '@testing-library/react';

import RoutesWithLayout from './RoutesWithLayout';

describe('<RoutesWithLayout>', () => {
afterEach(cleanup);

const Dashboard = () => <div>Dashboard</div>;
const Custom = ({ name }) => <div>Custom</div>;
const FirstResource = ({ name }) => <div>Default</div>;
Expand All @@ -20,7 +21,7 @@ describe('<RoutesWithLayout>', () => {
}));

it('should show dashboard on / when provided', () => {
const wrapper = mount(
const { queryByText } = render(
<Provider store={store}>
<MemoryRouter initialEntries={['/']}>
<RoutesWithLayout dashboard={Dashboard}>
Expand All @@ -31,11 +32,12 @@ describe('<RoutesWithLayout>', () => {
</MemoryRouter>
</Provider>
);
assert.equal(wrapper.find(Dashboard).length, 1);

expect(queryByText('Dashboard')).not.toBeNull();
});

it('should show the first resource on / when there is only one resource and no dashboard', () => {
const wrapper = mount(
const { queryByText } = render(
<Provider store={store}>
<MemoryRouter initialEntries={['/']}>
<RoutesWithLayout>
Expand All @@ -45,11 +47,11 @@ describe('<RoutesWithLayout>', () => {
</Provider>
);

assert.equal(wrapper.find(FirstResource).length, 1);
expect(queryByText('Default')).not.toBeNull();
});

it('should show the first resource on / when there are multiple resource and no dashboard', () => {
const wrapper = mount(
const { queryByText } = render(
<Provider store={store}>
<MemoryRouter initialEntries={['/']}>
<RoutesWithLayout>
Expand All @@ -61,15 +63,15 @@ describe('<RoutesWithLayout>', () => {
</Provider>
);

assert.equal(wrapper.find(FirstResource).length, 1);
assert.equal(wrapper.find(Resource).length, 0);
expect(queryByText('Default')).not.toBeNull();
expect(queryByText('Resource')).toBeNull();
});

it('should accept custom routes', () => {
const customRoutes = [
<Route key="custom" path="/custom" component={Custom} />,
]; // eslint-disable-line react/jsx-key
const wrapper = mount(
const { queryByText } = render(
<Provider store={store}>
<MemoryRouter initialEntries={['/custom']}>
<RoutesWithLayout customRoutes={customRoutes}>
Expand All @@ -80,6 +82,7 @@ describe('<RoutesWithLayout>', () => {
</MemoryRouter>
</Provider>
);
assert.equal(wrapper.find(Custom).length, 1);

expect(queryByText('Custom')).not.toBeNull();
});
});
8 changes: 5 additions & 3 deletions packages/ra-core/src/form/FormDataConsumer.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React from 'react';
import { shallow } from 'enzyme';
import { render, cleanup } from '@testing-library/react';

import { FormDataConsumerView } from './FormDataConsumer';

describe('FormDataConsumerView', () => {
afterEach(cleanup);

it('does not call its children function with scopedFormData and getSource if it did not receive an index prop', () => {
const children = jest.fn();
const formData = { id: 123, title: 'A title' };

shallow(
render(
<FormDataConsumerView
form="a-form"
formData={formData}
Expand All @@ -29,7 +31,7 @@ describe('FormDataConsumerView', () => {
});
const formData = { id: 123, title: 'A title', authors: [{ id: 0 }] };

shallow(
render(
<FormDataConsumerView
form="a-form"
source="authors[0]"
Expand Down
47 changes: 35 additions & 12 deletions packages/ra-core/src/form/FormField.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,44 @@
import assert from 'assert';
import { shallow } from 'enzyme';
import React from 'react';
import { Form } from 'react-final-form';
import { render, fireEvent, cleanup } from '@testing-library/react';
import FormField from './FormField';

describe('<FormField>', () => {
const Foo = () => <div />;
afterEach(cleanup);

const Foo = ({ input }) => <input type="text" {...input} />;

it('should render a <Field/> component for the input component', () => {
const wrapper = shallow(<FormField source="title" component={Foo} />);
const component = wrapper.find('Field');
assert.equal(component.length, 1);
assert.equal(wrapper.prop('component'), Foo);
let formApi;
const { getByRole } = render(
<Form
onSubmit={jest.fn()}
render={({ form }) => {
formApi = form;
return <FormField source="title" component={Foo} />;
}}
/>
);
const input = getByRole('textbox');
fireEvent.change(input, { target: { value: 'Lorem' } });
expect(formApi.getState().values.title).toEqual('Lorem');
});
it('should not render a <Field /> component the field has an input', () => {
const wrapper = shallow(
<FormField source="title" component={Foo} input={{}} />

it('should not render a <Field /> component if the field has an input', () => {
let formApi;
const { getByRole } = render(
<Form
onSubmit={jest.fn()}
render={({ form }) => {
formApi = form;
return (
<FormField source="title" component={Foo} input={{}} />
);
}}
/>
);
const component = wrapper.find('Field');
assert.equal(component.length, 0);
const input = getByRole('textbox');
fireEvent.change(input, { target: { value: 'Lorem' } });
expect(formApi.getState().values.title).not.toEqual('Lorem');
});
});
23 changes: 16 additions & 7 deletions packages/ra-ui-materialui/src/button/CloneButton.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import expect from 'expect';
import { shallow } from 'enzyme';
import { ThemeProvider, createMuiTheme } from '@material-ui/core';
import { render } from '@testing-library/react';
import React from 'react';
import { createMemoryHistory } from 'history';
import { Router } from 'react-router-dom';

import { CloneButton } from './CloneButton';

const theme = createMuiTheme();

describe('<CloneButton />', () => {
it('should pass a clone of the record in the location state', () => {
const wrapper = shallow(
<CloneButton record={{ id: 123, foo: 'bar' }} basePath="" />
const history = createMemoryHistory();
const { getByRole } = render(
<Router history={history}>
<ThemeProvider theme={theme}>
<CloneButton record={{ id: 123, foo: 'bar' }} basePath="" />
</ThemeProvider>
</Router>
);

expect(wrapper.prop('to')).toEqual(
expect.objectContaining({
search: 'source=%7B%22foo%22%3A%22bar%22%7D',
})
const button = getByRole('button');
expect(button.getAttribute('href')).toEqual(
'/create?source=%7B%22foo%22%3A%22bar%22%7D'
);
});
});
10 changes: 5 additions & 5 deletions packages/ra-ui-materialui/src/detail/SimpleShowLayout.spec.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import React from 'react';
import { shallow } from 'enzyme';
import { render } from '@testing-library/react';

import SimpleShowLayout from './SimpleShowLayout';
import TextField from '../field/TextField';

describe('<SimpleShowLayout />', () => {
it('should display children inputs of SimpleShowLayout', () => {
const wrapper = shallow(
<SimpleShowLayout>
const { queryByText } = render(
<SimpleShowLayout record={{ foo: 'foo', bar: 'bar' }}>
<TextField source="foo" />
<TextField source="bar" />
</SimpleShowLayout>
);
const inputs = wrapper.find('EnhancedTextField');
expect(inputs.map(i => i.prop('source'))).toEqual(['foo', 'bar']);
expect(queryByText('foo')).not.toBeNull();
expect(queryByText('bar')).not.toBeNull();
});
});
30 changes: 15 additions & 15 deletions packages/ra-ui-materialui/src/field/FunctionField.spec.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import React from 'react';
import assert from 'assert';
import { render, shallow } from 'enzyme';
import { render, cleanup } from '@testing-library/react';
import FunctionField from './FunctionField';

describe('<FunctionField />', () => {
afterEach(cleanup);

it('should render using the render function', () => {
const record = { foo: 'bar' };
const wrapper = render(
const { queryByText } = render(
<FunctionField record={record} render={r => r.foo.substr(0, 2)} />
);
assert.equal(wrapper.text(), 'ba');
expect(queryByText('ba')).not.toBeNull();
});

it('should use custom className', () =>
assert.deepEqual(
shallow(
<FunctionField
record={{ foo: true }}
render={r => r.foo.substr(0, 2)}
className="foo"
/>
).prop('className'),
'foo'
));
it('should use custom className', () => {
const { queryByText } = render(
<FunctionField
record={{ foo: 'bar' }}
render={r => r.foo}
className="foo"
/>
);
expect(queryByText('bar').classList).toContain('foo');
});
});
Loading

0 comments on commit a282acd

Please sign in to comment.