From 569b5bc53364cd9b427fbeb17c0907c77633fb84 Mon Sep 17 00:00:00 2001 From: Keith Grant Date: Tue, 3 Dec 2019 16:28:52 -0800 Subject: [PATCH] clean up multiple test 'act()' warnings --- .../CheckboxListItem.test.jsx | 1 + .../components/Lookup/shared/OptionsList.jsx | 2 +- .../Project/ProjectAdd/ProjectAdd.test.jsx | 28 ++++++++----- .../Project/shared/ProjectForm.test.jsx | 42 ++++++++++--------- .../src/screens/Team/TeamAdd/TeamAdd.test.jsx | 30 +++++++++---- .../screens/Team/TeamEdit/TeamEdit.test.jsx | 13 ++++-- .../JobTemplateAdd/JobTemplateAdd.test.jsx | 24 ++++++----- .../Template/shared/JobTemplateForm.jsx | 11 +++-- .../screens/User/UserList/UserList.test.jsx | 4 +- 9 files changed, 95 insertions(+), 60 deletions(-) diff --git a/awx/ui_next/src/components/CheckboxListItem/CheckboxListItem.test.jsx b/awx/ui_next/src/components/CheckboxListItem/CheckboxListItem.test.jsx index a28003b71a..3e61d9c980 100644 --- a/awx/ui_next/src/components/CheckboxListItem/CheckboxListItem.test.jsx +++ b/awx/ui_next/src/components/CheckboxListItem/CheckboxListItem.test.jsx @@ -12,6 +12,7 @@ describe('CheckboxListItem', () => { label="Buzz" isSelected={false} onSelect={() => {}} + onDeselect={() => {}} /> ); expect(wrapper).toHaveLength(1); diff --git a/awx/ui_next/src/components/Lookup/shared/OptionsList.jsx b/awx/ui_next/src/components/Lookup/shared/OptionsList.jsx index e988eb5656..77b4611c61 100644 --- a/awx/ui_next/src/components/Lookup/shared/OptionsList.jsx +++ b/awx/ui_next/src/components/Lookup/shared/OptionsList.jsx @@ -72,8 +72,8 @@ function OptionsList({ const Item = shape({ id: oneOfType([number, string]).isRequired, - url: string.isRequired, name: string.isRequired, + url: string, }); OptionsList.propTypes = { value: arrayOf(Item).isRequired, diff --git a/awx/ui_next/src/screens/Project/ProjectAdd/ProjectAdd.test.jsx b/awx/ui_next/src/screens/Project/ProjectAdd/ProjectAdd.test.jsx index 554ebf83ef..c4d5bc16f1 100644 --- a/awx/ui_next/src/screens/Project/ProjectAdd/ProjectAdd.test.jsx +++ b/awx/ui_next/src/screens/Project/ProjectAdd/ProjectAdd.test.jsx @@ -98,17 +98,19 @@ describe('', () => { }); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); const formik = wrapper.find('Formik').instance(); - const changeState = new Promise(resolve => { - formik.setState( - { - values: { - ...projectData, + await act(async () => { + const changeState = new Promise(resolve => { + formik.setState( + { + values: { + ...projectData, + }, }, - }, - () => resolve() - ); + () => resolve() + ); + }); + await changeState; }); - await changeState; await act(async () => { wrapper.find('form').simulate('submit'); }); @@ -146,7 +148,9 @@ describe('', () => { context: { router: { history } }, }).find('ProjectAdd CardHeader'); }); - wrapper.find('CardCloseButton').simulate('click'); + await act(async () => { + wrapper.find('CardCloseButton').simulate('click'); + }); expect(history.location.pathname).toEqual('/projects'); }); @@ -158,7 +162,9 @@ describe('', () => { }); }); await waitForElement(wrapper, 'EmptyStateBody', el => el.length === 0); - wrapper.find('ProjectAdd button[aria-label="Cancel"]').simulate('click'); + await act(async () => { + wrapper.find('ProjectAdd button[aria-label="Cancel"]').simulate('click'); + }); expect(history.location.pathname).toEqual('/projects'); }); }); diff --git a/awx/ui_next/src/screens/Project/shared/ProjectForm.test.jsx b/awx/ui_next/src/screens/Project/shared/ProjectForm.test.jsx index 584287444e..d4b901c47c 100644 --- a/awx/ui_next/src/screens/Project/shared/ProjectForm.test.jsx +++ b/awx/ui_next/src/screens/Project/shared/ProjectForm.test.jsx @@ -131,17 +131,19 @@ describe('', () => { }); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); const formik = wrapper.find('Formik').instance(); - const changeState = new Promise(resolve => { - formik.setState( - { - values: { - ...mockData, + await act(async () => { + const changeState = new Promise(resolve => { + formik.setState( + { + values: { + ...mockData, + }, }, - }, - () => resolve() - ); + () => resolve() + ); + }); + await changeState; }); - await changeState; wrapper.update(); expect(wrapper.find('FormGroup[label="SCM URL"]').length).toBe(1); expect( @@ -191,18 +193,20 @@ describe('', () => { }); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); const formik = wrapper.find('Formik').instance(); - const changeState = new Promise(resolve => { - formik.setState( - { - values: { - ...mockData, - scm_type: 'insights', + await act(async () => { + const changeState = new Promise(resolve => { + formik.setState( + { + values: { + ...mockData, + scm_type: 'insights', + }, }, - }, - () => resolve() - ); + () => resolve() + ); + }); + await changeState; }); - await changeState; wrapper.update(); expect(wrapper.find('FormGroup[label="Insights Credential"]').length).toBe( 1 diff --git a/awx/ui_next/src/screens/Team/TeamAdd/TeamAdd.test.jsx b/awx/ui_next/src/screens/Team/TeamAdd/TeamAdd.test.jsx index 20eb762710..02225fa733 100644 --- a/awx/ui_next/src/screens/Team/TeamAdd/TeamAdd.test.jsx +++ b/awx/ui_next/src/screens/Team/TeamAdd/TeamAdd.test.jsx @@ -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 TeamAdd from './TeamAdd'; @@ -7,32 +8,38 @@ import { TeamsAPI } from '@api'; jest.mock('@api'); describe('', () => { - test('handleSubmit should post to api', () => { + test('handleSubmit should post to api', async () => { const wrapper = mountWithContexts(); const updatedTeamData = { name: 'new name', description: 'new description', organization: 1, }; - wrapper.find('TeamForm').prop('handleSubmit')(updatedTeamData); + await act(async () => { + wrapper.find('TeamForm').invoke('handleSubmit')(updatedTeamData); + }); expect(TeamsAPI.create).toHaveBeenCalledWith(updatedTeamData); }); - test('should navigate to teams list when cancel is clicked', () => { + test('should navigate to teams list when cancel is clicked', async () => { const history = createMemoryHistory({}); const wrapper = mountWithContexts(, { context: { router: { history } }, }); - wrapper.find('button[aria-label="Cancel"]').prop('onClick')(); + await act(async () => { + wrapper.find('button[aria-label="Cancel"]').invoke('onClick')(); + }); expect(history.location.pathname).toEqual('/teams'); }); - test('should navigate to teams list when close (x) is clicked', () => { + test('should navigate to teams list when close (x) is clicked', async () => { const history = createMemoryHistory({}); const wrapper = mountWithContexts(, { context: { router: { history } }, }); - wrapper.find('button[aria-label="Close"]').prop('onClick')(); + await act(async () => { + wrapper.find('button[aria-label="Close"]').invoke('onClick')(); + }); expect(history.location.pathname).toEqual('/teams'); }); @@ -55,11 +62,16 @@ describe('', () => { }, }, }); - const wrapper = mountWithContexts(, { - context: { router: { history } }, + let wrapper; + await act(async () => { + wrapper = mountWithContexts(, { + context: { router: { history } }, + }); }); await waitForElement(wrapper, 'button[aria-label="Save"]'); - await wrapper.find('TeamForm').prop('handleSubmit')(teamData); + await act(async () => { + await wrapper.find('TeamForm').invoke('handleSubmit')(teamData); + }); expect(history.location.pathname).toEqual('/teams/5'); }); }); diff --git a/awx/ui_next/src/screens/Team/TeamEdit/TeamEdit.test.jsx b/awx/ui_next/src/screens/Team/TeamEdit/TeamEdit.test.jsx index 7ea335361a..cb410405b1 100644 --- a/awx/ui_next/src/screens/Team/TeamEdit/TeamEdit.test.jsx +++ b/awx/ui_next/src/screens/Team/TeamEdit/TeamEdit.test.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import { act } from 'react-dom/test-utils'; import { createMemoryHistory } from 'history'; import { TeamsAPI } from '@api'; import { mountWithContexts } from '@testUtils/enzymeHelpers'; @@ -19,25 +20,29 @@ describe('', () => { }, }; - test('handleSubmit should call api update', () => { + test('handleSubmit should call api update', async () => { const wrapper = mountWithContexts(); const updatedTeamData = { name: 'new name', description: 'new description', }; - wrapper.find('TeamForm').prop('handleSubmit')(updatedTeamData); + await act(async () => { + wrapper.find('TeamForm').invoke('handleSubmit')(updatedTeamData); + }); expect(TeamsAPI.update).toHaveBeenCalledWith(1, updatedTeamData); }); - test('should navigate to team detail when cancel is clicked', () => { + test('should navigate to team detail when cancel is clicked', async () => { const history = createMemoryHistory({}); const wrapper = mountWithContexts(, { context: { router: { history } }, }); - wrapper.find('button[aria-label="Cancel"]').prop('onClick')(); + await act(async () => { + wrapper.find('button[aria-label="Cancel"]').invoke('onClick')(); + }); expect(history.location.pathname).toEqual('/teams/1/details'); }); diff --git a/awx/ui_next/src/screens/Template/JobTemplateAdd/JobTemplateAdd.test.jsx b/awx/ui_next/src/screens/Template/JobTemplateAdd/JobTemplateAdd.test.jsx index 0539c657fe..bedb63e678 100644 --- a/awx/ui_next/src/screens/Template/JobTemplateAdd/JobTemplateAdd.test.jsx +++ b/awx/ui_next/src/screens/Template/JobTemplateAdd/JobTemplateAdd.test.jsx @@ -101,19 +101,21 @@ describe('', () => { }); await waitForElement(wrapper, 'EmptyStateBody', el => el.length === 0); const formik = wrapper.find('Formik').instance(); - const changeState = new Promise(resolve => { - formik.setState( - { - values: { - ...jobTemplateData, - labels: [], - instanceGroups: [], + await act(async () => { + const changeState = new Promise(resolve => { + formik.setState( + { + values: { + ...jobTemplateData, + labels: [], + instanceGroups: [], + }, }, - }, - () => resolve() - ); + () => resolve() + ); + }); + await changeState; }); - await changeState; wrapper.find('form').simulate('submit'); await sleep(1); expect(JobTemplatesAPI.create).toHaveBeenCalledWith(jobTemplateData); diff --git a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx index 67e94ced20..2f5ab24c64 100644 --- a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx +++ b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx @@ -79,6 +79,7 @@ class JobTemplateForm extends Component { }; this.handleProjectValidation = this.handleProjectValidation.bind(this); this.loadRelatedInstanceGroups = this.loadRelatedInstanceGroups.bind(this); + this.setContentError = this.setContentError.bind(this); } componentDidMount() { @@ -119,6 +120,10 @@ class JobTemplateForm extends Component { }; } + setContentError(contentError) { + this.setState({ contentError }); + } + render() { const { contentError, @@ -285,7 +290,7 @@ class JobTemplateForm extends Component { form={form} field={field} onBlur={() => form.setFieldTouched('playbook')} - onError={err => this.setState({ contentError: err })} + onError={this.setContentError} /> ); @@ -305,7 +310,7 @@ class JobTemplateForm extends Component { setFieldValue('labels', labels)} - onError={err => this.setState({ contentError: err })} + onError={this.setContentError} /> )} @@ -321,7 +326,7 @@ class JobTemplateForm extends Component { onChange={newCredentials => setFieldValue('credentials', newCredentials) } - onError={err => this.setState({ contentError: err })} + onError={this.setContentError} tooltip={i18n._( t`Select credentials that allow Tower to access the nodes this job will be ran against. You can only select one credential of each type. For machine credentials (SSH), checking "Prompt on launch" without selecting credentials will require you to select a machine credential at run time. If you select credentials and check "Prompt on launch", the selected credential(s) become the defaults that can be updated at run time.` )} diff --git a/awx/ui_next/src/screens/User/UserList/UserList.test.jsx b/awx/ui_next/src/screens/User/UserList/UserList.test.jsx index cc54d9d0f5..a727cdae81 100644 --- a/awx/ui_next/src/screens/User/UserList/UserList.test.jsx +++ b/awx/ui_next/src/screens/User/UserList/UserList.test.jsx @@ -214,7 +214,7 @@ describe('UsersList with full permissions', () => { ); }); - test('api is called to delete users for each selected user.', () => { + test('api is called to delete users for each selected user.', async () => { UsersAPI.destroy = jest.fn(); wrapper.find('UsersList').setState({ users: mockUsers, @@ -223,7 +223,7 @@ describe('UsersList with full permissions', () => { isModalOpen: true, selected: mockUsers, }); - wrapper.find('ToolbarDeleteButton').prop('onDelete')(); + await wrapper.find('ToolbarDeleteButton').prop('onDelete')(); expect(UsersAPI.destroy).toHaveBeenCalledTimes(2); });