diff --git a/awx/ui_next/src/App.test.jsx b/awx/ui_next/src/App.test.jsx index 805cbdc639..a76d9634b5 100644 --- a/awx/ui_next/src/App.test.jsx +++ b/awx/ui_next/src/App.test.jsx @@ -31,6 +31,5 @@ describe('', () => { }); expect(wrapper.length).toBe(1); jest.clearAllMocks(); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/components/About/About.test.jsx b/awx/ui_next/src/components/About/About.test.jsx index caed85e454..d2cb8a4637 100644 --- a/awx/ui_next/src/components/About/About.test.jsx +++ b/awx/ui_next/src/components/About/About.test.jsx @@ -1,22 +1,23 @@ import React from 'react'; -import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; +import { shallow } from 'enzyme'; import About from './About'; -describe('', () => { - let aboutWrapper; - let closeButton; - const onClose = jest.fn(); - test('initially renders without crashing', () => { - aboutWrapper = mountWithContexts(); - expect(aboutWrapper.length).toBe(1); - aboutWrapper.unmount(); - }); +jest.mock('../../util/useBrandName', () => ({ + __esModule: true, + default: () => ({ + current: 'AWX', + }), +})); - test('close button calls onClose handler', () => { - aboutWrapper = mountWithContexts(); - closeButton = aboutWrapper.find('AboutModalBoxCloseButton Button'); - closeButton.simulate('click'); - expect(onClose).toBeCalled(); - aboutWrapper.unmount(); +describe('', () => { + test('should render AboutModal', () => { + const onClose = jest.fn(); + const wrapper = shallow(); + + const modal = wrapper.find('AboutModal'); + expect(modal).toHaveLength(1); + expect(modal.prop('onClose')).toEqual(onClose); + expect(modal.prop('productName')).toEqual('AWX'); + expect(modal.prop('isOpen')).toEqual(true); }); }); diff --git a/awx/ui_next/src/components/AdHocCommands/AdHocCommands.test.jsx b/awx/ui_next/src/components/AdHocCommands/AdHocCommands.test.jsx index 417e2a08d7..e9879a84fa 100644 --- a/awx/ui_next/src/components/AdHocCommands/AdHocCommands.test.jsx +++ b/awx/ui_next/src/components/AdHocCommands/AdHocCommands.test.jsx @@ -76,8 +76,8 @@ describe('', () => { }); }); let wrapper; + afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/components/AdHocCommands/AdHocCommandsWizard.test.jsx b/awx/ui_next/src/components/AdHocCommands/AdHocCommandsWizard.test.jsx index 1393a94ebf..d2866e7965 100644 --- a/awx/ui_next/src/components/AdHocCommands/AdHocCommandsWizard.test.jsx +++ b/awx/ui_next/src/components/AdHocCommands/AdHocCommandsWizard.test.jsx @@ -54,7 +54,6 @@ describe('', () => { }); afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should mount properly', async () => { diff --git a/awx/ui_next/src/components/AdHocCommands/AdHocCredentialStep.test.jsx b/awx/ui_next/src/components/AdHocCommands/AdHocCredentialStep.test.jsx index 873b792278..f0cc546241 100644 --- a/awx/ui_next/src/components/AdHocCommands/AdHocCredentialStep.test.jsx +++ b/awx/ui_next/src/components/AdHocCommands/AdHocCredentialStep.test.jsx @@ -36,7 +36,6 @@ describe('', () => { }); afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should mount properly', async () => { diff --git a/awx/ui_next/src/components/AdHocCommands/AdHocExecutionEnironmentStep.test.jsx b/awx/ui_next/src/components/AdHocCommands/AdHocExecutionEnironmentStep.test.jsx index 539ec5874e..a78a0a673c 100644 --- a/awx/ui_next/src/components/AdHocCommands/AdHocExecutionEnironmentStep.test.jsx +++ b/awx/ui_next/src/components/AdHocCommands/AdHocExecutionEnironmentStep.test.jsx @@ -33,9 +33,9 @@ describe('', () => { ); }); }); + afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should mount properly', async () => { diff --git a/awx/ui_next/src/components/AddRole/AddResourceRole.test.jsx b/awx/ui_next/src/components/AddRole/AddResourceRole.test.jsx index 1f6ba521b7..53c450f0b9 100644 --- a/awx/ui_next/src/components/AddRole/AddResourceRole.test.jsx +++ b/awx/ui_next/src/components/AddRole/AddResourceRole.test.jsx @@ -16,7 +16,6 @@ jest.mock('../../api/models/Users'); jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), - useHistory: () => ({ push: jest.fn(), location: { pathname: {} } }), })); // TODO: Once error handling is functional in diff --git a/awx/ui_next/src/components/AddRole/SelectRoleStep.test.jsx b/awx/ui_next/src/components/AddRole/SelectRoleStep.test.jsx index 159ab0b3a1..c871db337e 100644 --- a/awx/ui_next/src/components/AddRole/SelectRoleStep.test.jsx +++ b/awx/ui_next/src/components/AddRole/SelectRoleStep.test.jsx @@ -34,6 +34,7 @@ describe('', () => { name: 'foo', }, ]; + test('initially renders without crashing', () => { wrapper = shallowWithContexts( ', () => { /> ); expect(wrapper.length).toBe(1); - wrapper.unmount(); }); + test('clicking role fires onRolesClick callback', () => { const onRolesClick = jest.fn(); wrapper = mountWithContexts( @@ -63,6 +64,5 @@ describe('', () => { name: 'Project Admin', description: 'Can manage all projects of the organization', }); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/components/AppContainer/NavExpandableGroup.jsx b/awx/ui_next/src/components/AppContainer/NavExpandableGroup.jsx index bfd5636b33..10a59fcd60 100644 --- a/awx/ui_next/src/components/AppContainer/NavExpandableGroup.jsx +++ b/awx/ui_next/src/components/AppContainer/NavExpandableGroup.jsx @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import PropTypes from 'prop-types'; +import PropTypes, { oneOfType, string, arrayOf } from 'prop-types'; import { matchPath, Link, withRouter } from 'react-router-dom'; import { NavExpandable, NavItem } from '@patternfly/react-core'; @@ -58,9 +58,9 @@ class NavExpandableGroup extends Component { } NavExpandableGroup.propTypes = { - groupId: PropTypes.string.isRequired, - groupTitle: PropTypes.element.isRequired, - routes: PropTypes.arrayOf(PropTypes.object).isRequired, + groupId: string.isRequired, + groupTitle: oneOfType([PropTypes.element, string]).isRequired, + routes: arrayOf(PropTypes.object).isRequired, }; export default withRouter(NavExpandableGroup); diff --git a/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.test.jsx b/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.test.jsx index 22b319289e..0966c8bc4e 100644 --- a/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.test.jsx +++ b/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.test.jsx @@ -14,10 +14,6 @@ describe('PageHeaderToolbar', () => { const onAboutClick = jest.fn(); const onLogoutClick = jest.fn(); - afterEach(() => { - wrapper.unmount(); - }); - test('expected content is rendered on initialization', async () => { await act(async () => { wrapper = mountWithContexts( diff --git a/awx/ui_next/src/components/CheckboxListItem/CheckboxListItem.test.jsx b/awx/ui_next/src/components/CheckboxListItem/CheckboxListItem.test.jsx index 3e61d9c980..b45cb6c3a8 100644 --- a/awx/ui_next/src/components/CheckboxListItem/CheckboxListItem.test.jsx +++ b/awx/ui_next/src/components/CheckboxListItem/CheckboxListItem.test.jsx @@ -6,14 +6,18 @@ import CheckboxListItem from './CheckboxListItem'; describe('CheckboxListItem', () => { test('renders the expected content', () => { const wrapper = mount( - {}} - onDeselect={() => {}} - /> + + + {}} + onDeselect={() => {}} + /> + +
); expect(wrapper).toHaveLength(1); }); diff --git a/awx/ui_next/src/components/CodeEditor/VariablesDetail.test.jsx b/awx/ui_next/src/components/CodeEditor/VariablesDetail.test.jsx index 8b5da1a9e3..0ad9fed51b 100644 --- a/awx/ui_next/src/components/CodeEditor/VariablesDetail.test.jsx +++ b/awx/ui_next/src/components/CodeEditor/VariablesDetail.test.jsx @@ -8,7 +8,7 @@ jest.mock('../../api'); describe('', () => { test('should render readonly CodeEditor', () => { const wrapper = mountWithContexts( - + ); const input = wrapper.find('VariablesDetail___StyledCodeEditor'); expect(input).toHaveLength(1); @@ -19,7 +19,7 @@ describe('', () => { test('should detect JSON', () => { const wrapper = mountWithContexts( - + ); const input = wrapper.find('VariablesDetail___StyledCodeEditor'); expect(input).toHaveLength(1); @@ -28,7 +28,7 @@ describe('', () => { test('should format JSON', () => { const wrapper = mountWithContexts( - + ); const input = wrapper.find('VariablesDetail___StyledCodeEditor'); expect(input).toHaveLength(1); @@ -37,7 +37,7 @@ describe('', () => { test('should convert between modes', () => { const wrapper = mountWithContexts( - + ); wrapper.find('MultiButtonToggle').invoke('onChange')('javascript'); const input = wrapper.find('VariablesDetail___StyledCodeEditor'); @@ -52,7 +52,7 @@ describe('', () => { test('should render label and value --- when there are no values', () => { const wrapper = mountWithContexts( - + ); expect(wrapper.find('VariablesDetail___StyledCodeEditor').length).toBe(1); expect(wrapper.find('.pf-c-form__label').text()).toBe('Variables'); @@ -60,7 +60,7 @@ describe('', () => { test('should update value if prop changes', () => { const wrapper = mountWithContexts( - + ); act(() => { wrapper.find('MultiButtonToggle').invoke('onChange')('javascript'); @@ -76,7 +76,7 @@ describe('', () => { test('should default yaml value to "---"', () => { const wrapper = mountWithContexts( - + ); const input = wrapper.find('VariablesDetail___StyledCodeEditor'); expect(input.prop('value')).toEqual('---'); @@ -84,7 +84,7 @@ describe('', () => { test('should default empty json to "{}"', () => { const wrapper = mountWithContexts( - + ); act(() => { wrapper.find('MultiButtonToggle').invoke('onChange')('javascript'); diff --git a/awx/ui_next/src/components/CopyButton/CopyButton.test.jsx b/awx/ui_next/src/components/CopyButton/CopyButton.test.jsx index 894431bc2d..d1926945c4 100644 --- a/awx/ui_next/src/components/CopyButton/CopyButton.test.jsx +++ b/awx/ui_next/src/components/CopyButton/CopyButton.test.jsx @@ -8,9 +8,6 @@ jest.mock('../../api'); let wrapper; describe('', () => { - afterEach(() => { - wrapper.unmount(); - }); test('should mount properly', async () => { await act(async () => { wrapper = mountWithContexts( @@ -24,6 +21,7 @@ describe('', () => { }); expect(wrapper.find('CopyButton').length).toBe(1); }); + test('should call the correct function on button click', async () => { const copyItem = jest.fn(); await act(async () => { diff --git a/awx/ui_next/src/components/DataListToolbar/DataListToolbar.test.jsx b/awx/ui_next/src/components/DataListToolbar/DataListToolbar.test.jsx index 5dcd594d22..42d76280fb 100644 --- a/awx/ui_next/src/components/DataListToolbar/DataListToolbar.test.jsx +++ b/awx/ui_next/src/components/DataListToolbar/DataListToolbar.test.jsx @@ -1,5 +1,6 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; +import { shallow } from 'enzyme'; import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import DataListToolbar from './DataListToolbar'; import AddDropDownButton from '../AddDropDownButton/AddDropDownButton'; @@ -14,13 +15,6 @@ describe('', () => { integerFields: ['page', 'page_size'], }; - afterEach(() => { - if (toolbar) { - toolbar.unmount(); - toolbar = null; - } - }); - const onSearch = jest.fn(); const onReplaceSearch = jest.fn(); const onSort = jest.fn(); @@ -100,6 +94,7 @@ describe('', () => { searchColumns={searchColumns} sortColumns={sortColumns} onSort={onSort} + onSearch={() => {}} /> ); const sortDropdownToggle = toolbar.find(sortDropdownToggleSelector); @@ -122,6 +117,7 @@ describe('', () => { searchColumns={searchColumns} sortColumns={sortColumns} onSort={onSort} + onSearch={() => {}} /> ); toolbar.update(); @@ -155,92 +151,28 @@ describe('', () => { searchDropdownItems.at(0).simulate('click', mockedSearchEvent); }); - test('it displays correct sort icon', () => { - const NUM_QS_CONFIG = { + test('should render sort icon', () => { + const qsConfig = { namespace: 'organization', dateFields: ['modified', 'created'], defaultParams: { page: 1, page_size: 5, order_by: 'id' }, integerFields: ['page', 'page_size', 'id'], }; + const sortColumns = [{ name: 'Name', key: 'name' }]; - const NUM_DESC_QS_CONFIG = { - namespace: 'organization', - dateFields: ['modified', 'created'], - defaultParams: { page: 1, page_size: 5, order_by: '-id' }, - integerFields: ['page', 'page_size', 'id'], - }; - - const ALPH_QS_CONFIG = { - namespace: 'organization', - dateFields: ['modified', 'created'], - defaultParams: { page: 1, page_size: 5, order_by: 'name' }, - integerFields: ['page', 'page_size', 'id'], - }; - - const ALPH_DESC_QS_CONFIG = { - namespace: 'organization', - dateFields: ['modified', 'created'], - defaultParams: { page: 1, page_size: 5, order_by: '-name' }, - integerFields: ['page', 'page_size', 'id'], - }; - - const forwardNumericIconSelector = 'SortNumericDownIcon'; - const reverseNumericIconSelector = 'SortNumericDownAltIcon'; - const forwardAlphaIconSelector = 'SortAlphaDownIcon'; - const reverseAlphaIconSelector = 'SortAlphaDownAltIcon'; - - const numericColumns = [{ name: 'ID', key: 'id' }]; - - const alphaColumns = [{ name: 'Name', key: 'name' }]; - - const searchColumns = [ - { name: 'Name', key: 'name', isDefault: true }, - { name: 'ID', key: 'id' }, - ]; - - toolbar = mountWithContexts( + const wrapper = shallow( ); - const reverseNumericIcon = toolbar.find(reverseNumericIconSelector); - expect(reverseNumericIcon.length).toBe(1); - - toolbar = mountWithContexts( - - ); - - const forwardNumericIcon = toolbar.find(forwardNumericIconSelector); - expect(forwardNumericIcon.length).toBe(1); - - toolbar = mountWithContexts( - - ); - - const reverseAlphaIcon = toolbar.find(reverseAlphaIconSelector); - expect(reverseAlphaIcon.length).toBe(1); - - toolbar = mountWithContexts( - - ); - - const forwardAlphaIcon = toolbar.find(forwardAlphaIconSelector); - expect(forwardAlphaIcon.length).toBe(1); + const sort = wrapper.find('Sort'); + expect(sort.prop('qsConfig')).toEqual(qsConfig); + expect(sort.prop('columns')).toEqual(sortColumns); + expect(sort.prop('onSort')).toEqual(onSort); }); test('should render additionalControls', () => { diff --git a/awx/ui_next/src/components/DisassociateButton/DisassociateButton.test.jsx b/awx/ui_next/src/components/DisassociateButton/DisassociateButton.test.jsx index 5f0b76d330..6bed1acf6a 100644 --- a/awx/ui_next/src/components/DisassociateButton/DisassociateButton.test.jsx +++ b/awx/ui_next/src/components/DisassociateButton/DisassociateButton.test.jsx @@ -40,7 +40,6 @@ describe('', () => { afterAll(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should render button', () => { diff --git a/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx b/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx index 2118fdfc9e..342121a6cb 100644 --- a/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx +++ b/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx @@ -36,6 +36,10 @@ function ErrorDetail({ error }) { const { response } = error; const [isExpanded, setIsExpanded] = useState(false); + if (!error) { + return null; + } + const handleToggle = () => { setIsExpanded(!isExpanded); }; @@ -84,7 +88,10 @@ function ErrorDetail({ error }) { } ErrorDetail.propTypes = { - error: PropTypes.instanceOf(Error).isRequired, + error: PropTypes.instanceOf(Error), +}; +ErrorDetail.defaultProps = { + error: null, }; export default ErrorDetail; diff --git a/awx/ui_next/src/components/ExpandCollapse/ExpandCollapse.test.jsx b/awx/ui_next/src/components/ExpandCollapse/ExpandCollapse.test.jsx index 74b37d6235..eb06b49c51 100644 --- a/awx/ui_next/src/components/ExpandCollapse/ExpandCollapse.test.jsx +++ b/awx/ui_next/src/components/ExpandCollapse/ExpandCollapse.test.jsx @@ -15,6 +15,5 @@ describe('', () => { /> ); expect(wrapper.length).toBe(1); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.test.jsx b/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.test.jsx index 21d24444b1..e3361a9576 100644 --- a/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.test.jsx +++ b/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.test.jsx @@ -6,10 +6,6 @@ import FieldWithPrompt from './FieldWithPrompt'; describe('FieldWithPrompt', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); - test('Required asterisk and Popover hidden when not required and tooltip not provided', () => { wrapper = mountWithContexts( ', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); test('should be disabled when no rows are selected', () => { wrapper = mountWithContexts(); expect(wrapper.find('JobListCancelButton button').props().disabled).toBe( diff --git a/awx/ui_next/src/components/JobList/JobListItem.test.jsx b/awx/ui_next/src/components/JobList/JobListItem.test.jsx index 2e35f181a0..70f89fdb63 100644 --- a/awx/ui_next/src/components/JobList/JobListItem.test.jsx +++ b/awx/ui_next/src/components/JobList/JobListItem.test.jsx @@ -41,10 +41,6 @@ describe('', () => { ); }); - afterEach(() => { - wrapper.unmount(); - }); - test('initially renders successfully', () => { expect(wrapper.find('JobListItem').length).toBe(1); }); @@ -118,10 +114,6 @@ describe('', () => { ); }); - afterEach(() => { - wrapper.unmount(); - }); - test('launch button shown to users with launch capabilities', () => { expect(wrapper.find('LaunchButton').length).toBe(1); }); diff --git a/awx/ui_next/src/components/ListHeader/ListHeader.test.jsx b/awx/ui_next/src/components/ListHeader/ListHeader.test.jsx index f7199fe4d4..6cca8a7969 100644 --- a/awx/ui_next/src/components/ListHeader/ListHeader.test.jsx +++ b/awx/ui_next/src/components/ListHeader/ListHeader.test.jsx @@ -24,7 +24,6 @@ describe('ListHeader', () => { /> ); expect(wrapper.length).toBe(1); - wrapper.unmount(); }); test('should navigate when DataListToolbar calls onSort prop', async () => { diff --git a/awx/ui_next/src/components/Lookup/ApplicationLookup.test.jsx b/awx/ui_next/src/components/Lookup/ApplicationLookup.test.jsx index 45986151f4..10eac993bb 100644 --- a/awx/ui_next/src/components/Lookup/ApplicationLookup.test.jsx +++ b/awx/ui_next/src/components/Lookup/ApplicationLookup.test.jsx @@ -36,7 +36,6 @@ describe('ApplicationLookup', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should render successfully', async () => { diff --git a/awx/ui_next/src/components/Lookup/ExecutionEnvironmentLookup.test.jsx b/awx/ui_next/src/components/Lookup/ExecutionEnvironmentLookup.test.jsx index a8a33d12a8..339f8235f7 100644 --- a/awx/ui_next/src/components/Lookup/ExecutionEnvironmentLookup.test.jsx +++ b/awx/ui_next/src/components/Lookup/ExecutionEnvironmentLookup.test.jsx @@ -38,7 +38,6 @@ describe('ExecutionEnvironmentLookup', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should render successfully', async () => { diff --git a/awx/ui_next/src/components/Lookup/InventoryLookup.test.jsx b/awx/ui_next/src/components/Lookup/InventoryLookup.test.jsx index ac0662ad30..765ad87bf7 100644 --- a/awx/ui_next/src/components/Lookup/InventoryLookup.test.jsx +++ b/awx/ui_next/src/components/Lookup/InventoryLookup.test.jsx @@ -26,7 +26,6 @@ describe('InventoryLookup', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should render successfully and fetch data', async () => { diff --git a/awx/ui_next/src/components/Lookup/Lookup.jsx b/awx/ui_next/src/components/Lookup/Lookup.jsx index 6a8a4130ed..1114006c3e 100644 --- a/awx/ui_next/src/components/Lookup/Lookup.jsx +++ b/awx/ui_next/src/components/Lookup/Lookup.jsx @@ -7,6 +7,7 @@ import { number, oneOfType, shape, + node, } from 'prop-types'; import { withRouter } from 'react-router-dom'; import { useField } from 'formik'; @@ -206,7 +207,7 @@ const Item = shape({ Lookup.propTypes = { id: string, header: string, - modalDescription: string, + modalDescription: oneOfType([string, node]), onChange: func.isRequired, value: oneOfType([Item, arrayOf(Item)]), multiple: bool, diff --git a/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.test.jsx b/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.test.jsx index 994a81b0b3..0cfb3a66b5 100644 --- a/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.test.jsx +++ b/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.test.jsx @@ -122,7 +122,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should load credential types', async () => { diff --git a/awx/ui_next/src/components/Lookup/OrganizationLookup.test.jsx b/awx/ui_next/src/components/Lookup/OrganizationLookup.test.jsx index e6941e71c8..873310120e 100644 --- a/awx/ui_next/src/components/Lookup/OrganizationLookup.test.jsx +++ b/awx/ui_next/src/components/Lookup/OrganizationLookup.test.jsx @@ -12,7 +12,6 @@ describe('OrganizationLookup', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should render successfully', async () => { diff --git a/awx/ui_next/src/components/MultiButtonToggle/MultiButtonToggle.jsx b/awx/ui_next/src/components/MultiButtonToggle/MultiButtonToggle.jsx index 02a9e5982f..50b772b0c9 100644 --- a/awx/ui_next/src/components/MultiButtonToggle/MultiButtonToggle.jsx +++ b/awx/ui_next/src/components/MultiButtonToggle/MultiButtonToggle.jsx @@ -10,6 +10,7 @@ const SmallButton = styled(Button)` font-size: var(--pf-global--FontSize--xs); } `; +SmallButton.displayName = 'SmallButton'; function MultiButtonToggle({ buttons, value, onChange, name }) { const setValue = newValue => { diff --git a/awx/ui_next/src/components/MultiButtonToggle/MultiButtonToggle.test.jsx b/awx/ui_next/src/components/MultiButtonToggle/MultiButtonToggle.test.jsx index 01dafe0cdd..c37e43b729 100644 --- a/awx/ui_next/src/components/MultiButtonToggle/MultiButtonToggle.test.jsx +++ b/awx/ui_next/src/components/MultiButtonToggle/MultiButtonToggle.test.jsx @@ -1,12 +1,13 @@ import React from 'react'; -import { mount } from 'enzyme'; +import { shallow } from 'enzyme'; import MultiButtonToggle from './MultiButtonToggle'; describe('', () => { let wrapper; const onChange = jest.fn(); + beforeAll(() => { - wrapper = mount( + wrapper = shallow( ', () => { ]} value="yaml" onChange={onChange} + name="the-button" /> ); }); - afterAll(() => { - wrapper.unmount(); - }); + it('should render buttons successfully', () => { - const buttons = wrapper.find('Button'); + const buttons = wrapper.find('SmallButton'); expect(buttons.length).toBe(2); expect(buttons.at(0).props().variant).toBe('primary'); expect(buttons.at(1).props().variant).toBe('secondary'); }); + it('should call onChange function when button clicked', () => { - const buttons = wrapper.find('Button'); + const buttons = wrapper.find('SmallButton'); buttons.at(1).simulate('click'); expect(onChange).toHaveBeenCalledWith('json'); }); diff --git a/awx/ui_next/src/components/NotificationList/NotificationListItem.test.jsx b/awx/ui_next/src/components/NotificationList/NotificationListItem.test.jsx index 2cf6556334..7e8e384055 100644 --- a/awx/ui_next/src/components/NotificationList/NotificationListItem.test.jsx +++ b/awx/ui_next/src/components/NotificationList/NotificationListItem.test.jsx @@ -21,10 +21,6 @@ describe('', () => { }); afterEach(() => { - if (wrapper) { - wrapper.unmount(); - wrapper = null; - } jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/components/PaginatedTable/ToolbarDeleteButton.test.jsx b/awx/ui_next/src/components/PaginatedTable/ToolbarDeleteButton.test.jsx index ef06a98e46..6acc5062e9 100644 --- a/awx/ui_next/src/components/PaginatedTable/ToolbarDeleteButton.test.jsx +++ b/awx/ui_next/src/components/PaginatedTable/ToolbarDeleteButton.test.jsx @@ -40,8 +40,8 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); + test('should render button', () => { wrapper = mountWithContexts( {}} itemsToDelete={[]} /> diff --git a/awx/ui_next/src/components/PromptDetail/PromptProjectDetail.test.jsx b/awx/ui_next/src/components/PromptDetail/PromptProjectDetail.test.jsx index 34a7249f66..239b4cdac4 100644 --- a/awx/ui_next/src/components/PromptDetail/PromptProjectDetail.test.jsx +++ b/awx/ui_next/src/components/PromptDetail/PromptProjectDetail.test.jsx @@ -25,10 +25,6 @@ describe('PromptProjectDetail', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('should render successfully', () => { expect(wrapper.find('PromptProjectDetail')).toHaveLength(1); }); diff --git a/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.test.jsx b/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.test.jsx index 6bcbc2b391..f4db363906 100644 --- a/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.test.jsx +++ b/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.test.jsx @@ -133,7 +133,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/components/Schedule/Schedule.test.jsx b/awx/ui_next/src/components/Schedule/Schedule.test.jsx index 280c6af6bb..4390ed5f44 100644 --- a/awx/ui_next/src/components/Schedule/Schedule.test.jsx +++ b/awx/ui_next/src/components/Schedule/Schedule.test.jsx @@ -113,12 +113,11 @@ describe('', () => { }); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); }); - afterAll(() => { - wrapper.unmount(); - }); + test('renders successfully', async () => { expect(wrapper.length).toBe(1); }); + test('expect all tabs to exist, including Back to Schedules', async () => { expect( wrapper.find('button[link="/templates/job_template/1/schedules"]').length diff --git a/awx/ui_next/src/components/Schedule/ScheduleAdd/ScheduleAdd.test.jsx b/awx/ui_next/src/components/Schedule/ScheduleAdd/ScheduleAdd.test.jsx index 6d115e00bc..a9bceda2dd 100644 --- a/awx/ui_next/src/components/Schedule/ScheduleAdd/ScheduleAdd.test.jsx +++ b/awx/ui_next/src/components/Schedule/ScheduleAdd/ScheduleAdd.test.jsx @@ -73,7 +73,9 @@ describe('', () => { /> ); }); + wrapper.update(); }); + test('Successfully creates a schedule with repeat frequency: None (run once)', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -95,6 +97,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200325T100000 RRULE:INTERVAL=1;COUNT=1;FREQ=MINUTELY', }); }); + test('Successfully creates a schedule with 10 minute repeat frequency after 10 occurrences', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -117,6 +120,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200325T103000 RRULE:INTERVAL=10;FREQ=MINUTELY;COUNT=10', }); }); + test('Successfully creates a schedule with hourly repeat frequency ending on a specific date/time', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -140,6 +144,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200325T104500 RRULE:INTERVAL=1;FREQ=HOURLY;UNTIL=20200326T104500', }); }); + test('Successfully creates a schedule with daily repeat frequency', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -161,6 +166,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200325T104500 RRULE:INTERVAL=1;FREQ=DAILY', }); }); + test('Successfully creates a schedule with weekly repeat frequency on mon/wed/fri', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -183,6 +189,7 @@ describe('', () => { rrule: `DTSTART;TZID=America/New_York:20200325T104500 RRULE:INTERVAL=1;FREQ=WEEKLY;BYDAY=${RRule.MO},${RRule.WE},${RRule.FR}`, }); }); + test('Successfully creates a schedule with monthly repeat frequency on the first day of the month', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -207,6 +214,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200401T104500 RRULE:INTERVAL=1;FREQ=MONTHLY;BYMONTHDAY=1', }); }); + test('Successfully creates a schedule with monthly repeat frequency on the last tuesday of the month', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -259,6 +267,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200301T000000 RRULE:INTERVAL=1;FREQ=YEARLY;BYMONTH=3;BYMONTHDAY=1', }); }); + test('Successfully creates a schedule with yearly repeat frequency on the second Friday in April', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -285,6 +294,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200410T111500 RRULE:INTERVAL=1;FREQ=YEARLY;BYSETPOS=2;BYDAY=FR;BYMONTH=4', }); }); + test('Successfully creates a schedule with yearly repeat frequency on the first weekday in October', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -464,6 +474,7 @@ describe('', () => { /> ); }); + scheduleSurveyWrapper.update(); await act(async () => { scheduleSurveyWrapper.find('Formik').invoke('onSubmit')({ description: 'test description', diff --git a/awx/ui_next/src/components/Schedule/ScheduleEdit/ScheduleEdit.test.jsx b/awx/ui_next/src/components/Schedule/ScheduleEdit/ScheduleEdit.test.jsx index faa505734c..39b77d5301 100644 --- a/awx/ui_next/src/components/Schedule/ScheduleEdit/ScheduleEdit.test.jsx +++ b/awx/ui_next/src/components/Schedule/ScheduleEdit/ScheduleEdit.test.jsx @@ -1,10 +1,7 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { RRule } from 'rrule'; -import { - mountWithContexts, - waitForElement, -} from '../../../../testUtils/enzymeHelpers'; +import { mountWithContexts } from '../../../../testUtils/enzymeHelpers'; import { SchedulesAPI, InventoriesAPI, @@ -191,12 +188,13 @@ describe('', () => { /> ); }); - await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); + wrapper.update(); }); + afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); + test('Successfully creates a schedule with repeat frequency: None (run once)', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -210,6 +208,7 @@ describe('', () => { timezone: 'America/New_York', }); }); + expect(SchedulesAPI.update).toHaveBeenCalledWith(27, { description: 'test description', name: 'Run once schedule', @@ -218,6 +217,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200325T100000 RRULE:INTERVAL=1;COUNT=1;FREQ=MINUTELY', }); }); + test('Successfully creates a schedule with 10 minute repeat frequency after 10 occurrences', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -241,6 +241,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200325T103000 RRULE:INTERVAL=10;FREQ=MINUTELY;COUNT=10', }); }); + test('Successfully creates a schedule with hourly repeat frequency ending on a specific date/time', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -256,6 +257,7 @@ describe('', () => { timezone: 'America/New_York', }); }); + expect(SchedulesAPI.update).toHaveBeenCalledWith(27, { description: 'test description', name: 'Run every hour until date', @@ -264,6 +266,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200325T104500 RRULE:INTERVAL=1;FREQ=HOURLY;UNTIL=20200326T104500', }); }); + test('Successfully creates a schedule with daily repeat frequency', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -308,6 +311,7 @@ describe('', () => { rrule: `DTSTART;TZID=America/New_York:20200325T104500 RRULE:INTERVAL=1;FREQ=WEEKLY;BYDAY=${RRule.MO},${RRule.WE},${RRule.FR}`, }); }); + test('Successfully creates a schedule with monthly repeat frequency on the first day of the month', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -333,6 +337,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200401T104500 RRULE:INTERVAL=1;FREQ=MONTHLY;BYMONTHDAY=1', }); }); + test('Successfully creates a schedule with monthly repeat frequency on the last tuesday of the month', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -362,6 +367,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200331T110000 RRULE:INTERVAL=1;FREQ=MONTHLY;BYSETPOS=-1;BYDAY=TU', }); }); + test('Successfully creates a schedule with yearly repeat frequency on the first day of March', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -388,6 +394,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200301T000000 RRULE:INTERVAL=1;FREQ=YEARLY;BYMONTH=3;BYMONTHDAY=1', }); }); + test('Successfully creates a schedule with yearly repeat frequency on the second Friday in April', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -416,6 +423,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200410T111500 RRULE:INTERVAL=1;FREQ=YEARLY;BYSETPOS=2;BYDAY=FR;BYMONTH=4', }); }); + test('Successfully creates a schedule with yearly repeat frequency on the first weekday in October', async () => { await act(async () => { wrapper.find('Formik').invoke('onSubmit')({ @@ -653,6 +661,7 @@ describe('', () => { 'DTSTART;TZID=America/New_York:20200402T184500 RRULE:INTERVAL=1;COUNT=1;FREQ=MINUTELY', }); }); + test('should submit survey with default values properly, without opening prompt wizard', async () => { let scheduleSurveyWrapper; await act(async () => { @@ -741,6 +750,8 @@ describe('', () => { /> ); }); + scheduleSurveyWrapper.update(); + await act(async () => { scheduleSurveyWrapper.find('Formik').invoke('onSubmit')({ description: 'test description', @@ -753,6 +764,7 @@ describe('', () => { timezone: 'America/New_York', }); }); + expect(SchedulesAPI.update).toHaveBeenCalledWith(27, { description: 'test description', name: 'Run once schedule', diff --git a/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleList.test.jsx b/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleList.test.jsx index 0981eac2bf..a7c5b876ec 100644 --- a/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleList.test.jsx +++ b/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleList.test.jsx @@ -52,10 +52,6 @@ describe('ScheduleList', () => { wrapper.update(); }); - afterEach(() => { - wrapper.unmount(); - }); - test('should fetch schedules from api and render the list', () => { expect(loadSchedules).toHaveBeenCalled(); expect(wrapper.find('ScheduleListItem').length).toBe(5); diff --git a/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.test.jsx b/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.test.jsx index 394128a095..94a48d9695 100644 --- a/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.test.jsx +++ b/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.test.jsx @@ -64,10 +64,6 @@ describe('ScheduleListItem', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('Name correctly shown with correct link', () => { expect( wrapper @@ -149,10 +145,6 @@ describe('ScheduleListItem', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('Name correctly shown with correct link', () => { expect( wrapper @@ -217,10 +209,6 @@ describe('ScheduleListItem', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('should show missing resource icon', () => { expect(wrapper.find('ExclamationTriangleIcon').length).toBe(1); expect(wrapper.find('ScheduleToggle').prop('isDisabled')).toBe(true); diff --git a/awx/ui_next/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.test.jsx b/awx/ui_next/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.test.jsx index 199cb3d1b0..e507a32420 100644 --- a/awx/ui_next/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.test.jsx +++ b/awx/ui_next/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.test.jsx @@ -15,15 +15,15 @@ describe('', () => { /> ); }); - afterAll(() => { - wrapper.unmount(); - }); + test('Local option initially set', async () => { expect(wrapper.find('MultiButtonToggle').props().value).toBe('local'); }); + test('It renders the correct number of dates', async () => { expect(wrapper.find('dd').children().length).toBe(2); }); + test('Clicking UTC button toggles the dates to utc', async () => { wrapper.find('button[aria-label="UTC"]').simulate('click'); expect(wrapper.find('MultiButtonToggle').props().value).toBe('utc'); @@ -44,6 +44,7 @@ describe('', () => { ).toBe('3/30/2020, 4:00:00 AM'); }); }); + describe('Only one date passed in', () => { test('Component should not render chldren', async () => { wrapper = mountWithContexts( @@ -55,7 +56,6 @@ describe('', () => { /> ); expect(wrapper.find('ScheduleOccurrences').children().length).toBe(0); - wrapper.unmount(); }); }); }); diff --git a/awx/ui_next/src/components/Schedule/Schedules.test.jsx b/awx/ui_next/src/components/Schedule/Schedules.test.jsx index 3efd1a7754..937745dfee 100644 --- a/awx/ui_next/src/components/Schedule/Schedules.test.jsx +++ b/awx/ui_next/src/components/Schedule/Schedules.test.jsx @@ -19,6 +19,7 @@ describe('', () => { jobTemplate={jobTemplate} loadSchedules={() => {}} loadScheduleOptions={() => {}} + apiModel={{ createSchedule: () => {} }} />, { diff --git a/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx b/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx index 510b0c0a83..f3e6d3893e 100644 --- a/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx +++ b/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx @@ -178,7 +178,6 @@ function ScheduleForm({ hasDaysToKeepField, handleCancel, handleSubmit, - schedule, submitError, resource, @@ -234,8 +233,14 @@ function ScheduleForm({ { zonesOptions: [], credentials: [], + isLoading: true, } ); + + useEffect(() => { + loadScheduleData(); + }, [loadScheduleData]); + const missingRequiredInventory = useCallback(() => { let missingInventory = false; if ( @@ -357,10 +362,6 @@ function ScheduleForm({ hasCredentialsThatPrompt, ]); - useEffect(() => { - loadScheduleData(); - }, [loadScheduleData]); - let showPromptButton = false; if ( diff --git a/awx/ui_next/src/components/Schedule/shared/ScheduleForm.test.jsx b/awx/ui_next/src/components/Schedule/shared/ScheduleForm.test.jsx index 4f5aac69c4..4891d337f6 100644 --- a/awx/ui_next/src/components/Schedule/shared/ScheduleForm.test.jsx +++ b/awx/ui_next/src/components/Schedule/shared/ScheduleForm.test.jsx @@ -168,6 +168,7 @@ describe('', () => { expect(wrapper.find('ContentError').length).toBe(1); }); }); + describe('Cancel', () => { test('should make the appropriate callback', async () => { const handleCancel = jest.fn(); @@ -226,8 +227,10 @@ describe('', () => { expect(handleCancel).toHaveBeenCalledTimes(1); }); }); + describe('Prompted Schedule', () => { let promptWrapper; + beforeEach(async () => { SchedulesAPI.readZoneInfo.mockResolvedValue({ data: [ @@ -284,8 +287,8 @@ describe('', () => { el => el.length > 0 ); }); + afterEach(() => { - promptWrapper.unmount(); jest.clearAllMocks(); }); @@ -375,6 +378,7 @@ describe('', () => { promptWrapper.update(); expect(promptWrapper.find('Wizard').length).toBe(0); }); + test('should render prompt button with disabled save button', async () => { await act(async () => { wrapper = mountWithContexts( @@ -423,6 +427,7 @@ describe('', () => { ); }); }); + describe('Add', () => { beforeAll(async () => { SchedulesAPI.readZoneInfo.mockResolvedValue({ @@ -473,9 +478,7 @@ describe('', () => { }); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); }); - afterAll(() => { - wrapper.unmount(); - }); + test('initially renders expected fields and values', () => { const now = new Date(); const closestQuarterHour = new Date( @@ -503,6 +506,7 @@ describe('', () => { 'none' ); }); + test('correct frequency details fields and values shown when frequency changed to minute', async () => { const runFrequencySelect = wrapper.find( 'FormGroup[label="Run frequency"] FormSelect' @@ -526,6 +530,7 @@ describe('', () => { expect(wrapper.find('input#end-after').prop('checked')).toBe(false); expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); }); + test('correct frequency details fields and values shown when frequency changed to hour', async () => { const runFrequencySelect = wrapper.find( 'FormGroup[label="Run frequency"] FormSelect' @@ -549,6 +554,7 @@ describe('', () => { expect(wrapper.find('input#end-after').prop('checked')).toBe(false); expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); }); + test('correct frequency details fields and values shown when frequency changed to day', async () => { const runFrequencySelect = wrapper.find( 'FormGroup[label="Run frequency"] FormSelect' @@ -572,6 +578,7 @@ describe('', () => { expect(wrapper.find('input#end-after').prop('checked')).toBe(false); expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); }); + test('correct frequency details fields and values shown when frequency changed to week', async () => { const runFrequencySelect = wrapper.find( 'FormGroup[label="Run frequency"] FormSelect' @@ -595,6 +602,7 @@ describe('', () => { expect(wrapper.find('input#end-after').prop('checked')).toBe(false); expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); }); + test('correct frequency details fields and values shown when frequency changed to month', async () => { const runFrequencySelect = wrapper.find( 'FormGroup[label="Run frequency"] FormSelect' @@ -629,6 +637,7 @@ describe('', () => { expect(wrapper.find('select#schedule-run-on-day-month').length).toBe(0); expect(wrapper.find('select#schedule-run-on-the-month').length).toBe(0); }); + test('correct frequency details fields and values shown when frequency changed to year', async () => { const runFrequencySelect = wrapper.find( 'FormGroup[label="Run frequency"] FormSelect' @@ -663,6 +672,7 @@ describe('', () => { expect(wrapper.find('select#schedule-run-on-day-month').length).toBe(1); expect(wrapper.find('select#schedule-run-on-the-month').length).toBe(1); }); + test('occurrences field properly shown when end after selection is made', async () => { await act(async () => { wrapper @@ -690,6 +700,7 @@ describe('', () => { }); wrapper.update(); }); + test('error shown when end date/time comes before start date/time', async () => { await act(async () => { wrapper @@ -719,15 +730,12 @@ describe('', () => { ); }); - await act(async () => { - wrapper.find('DatePicker[aria-label="End date"]').simulate('blur'); - }); - wrapper.update(); expect(wrapper.find('#schedule-End-datetime-helper').text()).toBe( 'Please select an end date/time that comes after the start date/time.' ); }); + test('error shown when on day number is not between 1 and 31', async () => { act(() => { wrapper.find('select[id="schedule-frequency"]').invoke('onChange')( @@ -761,6 +769,7 @@ describe('', () => { ); }); }); + describe('Edit', () => { beforeEach(async () => { SchedulesAPI.readZoneInfo.mockResolvedValue({ @@ -773,12 +782,12 @@ describe('', () => { SchedulesAPI.readCredentials.mockResolvedValue(credentials); }); + afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); - test('should make API calls to fetch credentials, launch configuration, and survey configuration', async () => { + test('should make API calls to fetch credentials, launch configuration, and survey configuration', async () => { await act(async () => { wrapper = mountWithContexts( ', () => { /> ); }); + wrapper.update(); expect(wrapper.find('ScheduleForm').length).toBe(1); defaultFieldsVisible(); expect(wrapper.find('FormGroup[label="Run every"]').length).toBe(0); @@ -920,6 +930,7 @@ describe('', () => { 'none' ); }); + test('initially renders expected fields and values with existing schedule that runs every 10 minutes', async () => { await act(async () => { wrapper = mountWithContexts( @@ -941,6 +952,8 @@ describe('', () => { /> ); }); + wrapper.update(); + expect(wrapper.find('ScheduleForm').length).toBe(1); defaultFieldsVisible(); expect(wrapper.find('FormGroup[label="End"]').length).toBe(1); @@ -959,6 +972,7 @@ describe('', () => { expect(wrapper.find('input#end-after').prop('checked')).toBe(false); expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); }); + test('initially renders expected fields and values with existing schedule that runs every hour 10 times', async () => { await act(async () => { wrapper = mountWithContexts( @@ -981,6 +995,8 @@ describe('', () => { /> ); }); + wrapper.update(); + expect(wrapper.find('ScheduleForm').length).toBe(1); defaultFieldsVisible(); expect(wrapper.find('FormGroup[label="End"]').length).toBe(1); @@ -1000,6 +1016,7 @@ describe('', () => { expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); expect(wrapper.find('input#schedule-occurrences').prop('value')).toBe(10); }); + test('initially renders expected fields and values with existing schedule that runs every day', async () => { await act(async () => { wrapper = mountWithContexts( @@ -1021,25 +1038,28 @@ describe('', () => { }} /> ); - expect(wrapper.find('ScheduleForm').length).toBe(1); - defaultFieldsVisible(); - expect(wrapper.find('FormGroup[label="Run every"]').length).toBe(1); - expect(wrapper.find('FormGroup[label="End"]').length).toBe(1); - expect(wrapper.find('FormGroup[label="On days"]').length).toBe(0); - expect(wrapper.find('FormGroup[label="Run on"]').length).toBe(0); - expect(wrapper.find('FormGroup[label="Occurrences"]').length).toBe(0); - expect(wrapper.find('FormGroup[label="End date/time"]').length).toBe(0); - - nonRRuleValuesMatch(); - expect(wrapper.find('select#schedule-frequency').prop('value')).toBe( - 'day' - ); - expect(wrapper.find('input#end-never').prop('checked')).toBe(true); - expect(wrapper.find('input#end-after').prop('checked')).toBe(false); - expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); - expect(wrapper.find('input#schedule-run-every').prop('value')).toBe(1); }); + wrapper.update(); + + expect(wrapper.find('ScheduleForm').length).toBe(1); + defaultFieldsVisible(); + expect(wrapper.find('FormGroup[label="Run every"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="End"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="On days"]').length).toBe(0); + expect(wrapper.find('FormGroup[label="Run on"]').length).toBe(0); + expect(wrapper.find('FormGroup[label="Occurrences"]').length).toBe(0); + expect(wrapper.find('FormGroup[label="End date/time"]').length).toBe(0); + + nonRRuleValuesMatch(); + expect(wrapper.find('select#schedule-frequency').prop('value')).toBe( + 'day' + ); + expect(wrapper.find('input#end-never').prop('checked')).toBe(true); + expect(wrapper.find('input#end-after').prop('checked')).toBe(false); + expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); + expect(wrapper.find('input#schedule-run-every').prop('value')).toBe(1); }); + test('initially renders expected fields and values with existing schedule that runs every week on m/w/f until Jan 1, 2020', async () => { await act(async () => { wrapper = mountWithContexts( @@ -1062,6 +1082,8 @@ describe('', () => { /> ); }); + wrapper.update(); + expect(wrapper.find('ScheduleForm').length).toBe(1); defaultFieldsVisible(); expect(wrapper.find('FormGroup[label="End"]').length).toBe(1); @@ -1107,6 +1129,7 @@ describe('', () => { wrapper.find('TimePicker[aria-label="End time"]').prop('value') ).toBe('1:00 AM'); }); + test('initially renders expected fields and values with existing schedule that runs every month on the last weekday', async () => { await act(async () => { wrapper = mountWithContexts( @@ -1128,37 +1151,43 @@ describe('', () => { }} /> ); - expect(wrapper.find('ScheduleForm').length).toBe(1); - defaultFieldsVisible(); - expect(wrapper.find('FormGroup[label="End"]').length).toBe(1); - expect(wrapper.find('FormGroup[label="Run every"]').length).toBe(1); - expect(wrapper.find('FormGroup[label="Run on"]').length).toBe(1); - expect(wrapper.find('FormGroup[label="End date/time"]').length).toBe(0); - expect(wrapper.find('FormGroup[label="On days"]').length).toBe(0); - expect(wrapper.find('FormGroup[label="Occurrences"]').length).toBe(0); - - nonRRuleValuesMatch(); - expect(wrapper.find('select#schedule-frequency').prop('value')).toBe( - 'month' - ); - expect(wrapper.find('input#end-never').prop('checked')).toBe(true); - expect(wrapper.find('input#end-after').prop('checked')).toBe(false); - expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); - expect(wrapper.find('input#schedule-run-every').prop('value')).toBe(1); - expect(wrapper.find('input#schedule-run-on-day').prop('checked')).toBe( - false - ); - expect(wrapper.find('input#schedule-run-on-the').prop('checked')).toBe( - true - ); - expect( - wrapper.find('select#schedule-run-on-the-occurrence').prop('value') - ).toBe(-1); - expect( - wrapper.find('select#schedule-run-on-the-day').prop('value') - ).toBe('weekday'); }); + wrapper.update(); + + expect(wrapper.find('ScheduleForm').length).toBe(1); + defaultFieldsVisible(); + + expect(wrapper.find('ScheduleForm').length).toBe(1); + defaultFieldsVisible(); + expect(wrapper.find('FormGroup[label="End"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="Run every"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="Run on"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="End date/time"]').length).toBe(0); + expect(wrapper.find('FormGroup[label="On days"]').length).toBe(0); + expect(wrapper.find('FormGroup[label="Occurrences"]').length).toBe(0); + + nonRRuleValuesMatch(); + expect(wrapper.find('select#schedule-frequency').prop('value')).toBe( + 'month' + ); + expect(wrapper.find('input#end-never').prop('checked')).toBe(true); + expect(wrapper.find('input#end-after').prop('checked')).toBe(false); + expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); + expect(wrapper.find('input#schedule-run-every').prop('value')).toBe(1); + expect(wrapper.find('input#schedule-run-on-day').prop('checked')).toBe( + false + ); + expect(wrapper.find('input#schedule-run-on-the').prop('checked')).toBe( + true + ); + expect( + wrapper.find('select#schedule-run-on-the-occurrence').prop('value') + ).toBe(-1); + expect(wrapper.find('select#schedule-run-on-the-day').prop('value')).toBe( + 'weekday' + ); }); + test('initially renders expected fields and values with existing schedule that runs every year on the May 6', async () => { await act(async () => { wrapper = mountWithContexts( @@ -1180,36 +1209,38 @@ describe('', () => { }} /> ); - expect(wrapper.find('ScheduleForm').length).toBe(1); - defaultFieldsVisible(); - expect(wrapper.find('FormGroup[label="End"]').length).toBe(1); - expect(wrapper.find('FormGroup[label="Run every"]').length).toBe(1); - expect(wrapper.find('FormGroup[label="Run on"]').length).toBe(1); - expect(wrapper.find('FormGroup[label="End date/time"]').length).toBe(0); - expect(wrapper.find('FormGroup[label="On days"]').length).toBe(0); - expect(wrapper.find('FormGroup[label="Occurrences"]').length).toBe(0); - - nonRRuleValuesMatch(); - expect(wrapper.find('select#schedule-frequency').prop('value')).toBe( - 'year' - ); - expect(wrapper.find('input#end-never').prop('checked')).toBe(true); - expect(wrapper.find('input#end-after').prop('checked')).toBe(false); - expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); - expect(wrapper.find('input#schedule-run-every').prop('value')).toBe(1); - expect(wrapper.find('input#schedule-run-on-day').prop('checked')).toBe( - true - ); - expect(wrapper.find('input#schedule-run-on-the').prop('checked')).toBe( - false - ); - expect( - wrapper.find('select#schedule-run-on-day-month').prop('value') - ).toBe(5); - expect( - wrapper.find('input#schedule-run-on-day-number').prop('value') - ).toBe(6); }); + wrapper.update(); + + expect(wrapper.find('ScheduleForm').length).toBe(1); + defaultFieldsVisible(); + expect(wrapper.find('FormGroup[label="End"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="Run every"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="Run on"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="End date/time"]').length).toBe(0); + expect(wrapper.find('FormGroup[label="On days"]').length).toBe(0); + expect(wrapper.find('FormGroup[label="Occurrences"]').length).toBe(0); + + nonRRuleValuesMatch(); + expect(wrapper.find('select#schedule-frequency').prop('value')).toBe( + 'year' + ); + expect(wrapper.find('input#end-never').prop('checked')).toBe(true); + expect(wrapper.find('input#end-after').prop('checked')).toBe(false); + expect(wrapper.find('input#end-on-date').prop('checked')).toBe(false); + expect(wrapper.find('input#schedule-run-every').prop('value')).toBe(1); + expect(wrapper.find('input#schedule-run-on-day').prop('checked')).toBe( + true + ); + expect(wrapper.find('input#schedule-run-on-the').prop('checked')).toBe( + false + ); + expect( + wrapper.find('select#schedule-run-on-day-month').prop('value') + ).toBe(5); + expect( + wrapper.find('input#schedule-run-on-day-number').prop('value') + ).toBe(6); }); }); }); diff --git a/awx/ui_next/src/components/ScreenHeader/ScreenHeader.test.jsx b/awx/ui_next/src/components/ScreenHeader/ScreenHeader.test.jsx index 99cee2f5d1..a0ba2b35dc 100644 --- a/awx/ui_next/src/components/ScreenHeader/ScreenHeader.test.jsx +++ b/awx/ui_next/src/components/ScreenHeader/ScreenHeader.test.jsx @@ -5,10 +5,6 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import ScreenHeader from './ScreenHeader'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); - describe('', () => { let breadcrumbWrapper; let breadcrumb; @@ -43,7 +39,6 @@ describe('', () => { expect(breadcrumbItem.first().text()).toBe('Foo'); expect(breadcrumbItem.last().text()).toBe('One'); expect(breadcrumbHeading.text()).toBe('Bar'); - breadcrumbWrapper.unmount(); }); test('renders breadcrumb items defined in breadcrumbConfig', () => { @@ -66,7 +61,6 @@ describe('', () => { expect(breadcrumbWrapper.find('BreadcrumbItem')).toHaveLength( crumbLength ); - breadcrumbWrapper.unmount(); }); }); }); diff --git a/awx/ui_next/src/components/Search/AdvancedSearch.test.jsx b/awx/ui_next/src/components/Search/AdvancedSearch.test.jsx index ef5a81c10a..79b63fe462 100644 --- a/awx/ui_next/src/components/Search/AdvancedSearch.test.jsx +++ b/awx/ui_next/src/components/Search/AdvancedSearch.test.jsx @@ -7,7 +7,6 @@ describe('', () => { let wrapper; afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/components/SelectableCard/SelectableCard.test.jsx b/awx/ui_next/src/components/SelectableCard/SelectableCard.test.jsx index a273161f55..75cab3dee6 100644 --- a/awx/ui_next/src/components/SelectableCard/SelectableCard.test.jsx +++ b/awx/ui_next/src/components/SelectableCard/SelectableCard.test.jsx @@ -8,11 +8,10 @@ describe('', () => { test('initially renders without crashing when not selected', () => { wrapper = shallow(); expect(wrapper.length).toBe(1); - wrapper.unmount(); }); + test('initially renders without crashing when selected', () => { wrapper = shallow(); expect(wrapper.length).toBe(1); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/components/SelectedList/DraggableSelectedList.test.jsx b/awx/ui_next/src/components/SelectedList/DraggableSelectedList.test.jsx index c0318069c7..32fcadfc90 100644 --- a/awx/ui_next/src/components/SelectedList/DraggableSelectedList.test.jsx +++ b/awx/ui_next/src/components/SelectedList/DraggableSelectedList.test.jsx @@ -6,8 +6,8 @@ describe('', () => { let wrapper; afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); + test('should render expected rows', () => { const mockSelected = [ { diff --git a/awx/ui_next/src/components/Sort/Sort.jsx b/awx/ui_next/src/components/Sort/Sort.jsx index 341f4bdede..667fa6a476 100644 --- a/awx/ui_next/src/components/Sort/Sort.jsx +++ b/awx/ui_next/src/components/Sort/Sort.jsx @@ -147,4 +147,7 @@ Sort.defaultProps = { onSort: null, }; -export default withRouter(Sort); +export { Sort as _Sort }; +const Wrapped = withRouter(Sort); +Wrapped.displayName = 'Sort'; +export default Wrapped; diff --git a/awx/ui_next/src/components/Sort/Sort.test.jsx b/awx/ui_next/src/components/Sort/Sort.test.jsx index f5b1fe0d2e..5ee3a52a23 100644 --- a/awx/ui_next/src/components/Sort/Sort.test.jsx +++ b/awx/ui_next/src/components/Sort/Sort.test.jsx @@ -1,11 +1,19 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; +import { shallow } from 'enzyme'; import { mountWithContexts, waitForElement, } from '../../../testUtils/enzymeHelpers'; -import Sort from './Sort'; +import Sort, { _Sort as SortUnwrapped } from './Sort'; + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useLocation: () => ({ + pathname: '/organizations', + }), +})); describe('', () => { let sort; @@ -16,7 +24,7 @@ describe('', () => { } }); - test('it triggers the expected callbacks', () => { + test('should trigger onSort callback', () => { const qsConfig = { namespace: 'item', defaultParams: { page: 1, page_size: 5, order_by: 'name' }, @@ -150,71 +158,79 @@ describe('', () => { expect(onSort).toBeCalledWith('bar', 'ascending'); }); - test('It displays correct sort icon', () => { - const forwardNumericIconSelector = 'SortNumericDownIcon'; - const reverseNumericIconSelector = 'SortNumericDownAltIcon'; - const forwardAlphaIconSelector = 'SortAlphaDownIcon'; - const reverseAlphaIconSelector = 'SortAlphaDownAltIcon'; - + test('should display numeric descending icon', () => { const qsConfigNumDown = { namespace: 'item', defaultParams: { page: 1, page_size: 5, order_by: '-id' }, integerFields: ['page', 'page_size', 'id'], }; + const numericColumns = [{ name: 'ID', key: 'id' }]; + + const wrapper = shallow( + + ); + + expect(wrapper.find('SortNumericDownAltIcon')).toHaveLength(1); + }); + + test('should display numeric ascending icon', () => { const qsConfigNumUp = { namespace: 'item', defaultParams: { page: 1, page_size: 5, order_by: 'id' }, integerFields: ['page', 'page_size', 'id'], }; + const numericColumns = [{ name: 'ID', key: 'id' }]; + + const wrapper = shallow( + + ); + + expect(wrapper.find('SortNumericDownIcon')).toHaveLength(1); + }); + + test('should display alphanumeric descending icon', () => { const qsConfigAlphaDown = { namespace: 'item', defaultParams: { page: 1, page_size: 5, order_by: '-name' }, integerFields: ['page', 'page_size'], }; - const qsConfigAlphaUp = { + const alphaColumns = [{ name: 'Name', key: 'name' }]; + + const wrapper = shallow( + + ); + + expect(wrapper.find('SortAlphaDownAltIcon')).toHaveLength(1); + }); + + test('should display alphanumeric ascending icon', () => { + const qsConfigAlphaDown = { namespace: 'item', defaultParams: { page: 1, page_size: 5, order_by: 'name' }, integerFields: ['page', 'page_size'], }; - - const numericColumns = [{ name: 'ID', key: 'id' }]; const alphaColumns = [{ name: 'Name', key: 'name' }]; - const onSort = jest.fn(); - sort = mountWithContexts( - - ); - - const reverseNumericIcon = sort.find(reverseNumericIconSelector); - expect(reverseNumericIcon.length).toBe(1); - - sort = mountWithContexts( - - ); - - const forwardNumericIcon = sort.find(forwardNumericIconSelector); - expect(forwardNumericIcon.length).toBe(1); - - sort = mountWithContexts( - ); - const reverseAlphaIcon = sort.find(reverseAlphaIconSelector); - expect(reverseAlphaIcon.length).toBe(1); - - sort = mountWithContexts( - - ); - - const forwardAlphaIcon = sort.find(forwardAlphaIconSelector); - expect(forwardAlphaIcon.length).toBe(1); + expect(wrapper.find('SortAlphaDownIcon')).toHaveLength(1); }); }); diff --git a/awx/ui_next/src/screens/ActivityStream/ActivityStream.test.jsx b/awx/ui_next/src/screens/ActivityStream/ActivityStream.test.jsx index b5afeef3d6..7db6360583 100644 --- a/awx/ui_next/src/screens/ActivityStream/ActivityStream.test.jsx +++ b/awx/ui_next/src/screens/ActivityStream/ActivityStream.test.jsx @@ -1,25 +1,17 @@ import React from 'react'; - +import { act } from 'react-dom/test-utils'; import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import ActivityStream from './ActivityStream'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); +jest.mock('../../api'); describe('', () => { - let pageWrapper; - - beforeEach(() => { - pageWrapper = mountWithContexts(); - }); - - afterEach(() => { - pageWrapper.unmount(); - }); - - test('initially renders without crashing', () => { + test('initially renders without crashing', async () => { + let pageWrapper; + await act(async () => { + pageWrapper = await mountWithContexts(); + }); expect(pageWrapper.length).toBe(1); }); }); diff --git a/awx/ui_next/src/screens/Application/Application/Application.test.jsx b/awx/ui_next/src/screens/Application/Application/Application.test.jsx index 136c468075..58f29395db 100644 --- a/awx/ui_next/src/screens/Application/Application/Application.test.jsx +++ b/awx/ui_next/src/screens/Application/Application/Application.test.jsx @@ -15,6 +15,7 @@ jest.mock('react-router-dom', () => ({ }), useParams: () => ({ id: 1 }), })); + const options = { data: { actions: { diff --git a/awx/ui_next/src/screens/Application/Applications.test.jsx b/awx/ui_next/src/screens/Application/Applications.test.jsx index 80c5f9a34c..a60292e2a5 100644 --- a/awx/ui_next/src/screens/Application/Applications.test.jsx +++ b/awx/ui_next/src/screens/Application/Applications.test.jsx @@ -1,21 +1,13 @@ import React from 'react'; -import { act } from 'react-dom/test-utils'; import { createMemoryHistory } from 'history'; +import { shallow } from 'enzyme'; import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import Applications from './Applications'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); - describe('', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); - test('renders successfully', () => { wrapper = mountWithContexts(); const pageSections = wrapper.find('PageSection'); @@ -28,22 +20,20 @@ describe('', () => { const history = createMemoryHistory({ initialEntries: ['/applications/add'], }); - wrapper = mountWithContexts(, { + wrapper = shallow(, { context: { router: { history } }, }); expect(wrapper.find('Modal[title="Application information"]').length).toBe( 0 ); - await act(async () => { - wrapper - .find('ApplicationAdd') - .props() - .onSuccessfulAdd({ - name: 'test', - client_id: 'foobar', - client_secret: 'aaaaaaaaaaaaaaaaaaaaaaaaaa', - }); - }); + wrapper + .find('ApplicationAdd') + .props() + .onSuccessfulAdd({ + name: 'test', + client_id: 'foobar', + client_secret: 'aaaaaaaaaaaaaaaaaaaaaaaaaa', + }); wrapper.update(); expect(wrapper.find('Modal[title="Application information"]').length).toBe( 1 diff --git a/awx/ui_next/src/screens/Credential/CredentialAdd/CredentialAdd.test.jsx b/awx/ui_next/src/screens/Credential/CredentialAdd/CredentialAdd.test.jsx index 5318a3b7cf..0807fe6a99 100644 --- a/awx/ui_next/src/screens/Credential/CredentialAdd/CredentialAdd.test.jsx +++ b/awx/ui_next/src/screens/Credential/CredentialAdd/CredentialAdd.test.jsx @@ -196,7 +196,6 @@ describe('', () => { }); wrapper.update(); expect(wrapper.find('ContentError').length).toBe(1); - wrapper.unmount(); }); }); }); diff --git a/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx b/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx index f8acddee12..ff35ce1525 100644 --- a/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx +++ b/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx @@ -350,10 +350,6 @@ describe('', () => { }); }); - afterEach(() => { - wrapper.unmount(); - }); - test('initially renders successfully', async () => { expect(wrapper.find('CredentialEdit').length).toBe(1); }); @@ -489,7 +485,6 @@ describe('', () => { }); wrapper.update(); expect(wrapper.find('ContentError').length).toBe(1); - wrapper.unmount(); }); }); }); diff --git a/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.test.jsx b/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.test.jsx index 35428638f0..0085c056a3 100644 --- a/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.test.jsx +++ b/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.test.jsx @@ -33,7 +33,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('initially renders successfully', () => { diff --git a/awx/ui_next/src/screens/Credential/CredentialList/CredentialListItem.test.jsx b/awx/ui_next/src/screens/Credential/CredentialList/CredentialListItem.test.jsx index 74bb7e6915..8644c11bdf 100644 --- a/awx/ui_next/src/screens/Credential/CredentialList/CredentialListItem.test.jsx +++ b/awx/ui_next/src/screens/Credential/CredentialList/CredentialListItem.test.jsx @@ -10,10 +10,6 @@ jest.mock('../../../api'); describe('', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); - test('edit button shown to users with edit capabilities', () => { wrapper = mountWithContexts( diff --git a/awx/ui_next/src/screens/Credential/Credentials.test.jsx b/awx/ui_next/src/screens/Credential/Credentials.test.jsx index bbef6628b5..f31143106e 100644 --- a/awx/ui_next/src/screens/Credential/Credentials.test.jsx +++ b/awx/ui_next/src/screens/Credential/Credentials.test.jsx @@ -1,60 +1,16 @@ import React from 'react'; -import { createMemoryHistory } from 'history'; -import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; +import { shallow } from 'enzyme'; import Credentials from './Credentials'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); - describe('', () => { - let wrapper; + test('should set breadcrumb config', () => { + const wrapper = shallow(); - afterEach(() => { - wrapper.unmount(); - }); - - test('initially renders successfully', () => { - wrapper = mountWithContexts(); - }); - - test('should display credential list breadcrumb heading', () => { - const history = createMemoryHistory({ - initialEntries: ['/credentials'], + const header = wrapper.find('ScreenHeader'); + expect(header.prop('streamType')).toEqual('credential'); + expect(header.prop('breadcrumbConfig')).toEqual({ + '/credentials': 'Credentials', + '/credentials/add': 'Create New Credential', }); - - wrapper = mountWithContexts(, { - context: { - router: { - history, - route: { - location: history.location, - }, - }, - }, - }); - - expect(wrapper.find('Crumb').length).toBe(0); - expect(wrapper.find('Title').text()).toBe('Credentials'); - }); - - test('should display create new credential breadcrumb heading', () => { - const history = createMemoryHistory({ - initialEntries: ['/credentials/add'], - }); - - wrapper = mountWithContexts(, { - context: { - router: { - history, - route: { - location: history.location, - }, - }, - }, - }); - - expect(wrapper.find('Crumb').length).toBe(2); - expect(wrapper.find('Title').text()).toBe('Create New Credential'); }); }); diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx index 8d77e90b3d..1aa33a9910 100644 --- a/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx +++ b/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx @@ -95,15 +95,15 @@ describe('', () => { ); }); }); - afterAll(() => { - wrapper.unmount(); - }); + test('should display form fields on add properly', async () => { addFieldExpects(); }); + test('should hide Test button initially', () => { expect(wrapper.find('Button[children="Test"]').length).toBe(0); }); + test('should update form values', async () => { // name and description change await act(async () => { @@ -135,6 +135,7 @@ describe('', () => { name: 'organization', }); }); + test('should display cred type subform when scm type select has a value', async () => { await act(async () => { await wrapper @@ -218,6 +219,7 @@ describe('', () => { wrapper.find('textarea#credential-ssh_key_data').prop('value') ).toBe(''); }); + test('should update field when RSA Private Key file uploaded', async () => { await act(async () => { wrapper.find('FileUpload#credential-ssh_key_data').invoke('onChange')( @@ -232,6 +234,7 @@ describe('', () => { '-----BEGIN PRIVATE KEY-----\\nBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\\n-----END PRIVATE KEY-----\\n' ); }); + test('should show error when error thrown parsing JSON', async () => { await act(async () => { await wrapper @@ -295,9 +298,6 @@ describe('', () => { }); describe('Edit', () => { - afterEach(() => { - wrapper.unmount(); - }); test('Initially renders successfully', async () => { await act(async () => { wrapper = mountWithContexts( diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialFormFields/CredentialField.test.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialFormFields/CredentialField.test.jsx index e7bf9e7edb..65a9998357 100644 --- a/awx/ui_next/src/screens/Credential/shared/CredentialFormFields/CredentialField.test.jsx +++ b/awx/ui_next/src/screens/Credential/shared/CredentialFormFields/CredentialField.test.jsx @@ -15,9 +15,6 @@ const fieldOptions = { describe('', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); test('renders correctly without initial value', () => { wrapper = mountWithContexts( ', () => { expect(wrapper.find('KeyIcon').length).toBe(1); expect(wrapper.find('PficonHistoryIcon').length).toBe(0); }); + test('renders correctly with initial value', () => { wrapper = mountWithContexts( ', () => { expect(wrapper.find('KeyIcon').length).toBe(1); expect(wrapper.find('PficonHistoryIcon').length).toBe(1); }); + test('replace/revert button behaves as expected', async () => { wrapper = mountWithContexts( ', () => { let wrapper; describe('No plugin configured', () => { @@ -34,20 +37,23 @@ describe('', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); + test('renders the expected content', () => { expect(wrapper.find('input').length).toBe(1); expect(wrapper.find('KeyIcon').length).toBe(1); expect(wrapper.find('CredentialPluginSelected').length).toBe(0); }); - test('clicking plugin button shows plugin prompt', () => { + + test('clicking plugin button shows plugin prompt', async () => { expect(wrapper.find('CredentialPluginPrompt').length).toBe(0); - wrapper.find('KeyIcon').simulate('click'); + await act(async () => { + wrapper.find('KeyIcon').simulate('click'); + }); + wrapper.update(); expect(wrapper.find('CredentialPluginPrompt').length).toBe(1); }); }); + describe('Plugin already configured', () => { beforeAll(() => { wrapper = mountWithContexts( @@ -78,9 +84,7 @@ describe('', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); + test('renders the expected content', () => { expect(wrapper.find('CredentialPluginPrompt').length).toBe(0); expect(wrapper.find('input').length).toBe(0); diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.test.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.test.jsx index bf4804d11c..6ca8c5869a 100644 --- a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.test.jsx +++ b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.test.jsx @@ -99,10 +99,6 @@ describe('', () => { }); }); - afterAll(() => { - wrapper.unmount(); - }); - test('should render Wizard with all steps', async () => { const wizard = await waitForElement(wrapper, 'Wizard'); const steps = wizard.prop('steps'); @@ -119,15 +115,18 @@ describe('', () => { wrapper.find('Radio').filterWhere(radio => radio.isChecked).length ).toBe(0); }); + test('next button disabled until credential selected', () => { expect(wrapper.find('Button[children="Next"]').prop('isDisabled')).toBe( true ); }); + test('clicking cancel button calls correct function', () => { wrapper.find('Button[children="Cancel"]').simulate('click'); expect(onClose).toHaveBeenCalledTimes(1); }); + test('clicking credential row enables next button', async () => { await waitForElement(wrapper, 'CheckboxListItem', el => el.length > 0); await act(async () => { @@ -207,9 +206,7 @@ describe('', () => { ); }); }); - afterAll(() => { - wrapper.unmount(); - }); + test('should render Wizard with all steps', async () => { const wizard = await waitForElement(wrapper, 'Wizard'); const steps = wizard.prop('steps'); @@ -218,6 +215,7 @@ describe('', () => { expect(steps[0].name).toEqual('Credential'); expect(steps[1].name).toEqual('Metadata'); }); + test('credentials step renders correctly', async () => { await waitForElement(wrapper, 'CheckboxListItem', el => el.length > 0); @@ -233,6 +231,7 @@ describe('', () => { false ); }); + test('metadata step renders correctly', async () => { await act(async () => { wrapper.find('Button[children="Next"]').simulate('click'); @@ -247,6 +246,7 @@ describe('', () => { wrapper.find('input#credential-secret_version').prop('value') ).toBe('9000'); }); + test('clicking Test button makes correct call', async () => { await act(async () => { wrapper.find('Button[children="Test"]').simulate('click'); diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginSelected.test.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginSelected.test.jsx index ce69724904..f11ba45242 100644 --- a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginSelected.test.jsx +++ b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginSelected.test.jsx @@ -16,17 +16,17 @@ describe('', () => { /> ); }); - afterAll(() => { - wrapper.unmount(); - }); + test('renders the expected content', () => { expect(wrapper.find('CredentialChip').length).toBe(1); expect(wrapper.find('KeyIcon').length).toBe(1); }); + test('clearing plugin calls expected function', () => { wrapper.find('CredentialChip button').simulate('click'); expect(onClearPlugin).toBeCalledTimes(1); }); + test('editing plugin calls expected function', () => { wrapper.find('KeyIcon').simulate('click'); expect(onEditPlugin).toBeCalledTimes(1); diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginTestAlert.test.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginTestAlert.test.jsx index 3934c866e6..533e6623e4 100644 --- a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginTestAlert.test.jsx +++ b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginTestAlert.test.jsx @@ -4,9 +4,7 @@ import CredentialPluginTestAlert from './CredentialPluginTestAlert'; describe('', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); + test('renders expected content when test is successful', () => { wrapper = mountWithContexts( ', () => { 'Test passed' ); }); + test('renders expected content when test fails with the expected return string formatting', () => { wrapper = mountWithContexts( ', () => { 'HTTP 404: not found' ); }); + test('renders expected content when test fails without the expected return string formatting', () => { wrapper = mountWithContexts( ', () => { let wrapper; - afterEach(() => wrapper.unmount()); + test('should display metadata fields correctly', async () => { wrapper = mountWithContexts( ', () => { expect(wrapper.find('input#credential-secret_key').length).toBe(1); expect(wrapper.find('input#credential-secret_version').length).toBe(1); }); + test('should make the test request correctly when testing an existing credential', async () => { wrapper = mountWithContexts( ', () => { }, }); }); + test('should make the test request correctly when testing a new credential', async () => { wrapper = mountWithContexts( ', () => { }, }); }); + test('should display the alert after a successful test', async () => { CredentialTypesAPI.test.mockResolvedValue({}); wrapper = mountWithContexts( @@ -148,6 +151,7 @@ describe('', () => { expect(wrapper.find('Alert').length).toBe(1); expect(wrapper.find('Alert').props().variant).toBe('success'); }); + test('should display the alert after a failed test', async () => { CredentialTypesAPI.test.mockRejectedValue({ inputs: `HTTP 404 diff --git a/awx/ui_next/src/screens/CredentialType/CredentialTypes.test.jsx b/awx/ui_next/src/screens/CredentialType/CredentialTypes.test.jsx index bd8eff8e21..e6321a2876 100644 --- a/awx/ui_next/src/screens/CredentialType/CredentialTypes.test.jsx +++ b/awx/ui_next/src/screens/CredentialType/CredentialTypes.test.jsx @@ -4,10 +4,6 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import CredentialTypes from './CredentialTypes'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); - describe('', () => { let pageWrapper; let pageSections; @@ -17,10 +13,6 @@ describe('', () => { pageSections = pageWrapper.find('PageSection'); }); - afterEach(() => { - pageWrapper.unmount(); - }); - test('initially renders without crashing', () => { expect(pageWrapper.length).toBe(1); expect(pageSections.length).toBe(1); diff --git a/awx/ui_next/src/screens/Dashboard/Dashboard.test.jsx b/awx/ui_next/src/screens/Dashboard/Dashboard.test.jsx index a412ee2a48..e58d063313 100644 --- a/awx/ui_next/src/screens/Dashboard/Dashboard.test.jsx +++ b/awx/ui_next/src/screens/Dashboard/Dashboard.test.jsx @@ -7,9 +7,6 @@ import { DashboardAPI } from '../../api'; import Dashboard from './Dashboard'; jest.mock('../../api'); -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); describe('', () => { let pageWrapper; @@ -24,10 +21,6 @@ describe('', () => { }); }); - afterEach(() => { - pageWrapper.unmount(); - }); - test('initially renders without crashing', () => { expect(pageWrapper.length).toBe(1); }); diff --git a/awx/ui_next/src/screens/Dashboard/DashboardGraph.test.jsx b/awx/ui_next/src/screens/Dashboard/DashboardGraph.test.jsx index d25d9d8d56..ca3c37bed8 100644 --- a/awx/ui_next/src/screens/Dashboard/DashboardGraph.test.jsx +++ b/awx/ui_next/src/screens/Dashboard/DashboardGraph.test.jsx @@ -7,9 +7,6 @@ import { DashboardAPI } from '../../api'; import DashboardGraph from './DashboardGraph'; jest.mock('../../api'); -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); describe('', () => { let pageWrapper; @@ -24,9 +21,6 @@ describe('', () => { }); }); - afterEach(() => { - pageWrapper.unmount(); - }); test('renders month-based/all job type chart by default', () => { expect(graphRequest).toHaveBeenCalledWith({ job_type: 'all', diff --git a/awx/ui_next/src/screens/Dashboard/shared/Count.test.jsx b/awx/ui_next/src/screens/Dashboard/shared/Count.test.jsx index 58b67ff9c3..ded7ad951b 100644 --- a/awx/ui_next/src/screens/Dashboard/shared/Count.test.jsx +++ b/awx/ui_next/src/screens/Dashboard/shared/Count.test.jsx @@ -7,10 +7,6 @@ import Count from './Count'; describe('', () => { let pageWrapper; - afterEach(() => { - pageWrapper.unmount(); - }); - test('initially renders without crashing', () => { pageWrapper = mountWithContexts(); expect(pageWrapper.length).toBe(1); diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentAdd/ExecutionEnvironmentAdd.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentAdd/ExecutionEnvironmentAdd.test.jsx index 7d24185997..6616b527b7 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentAdd/ExecutionEnvironmentAdd.test.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentAdd/ExecutionEnvironmentAdd.test.jsx @@ -90,7 +90,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('handleSubmit should call the api and redirect to details page', async () => { diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentEdit/ExecutionEnvironmentEdit.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentEdit/ExecutionEnvironmentEdit.test.jsx index 0477c346b9..eab08b97ab 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentEdit/ExecutionEnvironmentEdit.test.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentEdit/ExecutionEnvironmentEdit.test.jsx @@ -82,7 +82,6 @@ describe('', () => { afterAll(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('handleSubmit should call the api and redirect to details page', async () => { diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironments.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironments.test.jsx index 5ceb36ac93..e036174dc9 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironments.test.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironments.test.jsx @@ -13,10 +13,6 @@ describe('', () => { pageSections = pageWrapper.find('PageSection'); }); - afterEach(() => { - pageWrapper.unmount(); - }); - test('initially renders without crashing', () => { expect(pageWrapper.length).toBe(1); expect(pageSections.length).toBe(1); diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx index dadf06176a..1308eeda7d 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx @@ -145,7 +145,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('Initially renders successfully', () => { diff --git a/awx/ui_next/src/screens/Host/Host.test.jsx b/awx/ui_next/src/screens/Host/Host.test.jsx index a875d8777e..f825405621 100644 --- a/awx/ui_next/src/screens/Host/Host.test.jsx +++ b/awx/ui_next/src/screens/Host/Host.test.jsx @@ -37,10 +37,6 @@ describe('', () => { }); }); - afterEach(() => { - wrapper.unmount(); - }); - test('should render expected tabs', async () => { const expectedTabs = ['Details', 'Facts', 'Groups', 'Completed Jobs']; wrapper.find('RoutedTabs li').forEach((tab, index) => { diff --git a/awx/ui_next/src/screens/Host/HostGroups/HostGroupsList.test.jsx b/awx/ui_next/src/screens/Host/HostGroups/HostGroupsList.test.jsx index 65cf233717..26fee4978d 100644 --- a/awx/ui_next/src/screens/Host/HostGroups/HostGroupsList.test.jsx +++ b/awx/ui_next/src/screens/Host/HostGroups/HostGroupsList.test.jsx @@ -108,7 +108,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('initially renders successfully', () => { diff --git a/awx/ui_next/src/screens/Host/HostList/HostListItem.test.jsx b/awx/ui_next/src/screens/Host/HostList/HostListItem.test.jsx index 15d6db5ab1..3b19991bac 100644 --- a/awx/ui_next/src/screens/Host/HostList/HostListItem.test.jsx +++ b/awx/ui_next/src/screens/Host/HostList/HostListItem.test.jsx @@ -38,10 +38,6 @@ describe('', () => { ); }); - afterEach(() => { - wrapper.unmount(); - }); - test('edit button shown to users with edit capabilities', () => { expect(wrapper.find('PencilAltIcon').exists()).toBeTruthy(); }); diff --git a/awx/ui_next/src/screens/Host/Hosts.test.jsx b/awx/ui_next/src/screens/Host/Hosts.test.jsx index 530e312609..6ca584eda4 100644 --- a/awx/ui_next/src/screens/Host/Hosts.test.jsx +++ b/awx/ui_next/src/screens/Host/Hosts.test.jsx @@ -1,41 +1,28 @@ import React from 'react'; import { createMemoryHistory } from 'history'; +import { shallow } from 'enzyme'; +import { act } from 'react-dom/test-utils'; import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import Hosts from './Hosts'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); +jest.mock('../../api'); describe('', () => { - test('initially renders successfully', () => { - mountWithContexts(); - }); - test('should display a breadcrumb heading', () => { - const history = createMemoryHistory({ - initialEntries: ['/hosts'], - }); - const match = { path: '/hosts', url: '/hosts', isExact: true }; + const wrapper = shallow(); - const wrapper = mountWithContexts(, { - context: { - router: { - history, - route: { - location: history.location, - match, - }, - }, - }, + const header = wrapper.find('ScreenHeader'); + expect(header.prop('streamType')).toEqual('host'); + expect(header.prop('breadcrumbConfig')).toEqual({ + '/hosts': 'Hosts', + '/hosts/add': 'Create New Host', }); - expect(wrapper.find('Title').length).toBe(1); - wrapper.unmount(); }); - test('should render Host component', () => { + test('should render Host component', async () => { + let wrapper; const history = createMemoryHistory({ initialEntries: ['/hosts/1'], }); @@ -46,11 +33,12 @@ describe('', () => { isExact: true, }; - const wrapper = mountWithContexts(, { - context: { router: { history, route: { match } } }, + await act(async () => { + wrapper = await mountWithContexts(, { + context: { router: { history, route: { match } } }, + }); }); expect(wrapper.find('Host').length).toBe(1); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/screens/InstanceGroup/ContainerGroupAdd/ContainerGroupAdd.test.jsx b/awx/ui_next/src/screens/InstanceGroup/ContainerGroupAdd/ContainerGroupAdd.test.jsx index de9782eb58..08c46843ef 100644 --- a/awx/ui_next/src/screens/InstanceGroup/ContainerGroupAdd/ContainerGroupAdd.test.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/ContainerGroupAdd/ContainerGroupAdd.test.jsx @@ -67,7 +67,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('handleSubmit should call the api and redirect to details page', async () => { diff --git a/awx/ui_next/src/screens/InstanceGroup/ContainerGroupEdit/ContainerGroupEdit.test.jsx b/awx/ui_next/src/screens/InstanceGroup/ContainerGroupEdit/ContainerGroupEdit.test.jsx index f2d035c56c..6c8efccffc 100644 --- a/awx/ui_next/src/screens/InstanceGroup/ContainerGroupEdit/ContainerGroupEdit.test.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/ContainerGroupEdit/ContainerGroupEdit.test.jsx @@ -113,7 +113,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('initially renders successfully', async () => { diff --git a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupAdd/InstanceGroupAdd.test.jsx b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupAdd/InstanceGroupAdd.test.jsx index 1fb1d24927..029fe151de 100644 --- a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupAdd/InstanceGroupAdd.test.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupAdd/InstanceGroupAdd.test.jsx @@ -63,7 +63,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('handleSubmit should call the api and redirect to details page', async () => { diff --git a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupEdit/InstanceGroupEdit.test.jsx b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupEdit/InstanceGroupEdit.test.jsx index 9cf57a033d..21b957d150 100644 --- a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupEdit/InstanceGroupEdit.test.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupEdit/InstanceGroupEdit.test.jsx @@ -68,7 +68,6 @@ describe('', () => { afterAll(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('controlplane instance group name can not be updated', async () => { diff --git a/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.test.jsx b/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.test.jsx index db32e7e4eb..43d23a4475 100644 --- a/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.test.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.test.jsx @@ -4,10 +4,6 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import InstanceGroups from './InstanceGroups'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); - describe('', () => { let pageWrapper; let pageSections; @@ -17,10 +13,6 @@ describe('', () => { pageSections = pageWrapper.find('PageSection'); }); - afterEach(() => { - pageWrapper.unmount(); - }); - test('initially renders without crashing', () => { expect(pageWrapper.length).toBe(1); expect(pageSections.length).toBe(1); diff --git a/awx/ui_next/src/screens/InstanceGroup/Instances/InstanceList.test.jsx b/awx/ui_next/src/screens/InstanceGroup/Instances/InstanceList.test.jsx index d2c7edf32d..eee50ae06e 100644 --- a/awx/ui_next/src/screens/InstanceGroup/Instances/InstanceList.test.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/Instances/InstanceList.test.jsx @@ -134,7 +134,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should have data fetched', () => { diff --git a/awx/ui_next/src/screens/InstanceGroup/shared/ContainerGroupForm.test.jsx b/awx/ui_next/src/screens/InstanceGroup/shared/ContainerGroupForm.test.jsx index 29bfbb68ab..bd9859c122 100644 --- a/awx/ui_next/src/screens/InstanceGroup/shared/ContainerGroupForm.test.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/shared/ContainerGroupForm.test.jsx @@ -91,7 +91,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('Initially renders successfully', () => { diff --git a/awx/ui_next/src/screens/InstanceGroup/shared/InstanceGroupForm.test.jsx b/awx/ui_next/src/screens/InstanceGroup/shared/InstanceGroupForm.test.jsx index cb646ed608..8c03388d25 100644 --- a/awx/ui_next/src/screens/InstanceGroup/shared/InstanceGroupForm.test.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/shared/InstanceGroupForm.test.jsx @@ -60,7 +60,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('Initially renders successfully', () => { diff --git a/awx/ui_next/src/screens/Inventory/Inventories.test.jsx b/awx/ui_next/src/screens/Inventory/Inventories.test.jsx index 35e1ee5da0..23b5779e9c 100644 --- a/awx/ui_next/src/screens/Inventory/Inventories.test.jsx +++ b/awx/ui_next/src/screens/Inventory/Inventories.test.jsx @@ -4,10 +4,6 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import Inventories from './Inventories'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); - describe('', () => { let pageWrapper; @@ -15,10 +11,6 @@ describe('', () => { pageWrapper = mountWithContexts(); }); - afterEach(() => { - pageWrapper.unmount(); - }); - test('initially renders without crashing', () => { expect(pageWrapper.length).toBe(1); }); diff --git a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.test.jsx index 0ff7be6cc5..1fa3745996 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.test.jsx @@ -43,7 +43,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('initially renders successfully ', () => { diff --git a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.test.jsx index 85ea79463e..60bccf5507 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.test.jsx @@ -26,10 +26,6 @@ describe('', () => { ); }); - afterEach(() => { - wrapper.unmount(); - }); - test('should display expected row item content', () => { expect(wrapper.find('b').text()).toContain( '.host-000001.group-00000.dummy' diff --git a/awx/ui_next/src/screens/Inventory/InventoryGroups/InventoryGroupsList.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryGroups/InventoryGroupsList.test.jsx index 1dbd23b030..bd449de002 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryGroups/InventoryGroupsList.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryGroups/InventoryGroupsList.test.jsx @@ -96,7 +96,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should fetch groups from api and render them in the list', async () => { @@ -201,7 +200,6 @@ describe(' error handling', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should show content error when api throws error on initial render', async () => { diff --git a/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.test.jsx index e56360df7e..ed3f314123 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.test.jsx @@ -32,9 +32,7 @@ describe('', () => { let history; beforeEach(async () => { - InventoriesAPI.readHostDetail.mockResolvedValue({ - data: { ...mockHost }, - }); + InventoriesAPI.readHostDetail.mockResolvedValue(mockHost); await act(async () => { wrapper = mountWithContexts( @@ -43,10 +41,6 @@ describe('', () => { }); }); - afterEach(() => { - wrapper.unmount(); - }); - test('should render expected tabs', async () => { const expectedTabs = [ 'Back to Hosts', diff --git a/awx/ui_next/src/screens/Inventory/InventoryHostGroups/InventoryHostGroupsList.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryHostGroups/InventoryHostGroupsList.test.jsx index 043618c46a..9f46e5747e 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryHostGroups/InventoryHostGroupsList.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryHostGroups/InventoryHostGroupsList.test.jsx @@ -100,7 +100,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('initially renders successfully', () => { diff --git a/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHostItem.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHostItem.test.jsx index ce047cdaea..d5ab865de0 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHostItem.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHostItem.test.jsx @@ -44,10 +44,6 @@ describe('', () => { ); }); - afterEach(() => { - wrapper.unmount(); - }); - test('edit button shown to users with edit capabilities', () => { expect(wrapper.find('PencilAltIcon').exists()).toBeTruthy(); }); diff --git a/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHosts.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHosts.test.jsx index 4b25da701b..c9b0ec3d75 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHosts.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHosts.test.jsx @@ -3,6 +3,14 @@ import { createMemoryHistory } from 'history'; import { mountWithContexts } from '../../../../testUtils/enzymeHelpers'; import InventoryHosts from './InventoryHosts'; +jest.mock('./InventoryHostList', () => { + const InventoryHostList = () =>
; + return { + __esModule: true, + default: InventoryHostList, + }; +}); + describe('', () => { test('should render inventory host list', () => { const history = createMemoryHistory({ @@ -20,6 +28,5 @@ describe('', () => { }); expect(wrapper.find('InventoryHostList').length).toBe(1); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.test.jsx index 277a53413e..342090588b 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.test.jsx @@ -95,7 +95,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('initially renders successfully ', () => { diff --git a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.test.jsx index bafe3524af..4ab8fb17b1 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.test.jsx @@ -11,21 +11,21 @@ describe('', () => { beforeEach(() => { wrapper = mountWithContexts( - {}} - rowIndex={0} - /> +
+ + {}} + rowIndex={0} + /> + +
); }); - afterEach(() => { - wrapper.unmount(); - }); - test('should display expected row item content', () => { expect(wrapper.find('b').text()).toContain('Group 2 Inventory 0'); }); @@ -36,14 +36,18 @@ describe('', () => { test('edit button hidden from users without edit capabilities', () => { wrapper = mountWithContexts( - {}} - rowIndex={0} - /> + + + {}} + rowIndex={0} + /> + +
); expect(wrapper.find('PencilAltIcon').exists()).toBeFalsy(); }); diff --git a/awx/ui_next/src/screens/Inventory/InventorySourceAdd/InventorySourceAdd.test.jsx b/awx/ui_next/src/screens/Inventory/InventorySourceAdd/InventorySourceAdd.test.jsx index d9d0705b84..cb18aadca9 100644 --- a/awx/ui_next/src/screens/Inventory/InventorySourceAdd/InventorySourceAdd.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventorySourceAdd/InventorySourceAdd.test.jsx @@ -72,7 +72,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('new form displays primary form fields', async () => { diff --git a/awx/ui_next/src/screens/Inventory/InventorySources/InventorySourceListItem.test.jsx b/awx/ui_next/src/screens/Inventory/InventorySources/InventorySourceListItem.test.jsx index 58d815e8a2..deebb67fc6 100644 --- a/awx/ui_next/src/screens/Inventory/InventorySources/InventorySourceListItem.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventorySources/InventorySourceListItem.test.jsx @@ -23,7 +23,6 @@ const source = { describe('', () => { let wrapper; afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Inventory/InventorySources/InventorySources.test.jsx b/awx/ui_next/src/screens/Inventory/InventorySources/InventorySources.test.jsx index dba54734da..ee6b0bd75a 100644 --- a/awx/ui_next/src/screens/Inventory/InventorySources/InventorySources.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventorySources/InventorySources.test.jsx @@ -6,6 +6,5 @@ describe('', () => { test('initially renders without crashing', () => { const wrapper = shallow(); expect(wrapper.length).toBe(1); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx b/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx index ffbcaf7490..21d67ba48a 100644 --- a/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx +++ b/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx @@ -22,7 +22,6 @@ describe('', () => { let wrapper; afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Inventory/SmartInventoryHost/SmartInventoryHost.test.jsx b/awx/ui_next/src/screens/Inventory/SmartInventoryHost/SmartInventoryHost.test.jsx index 0664062847..c7f04f55c2 100644 --- a/awx/ui_next/src/screens/Inventory/SmartInventoryHost/SmartInventoryHost.test.jsx +++ b/awx/ui_next/src/screens/Inventory/SmartInventoryHost/SmartInventoryHost.test.jsx @@ -29,14 +29,11 @@ describe('', () => { let history; afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); test('should render expected tabs', async () => { - InventoriesAPI.readHostDetail.mockResolvedValue({ - data: { ...mockHost }, - }); + InventoriesAPI.readHostDetail.mockResolvedValue(mockHost); await act(async () => { wrapper = mountWithContexts( ', () => { }); test('should show content error when user attempts to navigate to erroneous route', async () => { - InventoriesAPI.readHostDetail.mockResolvedValue({ - data: { ...mockHost }, - }); + InventoriesAPI.readHostDetail.mockResolvedValue(mockHost); history = createMemoryHistory({ initialEntries: ['/inventories/smart_inventory/1/hosts/1/foobar'], }); diff --git a/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHostList.test.jsx b/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHostList.test.jsx index fe9dfa022b..ede08d64f4 100644 --- a/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHostList.test.jsx +++ b/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHostList.test.jsx @@ -37,7 +37,6 @@ describe('', () => { afterAll(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('initially renders successfully', () => { diff --git a/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHostListItem.test.jsx b/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHostListItem.test.jsx index 6c525d13d9..b3d26782ca 100644 --- a/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHostListItem.test.jsx +++ b/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHostListItem.test.jsx @@ -37,10 +37,6 @@ describe('', () => { ); }); - afterEach(() => { - wrapper.unmount(); - }); - test('should render expected row cells', () => { const cells = wrapper.find('Td'); expect(cells).toHaveLength(4); diff --git a/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHosts.test.jsx b/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHosts.test.jsx index 1db767dfe4..d159e8cd7f 100644 --- a/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHosts.test.jsx +++ b/awx/ui_next/src/screens/Inventory/SmartInventoryHosts/SmartInventoryHosts.test.jsx @@ -8,6 +8,13 @@ import { import SmartInventoryHosts from './SmartInventoryHosts'; jest.mock('../../../api'); +jest.mock('./SmartInventoryHostList', () => { + const SmartInventoryHostList = () =>
; + return { + __esModule: true, + default: SmartInventoryHostList, + }; +}); describe('', () => { test('should render smart inventory host list', () => { @@ -26,8 +33,10 @@ describe('', () => { } ); expect(wrapper.find('SmartInventoryHostList').length).toBe(1); + expect(wrapper.find('SmartInventoryHostList').prop('inventory')).toEqual({ + id: 1, + }); jest.clearAllMocks(); - wrapper.unmount(); }); test('should render smart inventory host details', async () => { @@ -51,6 +60,5 @@ describe('', () => { await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); expect(wrapper.find('SmartInventoryHost').length).toBe(1); jest.clearAllMocks(); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSyncButton.test.jsx b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSyncButton.test.jsx index b7c8508d99..011a8816d7 100644 --- a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSyncButton.test.jsx +++ b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSyncButton.test.jsx @@ -21,7 +21,6 @@ describe('', () => { ); }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Job/Job.test.jsx b/awx/ui_next/src/screens/Job/Job.test.jsx index 29b6185688..3a2ee99793 100644 --- a/awx/ui_next/src/screens/Job/Job.test.jsx +++ b/awx/ui_next/src/screens/Job/Job.test.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; -import Job from './Jobs'; +import Job from './Job'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), diff --git a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.test.jsx b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.test.jsx index 7b862b418b..cd39b520ab 100644 --- a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.test.jsx +++ b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.test.jsx @@ -15,8 +15,8 @@ describe('', () => { expect(wrapper.find(`Detail[label="${label}"] dt`).text()).toBe(label); expect(wrapper.find(`Detail[label="${label}"] dd`).text()).toBe(value); } + afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.test.jsx b/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.test.jsx index 3fe04f05a8..d09207ef41 100644 --- a/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.test.jsx +++ b/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.test.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import { shallow } from 'enzyme'; import { mountWithContexts } from '../../../../testUtils/enzymeHelpers'; import HostEventModal from './HostEventModal'; @@ -62,53 +63,53 @@ const jsonValue = `{ ] }`; -let detailsSection; -let jsonSection; -let standardOutSection; -let standardErrorSection; - -const findSections = wrapper => { - detailsSection = wrapper.find('section').at(0); - jsonSection = wrapper.find('section').at(1); - standardOutSection = wrapper.find('section').at(2); - standardErrorSection = wrapper.find('section').at(3); -}; +// let detailsSection; +// let jsonSection; +// let standardOutSection; +// let standardErrorSection; +// +// const findSections = wrapper => { +// detailsSection = wrapper.find('section').at(0); +// jsonSection = wrapper.find('section').at(1); +// standardOutSection = wrapper.find('section').at(2); +// standardErrorSection = wrapper.find('section').at(3); +// }; describe('HostEventModal', () => { test('initially renders successfully', () => { - const wrapper = mountWithContexts( + const wrapper = shallow( {}} /> ); expect(wrapper).toHaveLength(1); }); test('should render all tabs', () => { - const wrapper = mountWithContexts( + const wrapper = shallow( {}} isOpen /> ); - /* eslint-disable react/button-has-type */ - expect(wrapper.find('Tabs TabButton').length).toEqual(4); + expect(wrapper.find('Tabs Tab').length).toEqual(4); }); - test('should show details tab content on mount', () => { - const wrapper = mountWithContexts( + test('should initially show details tab', () => { + const wrapper = shallow( {}} isOpen /> ); - findSections(wrapper); - expect(detailsSection.find('TextList').length).toBe(1); + expect(wrapper.find('Tabs').prop('activeKey')).toEqual(0); + expect(wrapper.find('Detail')).toHaveLength(5); - function assertDetail(label, value) { - expect(wrapper.find(`Detail[label="${label}"] dt`).text()).toBe(label); - expect(wrapper.find(`Detail[label="${label}"] dd`).text()).toBe(value); + function assertDetail(index, label, value) { + const detail = wrapper.find('Detail').at(index); + expect(detail.prop('label')).toEqual(label); + expect(detail.prop('value')).toEqual(value); } - // StatusIcon adds visibly hidden accessibility text " changed " - assertDetail('Host Name', ' changed foo'); - assertDetail('Play', 'all'); - assertDetail('Task', 'command'); - assertDetail('Module', 'command'); - assertDetail('Command', 'free-m'); + const detail = wrapper.find('Detail').first(); + expect(detail.prop('value').props.children).toEqual([null, 'foo']); + assertDetail(1, 'Play', 'all'); + assertDetail(2, 'Task', 'command'); + assertDetail(3, 'Module', 'command'); + assertDetail(4, 'Command', hostEvent.event_data.res.cmd); }); test('should display successful host status icon', () => { @@ -180,34 +181,30 @@ describe('HostEventModal', () => { }); test('should display JSON tab content on tab click', () => { - const wrapper = mountWithContexts( + const wrapper = shallow( {}} isOpen /> ); - findSections(wrapper); - expect(jsonSection.find('EmptyState').length).toBe(1); - wrapper.find('button[aria-label="JSON tab"]').simulate('click'); - findSections(wrapper); - expect(jsonSection.find('CodeEditor').length).toBe(1); + const handleTabClick = wrapper.find('Tabs').prop('onSelect'); + handleTabClick(null, 1); + wrapper.update(); - const codeEditor = jsonSection.find('CodeEditor'); + const codeEditor = wrapper.find('CodeEditor'); expect(codeEditor.prop('mode')).toBe('javascript'); expect(codeEditor.prop('readOnly')).toBe(true); expect(codeEditor.prop('value')).toEqual(jsonValue); }); test('should display Standard Out tab content on tab click', () => { - const wrapper = mountWithContexts( + const wrapper = shallow( {}} isOpen /> ); - findSections(wrapper); - expect(standardOutSection.find('EmptyState').length).toBe(1); - wrapper.find('button[aria-label="Standard out tab"]').simulate('click'); - findSections(wrapper); - expect(standardOutSection.find('CodeEditor').length).toBe(1); + const handleTabClick = wrapper.find('Tabs').prop('onSelect'); + handleTabClick(null, 2); + wrapper.update(); - const codeEditor = standardOutSection.find('CodeEditor'); + const codeEditor = wrapper.find('CodeEditor'); expect(codeEditor.prop('mode')).toBe('javascript'); expect(codeEditor.prop('readOnly')).toBe(true); expect(codeEditor.prop('value')).toEqual(hostEvent.event_data.res.stdout); @@ -222,28 +219,27 @@ describe('HostEventModal', () => { }, }, }; - const wrapper = mountWithContexts( + const wrapper = shallow( {}} isOpen /> ); - findSections(wrapper); - expect(standardErrorSection.find('EmptyState').length).toBe(1); - wrapper.find('button[aria-label="Standard error tab"]').simulate('click'); - findSections(wrapper); - expect(standardErrorSection.find('CodeEditor').length).toBe(1); - const codeEditor = standardErrorSection.find('CodeEditor'); + const handleTabClick = wrapper.find('Tabs').prop('onSelect'); + handleTabClick(null, 3); + wrapper.update(); + + const codeEditor = wrapper.find('CodeEditor'); expect(codeEditor.prop('mode')).toBe('javascript'); expect(codeEditor.prop('readOnly')).toBe(true); expect(codeEditor.prop('value')).toEqual(' '); }); - test('should call onClose when close button is clicked', () => { + test('should pass onClose to Modal', () => { const onClose = jest.fn(); - const wrapper = mountWithContexts( + const wrapper = shallow( ); - wrapper.find('button[aria-label="Close"]').simulate('click'); - expect(onClose).toBeCalled(); + + expect(wrapper.find('Modal').prop('onClose')).toEqual(onClose); }); test('should render standard out of debug task', () => { @@ -258,12 +254,17 @@ describe('HostEventModal', () => { }, }, }; - const wrapper = mountWithContexts( + const wrapper = shallow( {}} isOpen /> ); - wrapper.find('button[aria-label="Standard out tab"]').simulate('click'); - findSections(wrapper); - const codeEditor = standardOutSection.find('CodeEditor'); + + const handleTabClick = wrapper.find('Tabs').prop('onSelect'); + handleTabClick(null, 2); + wrapper.update(); + + const codeEditor = wrapper.find('CodeEditor'); + expect(codeEditor.prop('mode')).toBe('javascript'); + expect(codeEditor.prop('readOnly')).toBe(true); expect(codeEditor.prop('value')).toEqual('foo bar'); }); @@ -277,12 +278,17 @@ describe('HostEventModal', () => { }, }, }; - const wrapper = mountWithContexts( + const wrapper = shallow( {}} isOpen /> ); - wrapper.find('button[aria-label="Standard out tab"]').simulate('click'); - findSections(wrapper); - const codeEditor = standardOutSection.find('CodeEditor'); + + const handleTabClick = wrapper.find('Tabs').prop('onSelect'); + handleTabClick(null, 2); + wrapper.update(); + + const codeEditor = wrapper.find('CodeEditor'); + expect(codeEditor.prop('mode')).toBe('javascript'); + expect(codeEditor.prop('readOnly')).toBe(true); expect(codeEditor.prop('value')).toEqual('baz'); }); }); diff --git a/awx/ui_next/src/screens/Job/JobOutput/shared/HostStatusBar.test.jsx b/awx/ui_next/src/screens/Job/JobOutput/shared/HostStatusBar.test.jsx index 7e4237ba60..623557126f 100644 --- a/awx/ui_next/src/screens/Job/JobOutput/shared/HostStatusBar.test.jsx +++ b/awx/ui_next/src/screens/Job/JobOutput/shared/HostStatusBar.test.jsx @@ -13,10 +13,6 @@ describe('', () => { wrapper = mountWithContexts(); }); - afterEach(() => { - wrapper.unmount(); - }); - test('initially renders without crashing', () => { expect(wrapper.length).toBe(1); }); diff --git a/awx/ui_next/src/screens/Job/JobOutput/shared/OutputToolbar.test.jsx b/awx/ui_next/src/screens/Job/JobOutput/shared/OutputToolbar.test.jsx index 2fa8ca29ae..a1cbc4cafb 100644 --- a/awx/ui_next/src/screens/Job/JobOutput/shared/OutputToolbar.test.jsx +++ b/awx/ui_next/src/screens/Job/JobOutput/shared/OutputToolbar.test.jsx @@ -22,10 +22,6 @@ describe('', () => { ); }); - afterEach(() => { - wrapper.unmount(); - }); - test('initially renders without crashing', () => { expect(wrapper.length).toBe(1); }); diff --git a/awx/ui_next/src/screens/Job/Jobs.test.jsx b/awx/ui_next/src/screens/Job/Jobs.test.jsx index 8463bbd1a7..55685907f8 100644 --- a/awx/ui_next/src/screens/Job/Jobs.test.jsx +++ b/awx/ui_next/src/screens/Job/Jobs.test.jsx @@ -1,37 +1,26 @@ import React from 'react'; -import { createMemoryHistory } from 'history'; - -import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; - +import { shallow } from 'enzyme'; import Jobs from './Jobs'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), + useRouteMatch: () => ({ + path: '/', + }), })); describe('', () => { - test('initially renders successfully', () => { - mountWithContexts(); + test('initially renders successfully', async () => { + const wrapper = shallow(); + expect(wrapper.find('JobList')).toHaveLength(1); }); test('should display a breadcrumb heading', () => { - const history = createMemoryHistory({ - initialEntries: ['/jobs'], + const wrapper = shallow(); + const screenHeader = wrapper.find('ScreenHeader'); + expect(screenHeader).toHaveLength(1); + expect(screenHeader.prop('breadcrumbConfig')).toEqual({ + '/jobs': 'Jobs', }); - const match = { path: '/jobs', url: '/jobs', isExact: true }; - - const wrapper = mountWithContexts(, { - context: { - router: { - history, - route: { - location: history.location, - match, - }, - }, - }, - }); - expect(wrapper.find('Title').length).toBe(1); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.test.jsx b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.test.jsx index eaea9a2162..91c25293f3 100644 --- a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.test.jsx +++ b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.test.jsx @@ -115,7 +115,6 @@ describe('WorkflowOutput', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); delete window.SVGElement.prototype.getBBox; delete window.SVGElement.prototype.getBoundingClientRect; delete window.SVGElement.prototype.height; diff --git a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputToolbar.test.jsx b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputToolbar.test.jsx index b597c35f0d..3f365f9868 100644 --- a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputToolbar.test.jsx +++ b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputToolbar.test.jsx @@ -44,10 +44,6 @@ describe('WorkflowOutputToolbar', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('should render correct toolbar item', () => { shouldFind(`Button[ouiaId="edit-workflow"]`); shouldFind('Button#workflow-output-toggle-legend'); diff --git a/awx/ui_next/src/screens/ManagementJob/ManagementJobs.test.jsx b/awx/ui_next/src/screens/ManagementJob/ManagementJobs.test.jsx index 04e9ed4894..173d343633 100644 --- a/awx/ui_next/src/screens/ManagementJob/ManagementJobs.test.jsx +++ b/awx/ui_next/src/screens/ManagementJob/ManagementJobs.test.jsx @@ -4,10 +4,6 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import ManagementJobs from './ManagementJobs'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); - describe('', () => { let pageWrapper; let pageSections; @@ -17,10 +13,6 @@ describe('', () => { pageSections = pageWrapper.find('PageSection'); }); - afterEach(() => { - pageWrapper.unmount(); - }); - test('renders ok', () => { expect(pageWrapper.length).toBe(1); expect(pageWrapper.find('ScreenHeader').length).toBe(1); diff --git a/awx/ui_next/src/screens/Metrics/Metrics.test.jsx b/awx/ui_next/src/screens/Metrics/Metrics.test.jsx index b317e2e568..33b36e1b10 100644 --- a/awx/ui_next/src/screens/Metrics/Metrics.test.jsx +++ b/awx/ui_next/src/screens/Metrics/Metrics.test.jsx @@ -33,7 +33,6 @@ describe('', () => { }); }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); test('should mound properly', () => { diff --git a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplates.test.jsx b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplates.test.jsx index f8b02d4735..63ac3898be 100644 --- a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplates.test.jsx +++ b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplates.test.jsx @@ -2,26 +2,21 @@ import React from 'react'; import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import NotificationTemplates from './NotificationTemplates'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); +jest.mock('./NotificationTemplateList', () => { + const NotificationTemplateList = () =>
; + return { + __esModule: true, + default: NotificationTemplateList, + }; +}); describe('', () => { - let pageWrapper; - let pageSections; - - beforeEach(() => { - pageWrapper = mountWithContexts(); - pageSections = pageWrapper.find('PageSection'); - }); - - afterEach(() => { - pageWrapper.unmount(); - }); - test('initially renders without crashing', () => { - expect(pageWrapper.length).toBe(1); - expect(pageSections.length).toBe(2); + const wrapper = mountWithContexts(); + + const pageSections = wrapper.find('PageSection'); + expect(pageSections).toHaveLength(1); expect(pageSections.first().props().variant).toBe('light'); + expect(wrapper.find('NotificationTemplateList')).toHaveLength(1); }); }); diff --git a/awx/ui_next/src/screens/Organization/OrganizationDetail/OrganizationDetail.jsx b/awx/ui_next/src/screens/Organization/OrganizationDetail/OrganizationDetail.jsx index 83c2e9dc37..fe6667c56e 100644 --- a/awx/ui_next/src/screens/Organization/OrganizationDetail/OrganizationDetail.jsx +++ b/awx/ui_next/src/screens/Organization/OrganizationDetail/OrganizationDetail.jsx @@ -124,7 +124,7 @@ function OrganizationDetail({ organization }) { value={ {instanceGroups.map(ig => ( - + {ig.name} 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 a1fbdb0831..72c61b9f3b 100644 --- a/awx/ui_next/src/screens/Organization/OrganizationEdit/OrganizationEdit.test.jsx +++ b/awx/ui_next/src/screens/Organization/OrganizationEdit/OrganizationEdit.test.jsx @@ -39,7 +39,9 @@ describe('', () => { description: 'new description', default_environment: null, }; - wrapper.find('OrganizationForm').prop('onSubmit')(updatedOrgData, [], []); + await act(async () => { + wrapper.find('OrganizationForm').prop('onSubmit')(updatedOrgData, [], []); + }); expect(OrganizationsAPI.update).toHaveBeenCalledWith(1, updatedOrgData); }); diff --git a/awx/ui_next/src/screens/Project/Projects.test.jsx b/awx/ui_next/src/screens/Project/Projects.test.jsx index 2e4023c9b9..b7e734700a 100644 --- a/awx/ui_next/src/screens/Project/Projects.test.jsx +++ b/awx/ui_next/src/screens/Project/Projects.test.jsx @@ -1,37 +1,16 @@ import React from 'react'; -import { createMemoryHistory } from 'history'; - -import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; - -import Projects from './Projects'; - -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); +import { shallow } from 'enzyme'; +import { _Projects as Projects } from './Projects'; describe('', () => { - test('initially renders successfully', () => { - mountWithContexts(); - }); - test('should display a breadcrumb heading', () => { - const history = createMemoryHistory({ - initialEntries: ['/projects'], - }); - const match = { path: '/projects', url: '/projects', isExact: true }; + const wrapper = shallow(); - const wrapper = mountWithContexts(, { - context: { - router: { - history, - route: { - location: history.location, - match, - }, - }, - }, + const header = wrapper.find('ScreenHeader'); + expect(header.prop('streamType')).toBe('project'); + expect(header.prop('breadcrumbConfig')).toEqual({ + '/projects': 'Projects', + '/projects/add': 'Create New Project', }); - expect(wrapper.find('Title').length).toBe(1); - wrapper.unmount(); }); }); 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 8c99c0b6c7..b466f49e47 100644 --- a/awx/ui_next/src/screens/Project/shared/ProjectForm.test.jsx +++ b/awx/ui_next/src/screens/Project/shared/ProjectForm.test.jsx @@ -98,7 +98,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Schedule/AllSchedules.test.jsx b/awx/ui_next/src/screens/Schedule/AllSchedules.test.jsx index 9015571e7b..82bedfc97b 100644 --- a/awx/ui_next/src/screens/Schedule/AllSchedules.test.jsx +++ b/awx/ui_next/src/screens/Schedule/AllSchedules.test.jsx @@ -1,39 +1,15 @@ import React from 'react'; -import { createMemoryHistory } from 'history'; -import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; +import { shallow } from 'enzyme'; import AllSchedules from './AllSchedules'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); - describe('', () => { - let wrapper; + test('should set breadcrumb config', () => { + const wrapper = shallow(); - afterEach(() => { - wrapper.unmount(); - }); - - test('initially renders successfully', () => { - wrapper = mountWithContexts(); - }); - - test('should display schedule list breadcrumb heading', () => { - const history = createMemoryHistory({ - initialEntries: ['/schedules'], + const header = wrapper.find('ScreenHeader'); + expect(header.prop('streamType')).toEqual('schedule'); + expect(header.prop('breadcrumbConfig')).toEqual({ + '/schedules': 'Schedules', }); - - wrapper = mountWithContexts(, { - context: { - router: { - history, - route: { - location: history.location, - }, - }, - }, - }); - - expect(wrapper.find('Title').text()).toBe('Schedules'); }); }); diff --git a/awx/ui_next/src/screens/Setting/Jobs/Jobs.test.jsx b/awx/ui_next/src/screens/Setting/Jobs/Jobs.test.jsx index f4dfb40f2a..46174489fb 100644 --- a/awx/ui_next/src/screens/Setting/Jobs/Jobs.test.jsx +++ b/awx/ui_next/src/screens/Setting/Jobs/Jobs.test.jsx @@ -18,7 +18,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/Jobs/JobsDetail/JobsDetail.test.jsx b/awx/ui_next/src/screens/Setting/Jobs/JobsDetail/JobsDetail.test.jsx index 3ebcdbe0f4..844d449910 100644 --- a/awx/ui_next/src/screens/Setting/Jobs/JobsDetail/JobsDetail.test.jsx +++ b/awx/ui_next/src/screens/Setting/Jobs/JobsDetail/JobsDetail.test.jsx @@ -37,7 +37,6 @@ describe('', () => { }); afterAll(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/LDAP/LDAP.test.jsx b/awx/ui_next/src/screens/Setting/LDAP/LDAP.test.jsx index 88ca337048..c2c1d0b741 100644 --- a/awx/ui_next/src/screens/Setting/LDAP/LDAP.test.jsx +++ b/awx/ui_next/src/screens/Setting/LDAP/LDAP.test.jsx @@ -18,7 +18,6 @@ describe('', () => { let wrapper; afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/LDAP/LDAPDetail/LDAPDetail.test.jsx b/awx/ui_next/src/screens/Setting/LDAP/LDAPDetail/LDAPDetail.test.jsx index b326e15204..4843978287 100644 --- a/awx/ui_next/src/screens/Setting/LDAP/LDAPDetail/LDAPDetail.test.jsx +++ b/awx/ui_next/src/screens/Setting/LDAP/LDAPDetail/LDAPDetail.test.jsx @@ -46,7 +46,6 @@ describe('', () => { }); afterAll(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/Logging/Logging.test.jsx b/awx/ui_next/src/screens/Setting/Logging/Logging.test.jsx index 14f7bc5b15..1d8d82a0b6 100644 --- a/awx/ui_next/src/screens/Setting/Logging/Logging.test.jsx +++ b/awx/ui_next/src/screens/Setting/Logging/Logging.test.jsx @@ -39,7 +39,6 @@ describe('', () => { let wrapper; afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/Logging/LoggingDetail/LoggingDetail.test.jsx b/awx/ui_next/src/screens/Setting/Logging/LoggingDetail/LoggingDetail.test.jsx index be2f42f559..98fb6ef4d1 100644 --- a/awx/ui_next/src/screens/Setting/Logging/LoggingDetail/LoggingDetail.test.jsx +++ b/awx/ui_next/src/screens/Setting/Logging/LoggingDetail/LoggingDetail.test.jsx @@ -34,7 +34,6 @@ describe('', () => { }); afterAll(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthentication.test.jsx b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthentication.test.jsx index 6d23d24933..39feca358e 100644 --- a/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthentication.test.jsx +++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthentication.test.jsx @@ -20,7 +20,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystem.test.jsx b/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystem.test.jsx index 341f85573b..334b492154 100644 --- a/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystem.test.jsx +++ b/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystem.test.jsx @@ -20,7 +20,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/RADIUS/RADIUS.test.jsx b/awx/ui_next/src/screens/Setting/RADIUS/RADIUS.test.jsx index 8406a346dd..1d4517ca19 100644 --- a/awx/ui_next/src/screens/Setting/RADIUS/RADIUS.test.jsx +++ b/awx/ui_next/src/screens/Setting/RADIUS/RADIUS.test.jsx @@ -23,7 +23,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/RADIUS/RADIUSEdit/RADIUSEdit.test.jsx b/awx/ui_next/src/screens/Setting/RADIUS/RADIUSEdit/RADIUSEdit.test.jsx index e6764fb858..5b35e43cfd 100644 --- a/awx/ui_next/src/screens/Setting/RADIUS/RADIUSEdit/RADIUSEdit.test.jsx +++ b/awx/ui_next/src/screens/Setting/RADIUS/RADIUSEdit/RADIUSEdit.test.jsx @@ -29,7 +29,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/SAML/SAMLDetail/SAMLDetail.test.jsx b/awx/ui_next/src/screens/Setting/SAML/SAMLDetail/SAMLDetail.test.jsx index a32fca7b7e..8243c85637 100644 --- a/awx/ui_next/src/screens/Setting/SAML/SAMLDetail/SAMLDetail.test.jsx +++ b/awx/ui_next/src/screens/Setting/SAML/SAMLDetail/SAMLDetail.test.jsx @@ -54,7 +54,6 @@ describe('', () => { }); afterAll(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/SettingList.test.jsx b/awx/ui_next/src/screens/Setting/SettingList.test.jsx index 373d6ba5a4..a56f39955d 100644 --- a/awx/ui_next/src/screens/Setting/SettingList.test.jsx +++ b/awx/ui_next/src/screens/Setting/SettingList.test.jsx @@ -7,9 +7,7 @@ describe('', () => { beforeEach(() => { wrapper = mountWithContexts(); }); - afterEach(() => { - wrapper.unmount(); - }); + test('initially renders without crashing', () => { expect(wrapper.length).toBe(1); }); diff --git a/awx/ui_next/src/screens/Setting/Settings.test.jsx b/awx/ui_next/src/screens/Setting/Settings.test.jsx index 3de824527c..0a8a4cd0a9 100644 --- a/awx/ui_next/src/screens/Setting/Settings.test.jsx +++ b/awx/ui_next/src/screens/Setting/Settings.test.jsx @@ -11,10 +11,6 @@ import Settings from './Settings'; jest.mock('../../api'); -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); - describe('', () => { let wrapper; @@ -30,7 +26,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/Subscription/Subscription.test.jsx b/awx/ui_next/src/screens/Setting/Subscription/Subscription.test.jsx index ac46977f96..03ed7fa134 100644 --- a/awx/ui_next/src/screens/Setting/Subscription/Subscription.test.jsx +++ b/awx/ui_next/src/screens/Setting/Subscription/Subscription.test.jsx @@ -24,7 +24,6 @@ describe('', () => { let wrapper; afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); @@ -41,6 +40,8 @@ describe('', () => { config: { license_info: { license_type: 'enterprise', + automated_instances: '1', + automated_since: '1614714228', }, }, }, diff --git a/awx/ui_next/src/screens/Setting/Subscription/SubscriptionDetail/SubscriptionDetail.test.jsx b/awx/ui_next/src/screens/Setting/Subscription/SubscriptionDetail/SubscriptionDetail.test.jsx index fffea57a4f..cd36291b40 100644 --- a/awx/ui_next/src/screens/Setting/Subscription/SubscriptionDetail/SubscriptionDetail.test.jsx +++ b/awx/ui_next/src/screens/Setting/Subscription/SubscriptionDetail/SubscriptionDetail.test.jsx @@ -44,10 +44,6 @@ describe('', () => { }); }); - afterEach(() => { - wrapper.unmount(); - }); - test('initially renders without crashing', () => { expect(wrapper.find('SubscriptionDetail').length).toBe(1); }); @@ -76,7 +72,12 @@ describe('', () => { test('should render edit button for system admin', () => { wrapper = mountWithContexts(, { - context: { ...config, me: { is_superuser: true } }, + context: { + config: { + ...config, + me: { is_superuser: true }, + }, + }, }); expect(wrapper.find('Button[aria-label="edit"]').length).toBe(1); diff --git a/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/AnalyticsStep.test.jsx b/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/AnalyticsStep.test.jsx index 039bea87fb..3812f4119b 100644 --- a/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/AnalyticsStep.test.jsx +++ b/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/AnalyticsStep.test.jsx @@ -29,7 +29,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('initially renders without crashing', async () => { diff --git a/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/EulaStep.test.jsx b/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/EulaStep.test.jsx index ebb2370dd6..889b57a7e1 100644 --- a/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/EulaStep.test.jsx +++ b/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/EulaStep.test.jsx @@ -29,7 +29,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('initially renders without crashing', async () => { diff --git a/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/SubscriptionModal.test.jsx b/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/SubscriptionModal.test.jsx index 3724308409..cb41e0b8a3 100644 --- a/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/SubscriptionModal.test.jsx +++ b/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/SubscriptionModal.test.jsx @@ -54,7 +54,6 @@ describe('', () => { afterAll(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('initially renders without crashing', async () => { diff --git a/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/SubscriptionStep.test.jsx b/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/SubscriptionStep.test.jsx index ab9ad2a289..c3a8bfa314 100644 --- a/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/SubscriptionStep.test.jsx +++ b/awx/ui_next/src/screens/Setting/Subscription/SubscriptionEdit/SubscriptionStep.test.jsx @@ -29,7 +29,6 @@ describe('', () => { afterAll(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('initially renders without crashing', async () => { diff --git a/awx/ui_next/src/screens/Setting/TACACS/TACACS.test.jsx b/awx/ui_next/src/screens/Setting/TACACS/TACACS.test.jsx index ad8fcdbe61..71ebe071e3 100644 --- a/awx/ui_next/src/screens/Setting/TACACS/TACACS.test.jsx +++ b/awx/ui_next/src/screens/Setting/TACACS/TACACS.test.jsx @@ -22,7 +22,6 @@ describe('', () => { let wrapper; afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/TACACS/TACACSDetail/TACACSDetail.test.jsx b/awx/ui_next/src/screens/Setting/TACACS/TACACSDetail/TACACSDetail.test.jsx index da6c5d8ca8..3160a32a68 100644 --- a/awx/ui_next/src/screens/Setting/TACACS/TACACSDetail/TACACSDetail.test.jsx +++ b/awx/ui_next/src/screens/Setting/TACACS/TACACSDetail/TACACSDetail.test.jsx @@ -39,7 +39,6 @@ describe('', () => { }); afterAll(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/TACACS/TACACSEdit/TACACSEdit.test.jsx b/awx/ui_next/src/screens/Setting/TACACS/TACACSEdit/TACACSEdit.test.jsx index 53e76a9e09..469d3e6bd8 100644 --- a/awx/ui_next/src/screens/Setting/TACACS/TACACSEdit/TACACSEdit.test.jsx +++ b/awx/ui_next/src/screens/Setting/TACACS/TACACSEdit/TACACSEdit.test.jsx @@ -31,7 +31,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/UI/UI.test.jsx b/awx/ui_next/src/screens/Setting/UI/UI.test.jsx index fc5aafadcd..8daecacfa8 100644 --- a/awx/ui_next/src/screens/Setting/UI/UI.test.jsx +++ b/awx/ui_next/src/screens/Setting/UI/UI.test.jsx @@ -23,7 +23,6 @@ describe('', () => { let wrapper; afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/UI/UIDetail/UIDetail.test.jsx b/awx/ui_next/src/screens/Setting/UI/UIDetail/UIDetail.test.jsx index 7567f1983b..254a01fb30 100644 --- a/awx/ui_next/src/screens/Setting/UI/UIDetail/UIDetail.test.jsx +++ b/awx/ui_next/src/screens/Setting/UI/UIDetail/UIDetail.test.jsx @@ -37,7 +37,6 @@ describe('', () => { }); afterAll(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/UI/UIEdit/UIEdit.test.jsx b/awx/ui_next/src/screens/Setting/UI/UIEdit/UIEdit.test.jsx index 77ac828d36..22cff7f295 100644 --- a/awx/ui_next/src/screens/Setting/UI/UIEdit/UIEdit.test.jsx +++ b/awx/ui_next/src/screens/Setting/UI/UIEdit/UIEdit.test.jsx @@ -29,7 +29,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Setting/shared/RevertAllAlert.test.jsx b/awx/ui_next/src/screens/Setting/shared/RevertAllAlert.test.jsx index a4ef356b28..dea34403cc 100644 --- a/awx/ui_next/src/screens/Setting/shared/RevertAllAlert.test.jsx +++ b/awx/ui_next/src/screens/Setting/shared/RevertAllAlert.test.jsx @@ -8,6 +8,5 @@ describe('RevertAllAlert', () => { {}} onRevertAll={() => {}} /> ); expect(wrapper).toHaveLength(1); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/screens/Setting/shared/RevertButton.test.jsx b/awx/ui_next/src/screens/Setting/shared/RevertButton.test.jsx index 1af4e7f223..e2801843fe 100644 --- a/awx/ui_next/src/screens/Setting/shared/RevertButton.test.jsx +++ b/awx/ui_next/src/screens/Setting/shared/RevertButton.test.jsx @@ -7,10 +7,6 @@ import RevertButton from './RevertButton'; describe('RevertButton', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); - test('button text should display "Revert"', async () => { wrapper = mountWithContexts( { /> ); expect(wrapper).toHaveLength(1); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/screens/Team/TeamDetail/TeamDetail.test.jsx b/awx/ui_next/src/screens/Team/TeamDetail/TeamDetail.test.jsx index ff456ede0e..f7261ff165 100644 --- a/awx/ui_next/src/screens/Team/TeamDetail/TeamDetail.test.jsx +++ b/awx/ui_next/src/screens/Team/TeamDetail/TeamDetail.test.jsx @@ -33,10 +33,6 @@ describe('', () => { await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); }); - afterEach(() => { - wrapper.unmount(); - }); - test('initially renders successfully', async () => { await waitForElement(wrapper, 'TeamDetail'); }); diff --git a/awx/ui_next/src/screens/Team/TeamRoles/TeamRoleListItem.test.jsx b/awx/ui_next/src/screens/Team/TeamRoles/TeamRoleListItem.test.jsx index 031adcdccc..200cd67672 100644 --- a/awx/ui_next/src/screens/Team/TeamRoles/TeamRoleListItem.test.jsx +++ b/awx/ui_next/src/screens/Team/TeamRoles/TeamRoleListItem.test.jsx @@ -20,10 +20,14 @@ describe('', () => { test('should mount properly', () => { wrapper = mountWithContexts( - + + + + +
); expect(wrapper.length).toBe(1); @@ -31,10 +35,14 @@ describe('', () => { test('should render proper list item data', () => { wrapper = mountWithContexts( - + + + + +
); expect(wrapper.find('Td[dataLabel="Resource Name"]').text()).toBe( 'template delete project' @@ -47,20 +55,28 @@ describe('', () => { test('should render deletable chip', () => { wrapper = mountWithContexts( - + + + + +
); expect(wrapper.find('Chip').prop('isReadOnly')).toBe(false); }); test('should render read only chip', () => { role.summary_fields.user_capabilities.unattach = false; wrapper = mountWithContexts( - + + + + +
); expect(wrapper.find('Chip').prop('isReadOnly')).toBe(true); }); diff --git a/awx/ui_next/src/screens/Team/TeamRoles/TeamRolesList.test.jsx b/awx/ui_next/src/screens/Team/TeamRoles/TeamRolesList.test.jsx index 1ab2d0755a..15e3f72a16 100644 --- a/awx/ui_next/src/screens/Team/TeamRoles/TeamRolesList.test.jsx +++ b/awx/ui_next/src/screens/Team/TeamRoles/TeamRolesList.test.jsx @@ -175,7 +175,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should render properly', async () => { TeamsAPI.readRoles.mockResolvedValue(roles); 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 874a9f5c73..81bbf900e1 100644 --- a/awx/ui_next/src/screens/Team/shared/TeamForm.test.jsx +++ b/awx/ui_next/src/screens/Team/shared/TeamForm.test.jsx @@ -30,7 +30,6 @@ describe('', () => { }; afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx b/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx index 6fcc51714e..f74df4705b 100644 --- a/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx +++ b/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx @@ -222,7 +222,7 @@ function JobTemplateDetail({ template }) { virtualEnvironment={custom_virtualenv} executionEnvironment={summary_fields?.resolved_environment} helpText={t`The execution environment that will be used when launching - this job template. The resolved execution environment can be overridden by + this job template. The resolved execution environment can be overridden by explicitly assigning a different one to this job template.`} /> @@ -290,7 +290,7 @@ function JobTemplateDetail({ template }) { totalChips={summary_fields.credentials.length} > {summary_fields.credentials.map(c => ( - + ))} diff --git a/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.test.jsx b/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.test.jsx index ccd698da10..5acf32b9aa 100644 --- a/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.test.jsx +++ b/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.test.jsx @@ -37,6 +37,7 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); }); + test('should render successfully with missing summary fields', async () => { await act(async () => { wrapper = mountWithContexts( diff --git a/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.test.jsx b/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.test.jsx index fd7683d902..6fee90259d 100644 --- a/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.test.jsx +++ b/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.test.jsx @@ -299,7 +299,10 @@ describe('', () => { let wrapper; await act(async () => { wrapper = mountWithContexts( - + ); }); wrapper.update(); diff --git a/awx/ui_next/src/screens/Template/Survey/MultipleChoiceField.test.jsx b/awx/ui_next/src/screens/Template/Survey/MultipleChoiceField.test.jsx index e5a2cc50d0..bf1e9ee678 100644 --- a/awx/ui_next/src/screens/Template/Survey/MultipleChoiceField.test.jsx +++ b/awx/ui_next/src/screens/Template/Survey/MultipleChoiceField.test.jsx @@ -13,9 +13,9 @@ describe('', () => { ', () => { }); waitForElement(wrapper, 'Form'); }); - afterAll(() => { - wrapper.unmount(); - }); - test('renders successfully', async () => { - expect(wrapper.find('SurveyPreviewModal').length).toBe(1); - }); test('Renders proper fields', async () => { const question1 = wrapper.find('FormGroup[label="Text Question"]'); diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyQuestionEdit.test.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyQuestionEdit.test.jsx index de51ab4e8d..ab7ea59d55 100644 --- a/awx/ui_next/src/screens/Template/Survey/SurveyQuestionEdit.test.jsx +++ b/awx/ui_next/src/screens/Template/Survey/SurveyQuestionEdit.test.jsx @@ -55,10 +55,6 @@ describe('', () => { }); }); - afterEach(() => { - wrapper.unmount(); - }); - test('should render form', () => { expect(wrapper.find('SurveyQuestionForm')).toHaveLength(1); }); @@ -149,8 +145,6 @@ describe('', () => { expect(history.location.pathname).toEqual( '/templates/job_templates/1/survey' ); - - wrapper.unmount(); }); }); }); diff --git a/awx/ui_next/src/screens/Template/Templates.test.jsx b/awx/ui_next/src/screens/Template/Templates.test.jsx index 1b126cda31..0e756c2f0f 100644 --- a/awx/ui_next/src/screens/Template/Templates.test.jsx +++ b/awx/ui_next/src/screens/Template/Templates.test.jsx @@ -3,10 +3,6 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import Templates from './Templates'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); - describe('', () => { let pageWrapper; @@ -14,10 +10,6 @@ describe('', () => { pageWrapper = mountWithContexts(); }); - afterEach(() => { - pageWrapper.unmount(); - }); - test('initially renders without crashing', () => { expect(pageWrapper.length).toBe(1); }); diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplate.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplate.test.jsx index b68d0f6b56..2888b8682d 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplate.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplate.test.jsx @@ -50,10 +50,11 @@ describe('', () => { }, }); }); + afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); + test('initially renders successfully', async () => { await act(async () => { wrapper = mountWithContexts( @@ -61,6 +62,7 @@ describe('', () => { ); }); }); + test('When component mounts API is called and the response is put in state', async () => { await act(async () => { wrapper = mountWithContexts( @@ -70,6 +72,7 @@ describe('', () => { expect(WorkflowJobTemplatesAPI.readDetail).toBeCalled(); expect(OrganizationsAPI.read).toBeCalled(); }); + test('notifications tab shown for admins', async () => { await act(async () => { wrapper = mountWithContexts( @@ -84,6 +87,7 @@ describe('', () => { ); expect(tabs.at(3).text()).toEqual('Notifications'); }); + test('notifications tab hidden with reduced permissions', async () => { OrganizationsAPI.read.mockResolvedValue({ data: { @@ -135,6 +139,7 @@ describe('', () => { await waitForElement(wrapper, 'ContentError', el => el.length === 1); }); + test('should call to get webhook key', async () => { const history = createMemoryHistory({ initialEntries: ['/templates/workflow_job_template/1/foobar'], @@ -161,6 +166,7 @@ describe('', () => { }); expect(WorkflowJobTemplatesAPI.readWebhookKey).toHaveBeenCalled(); }); + test('should not call to get webhook key', async () => { WorkflowJobTemplatesAPI.readWorkflowJobTemplateOptions.mockResolvedValueOnce( { diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateAdd/WorkflowJobTemplateAdd.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateAdd/WorkflowJobTemplateAdd.test.jsx index 0788c74431..33673e7a6c 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateAdd/WorkflowJobTemplateAdd.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateAdd/WorkflowJobTemplateAdd.test.jsx @@ -116,7 +116,7 @@ describe('', () => { description: '', extra_vars: '---', inventory: undefined, - limit: null, + limit: '', organization: undefined, scm_branch: '', webhook_credential: undefined, diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/DeleteAllNodesModal.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/DeleteAllNodesModal.test.jsx index 26c806da26..1924c82092 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/DeleteAllNodesModal.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/DeleteAllNodesModal.test.jsx @@ -15,10 +15,6 @@ describe('DeleteAllNodesModal', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('Delete All button dispatches as expected', () => { wrapper.find('button#confirm-delete-all-nodes').simulate('click'); expect(dispatch).toHaveBeenCalledWith({ diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkDeleteModal.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkDeleteModal.test.jsx index d0cee96579..64103aeb78 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkDeleteModal.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkDeleteModal.test.jsx @@ -32,10 +32,6 @@ describe('LinkDeleteModal', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('Confirm button dispatches as expected', () => { wrapper.find('button#confirm-link-removal').simulate('click'); expect(dispatch).toHaveBeenCalledWith({ diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkModal.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkModal.test.jsx index 787e891306..e98a49f10d 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkModal.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkModal.test.jsx @@ -27,10 +27,6 @@ describe('LinkModal', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('Dropdown defaults to success when adding new link', () => { expect(wrapper.find('AnsibleSelect').prop('value')).toBe('success'); }); @@ -57,6 +53,7 @@ describe('LinkModal', () => { expect(onConfirm).toHaveBeenCalledWith('always'); }); }); + describe('Editing existing link', () => { test('Dropdown defaults to existing link type when editing link', () => { wrapper = mountWithContexts( @@ -79,7 +76,6 @@ describe('LinkModal', () => { ); expect(wrapper.find('AnsibleSelect').prop('value')).toBe('failure'); - wrapper.unmount(); }); }); }); diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeDeleteModal.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeDeleteModal.test.jsx index 880af36e50..0bc87046c2 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeDeleteModal.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeDeleteModal.test.jsx @@ -32,10 +32,6 @@ describe('NodeDeleteModal', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('Mounts successfully', () => { expect(wrapper.length).toBe(1); }); @@ -63,6 +59,7 @@ describe('NodeDeleteModal', () => { }); }); }); + describe('Node without unified job template', () => { test('Mounts successfully', () => { wrapper = mountWithContexts( @@ -79,7 +76,6 @@ describe('NodeDeleteModal', () => { ); expect(wrapper.length).toBe(1); - wrapper.unmount(); }); }); }); diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeNextButton.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeNextButton.test.jsx index 8a254db9b1..4950e12391 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeNextButton.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeNextButton.test.jsx @@ -28,10 +28,6 @@ describe('NodeNextButton', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('Button text matches', () => { expect(wrapper.find('button').text()).toBe(buttonText); }); diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/InventorySourcesList.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/InventorySourcesList.test.jsx index e5237734b0..e6b339500d 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/InventorySourcesList.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/InventorySourcesList.test.jsx @@ -15,9 +15,6 @@ const onUpdateNodeResource = jest.fn(); describe('InventorySourcesList', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); test('Row selected when nodeResource id matches row id and clicking new row makes expected callback', async () => { InventorySourcesAPI.read.mockResolvedValueOnce({ data: { @@ -74,6 +71,7 @@ describe('InventorySourcesList', () => { url: '/api/v2/inventory_sources/2', }); }); + test('Error shown when read() request errors', async () => { InventorySourcesAPI.read.mockRejectedValue(new Error()); await act(async () => { diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/JobTemplatesList.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/JobTemplatesList.test.jsx index b66a6b1c38..8c15382a2c 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/JobTemplatesList.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/JobTemplatesList.test.jsx @@ -17,8 +17,8 @@ describe('JobTemplatesList', () => { let wrapper; afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); + test('Row selected when nodeResource id matches row id and clicking new row makes expected callback', async () => { JobTemplatesAPI.read.mockResolvedValueOnce({ data: { @@ -81,6 +81,7 @@ describe('JobTemplatesList', () => { project: 2, }); }); + test('Error shown when read() request errors', async () => { JobTemplatesAPI.read.mockRejectedValue(new Error()); JobTemplatesAPI.readOptions.mockResolvedValue({ diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/ProjectsList.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/ProjectsList.test.jsx index a6761c999e..7ecf17c088 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/ProjectsList.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/ProjectsList.test.jsx @@ -15,9 +15,7 @@ const onUpdateNodeResource = jest.fn(); describe('ProjectsList', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); + test('Row selected when nodeResource id matches row id and clicking new row makes expected callback', async () => { ProjectsAPI.read.mockResolvedValueOnce({ data: { @@ -70,6 +68,7 @@ describe('ProjectsList', () => { url: '/api/v2/projects/2', }); }); + test('Error shown when read() request errors', async () => { ProjectsAPI.read.mockRejectedValue(new Error()); await act(async () => { diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/WorkflowJobTemplatesList.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/WorkflowJobTemplatesList.test.jsx index a844f56a11..5ad36450ab 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/WorkflowJobTemplatesList.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/WorkflowJobTemplatesList.test.jsx @@ -15,9 +15,7 @@ const onUpdateNodeResource = jest.fn(); describe('WorkflowJobTemplatesList', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); + test('Row selected when nodeResource id matches row id and clicking new row makes expected callback', async () => { WorkflowJobTemplatesAPI.read.mockResolvedValueOnce({ data: { @@ -76,6 +74,7 @@ describe('WorkflowJobTemplatesList', () => { url: '/api/v2/workflow_job_templates/2', }); }); + test('Error shown when read() request errors', async () => { WorkflowJobTemplatesAPI.read.mockRejectedValue(new Error()); await act(async () => { diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeViewModal.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeViewModal.test.jsx index 5abca07f18..e7d7a92f06 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeViewModal.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeViewModal.test.jsx @@ -85,7 +85,6 @@ describe('NodeViewModal', () => { afterAll(() => { jest.resetAllMocks(); - wrapper.unmount(); }); test('should render prompt detail', () => { @@ -151,7 +150,6 @@ describe('NodeViewModal', () => { expect(JobTemplatesAPI.readWebhookKey).not.toHaveBeenCalledWith(); expect(JobTemplatesAPI.readLaunch).toHaveBeenCalledWith(1); expect(JobTemplatesAPI.readInstanceGroups).toHaveBeenCalledTimes(1); - wrapper.unmount(); jest.clearAllMocks(); }); @@ -169,7 +167,6 @@ describe('NodeViewModal', () => { }); waitForLoaded(wrapper); expect(wrapper.find('ContentError').length).toBe(1); - wrapper.unmount(); jest.clearAllMocks(); }); @@ -186,7 +183,6 @@ describe('NodeViewModal', () => { }); waitForLoaded(wrapper); expect(wrapper.find('Button#node-view-edit-button').length).toBe(1); - wrapper.unmount(); jest.clearAllMocks(); }); @@ -203,7 +199,6 @@ describe('NodeViewModal', () => { }); waitForLoaded(wrapper); expect(wrapper.find('Button#node-view-edit-button').length).toBe(0); - wrapper.unmount(); jest.clearAllMocks(); }); }); @@ -237,7 +232,6 @@ describe('NodeViewModal', () => { expect(WorkflowJobTemplatesAPI.readLaunch).not.toHaveBeenCalled(); expect(JobTemplatesAPI.readLaunch).not.toHaveBeenCalled(); expect(JobTemplatesAPI.readInstanceGroups).not.toHaveBeenCalled(); - wrapper.unmount(); jest.clearAllMocks(); }); }); @@ -271,7 +265,6 @@ describe('NodeViewModal', () => { expect(WorkflowJobTemplatesAPI.readLaunch).not.toHaveBeenCalled(); expect(JobTemplatesAPI.readLaunch).not.toHaveBeenCalled(); expect(JobTemplatesAPI.readInstanceGroups).not.toHaveBeenCalled(); - wrapper.unmount(); jest.clearAllMocks(); }); }); @@ -305,7 +298,6 @@ describe('NodeViewModal', () => { expect(WorkflowJobTemplatesAPI.readLaunch).not.toHaveBeenCalled(); expect(JobTemplatesAPI.readLaunch).not.toHaveBeenCalled(); expect(JobTemplatesAPI.readInstanceGroups).not.toHaveBeenCalled(); - wrapper.unmount(); jest.clearAllMocks(); }); }); diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/RunStep.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/RunStep.test.jsx index e8ff15780c..2424d819b6 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/RunStep.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/RunStep.test.jsx @@ -16,10 +16,6 @@ describe('RunStep', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('Default selected card matches default link type when present', () => { expect(wrapper.find('#link-type-success').props().isSelected).toBe(true); expect(wrapper.find('#link-type-failure').props().isSelected).toBe(false); diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/UnsavedChangesModal.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/UnsavedChangesModal.test.jsx index 5695469ce2..92fe520e06 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/UnsavedChangesModal.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/UnsavedChangesModal.test.jsx @@ -17,10 +17,6 @@ describe('UnsavedChangesModal', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('Exit Without Saving button dispatches as expected', () => { wrapper.find('button#confirm-exit-without-saving').simulate('click'); expect(onExit).toHaveBeenCalled(); diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.test.jsx index 8a93cd116d..0ee9209487 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.test.jsx @@ -141,7 +141,6 @@ describe('Visualizer', () => { }); afterAll(() => { - wrapper.unmount(); delete window.SVGElement.prototype.getBBox; delete window.SVGElement.prototype.getBoundingClientRect; delete window.SVGElement.prototype.height; diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerLink.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerLink.test.jsx index ceb16b6b2d..5a8c90ef5d 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerLink.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerLink.test.jsx @@ -62,9 +62,6 @@ describe('VisualizerLink', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); test('Displays action tooltip on hover and updates help text on hover', () => { expect(wrapper.find('WorkflowActionTooltip').length).toBe(0); diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerNode.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerNode.test.jsx index 184b56373b..7a47356557 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerNode.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerNode.test.jsx @@ -73,12 +73,11 @@ describe('VisualizerNode', () => { afterEach(() => { jest.clearAllMocks(); }); - afterAll(() => { - wrapper.unmount(); - }); + test('Displays unified job template name inside node', () => { expect(wrapper.find('NodeResourceName').text()).toBe('Automation JT'); }); + test('Displays action tooltip on hover and updates help text on hover', () => { expect(wrapper.find('WorkflowActionTooltip').length).toBe(0); wrapper.find('g').simulate('mouseenter'); @@ -234,9 +233,7 @@ describe('VisualizerNode', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); + test('Displays correct help text when hovering over node while adding link', () => { expect(wrapper.find('WorkflowActionTooltip').length).toBe(0); wrapper.find('g').simulate('mouseenter'); @@ -248,6 +245,7 @@ describe('VisualizerNode', () => { expect(wrapper.find('WorkflowActionTooltip').length).toBe(0); expect(updateHelpText).toHaveBeenCalledWith(null); }); + test('Dispatches properly when node is clicked', () => { wrapper .find('foreignObject') @@ -259,6 +257,7 @@ describe('VisualizerNode', () => { }); }); }); + describe('Node without unified job template', () => { test('Displays DELETED text inside node when unified job template is missing', () => { const wrapper = mountWithContexts( @@ -279,6 +278,7 @@ describe('VisualizerNode', () => { expect(wrapper.find('NodeResourceName').text()).toBe('DELETED'); }); }); + describe('Node without full unified job template', () => { let wrapper; beforeEach(() => { @@ -336,9 +336,7 @@ describe('VisualizerNode', () => { ); }); - afterEach(() => { - wrapper.unmount(); - }); + test('Attempts to fetch full unified job template on view', async () => { wrapper.find('g').simulate('mouseenter'); await act(async () => { @@ -348,6 +346,7 @@ describe('VisualizerNode', () => { }); expect(JobTemplatesAPI.readDetail).toHaveBeenCalledWith(7); }); + test('Displays error fetching full unified job template', async () => { JobTemplatesAPI.readDetail.mockRejectedValueOnce( new Error({ @@ -371,6 +370,7 @@ describe('VisualizerNode', () => { wrapper.update(); expect(wrapper.find('AlertModal').length).toBe(1); }); + test('Attempts to fetch credentials on view', async () => { JobTemplatesAPI.readDetail.mockResolvedValueOnce({ data: { diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.test.jsx index 3a6035eff1..aa55c4c6f3 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.test.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.test.jsx @@ -54,10 +54,6 @@ describe('VisualizerToolbar', () => { ); }); - afterAll(() => { - wrapper.unmount(); - }); - test('Shows correct number of nodes', () => { // The start node (id=1) and deleted nodes (isDeleted=true) should be ignored expect(wrapper.find('Badge').text()).toBe('1'); diff --git a/awx/ui_next/src/screens/Template/shared/WebhookSubForm.test.jsx b/awx/ui_next/src/screens/Template/shared/WebhookSubForm.test.jsx index 2f8f92da1c..19413fb369 100644 --- a/awx/ui_next/src/screens/Template/shared/WebhookSubForm.test.jsx +++ b/awx/ui_next/src/screens/Template/shared/WebhookSubForm.test.jsx @@ -23,6 +23,7 @@ describe('', () => { webhook_service: 'github', webhook_key: 'webhook key', }; + beforeEach(async () => { history = createMemoryHistory({ initialEntries: ['templates/job_template/51/edit'], @@ -51,13 +52,11 @@ describe('', () => { ); }); }); + afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); - }); - test('mounts properly', () => { - expect(wrapper.length).toBe(1); }); + test('should render initial values properly', () => { waitForElement(wrapper, 'Lookup__ChipHolder', el => el.lenth > 0); expect(wrapper.find('AnsibleSelect').prop('value')).toBe('github'); @@ -73,6 +72,7 @@ describe('', () => { 'Github credential' ); }); + test('should make other credential type available', async () => { CredentialsAPI.read.mockResolvedValue({ data: { results: [{ id: 13, name: 'GitLab credential' }] }, @@ -93,6 +93,7 @@ describe('', () => { .prop('value') ).toBe('A NEW WEBHOOK KEY WILL BE GENERATED ON SAVE.'); }); + test('should have disabled button to update webhook key', async () => { let newWrapper; await act(async () => { diff --git a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx index 23c9329b4e..c71bf1a970 100644 --- a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx +++ b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx @@ -290,7 +290,7 @@ const FormikApp = withFormik({ organization: template?.summary_fields?.organization || null, labels: template.summary_fields?.labels?.results || [], extra_vars: template.extra_vars || '---', - limit: template.limit || null, + limit: template.limit || '', scm_branch: template.scm_branch || '', allow_simultaneous: template.allow_simultaneous || false, webhook_credential: template?.summary_fields?.webhook_credential || null, diff --git a/awx/ui_next/src/screens/User/UserList/UserListItem.test.jsx b/awx/ui_next/src/screens/User/UserList/UserListItem.test.jsx index d41104b1dc..5bc6b4d7ac 100644 --- a/awx/ui_next/src/screens/User/UserList/UserListItem.test.jsx +++ b/awx/ui_next/src/screens/User/UserList/UserListItem.test.jsx @@ -16,10 +16,6 @@ i18n.activate('en'); let wrapper; -afterEach(() => { - wrapper.unmount(); -}); - describe('UserListItem with full permissions', () => { beforeEach(() => { wrapper = mountWithContexts( @@ -39,9 +35,11 @@ describe('UserListItem with full permissions', () => { ); }); + test('initially renders successfully', () => { expect(wrapper.length).toBe(1); }); + test('edit button shown to users with edit capabilities', () => { expect(wrapper.find('PencilAltIcon').exists()).toBeTruthy(); }); diff --git a/awx/ui_next/src/screens/User/UserRoles/UserRolesList.test.jsx b/awx/ui_next/src/screens/User/UserRoles/UserRolesList.test.jsx index a4e11c93f9..367ded2bb0 100644 --- a/awx/ui_next/src/screens/User/UserRoles/UserRolesList.test.jsx +++ b/awx/ui_next/src/screens/User/UserRoles/UserRolesList.test.jsx @@ -94,6 +94,7 @@ const roles = { }; describe('', () => { + let wrapper; beforeEach(() => { UsersAPI.readOptions.mockResolvedValue({ data: { @@ -102,11 +103,11 @@ describe('', () => { }, }); }); - let wrapper; + afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); + test('should render properly', async () => { UsersAPI.readRoles.mockResolvedValue(roles); diff --git a/awx/ui_next/src/screens/User/UserTeams/UserTeamList.test.jsx b/awx/ui_next/src/screens/User/UserTeams/UserTeamList.test.jsx index 5d17e6e7ee..b1b385e4ad 100644 --- a/awx/ui_next/src/screens/User/UserTeams/UserTeamList.test.jsx +++ b/awx/ui_next/src/screens/User/UserTeams/UserTeamList.test.jsx @@ -118,7 +118,6 @@ describe('', () => { afterEach(() => { jest.clearAllMocks(); - wrapper.unmount(); }); test('should load and render teams', async () => { diff --git a/awx/ui_next/src/screens/User/UserTokenAdd/UserTokenAdd.test.jsx b/awx/ui_next/src/screens/User/UserTokenAdd/UserTokenAdd.test.jsx index b74d2712c1..c003b059fd 100644 --- a/awx/ui_next/src/screens/User/UserTokenAdd/UserTokenAdd.test.jsx +++ b/awx/ui_next/src/screens/User/UserTokenAdd/UserTokenAdd.test.jsx @@ -22,9 +22,9 @@ const onSuccessfulAdd = jest.fn(); describe('', () => { afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); + test('handleSubmit should post to api', async () => { await act(async () => { wrapper = mountWithContexts( diff --git a/awx/ui_next/src/screens/User/UserTokens/UserTokens.test.jsx b/awx/ui_next/src/screens/User/UserTokens/UserTokens.test.jsx index 7a66eadca7..16017a5aa5 100644 --- a/awx/ui_next/src/screens/User/UserTokens/UserTokens.test.jsx +++ b/awx/ui_next/src/screens/User/UserTokens/UserTokens.test.jsx @@ -8,10 +8,6 @@ import UserTokens from './UserTokens'; describe('', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); - test('renders successfully', () => { wrapper = mountWithContexts(); expect(wrapper.length).toBe(1); diff --git a/awx/ui_next/src/screens/User/Users.test.jsx b/awx/ui_next/src/screens/User/Users.test.jsx index 146599b762..605aa9b797 100644 --- a/awx/ui_next/src/screens/User/Users.test.jsx +++ b/awx/ui_next/src/screens/User/Users.test.jsx @@ -1,38 +1,23 @@ import React from 'react'; -import { createMemoryHistory } from 'history'; - -import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; - +import { shallow } from 'enzyme'; import Users from './Users'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), + useRouteMatch: () => ({ + path: 'users', + }), })); describe('', () => { - test('initially renders successfully', () => { - const wrapper = mountWithContexts(); - wrapper.unmount(); - }); + test('should set breadcrumbs', () => { + const wrapper = shallow(); - test('should display a breadcrumb heading', () => { - const history = createMemoryHistory({ - initialEntries: ['/users'], + const header = wrapper.find('ScreenHeader'); + expect(header.prop('streamType')).toBe('user'); + expect(header.prop('breadcrumbConfig')).toEqual({ + '/users': 'Users', + '/users/add': 'Create New User', }); - const match = { path: '/users', url: '/users', isExact: true }; - - const wrapper = mountWithContexts(, { - context: { - router: { - history, - route: { - location: history.location, - match, - }, - }, - }, - }); - expect(wrapper.find('Title').length).toBe(1); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/screens/User/shared/UserForm.test.jsx b/awx/ui_next/src/screens/User/shared/UserForm.test.jsx index 69c777bc5b..6e327290a9 100644 --- a/awx/ui_next/src/screens/User/shared/UserForm.test.jsx +++ b/awx/ui_next/src/screens/User/shared/UserForm.test.jsx @@ -27,7 +27,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/User/shared/UserTokenForm.test.jsx b/awx/ui_next/src/screens/User/shared/UserTokenForm.test.jsx index ddfcbd6cb4..9e6f2df703 100644 --- a/awx/ui_next/src/screens/User/shared/UserTokenForm.test.jsx +++ b/awx/ui_next/src/screens/User/shared/UserTokenForm.test.jsx @@ -28,9 +28,7 @@ const applications = { }; describe('', () => { let wrapper; - beforeEach(() => {}); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalList.test.jsx b/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalList.test.jsx index 78a299d1ad..0358252713 100644 --- a/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalList.test.jsx +++ b/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalList.test.jsx @@ -29,7 +29,6 @@ describe('', () => { }); afterEach(() => { - wrapper.unmount(); jest.clearAllMocks(); }); diff --git a/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListItem.test.jsx b/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListItem.test.jsx index e64db9f3cc..06a0f18600 100644 --- a/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListItem.test.jsx +++ b/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListItem.test.jsx @@ -9,9 +9,6 @@ jest.mock('../../../api/models/WorkflowApprovals'); describe('', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); test('should display never expires status', () => { wrapper = mountWithContexts( @@ -28,6 +25,7 @@ describe('', () => { ); expect(wrapper.find('Label[children="Never expires"]').length).toBe(1); }); + test('should display timed out status', () => { wrapper = mountWithContexts( @@ -47,6 +45,7 @@ describe('', () => { ); expect(wrapper.find('Label[children="Timed out"]').length).toBe(1); }); + test('should display canceled status', () => { wrapper = mountWithContexts(
@@ -66,6 +65,7 @@ describe('', () => { ); expect(wrapper.find('Label[children="Canceled"]').length).toBe(1); }); + test('should display approved status', () => { wrapper = mountWithContexts(
@@ -93,6 +93,7 @@ describe('', () => { ); expect(wrapper.find('Label[children="Approved"]').length).toBe(1); }); + test('should display denied status', () => { wrapper = mountWithContexts(
diff --git a/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovals.test.jsx b/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovals.test.jsx index 4e7d81b18f..05b1bf08b2 100644 --- a/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovals.test.jsx +++ b/awx/ui_next/src/screens/WorkflowApproval/WorkflowApprovals.test.jsx @@ -11,10 +11,6 @@ import mockWorkflowApprovals from './data.workflowApprovals.json'; jest.mock('../../api'); -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), -})); - describe('', () => { beforeEach(() => { WorkflowApprovalsAPI.read.mockResolvedValue({ @@ -70,6 +66,5 @@ describe('', () => { await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); expect(wrapper.find('Title').length).toBe(1); - wrapper.unmount(); }); }); diff --git a/awx/ui_next/src/screens/WorkflowApproval/shared/WorkflowApprovalStatus.test.jsx b/awx/ui_next/src/screens/WorkflowApproval/shared/WorkflowApprovalStatus.test.jsx index 41d4965d26..e28ff7638b 100644 --- a/awx/ui_next/src/screens/WorkflowApproval/shared/WorkflowApprovalStatus.test.jsx +++ b/awx/ui_next/src/screens/WorkflowApproval/shared/WorkflowApprovalStatus.test.jsx @@ -8,15 +8,14 @@ const workflowApproval = mockWorkflowApprovals.results[0]; describe('', () => { let wrapper; - afterEach(() => { - wrapper.unmount(); - }); + test('shows no expiration when approval status is pending and no approval_expiration', () => { wrapper = mountWithContexts( ); expect(wrapper.text()).toBe('Never expires'); }); + test('shows expiration date/time when approval status is pending and approval_expiration present', () => { wrapper = mountWithContexts( ', () => { `Expires on ${formatDateString('2020-10-10T17:13:12.067947Z')}` ); }); + test('shows when an approval has timed out', () => { wrapper = mountWithContexts( ', () => { ); expect(wrapper.find('Label').text()).toBe('Timed out'); }); + test('shows when an approval has canceled', () => { wrapper = mountWithContexts( ', () => { ); expect(wrapper.find('Label').text()).toBe('Canceled'); }); + test('shows when an approval has approved', () => { wrapper = mountWithContexts( ', () => { ); expect(wrapper.find('Label').text()).toBe('Approved'); }); + test('shows when an approval has denied', () => { wrapper = mountWithContexts( new Promise(resolve => setImmediate(resolve)); -// this ensures that debug messages don't get logged out to the console -// while tests are running i.e. websocket connect/disconnect +let hasConsoleError = false; +let hasConsoleWarn = false; +const { error, warn } = global.console; + global.console = { ...console, + // this ensures that debug messages don't get logged out to the console + // while tests are running i.e. websocket connect/disconnect debug: jest.fn(), + // fail tests that log errors. + // adapted from https://github.com/facebook/jest/issues/6121#issuecomment-708330601 + error: (...args) => { + hasConsoleError = true; + error(...args); + }, + warn: (...args) => { + hasConsoleWarn = true; + warn(...args); + }, }; +afterEach(() => { + if (hasConsoleError) { + hasConsoleError = false; + throw new Error('Error logged to console'); + } + if (hasConsoleWarn) { + hasConsoleWarn = false; + throw new Error('Warning logged to console'); + } +}); + // This global variable is part of our Content Security Policy framework // and so this mock ensures that we don't encounter a reference error // when running the tests diff --git a/awx/ui_next/src/util/validators.jsx b/awx/ui_next/src/util/validators.jsx index d590935938..c4fbbb93b0 100644 --- a/awx/ui_next/src/util/validators.jsx +++ b/awx/ui_next/src/util/validators.jsx @@ -16,6 +16,7 @@ export function required(message) { return undefined; }; } + export function validateTime() { return value => { const timeRegex = new RegExp( diff --git a/awx/ui_next/src/util/validators.test.js b/awx/ui_next/src/util/validators.test.js index 56dde08e8e..0bbd4d1f19 100644 --- a/awx/ui_next/src/util/validators.test.js +++ b/awx/ui_next/src/util/validators.test.js @@ -1,3 +1,5 @@ +import { i18n } from '@lingui/core'; +import en from '../locales/en/messages'; import { required, minLength, @@ -13,6 +15,12 @@ import { } from './validators'; describe('validators', () => { + beforeAll(() => { + i18n.loadLocaleData({ en: { plurals: en } }); + i18n.load({ en }); + i18n.activate('en'); + }); + test('required returns undefined if value given', () => { expect(required(null)('some value')).toBeUndefined(); expect(required('oops')('some value')).toBeUndefined(); @@ -169,6 +177,7 @@ describe('validators', () => { test('bob has email', () => { expect(requiredEmail()('bob@localhost')).toBeUndefined(); }); + test('validate time validates properly', () => { expect(validateTime()('12:15 PM')).toBeUndefined(); expect(validateTime()('1:15 PM')).toBeUndefined(); diff --git a/awx/ui_next/testUtils/enzymeHelpers.jsx b/awx/ui_next/testUtils/enzymeHelpers.jsx index 18deb63e0e..5d2a944677 100644 --- a/awx/ui_next/testUtils/enzymeHelpers.jsx +++ b/awx/ui_next/testUtils/enzymeHelpers.jsx @@ -61,6 +61,7 @@ const defaultContexts = { session: { isSessionExpired: false, logout: () => {}, + setAuthRedirectTo: () => {}, }, };