From 99356be8623649f21f9022f0d326ea44b0e9fc62 Mon Sep 17 00:00:00 2001 From: John Mitsch Date: Mon, 27 Apr 2020 16:20:34 +0000 Subject: [PATCH] Fixes #29637 - Allow jest test to use foremanReact Jest allows local modules to be specified by path, which allows us to use foremanReact as long as foreman is present in a sibling directory to Katello --- .babelrc.js => babel.config.js | 0 jest.config.js | 64 +++++++++++++++++++ package.json | 29 --------- webpack/__mocks__/foremanReact/common/I18n.js | 5 -- .../__mocks__/foremanReact/common/helpers.js | 21 ------ .../__mocks__/foremanReact/common/keyCodes.js | 8 --- .../index.js} | 1 - .../components/PermissionDenied/index.js | 2 - .../components/common/ModalProgressBar.js | 8 --- .../foremanReact/components/common/table.js | 6 -- .../IntervalMiddleware/IntervalSelectors.js | 6 -- .../middlewares/IntervalMiddleware/index.js | 11 ---- webpack/__mocks__/react-intl/index.js | 3 + .../__mocks__/react-intl/locale-data/en.js | 1 + .../__snapshots__/Table.test.js.snap | 1 + .../RedHatRepositoriesPage.test.js.snap | 8 +++ .../ManageManifestModal.test.js.snap | 5 +- .../SubscriptionsActions.test.js.snap | 6 +- .../SubscriptionsPage.test.js.snap | 8 +++ .../__tests__/SubscriptionsTable.test.js | 1 - .../SubscriptionsToolbar.test.js.snap | 10 +++ .../__snapshots__/TaskActions.test.js.snap | 4 +- webpack/test_setup.js | 3 + 23 files changed, 106 insertions(+), 105 deletions(-) rename .babelrc.js => babel.config.js (100%) create mode 100644 jest.config.js delete mode 100644 webpack/__mocks__/foremanReact/common/I18n.js delete mode 100644 webpack/__mocks__/foremanReact/common/helpers.js delete mode 100644 webpack/__mocks__/foremanReact/common/keyCodes.js rename webpack/__mocks__/foremanReact/components/{BreadcrumbBar.js => BreadcrumbBar/index.js} (98%) delete mode 100644 webpack/__mocks__/foremanReact/components/PermissionDenied/index.js delete mode 100644 webpack/__mocks__/foremanReact/components/common/ModalProgressBar.js delete mode 100644 webpack/__mocks__/foremanReact/components/common/table.js delete mode 100644 webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/IntervalSelectors.js delete mode 100644 webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/index.js create mode 100644 webpack/__mocks__/react-intl/index.js create mode 100644 webpack/__mocks__/react-intl/locale-data/en.js diff --git a/.babelrc.js b/babel.config.js similarity index 100% rename from .babelrc.js rename to babel.config.js diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000000..69909ebac45 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,64 @@ +const path = require('path'); +const fs = require('fs'); + +// Check for foremanReact files provided by Foreman and make available as module in Jest. +const checkForForemanReact = (foremanLocations, foremanReact) => { + const currentDir = process.cwd(); + + let foremanReactFullPath; + foremanLocations.forEach((relativeForemanPath) => { + if (fs.existsSync(path.join(currentDir, relativeForemanPath))) { + const fullPath = path.join(currentDir, relativeForemanPath, foremanReact); + if (fs.existsSync(fullPath)) foremanReactFullPath = fullPath; + } + }); + return foremanReactFullPath; +}; + +const foremanReactRelative = 'webpack/assets/javascripts/react_app'; +const possibleForemanLocations = ['./foreman', '../foreman', '../../foreman']; +const notFound = 'Foreman directory can not be found! These tests require Foreman to be present ' + +'in either a parent, sibling, or child directory relative to Katello and contain the expected ' + +`files in ./${foremanReactRelative}, relative to the Foreman directory.`; + +const foremanReactFull = checkForForemanReact(possibleForemanLocations, foremanReactRelative); +if (!foremanReactFull) throw new Error(notFound); + +// Jest configuration +module.exports = { + collectCoverage: true, + collectCoverageFrom: [ + 'webpack/**/*.js', + '!webpack/**/bundle*', + ], + coverageReporters: [ + 'lcov', + ], + testURL: 'http://localhost/', + setupFiles: [ + 'raf/polyfill', + './webpack/test_setup.js', + ], + setupFilesAfterEnv: [ + './webpack/global_test_setup.js', + ], + testPathIgnorePatterns: [ + '/node_modules/', + '/foreman/', + '/.+fixtures.+', + '/engines', + ], + moduleDirectories: [ + 'node_modules/@theforeman/vendor-core/node_modules', + 'node_modules', + 'webpack/test-utils', + ], + modulePathIgnorePatterns: [ + '/foreman/', + ], + moduleNameMapper: { + '^.+\\.(css|scss)$': 'identity-obj-proxy', + '^foremanReact(.*)$': `${foremanReactFull}$1`, + }, +}; + diff --git a/package.json b/package.json index 2ad44eaad70..8981540f80c 100644 --- a/package.json +++ b/package.json @@ -61,34 +61,5 @@ "ngreact": "^0.5.0", "query-string": "^6.1.0", "react-bootstrap": "^0.32.1" - }, - "jest": { - "collectCoverage": true, - "collectCoverageFrom": [ - "webpack/**/*.js", - "!webpack/**/bundle*" - ], - "coverageReporters": [ - "lcov" - ], - "testURL": "http://localhost/", - "setupFiles": [ - "raf/polyfill", - "./webpack/test_setup.js" - ], - "setupTestFrameworkScriptFile": "./webpack/global_test_setup.js", - "testPathIgnorePatterns": [ - "/node_modules/", - "/foreman/", - "/.+fixtures.+", - "/engines" - ], - "moduleDirectories": [ - "node_modules/@theforeman/vendor-core/node_modules", - "node_modules" - ], - "moduleNameMapper": { - "^.+\\.(css|scss)$": "identity-obj-proxy" - } } } diff --git a/webpack/__mocks__/foremanReact/common/I18n.js b/webpack/__mocks__/foremanReact/common/I18n.js deleted file mode 100644 index 5a9fb5c253d..00000000000 --- a/webpack/__mocks__/foremanReact/common/I18n.js +++ /dev/null @@ -1,5 +0,0 @@ -export { sprintf } from 'jed'; - -export const translate = s => s; - -export const ngettext = s => s; diff --git a/webpack/__mocks__/foremanReact/common/helpers.js b/webpack/__mocks__/foremanReact/common/helpers.js deleted file mode 100644 index dce2847566a..00000000000 --- a/webpack/__mocks__/foremanReact/common/helpers.js +++ /dev/null @@ -1,21 +0,0 @@ -import { snakeCase, camelCase } from 'lodash'; - -export const stringIsPositiveNumber = (value) => { - const reg = new RegExp('^[0-9]+$'); - return reg.test(value); -}; -const propsToCase = (casingFn, errorMsg, ob) => { - if (typeof ob !== 'object') throw Error(errorMsg); - - return Object.keys(ob).reduce((memo, key) => { - // eslint-disable-next-line no-param-reassign - memo[casingFn(key)] = ob[key]; - return memo; - }, {}); -}; - -export const propsToSnakeCase = ob => - propsToCase(snakeCase, 'propsToSnakeCase only takes objects', ob); - -export const propsToCamelCase = ob => - propsToCase(camelCase, 'propsToCamelCase only takes objects', ob); diff --git a/webpack/__mocks__/foremanReact/common/keyCodes.js b/webpack/__mocks__/foremanReact/common/keyCodes.js deleted file mode 100644 index 558fcfdb6de..00000000000 --- a/webpack/__mocks__/foremanReact/common/keyCodes.js +++ /dev/null @@ -1,8 +0,0 @@ -export const KEYCODES = { - ENTER: 13, - FWD_SLASH: 47, - BACK_SLASH: 46, - ESC: 27, - TAB_KEY: 9, -}; -export default { KEYCODES }; diff --git a/webpack/__mocks__/foremanReact/components/BreadcrumbBar.js b/webpack/__mocks__/foremanReact/components/BreadcrumbBar/index.js similarity index 98% rename from webpack/__mocks__/foremanReact/components/BreadcrumbBar.js rename to webpack/__mocks__/foremanReact/components/BreadcrumbBar/index.js index 3b3c7863ecb..ce091f694a0 100644 --- a/webpack/__mocks__/foremanReact/components/BreadcrumbBar.js +++ b/webpack/__mocks__/foremanReact/components/BreadcrumbBar/index.js @@ -1,3 +1,2 @@ - const BreadcrumbsBar = () => jest.fn(); export default BreadcrumbsBar; diff --git a/webpack/__mocks__/foremanReact/components/PermissionDenied/index.js b/webpack/__mocks__/foremanReact/components/PermissionDenied/index.js deleted file mode 100644 index 72936a2450c..00000000000 --- a/webpack/__mocks__/foremanReact/components/PermissionDenied/index.js +++ /dev/null @@ -1,2 +0,0 @@ -const PermissionDenied = () => jest.fn(); -export default PermissionDenied; diff --git a/webpack/__mocks__/foremanReact/components/common/ModalProgressBar.js b/webpack/__mocks__/foremanReact/components/common/ModalProgressBar.js deleted file mode 100644 index cfc5e28b9c6..00000000000 --- a/webpack/__mocks__/foremanReact/components/common/ModalProgressBar.js +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react'; - -const ModalProgressBar = props => ( -
- {`ModalProgressBar: ${JSON.stringify(props)}`} -
-); -export default ModalProgressBar; diff --git a/webpack/__mocks__/foremanReact/components/common/table.js b/webpack/__mocks__/foremanReact/components/common/table.js deleted file mode 100644 index 783531beeb8..00000000000 --- a/webpack/__mocks__/foremanReact/components/common/table.js +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react'; - -export const headerFormat = value => {value}; -export const cellFormat = value => {value}; -const Table = () => ; -export default Table; diff --git a/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/IntervalSelectors.js b/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/IntervalSelectors.js deleted file mode 100644 index 8cb90a68d3a..00000000000 --- a/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/IntervalSelectors.js +++ /dev/null @@ -1,6 +0,0 @@ -export const selectDoesIntervalExist = (state, key) => { - const intervals = state.intervals || {}; - return !!intervals[key]; -}; - -export default selectDoesIntervalExist; diff --git a/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/index.js b/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/index.js deleted file mode 100644 index bceaa95916a..00000000000 --- a/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/index.js +++ /dev/null @@ -1,11 +0,0 @@ -export const withInterval = (action, interval = 1000) => ({ - ...action, - interval, -}); - -export const stopInterval = key => ({ - type: 'STOP_INTERVAL', - key, -}); - -export default stopInterval; diff --git a/webpack/__mocks__/react-intl/index.js b/webpack/__mocks__/react-intl/index.js new file mode 100644 index 00000000000..71efa7aed59 --- /dev/null +++ b/webpack/__mocks__/react-intl/index.js @@ -0,0 +1,3 @@ +export const addLocaleData = jest.fn(); +export const FormattedRelative = jest.fn(); +export const intlShape = jest.fn(); diff --git a/webpack/__mocks__/react-intl/locale-data/en.js b/webpack/__mocks__/react-intl/locale-data/en.js new file mode 100644 index 00000000000..ff8b4c56321 --- /dev/null +++ b/webpack/__mocks__/react-intl/locale-data/en.js @@ -0,0 +1 @@ +export default {}; diff --git a/webpack/move_to_foreman/components/common/table/components/__snapshots__/Table.test.js.snap b/webpack/move_to_foreman/components/common/table/components/__snapshots__/Table.test.js.snap index a07009daeb6..944dc97e55b 100644 --- a/webpack/move_to_foreman/components/common/table/components/__snapshots__/Table.test.js.snap +++ b/webpack/move_to_foreman/components/common/table/components/__snapshots__/Table.test.js.snap @@ -139,6 +139,7 @@ exports[`Table renders Table with pagination 1`] = ` when permissions are missing 1`] = ` `; diff --git a/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap b/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap index b0104e25bb9..ddd76a71e59 100644 --- a/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +++ b/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap @@ -83,6 +83,7 @@ exports[`manage manifest modal should render 1`] = ` "header": "There is no Manifest History to display.", } } + onPaginationChange={[Function]} rows={ Array [ Object { @@ -141,7 +142,7 @@ exports[`manage manifest modal should render 1`] = ` - + - + `; diff --git a/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap b/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap index fb4e46b7cc0..7484152923d 100644 --- a/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +++ b/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap @@ -61,7 +61,7 @@ Array [ "type": "SUBSCRIPTIONS_RESET_TASKS", }, Object { - "interval": 1000, + "interval": 5000, "key": "SUBSCRIPTIONS_TASK_SEARCH", "params": Object { "search": "organization_id=1 and result=pending and label=Actions::Katello::Organization::ManifestImport or Actions::Katello::Organization::ManifestRefresh or Actions::Katello::Organization::ManifestDelete or Actions::Katello::UpstreamSubscriptions::BindEntitlements or Actions::Katello::UpstreamSubscriptions::UpdateEntitlement or Actions::Katello::UpstreamSubscriptions::RemoveEntitlements or Actions::Katello::UpstreamSubscriptions::UpdateEntitlements", @@ -82,7 +82,7 @@ Array [ "type": "STOP_INTERVAL", }, Object { - "interval": 1000, + "interval": 5000, "key": "SUBSCRIPTIONS_POLL_TASK", "type": "API_GET", "url": "/foreman_tasks/api/tasks/eb1b6271-8a69-4d98-84fc-bea06ddcc166", @@ -92,7 +92,7 @@ Array [ exports[`subscription actions pollTasks can search tasks 1`] = ` Object { - "interval": 1000, + "interval": 5000, "key": "SUBSCRIPTIONS_TASK_SEARCH", "params": Object { "search": "organization_id=1 and result=pending and label=Actions::Katello::Organization::ManifestImport or Actions::Katello::Organization::ManifestRefresh or Actions::Katello::Organization::ManifestDelete or Actions::Katello::UpstreamSubscriptions::BindEntitlements or Actions::Katello::UpstreamSubscriptions::UpdateEntitlement or Actions::Katello::UpstreamSubscriptions::RemoveEntitlements or Actions::Katello::UpstreamSubscriptions::UpdateEntitlements", diff --git a/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap b/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap index 37de9887e15..bc363dbd620 100644 --- a/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +++ b/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap @@ -2,11 +2,19 @@ exports[`subscriptions page should render when permissions are missing 1`] = ` `; diff --git a/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js b/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js index d4c802827bb..30313a1e361 100644 --- a/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +++ b/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js @@ -7,7 +7,6 @@ import SubscriptionsTable from '../SubscriptionsTable'; import { successState, loadingState, emptyState, groupedSubscriptions } from '../../../__tests__/subscriptions.fixtures'; import { loadSubscriptions, updateQuantity } from '../../../SubscriptionActions'; -jest.mock('foremanReact/components/Pagination/PaginationWrapper'); jest.useFakeTimers(); const tableColumns = [ diff --git a/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/__snapshots__/SubscriptionsToolbar.test.js.snap b/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/__snapshots__/SubscriptionsToolbar.test.js.snap index c70116d884d..01eb53bdfc5 100644 --- a/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/__snapshots__/SubscriptionsToolbar.test.js.snap +++ b/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/__snapshots__/SubscriptionsToolbar.test.js.snap @@ -53,6 +53,7 @@ exports[`SubscriptionsToolbar renders SubscriptionsToolbar 1`] = ` bsClass="btn" bsStyle="default" disabled={false} + onClick={[Function]} > Manage Manifest @@ -62,6 +63,7 @@ exports[`SubscriptionsToolbar renders SubscriptionsToolbar 1`] = ` bsClass="btn" bsStyle="default" disabled={false} + onClick={[Function]} > Export CSV @@ -125,6 +127,7 @@ exports[`SubscriptionsToolbar renders SubscriptionsToolbar with disabled add but bsClass="btn" bsStyle="default" disabled={false} + onClick={[Function]} > Manage Manifest @@ -134,6 +137,7 @@ exports[`SubscriptionsToolbar renders SubscriptionsToolbar with disabled add but bsClass="btn" bsStyle="default" disabled={false} + onClick={[Function]} > Export CSV @@ -197,6 +201,7 @@ exports[`SubscriptionsToolbar renders SubscriptionsToolbar with disabled delete bsClass="btn" bsStyle="default" disabled={false} + onClick={[Function]} > Manage Manifest @@ -206,6 +211,7 @@ exports[`SubscriptionsToolbar renders SubscriptionsToolbar with disabled delete bsClass="btn" bsStyle="default" disabled={false} + onClick={[Function]} > Export CSV @@ -269,6 +275,7 @@ exports[`SubscriptionsToolbar renders SubscriptionsToolbar with disabled manifes bsClass="btn" bsStyle="default" disabled={false} + onClick={[Function]} > Manage Manifest @@ -278,6 +285,7 @@ exports[`SubscriptionsToolbar renders SubscriptionsToolbar with disabled manifes bsClass="btn" bsStyle="default" disabled={false} + onClick={[Function]} > Export CSV @@ -359,6 +367,7 @@ exports[`SubscriptionsToolbar renders SubscriptionsToolbar with table columns 1` bsClass="btn" bsStyle="default" disabled={false} + onClick={[Function]} > Manage Manifest @@ -368,6 +377,7 @@ exports[`SubscriptionsToolbar renders SubscriptionsToolbar with table columns 1` bsClass="btn" bsStyle="default" disabled={false} + onClick={[Function]} > Export CSV diff --git a/webpack/scenes/Tasks/__tests__/__snapshots__/TaskActions.test.js.snap b/webpack/scenes/Tasks/__tests__/__snapshots__/TaskActions.test.js.snap index 12e14c80976..d5b93d8d78c 100644 --- a/webpack/scenes/Tasks/__tests__/__snapshots__/TaskActions.test.js.snap +++ b/webpack/scenes/Tasks/__tests__/__snapshots__/TaskActions.test.js.snap @@ -2,7 +2,7 @@ exports[`task actions can poll a task 1`] = ` Object { - "interval": 1000, + "interval": 5000, "key": "TEST_POLL_TASK", "type": "API_GET", "url": "/foreman_tasks/api/tasks/12345", @@ -11,7 +11,7 @@ Object { exports[`task actions can search tasks 1`] = ` Object { - "interval": 1000, + "interval": 5000, "key": "TEST_TASK_SEARCH", "params": Object { "search": "", diff --git a/webpack/test_setup.js b/webpack/test_setup.js index 59ac0ba8c92..0d2dfea0416 100644 --- a/webpack/test_setup.js +++ b/webpack/test_setup.js @@ -12,3 +12,6 @@ configure({ adapter: new Adapter() }); // Mocking translation function global.__ = text => text; // eslint-disable-line Services.orgId = () => 1; + +// Mocking locales to prevent unnecessary fallback messages +window.locales = { en: { domain: 'app', locale_data: { app: { '': {} } } } };