diff --git a/awx/ui_next/src/components/Search/Search.js b/awx/ui_next/src/components/Search/Search.js index 6a88c2c502..f38f609e18 100644 --- a/awx/ui_next/src/components/Search/Search.js +++ b/awx/ui_next/src/components/Search/Search.js @@ -3,7 +3,7 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { t } from '@lingui/macro'; -import { withRouter } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; import { Button, ButtonVariant, @@ -36,7 +36,6 @@ function Search({ onReplaceSearch, onRemove, qsConfig, - location, searchableKeys, relatedSearchableKeys, onShowAdvancedSearch, @@ -45,6 +44,7 @@ function Search({ enableNegativeFiltering, enableRelatedFuzzyFiltering, }) { + const location = useLocation(); const [isSearchDropdownOpen, setIsSearchDropdownOpen] = useState(false); const [searchKey, setSearchKey] = useState( (() => { @@ -341,4 +341,4 @@ Search.defaultProps = { enableRelatedFuzzyFiltering: true, }; -export default withRouter(Search); +export default Search; diff --git a/awx/ui_next/src/components/Sort/Sort.js b/awx/ui_next/src/components/Sort/Sort.js index ec093ee5cb..a5edc11d44 100644 --- a/awx/ui_next/src/components/Sort/Sort.js +++ b/awx/ui_next/src/components/Sort/Sort.js @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; -import { useLocation, withRouter } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; import { t } from '@lingui/macro'; import { Button, @@ -147,7 +147,4 @@ Sort.defaultProps = { onSort: null, }; -export { Sort as _Sort }; -const Wrapped = withRouter(Sort); -Wrapped.displayName = 'Sort'; -export default Wrapped; +export default Sort; diff --git a/awx/ui_next/src/components/Sort/Sort.test.js b/awx/ui_next/src/components/Sort/Sort.test.js index 25f04815c8..4e3fe74283 100644 --- a/awx/ui_next/src/components/Sort/Sort.test.js +++ b/awx/ui_next/src/components/Sort/Sort.test.js @@ -6,7 +6,7 @@ import { waitForElement, } from '../../../testUtils/enzymeHelpers'; -import Sort, { _Sort as SortUnwrapped } from './Sort'; +import Sort from './Sort'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), @@ -168,7 +168,7 @@ describe('', () => { const numericColumns = [{ name: 'ID', key: 'id' }]; const wrapper = shallow( - ', () => { const numericColumns = [{ name: 'ID', key: 'id' }]; const wrapper = shallow( - ', () => { const alphaColumns = [{ name: 'Name', key: 'name' }]; const wrapper = shallow( - ', () => { const alphaColumns = [{ name: 'Name', key: 'name' }]; const wrapper = shallow( - ', () => { }) ); - jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useParams: () => ({ - id: 'a', - }), - })); - await act(async () => wrapper.find('SelectableCard[label="Job templates"]').prop('onClick')({ fetchItems: JobTemplatesAPI.read, diff --git a/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.test.js b/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.test.js index 43d23a4475..1a310dbe1b 100644 --- a/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.test.js +++ b/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.test.js @@ -1,21 +1,18 @@ import React from 'react'; - -import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; +import { shallow } from 'enzyme'; import InstanceGroups from './InstanceGroups'; describe('', () => { - let pageWrapper; - let pageSections; + test('should set breadcrumbs', () => { + const wrapper = shallow(); - beforeEach(() => { - pageWrapper = mountWithContexts(); - pageSections = pageWrapper.find('PageSection'); - }); - - test('initially renders without crashing', () => { - expect(pageWrapper.length).toBe(1); - expect(pageSections.length).toBe(1); - expect(pageSections.first().props().variant).toBe('light'); + const header = wrapper.find('ScreenHeader'); + expect(header.prop('streamType')).toEqual('instance_group'); + expect(header.prop('breadcrumbConfig')).toEqual({ + '/instance_groups': 'Instance Groups', + '/instance_groups/add': 'Create new instance group', + '/instance_groups/container_group/add': 'Create new container group', + }); }); }); diff --git a/awx/ui_next/src/screens/Job/Job.js b/awx/ui_next/src/screens/Job/Job.js index dbc7f6305d..0289c8c32c 100644 --- a/awx/ui_next/src/screens/Job/Job.js +++ b/awx/ui_next/src/screens/Job/Job.js @@ -119,7 +119,7 @@ function Job({ setBreadcrumb }) { - {error.response.status === 404 && ( + {error.response?.status === 404 && ( {t`The page you requested could not be found.`}{' '} {t`View all Jobs.`} diff --git a/awx/ui_next/src/screens/Job/Job.test.js b/awx/ui_next/src/screens/Job/Job.test.js index 3a2ee99793..d90839f0bb 100644 --- a/awx/ui_next/src/screens/Job/Job.test.js +++ b/awx/ui_next/src/screens/Job/Job.test.js @@ -1,15 +1,22 @@ import React from 'react'; - +import { act } from 'react-dom/test-utils'; import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import Job from './Job'; +jest.mock('../../api'); jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), + useParams: () => ({ + id: 1, + typeSegment: 'project', + }), })); describe('', () => { - test('initially renders successfully', () => { - mountWithContexts(); + test('initially renders successfully', async () => { + await act(async () => { + await mountWithContexts( {}} />); + }); }); }); diff --git a/awx/ui_next/src/screens/Setting/SettingList.test.js b/awx/ui_next/src/screens/Setting/SettingList.test.js index a56f39955d..af50e50ded 100644 --- a/awx/ui_next/src/screens/Setting/SettingList.test.js +++ b/awx/ui_next/src/screens/Setting/SettingList.test.js @@ -2,6 +2,14 @@ import React from 'react'; import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import SettingList from './SettingList'; +jest.mock('../../api'); +jest.mock('hooks/useBrandName', () => ({ + __esModule: true, + default: () => ({ + current: 'AWX', + }), +})); + describe('', () => { let wrapper; beforeEach(() => { diff --git a/awx/ui_next/src/screens/User/UserOrganizations/UserOrganizations.test.js b/awx/ui_next/src/screens/User/UserOrganizations/UserOrganizations.test.js index 9aa3b4b79f..f62c711e5d 100644 --- a/awx/ui_next/src/screens/User/UserOrganizations/UserOrganizations.test.js +++ b/awx/ui_next/src/screens/User/UserOrganizations/UserOrganizations.test.js @@ -1,39 +1,11 @@ import React from 'react'; -import { Route } from 'react-router-dom'; -import { act } from 'react-dom/test-utils'; -import { createMemoryHistory } from 'history'; -import { - mountWithContexts, - waitForElement, -} from '../../../../testUtils/enzymeHelpers'; +import { shallow } from 'enzyme'; import UserOrganizations from './UserOrganizations'; describe('', () => { - test('userOrganizations mounts successfully', () => { - const history = createMemoryHistory({ - initialEntries: ['/users/1/organizations'], - }); - let wrapper; - act(() => { - wrapper = mountWithContexts( - } - />, - { - context: { - router: { - history, - route: { - location: history.location, - match: { params: { id: 1 } }, - }, - }, - }, - } - ); - }); - waitForElement(wrapper, 'UserOrganizationList'); + test('should render UserOrganizationList', () => { + const wrapper = shallow(); + expect(wrapper.find('UserOrganizationList')).toHaveLength(1); }); }); diff --git a/awx/ui_next/src/screens/User/UserTokens/UserTokens.test.js b/awx/ui_next/src/screens/User/UserTokens/UserTokens.test.js index ef034beb4c..7e2900f82b 100644 --- a/awx/ui_next/src/screens/User/UserTokens/UserTokens.test.js +++ b/awx/ui_next/src/screens/User/UserTokens/UserTokens.test.js @@ -5,14 +5,11 @@ import { mountWithContexts } from '../../../../testUtils/enzymeHelpers'; import UserTokens from './UserTokens'; +jest.mock('../../../api'); + describe('', () => { let wrapper; - test('renders successfully', () => { - wrapper = mountWithContexts(); - expect(wrapper.length).toBe(1); - }); - test('shows Application information modal after successful creation', async () => { const history = createMemoryHistory({ initialEntries: ['/users/1/tokens/add'], diff --git a/awx/ui_next/src/setupTests.js b/awx/ui_next/src/setupTests.js index e919f976fc..81b6f9ce62 100644 --- a/awx/ui_next/src/setupTests.js +++ b/awx/ui_next/src/setupTests.js @@ -16,6 +16,7 @@ export const asyncFlush = () => new Promise((resolve) => setImmediate(resolve)); let hasConsoleError = false; let hasConsoleWarn = false; +let networkRequestUrl = false; const { error, warn } = global.console; global.console = { @@ -26,8 +27,10 @@ global.console = { // fail tests that log errors. // adapted from https://github.com/facebook/jest/issues/6121#issuecomment-708330601 error: (...args) => { - hasConsoleError = true; - error(...args); + if (!networkRequestUrl) { + hasConsoleError = true; + error(...args); + } }, warn: (...args) => { hasConsoleWarn = true; @@ -35,7 +38,39 @@ global.console = { }, }; +const logNetworkRequestError = url => { + networkRequestUrl = url || true; + return { + status: 200, + data: {}, + }; +}; +jest.mock('axios', () => { + return { + create: () => ({ + get: logNetworkRequestError, + post: logNetworkRequestError, + delete: logNetworkRequestError, + put: logNetworkRequestError, + patch: logNetworkRequestError, + options: logNetworkRequestError, + interceptors: { + response: { + use: () => {}, + }, + }, + }), + }; +}); + afterEach(() => { + if (networkRequestUrl) { + const url = networkRequestUrl; + networkRequestUrl = false; + throw new Error( + `Network request was attempted to URL ${url} — API should be stubbed using jest.mock()` + ); + } if (hasConsoleError) { hasConsoleError = false; throw new Error('Error logged to console'); diff --git a/awx/ui_next/src/util/getRelatedResouceDeleteDetails.test.js b/awx/ui_next/src/util/getRelatedResourceDeleteDetails.test.js similarity index 97% rename from awx/ui_next/src/util/getRelatedResouceDeleteDetails.test.js rename to awx/ui_next/src/util/getRelatedResourceDeleteDetails.test.js index 6e77116e35..9eac2731e9 100644 --- a/awx/ui_next/src/util/getRelatedResouceDeleteDetails.test.js +++ b/awx/ui_next/src/util/getRelatedResourceDeleteDetails.test.js @@ -23,6 +23,9 @@ jest.mock('../api/models/WorkflowJobTemplates'); jest.mock('../api/models/WorkflowJobTemplateNodes'); jest.mock('../api/models/CredentialInputSources'); jest.mock('../api/models/ExecutionEnvironments'); +jest.mock('../api/models/Applications'); +jest.mock('../api/models/NotificationTemplates'); +jest.mock('../api/models/Teams'); describe('delete details', () => { afterEach(() => {