clean up act() errors in form tests after Lookup changes

This commit is contained in:
Keith Grant 2019-12-04 10:36:25 -08:00
parent 75b7d74f91
commit 6e64b5c070
7 changed files with 261 additions and 186 deletions

View File

@ -25,7 +25,7 @@ class AnsibleSelect extends React.Component {
}
render() {
const { id, data, i18n, isValid, onBlur, value } = this.props;
const { id, data, i18n, isValid, onBlur, value, className } = this.props;
return (
<FormSelect
@ -35,6 +35,7 @@ class AnsibleSelect extends React.Component {
onBlur={onBlur}
aria-label={i18n._(t`Select Input`)}
isValid={isValid}
className={className}
>
{data.map(option => (
<FormSelectOption
@ -60,6 +61,7 @@ AnsibleSelect.defaultProps = {
data: [],
isValid: true,
onBlur: () => {},
className: '',
};
AnsibleSelect.propTypes = {
@ -69,6 +71,7 @@ AnsibleSelect.propTypes = {
onBlur: func,
onChange: func.isRequired,
value: oneOfType([string, number]).isRequired,
className: string,
};
export { AnsibleSelect as _AnsibleSelect };

View File

@ -1,4 +1,5 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { createMemoryHistory } from 'history';
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
import HostAdd from './HostAdd';
@ -7,8 +8,11 @@ import { HostsAPI } from '@api';
jest.mock('@api');
describe('<HostAdd />', () => {
test('handleSubmit should post to api', () => {
const wrapper = mountWithContexts(<HostAdd />);
test('handleSubmit should post to api', async () => {
let wrapper;
await act(async () => {
wrapper = mountWithContexts(<HostAdd />);
});
const updatedHostData = {
name: 'new name',
description: 'new description',
@ -19,21 +23,27 @@ describe('<HostAdd />', () => {
expect(HostsAPI.create).toHaveBeenCalledWith(updatedHostData);
});
test('should navigate to hosts list when cancel is clicked', () => {
test('should navigate to hosts list when cancel is clicked', async () => {
const history = createMemoryHistory({});
const wrapper = mountWithContexts(<HostAdd />, {
context: { router: { history } },
let wrapper;
await act(async () => {
wrapper = mountWithContexts(<HostAdd />, {
context: { router: { history } },
});
});
wrapper.find('button[aria-label="Cancel"]').prop('onClick')();
wrapper.find('button[aria-label="Cancel"]').invoke('onClick')();
expect(history.location.pathname).toEqual('/hosts');
});
test('should navigate to hosts list when close (x) is clicked', () => {
test('should navigate to hosts list when close (x) is clicked', async () => {
const history = createMemoryHistory({});
const wrapper = mountWithContexts(<HostAdd />, {
context: { router: { history } },
let wrapper;
await act(async () => {
wrapper = mountWithContexts(<HostAdd />, {
context: { router: { history } },
});
});
wrapper.find('button[aria-label="Close"]').prop('onClick')();
wrapper.find('button[aria-label="Close"]').invoke('onClick')();
expect(history.location.pathname).toEqual('/hosts');
});
@ -51,11 +61,14 @@ describe('<HostAdd />', () => {
...hostData,
},
});
const wrapper = mountWithContexts(<HostAdd />, {
context: { router: { history } },
let wrapper;
await act(async () => {
wrapper = mountWithContexts(<HostAdd />, {
context: { router: { history } },
});
});
await waitForElement(wrapper, 'button[aria-label="Save"]');
await wrapper.find('HostForm').prop('handleSubmit')(hostData);
await wrapper.find('HostForm').invoke('handleSubmit')(hostData);
expect(history.location.pathname).toEqual('/hosts/5');
});
});

View File

@ -9,6 +9,10 @@ jest.mock('@api');
describe('<OrganizationAdd />', () => {
test('handleSubmit should post to api', async () => {
let wrapper;
await act(async () => {
wrapper = mountWithContexts(<OrganizationAdd />);
});
const updatedOrgData = {
name: 'new name',
description: 'new description',
@ -27,22 +31,24 @@ describe('<OrganizationAdd />', () => {
test('should navigate to organizations list when cancel is clicked', async () => {
const history = createMemoryHistory({});
let wrapper;
await act(async () => {
const wrapper = mountWithContexts(<OrganizationAdd />, {
wrapper = mountWithContexts(<OrganizationAdd />, {
context: { router: { history } },
});
wrapper.find('button[aria-label="Cancel"]').prop('onClick')();
wrapper.find('button[aria-label="Cancel"]').invoke('onClick')();
});
expect(history.location.pathname).toEqual('/organizations');
});
test('should navigate to organizations list when close (x) is clicked', async () => {
const history = createMemoryHistory({});
let wrapper;
await act(async () => {
const wrapper = mountWithContexts(<OrganizationAdd />, {
wrapper = mountWithContexts(<OrganizationAdd />, {
context: { router: { history } },
});
wrapper.find('button[aria-label="Close"]').prop('onClick')();
wrapper.find('button[aria-label="Close"]').invoke('onClick')();
});
expect(history.location.pathname).toEqual('/organizations');
});
@ -63,8 +69,9 @@ describe('<OrganizationAdd />', () => {
...orgData,
},
});
let wrapper;
await act(async () => {
const wrapper = mountWithContexts(<OrganizationAdd />, {
wrapper = mountWithContexts(<OrganizationAdd />, {
context: { router: { history } },
});
await waitForElement(wrapper, 'button[aria-label="Save"]');
@ -92,23 +99,27 @@ describe('<OrganizationAdd />', () => {
...orgData,
},
});
let wrapper;
await act(async () => {
const wrapper = mountWithContexts(<OrganizationAdd />);
await waitForElement(wrapper, 'button[aria-label="Save"]');
await wrapper.find('OrganizationForm').prop('handleSubmit')(
orgData,
[3],
[]
);
wrapper = mountWithContexts(<OrganizationAdd />);
});
await waitForElement(wrapper, 'button[aria-label="Save"]');
await wrapper.find('OrganizationForm').prop('handleSubmit')(
orgData,
[3],
[]
);
expect(OrganizationsAPI.associateInstanceGroup).toHaveBeenCalledWith(5, 3);
});
test('AnsibleSelect component renders if there are virtual environments', async () => {
const config = {
custom_virtualenvs: ['foo', 'bar'],
};
let wrapper;
await act(async () => {
wrapper = mountWithContexts(<OrganizationAdd />, {
context: { config: { custom_virtualenvs: ['foo', 'bar'] } },
context: { config },
}).find('AnsibleSelect');
});
expect(wrapper.find('FormSelect')).toHaveLength(1);
@ -122,10 +133,13 @@ describe('<OrganizationAdd />', () => {
});
test('AnsibleSelect component does not render if there are 0 virtual environments', async () => {
const config = {
custom_virtualenvs: [],
};
let wrapper;
await act(async () => {
wrapper = mountWithContexts(<OrganizationAdd />, {
context: { config: { custom_virtualenvs: [] } },
context: { config },
}).find('AnsibleSelect');
});
expect(wrapper.find('FormSelect')).toHaveLength(0);

View File

@ -1,4 +1,5 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { createMemoryHistory } from 'history';
import { OrganizationsAPI } from '@api';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
@ -19,10 +20,11 @@ describe('<OrganizationEdit />', () => {
},
};
test('handleSubmit should call api update', () => {
const wrapper = mountWithContexts(
<OrganizationEdit organization={mockData} />
);
test('handleSubmit should call api update', async () => {
let wrapper;
await act(async () => {
wrapper = mountWithContexts(<OrganizationEdit organization={mockData} />);
});
const updatedOrgData = {
name: 'new name',
@ -39,21 +41,23 @@ describe('<OrganizationEdit />', () => {
});
test('handleSubmit associates and disassociates instance groups', async () => {
const wrapper = mountWithContexts(
<OrganizationEdit organization={mockData} />
);
let wrapper;
await act(async () => {
wrapper = mountWithContexts(<OrganizationEdit organization={mockData} />);
});
const updatedOrgData = {
name: 'new name',
description: 'new description',
custom_virtualenv: 'Buzz',
};
wrapper.find('OrganizationForm').prop('handleSubmit')(
updatedOrgData,
[3, 4],
[2]
);
await sleep(1);
await act(async () => {
wrapper.find('OrganizationForm').invoke('handleSubmit')(
updatedOrgData,
[3, 4],
[2]
);
});
expect(OrganizationsAPI.associateInstanceGroup).toHaveBeenCalledWith(1, 3);
expect(OrganizationsAPI.associateInstanceGroup).toHaveBeenCalledWith(1, 4);
@ -63,14 +67,17 @@ describe('<OrganizationEdit />', () => {
);
});
test('should navigate to organization detail when cancel is clicked', () => {
test('should navigate to organization detail when cancel is clicked', async () => {
const history = createMemoryHistory({});
const wrapper = mountWithContexts(
<OrganizationEdit organization={mockData} />,
{ context: { router: { history } } }
);
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<OrganizationEdit organization={mockData} />,
{ context: { router: { history } } }
);
});
wrapper.find('button[aria-label="Cancel"]').prop('onClick')();
wrapper.find('button[aria-label="Cancel"]').invoke('onClick')();
expect(history.location.pathname).toEqual('/organizations/1/details');
});

View File

@ -1,5 +1,5 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { sleep } from '@testUtils/testUtils';
import { OrganizationsAPI } from '@api';
@ -30,18 +30,20 @@ describe('<OrganizationForm />', () => {
jest.clearAllMocks();
});
test('should request related instance groups from api', () => {
mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>,
{
context: { network },
}
);
test('should request related instance groups from api', async () => {
await act(async () => {
mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>,
{
context: { network },
}
);
});
expect(OrganizationsAPI.readInstanceGroups).toHaveBeenCalledTimes(1);
});
@ -53,34 +55,39 @@ describe('<OrganizationForm />', () => {
results: mockInstanceGroups,
},
});
const wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>,
{
context: { network },
}
);
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>,
{
context: { network },
}
);
});
await sleep(0);
expect(OrganizationsAPI.readInstanceGroups).toHaveBeenCalled();
expect(wrapper.find('OrganizationForm').state().instanceGroups).toEqual(
mockInstanceGroups
);
});
test('changing instance group successfully sets instanceGroups state', () => {
const wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
test('changing instance group successfully sets instanceGroups state', async () => {
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
});
const lookup = wrapper.find('InstanceGroupsLookup');
expect(lookup.length).toBe(1);
@ -102,15 +109,18 @@ describe('<OrganizationForm />', () => {
]);
});
test('changing inputs should update form values', () => {
const wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
test('changing inputs should update form values', async () => {
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
});
const form = wrapper.find('Formik');
wrapper.find('input#org-name').simulate('change', {
@ -127,21 +137,24 @@ describe('<OrganizationForm />', () => {
expect(form.state('values').max_hosts).toEqual('134');
});
test('AnsibleSelect component renders if there are virtual environments', () => {
test('AnsibleSelect component renders if there are virtual environments', async () => {
const config = {
custom_virtualenvs: ['foo', 'bar'],
};
const wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>,
{
context: { config },
}
);
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>,
{
context: { config },
}
);
});
expect(wrapper.find('FormSelect')).toHaveLength(1);
expect(wrapper.find('FormSelectOption')).toHaveLength(3);
expect(
@ -154,14 +167,17 @@ describe('<OrganizationForm />', () => {
test('calls handleSubmit when form submitted', async () => {
const handleSubmit = jest.fn();
const wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
});
expect(handleSubmit).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Save"]').simulate('click');
await sleep(1);
@ -194,18 +210,20 @@ describe('<OrganizationForm />', () => {
OrganizationsAPI.update.mockResolvedValue(1, mockDataForm);
OrganizationsAPI.associateInstanceGroup.mockResolvedValue('done');
OrganizationsAPI.disassociateInstanceGroup.mockResolvedValue('done');
const wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>,
{
context: { network },
}
);
await sleep(0);
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>,
{
context: { network },
}
);
});
wrapper.find('InstanceGroupsLookup').prop('onChange')(
[{ name: 'One', id: 1 }, { name: 'Three', id: 3 }],
'instanceGroups'
@ -219,15 +237,17 @@ describe('<OrganizationForm />', () => {
test('handleSubmit is called with max_hosts value if it is in range', async () => {
const handleSubmit = jest.fn();
// normal mount
const wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
});
wrapper.find('button[aria-label="Save"]').simulate('click');
await sleep(0);
expect(handleSubmit).toHaveBeenCalledWith(
@ -245,32 +265,38 @@ describe('<OrganizationForm />', () => {
test('handleSubmit does not get called if max_hosts value is out of range', async () => {
const handleSubmit = jest.fn();
// not mount with Negative value
// mount with negative value
let wrapper1;
const mockDataNegative = JSON.parse(JSON.stringify(mockData));
mockDataNegative.max_hosts = -5;
const wrapper1 = mountWithContexts(
<OrganizationForm
organization={mockDataNegative}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
await act(async () => {
wrapper1 = mountWithContexts(
<OrganizationForm
organization={mockDataNegative}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
});
wrapper1.find('button[aria-label="Save"]').simulate('click');
await sleep(0);
expect(handleSubmit).not.toHaveBeenCalled();
// not mount with Out of Range value
// mount with out of range value
let wrapper2;
const mockDataOoR = JSON.parse(JSON.stringify(mockData));
mockDataOoR.max_hosts = 999999999999;
const wrapper2 = mountWithContexts(
<OrganizationForm
organization={mockDataOoR}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
await act(async () => {
wrapper2 = mountWithContexts(
<OrganizationForm
organization={mockDataOoR}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
});
wrapper2.find('button[aria-label="Save"]').simulate('click');
await sleep(0);
expect(handleSubmit).not.toHaveBeenCalled();
@ -282,14 +308,17 @@ describe('<OrganizationForm />', () => {
// mount with String value (default to zero)
const mockDataString = JSON.parse(JSON.stringify(mockData));
mockDataString.max_hosts = 'Bee';
const wrapper = mountWithContexts(
<OrganizationForm
organization={mockDataString}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<OrganizationForm
organization={mockDataString}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
});
wrapper.find('button[aria-label="Save"]').simulate('click');
await sleep(0);
expect(handleSubmit).toHaveBeenCalledWith(
@ -304,17 +333,20 @@ describe('<OrganizationForm />', () => {
);
});
test('calls "handleCancel" when Cancel button is clicked', () => {
test('calls "handleCancel" when Cancel button is clicked', async () => {
const handleCancel = jest.fn();
const wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={handleCancel}
me={meConfig.me}
/>
);
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<OrganizationForm
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={handleCancel}
me={meConfig.me}
/>
);
});
expect(handleCancel).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Cancel"]').prop('onClick')();
expect(handleCancel).toBeCalled();

View File

@ -144,8 +144,8 @@ describe('<ProjectEdit />', () => {
wrapper = mountWithContexts(<ProjectEdit project={projectData} />, {
context: { router: { history } },
});
wrapper.find('CardCloseButton').simulate('click');
});
wrapper.find('CardCloseButton').simulate('click');
expect(history.location.pathname).toEqual('/projects/123/details');
});
@ -157,7 +157,9 @@ describe('<ProjectEdit />', () => {
});
});
await waitForElement(wrapper, 'EmptyStateBody', el => el.length === 0);
wrapper.find('ProjectEdit button[aria-label="Cancel"]').simulate('click');
await act(async () => {
wrapper.find('ProjectEdit button[aria-label="Cancel"]').simulate('click');
});
expect(history.location.pathname).toEqual('/projects/123/details');
});
});

View File

@ -30,15 +30,17 @@ describe('<TeamForm />', () => {
jest.clearAllMocks();
});
test('changing inputs should update form values', () => {
wrapper = mountWithContexts(
<TeamForm
team={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
test('changing inputs should update form values', async () => {
await act(async () => {
wrapper = mountWithContexts(
<TeamForm
team={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
me={meConfig.me}
/>
);
});
const form = wrapper.find('Formik');
wrapper.find('input#team-name').simulate('change', {
@ -78,17 +80,19 @@ describe('<TeamForm />', () => {
expect(handleSubmit).toBeCalled();
});
test('calls handleCancel when Cancel button is clicked', () => {
test('calls handleCancel when Cancel button is clicked', async () => {
const handleCancel = jest.fn();
wrapper = mountWithContexts(
<TeamForm
team={mockData}
handleSubmit={jest.fn()}
handleCancel={handleCancel}
me={meConfig.me}
/>
);
await act(async () => {
wrapper = mountWithContexts(
<TeamForm
team={mockData}
handleSubmit={jest.fn()}
handleCancel={handleCancel}
me={meConfig.me}
/>
);
});
expect(handleCancel).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Cancel"]').prop('onClick')();
expect(handleCancel).toBeCalled();