diff --git a/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx b/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx index c6e427309d..cf860ab8f0 100644 --- a/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx +++ b/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx @@ -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 ( {data.map(option => ( {}, + 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 }; diff --git a/awx/ui_next/src/screens/Host/HostAdd/HostAdd.test.jsx b/awx/ui_next/src/screens/Host/HostAdd/HostAdd.test.jsx index ab1be4ed6f..cd561c5815 100644 --- a/awx/ui_next/src/screens/Host/HostAdd/HostAdd.test.jsx +++ b/awx/ui_next/src/screens/Host/HostAdd/HostAdd.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 HostAdd from './HostAdd'; @@ -7,8 +8,11 @@ import { HostsAPI } from '@api'; jest.mock('@api'); describe('', () => { - test('handleSubmit should post to api', () => { - const wrapper = mountWithContexts(); + test('handleSubmit should post to api', async () => { + let wrapper; + await act(async () => { + wrapper = mountWithContexts(); + }); const updatedHostData = { name: 'new name', description: 'new description', @@ -19,21 +23,27 @@ describe('', () => { 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(, { - context: { router: { history } }, + let wrapper; + await act(async () => { + wrapper = mountWithContexts(, { + 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(, { - context: { router: { history } }, + let wrapper; + await act(async () => { + wrapper = mountWithContexts(, { + 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('', () => { ...hostData, }, }); - 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('HostForm').prop('handleSubmit')(hostData); + await wrapper.find('HostForm').invoke('handleSubmit')(hostData); expect(history.location.pathname).toEqual('/hosts/5'); }); }); diff --git a/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.test.jsx b/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.test.jsx index b5823fa1c4..6d5974b217 100644 --- a/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.test.jsx +++ b/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.test.jsx @@ -9,6 +9,10 @@ jest.mock('@api'); describe('', () => { test('handleSubmit should post to api', async () => { + let wrapper; + await act(async () => { + wrapper = mountWithContexts(); + }); const updatedOrgData = { name: 'new name', description: 'new description', @@ -27,22 +31,24 @@ describe('', () => { test('should navigate to organizations list when cancel is clicked', async () => { const history = createMemoryHistory({}); + let wrapper; await act(async () => { - const wrapper = mountWithContexts(, { + wrapper = mountWithContexts(, { 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(, { + wrapper = mountWithContexts(, { 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('', () => { ...orgData, }, }); + let wrapper; await act(async () => { - const wrapper = mountWithContexts(, { + wrapper = mountWithContexts(, { context: { router: { history } }, }); await waitForElement(wrapper, 'button[aria-label="Save"]'); @@ -92,23 +99,27 @@ describe('', () => { ...orgData, }, }); + let wrapper; await act(async () => { - const wrapper = mountWithContexts(); - await waitForElement(wrapper, 'button[aria-label="Save"]'); - await wrapper.find('OrganizationForm').prop('handleSubmit')( - orgData, - [3], - [] - ); + wrapper = mountWithContexts(); }); + 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(, { - context: { config: { custom_virtualenvs: ['foo', 'bar'] } }, + context: { config }, }).find('AnsibleSelect'); }); expect(wrapper.find('FormSelect')).toHaveLength(1); @@ -122,10 +133,13 @@ describe('', () => { }); test('AnsibleSelect component does not render if there are 0 virtual environments', async () => { + const config = { + custom_virtualenvs: [], + }; let wrapper; await act(async () => { wrapper = mountWithContexts(, { - context: { config: { custom_virtualenvs: [] } }, + context: { config }, }).find('AnsibleSelect'); }); expect(wrapper.find('FormSelect')).toHaveLength(0); diff --git a/awx/ui_next/src/screens/Organization/OrganizationEdit/OrganizationEdit.test.jsx b/awx/ui_next/src/screens/Organization/OrganizationEdit/OrganizationEdit.test.jsx index 0a9a4f9e82..42093807ae 100644 --- a/awx/ui_next/src/screens/Organization/OrganizationEdit/OrganizationEdit.test.jsx +++ b/awx/ui_next/src/screens/Organization/OrganizationEdit/OrganizationEdit.test.jsx @@ -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('', () => { }, }; - test('handleSubmit should call api update', () => { - const wrapper = mountWithContexts( - - ); + test('handleSubmit should call api update', async () => { + let wrapper; + await act(async () => { + wrapper = mountWithContexts(); + }); const updatedOrgData = { name: 'new name', @@ -39,21 +41,23 @@ describe('', () => { }); test('handleSubmit associates and disassociates instance groups', async () => { - const wrapper = mountWithContexts( - - ); + let wrapper; + await act(async () => { + wrapper = mountWithContexts(); + }); 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('', () => { ); }); - 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( - , - { context: { router: { history } } } - ); + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + , + { 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'); }); diff --git a/awx/ui_next/src/screens/Organization/shared/OrganizationForm.test.jsx b/awx/ui_next/src/screens/Organization/shared/OrganizationForm.test.jsx index 52e234cf9c..9fda0b279d 100644 --- a/awx/ui_next/src/screens/Organization/shared/OrganizationForm.test.jsx +++ b/awx/ui_next/src/screens/Organization/shared/OrganizationForm.test.jsx @@ -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('', () => { jest.clearAllMocks(); }); - test('should request related instance groups from api', () => { - mountWithContexts( - , - { - context: { network }, - } - ); + test('should request related instance groups from api', async () => { + await act(async () => { + mountWithContexts( + , + { + context: { network }, + } + ); + }); expect(OrganizationsAPI.readInstanceGroups).toHaveBeenCalledTimes(1); }); @@ -53,34 +55,39 @@ describe('', () => { results: mockInstanceGroups, }, }); - const wrapper = mountWithContexts( - , - { - context: { network }, - } - ); + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + , + { + 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( - - ); + test('changing instance group successfully sets instanceGroups state', async () => { + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + ); + }); const lookup = wrapper.find('InstanceGroupsLookup'); expect(lookup.length).toBe(1); @@ -102,15 +109,18 @@ describe('', () => { ]); }); - test('changing inputs should update form values', () => { - const wrapper = mountWithContexts( - - ); + test('changing inputs should update form values', async () => { + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + ); + }); const form = wrapper.find('Formik'); wrapper.find('input#org-name').simulate('change', { @@ -127,21 +137,24 @@ describe('', () => { 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( - , - { - context: { config }, - } - ); + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + , + { + context: { config }, + } + ); + }); expect(wrapper.find('FormSelect')).toHaveLength(1); expect(wrapper.find('FormSelectOption')).toHaveLength(3); expect( @@ -154,14 +167,17 @@ describe('', () => { test('calls handleSubmit when form submitted', async () => { const handleSubmit = jest.fn(); - const wrapper = mountWithContexts( - - ); + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + ); + }); expect(handleSubmit).not.toHaveBeenCalled(); wrapper.find('button[aria-label="Save"]').simulate('click'); await sleep(1); @@ -194,18 +210,20 @@ describe('', () => { OrganizationsAPI.update.mockResolvedValue(1, mockDataForm); OrganizationsAPI.associateInstanceGroup.mockResolvedValue('done'); OrganizationsAPI.disassociateInstanceGroup.mockResolvedValue('done'); - const wrapper = mountWithContexts( - , - { - context: { network }, - } - ); - await sleep(0); + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + , + { + context: { network }, + } + ); + }); wrapper.find('InstanceGroupsLookup').prop('onChange')( [{ name: 'One', id: 1 }, { name: 'Three', id: 3 }], 'instanceGroups' @@ -219,15 +237,17 @@ describe('', () => { test('handleSubmit is called with max_hosts value if it is in range', async () => { const handleSubmit = jest.fn(); - // normal mount - const wrapper = mountWithContexts( - - ); + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + ); + }); wrapper.find('button[aria-label="Save"]').simulate('click'); await sleep(0); expect(handleSubmit).toHaveBeenCalledWith( @@ -245,32 +265,38 @@ describe('', () => { 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( - - ); + await act(async () => { + wrapper1 = mountWithContexts( + + ); + }); 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( - - ); + await act(async () => { + wrapper2 = mountWithContexts( + + ); + }); wrapper2.find('button[aria-label="Save"]').simulate('click'); await sleep(0); expect(handleSubmit).not.toHaveBeenCalled(); @@ -282,14 +308,17 @@ describe('', () => { // mount with String value (default to zero) const mockDataString = JSON.parse(JSON.stringify(mockData)); mockDataString.max_hosts = 'Bee'; - const wrapper = mountWithContexts( - - ); + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + ); + }); wrapper.find('button[aria-label="Save"]').simulate('click'); await sleep(0); expect(handleSubmit).toHaveBeenCalledWith( @@ -304,17 +333,20 @@ describe('', () => { ); }); - test('calls "handleCancel" when Cancel button is clicked', () => { + test('calls "handleCancel" when Cancel button is clicked', async () => { const handleCancel = jest.fn(); - const wrapper = mountWithContexts( - - ); + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + ); + }); expect(handleCancel).not.toHaveBeenCalled(); wrapper.find('button[aria-label="Cancel"]').prop('onClick')(); expect(handleCancel).toBeCalled(); diff --git a/awx/ui_next/src/screens/Project/ProjectEdit/ProjectEdit.test.jsx b/awx/ui_next/src/screens/Project/ProjectEdit/ProjectEdit.test.jsx index 8f8b400cf1..8927dff7c2 100644 --- a/awx/ui_next/src/screens/Project/ProjectEdit/ProjectEdit.test.jsx +++ b/awx/ui_next/src/screens/Project/ProjectEdit/ProjectEdit.test.jsx @@ -144,8 +144,8 @@ describe('', () => { wrapper = mountWithContexts(, { 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('', () => { }); }); 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'); }); }); diff --git a/awx/ui_next/src/screens/Team/shared/TeamForm.test.jsx b/awx/ui_next/src/screens/Team/shared/TeamForm.test.jsx index 0d8a483417..da8a5d282e 100644 --- a/awx/ui_next/src/screens/Team/shared/TeamForm.test.jsx +++ b/awx/ui_next/src/screens/Team/shared/TeamForm.test.jsx @@ -30,15 +30,17 @@ describe('', () => { jest.clearAllMocks(); }); - test('changing inputs should update form values', () => { - wrapper = mountWithContexts( - - ); + test('changing inputs should update form values', async () => { + await act(async () => { + wrapper = mountWithContexts( + + ); + }); const form = wrapper.find('Formik'); wrapper.find('input#team-name').simulate('change', { @@ -78,17 +80,19 @@ describe('', () => { 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( - - ); + await act(async () => { + wrapper = mountWithContexts( + + ); + }); expect(handleCancel).not.toHaveBeenCalled(); wrapper.find('button[aria-label="Cancel"]').prop('onClick')(); expect(handleCancel).toBeCalled();