From e1649328003290a0a1200c50f338d579c32064f3 Mon Sep 17 00:00:00 2001 From: MariaAga Date: Tue, 9 Jul 2024 12:11:38 +0100 Subject: [PATCH 1/7] Fixes #37636 - remove "@theforeman/test" imports --- webpack/assets/javascripts/react_app/common/HOC.test.js | 2 +- .../react_app/common/IntegrationTestHelper.js | 2 +- .../assets/javascripts/react_app/common/testHelpers.js | 5 ++--- .../BreadcrumbBar/__tests__/BreadcrumbBar.test.js | 1 - .../react_app/components/ChartBox/ChartBox.test.js | 2 +- .../components/ConfigReports/ConfigReports.test.js | 2 +- .../ConfigReports/DiffModal/__tests__/DiffModal.test.js | 2 +- .../components/ConfirmModal/integration.test.js | 2 +- .../react_app/components/Editor/__tests__/Editor.test.js | 2 +- .../Editor/components/__tests__/EditorNavbar.test.js | 2 +- .../Editor/components/__tests__/EditorOptions.test.js | 2 +- .../ExternalLogout/__tests__/ExternalLogout.test.js | 2 +- .../subcomponents/SubmitOrCancel/SubmitOrCancel.test.js | 2 +- .../subcomponents/__tests__/ForemanModalFooter.test.js | 2 +- .../subcomponents/__tests__/ForemanModalHeader.test.js | 2 +- .../components/ImpersonateIcon/ImpersonateIcon.test.js | 2 +- .../Layout/components/Toolbar/HeaderToolbar.test.js | 2 +- .../__tests__/MemoryAllocationInput.test.js | 2 +- .../components/PF4/Bookmarks/__tests__/Bookmarks.test.js | 1 - .../PF4/DocumentationLink/DocumentationLink.test.js | 2 +- .../PasswordStrength/__tests__/PasswordStrength.test.js | 2 +- .../__tests__/SettingRecordsReducer.test.js | 2 +- .../__tests__/SettingRecordsSelectors.test.js | 2 +- .../SettingUpdateModal/SettingUpdateModal.test.js | 2 +- .../components/SettingValueField.test.js | 2 +- .../SettingsTable/__tests__/SettingsTable.test.js | 2 +- .../components/__tests__/SettingCell.test.js | 2 +- .../components/__tests__/SettingName.test.js | 2 +- .../components/ToastsList/__tests__/integration.test.js | 2 +- .../common/ActionButtons/ActionButtons.test.js | 2 +- .../react_app/components/common/Alert/AlertBody.test.js | 2 +- .../react_app/components/common/Alert/AlertLink.test.js | 2 +- .../common/ComponentWrapper/ComponentWrapper.test.js | 2 +- .../DateTimePicker/DateComponents/DateInput.test.js | 2 +- .../common/DateTimePicker/DateComponents/Day.test.js | 2 +- .../DateTimePicker/DateComponents/DecadeView.test.js | 2 +- .../DateComponents/DecadeViewHeader.test.js | 2 +- .../DateComponents/DecadeViewTable.test.js | 2 +- .../common/DateTimePicker/DateComponents/Header.test.js | 2 +- .../DateTimePicker/DateComponents/MonthView.test.js | 2 +- .../DateTimePicker/DateComponents/TodayButton.test.js | 2 +- .../DateTimePicker/DateComponents/YearView.test.js | 2 +- .../components/common/DateTimePicker/DatePicker.test.js | 2 +- .../common/DateTimePicker/DateTimePicker.test.js | 2 +- .../DateTimePicker/TimeComponents/PickTimeClock.test.js | 2 +- .../DateTimePicker/TimeComponents/PickTimeTable.test.js | 2 +- .../DateTimePicker/TimeComponents/TimeInput.test.js | 2 +- .../components/common/DateTimePicker/TimePicker.test.js | 2 +- .../common/DocumentationLink/DocumentationLink.test.js | 2 +- .../components/common/Fill/__tests__/FillReducer.test.js | 2 +- .../react_app/components/common/Loader/Loader.test.js | 2 +- .../components/common/MessageBox/MessageBox.test.js | 2 +- .../ModalProgressBar/__tests__/ModalProgressBar.test.js | 2 +- .../RedirectCancelButton/RedirectCancelButton.test.js | 2 +- .../components/common/SearchInput/SearchInput.test.js | 2 +- .../common/SkeletonLoader/SkeletonLoader.test.js | 2 +- .../components/common/charts/BarChart/BarChart.test.js | 2 +- .../common/charts/DonutChart/DonutChart.test.js | 2 +- .../components/common/charts/LineChart/LineChart.test.js | 2 +- .../react_app/components/common/dates/IsoDate.test.js | 2 +- .../components/common/dates/LongDateTime.test.js | 2 +- .../components/common/dates/RelativeDateTime.test.js | 2 +- .../components/common/dates/ShortDateTime.test.js | 2 +- .../react_app/components/common/forms/Actions.test.js | 2 +- .../react_app/components/common/forms/CommonForm.test.js | 2 +- .../forms/CounterInput/__tests__/CounterInput.test.js | 2 +- .../common/forms/ForemanForm/ForemanForm.test.js | 2 +- .../common/forms/ForemanForm/integration.test.js | 2 +- .../react_app/components/common/forms/Form.test.js | 2 +- .../OrderableSelect/__tests__/OrderableSelect.test.js | 2 +- .../forms/RadioButtonGroup/RadioButtonGroup.test.js | 2 +- .../react_app/components/common/forms/Select.test.js | 9 ++++----- .../common/table/actions/selectionActions.test.js | 2 +- .../table/components/__tests__/DeleteButton.test.js | 2 +- .../table/components/__tests__/HostsCountCell.test.js | 2 +- .../common/table/components/__tests__/NameCell.test.js | 2 +- .../table/components/__tests__/SortableHeader.test.js | 2 +- .../components/__tests__/TableSelectionCell.test.js | 2 +- .../__tests__/TableSelectionHeaderCell.test.js | 2 +- .../common/table/reducers/selectionReducer.test.js | 2 +- .../hosts/powerStatus/__tests__/PowerStatus.test.js | 2 +- .../hosts/storage/vmware/controller/controller.test.js | 2 +- .../hosts/storage/vmware/controller/disk/disk.test.js | 2 +- webpack/assets/javascripts/react_app/mockRequests.js | 2 +- .../RegistrationCommandsPage/__tests__/helpers.test.js | 2 +- .../javascripts/react_app/routes/__test__/Routes.test.js | 2 +- .../components/ExportButton/ExportButton.test.js | 2 +- .../javascripts/services/charts/LineChartService.test.js | 2 +- 88 files changed, 90 insertions(+), 94 deletions(-) diff --git a/webpack/assets/javascripts/react_app/common/HOC.test.js b/webpack/assets/javascripts/react_app/common/HOC.test.js index ab6d9614251..6727eff09f2 100644 --- a/webpack/assets/javascripts/react_app/common/HOC.test.js +++ b/webpack/assets/javascripts/react_app/common/HOC.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import { callOnMount, withRenderHandler, callOnPopState } from './HOC'; diff --git a/webpack/assets/javascripts/react_app/common/IntegrationTestHelper.js b/webpack/assets/javascripts/react_app/common/IntegrationTestHelper.js index 501f64966cc..6625f928b3f 100644 --- a/webpack/assets/javascripts/react_app/common/IntegrationTestHelper.js +++ b/webpack/assets/javascripts/react_app/common/IntegrationTestHelper.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import { Provider } from 'react-redux'; import { applyMiddleware, combineReducers, createStore } from 'redux'; import thunk from 'redux-thunk'; diff --git a/webpack/assets/javascripts/react_app/common/testHelpers.js b/webpack/assets/javascripts/react_app/common/testHelpers.js index ecb0c97268d..5b63970ef16 100644 --- a/webpack/assets/javascripts/react_app/common/testHelpers.js +++ b/webpack/assets/javascripts/react_app/common/testHelpers.js @@ -1,7 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; - -jest.useFakeTimers(); +import { shallow } from 'enzyme'; export default { mockStorage: () => { @@ -80,6 +78,7 @@ const resolveDispatch = async (action, depth) => { if (depth && typeof action === 'function') { const dispatch = jest.fn(); await action(dispatch); + jest.useFakeTimers(); jest.runOnlyPendingTimers(); return Promise.all( diff --git a/webpack/assets/javascripts/react_app/components/BreadcrumbBar/__tests__/BreadcrumbBar.test.js b/webpack/assets/javascripts/react_app/components/BreadcrumbBar/__tests__/BreadcrumbBar.test.js index a86dfd49f0d..ddf0d33a9fb 100644 --- a/webpack/assets/javascripts/react_app/components/BreadcrumbBar/__tests__/BreadcrumbBar.test.js +++ b/webpack/assets/javascripts/react_app/components/BreadcrumbBar/__tests__/BreadcrumbBar.test.js @@ -1,6 +1,5 @@ import React from 'react'; import { render, fireEvent, screen, act } from '@testing-library/react'; -import { mount } from '@theforeman/test'; import { testComponentSnapshotsWithFixtures } from '../../../common/testHelpers'; diff --git a/webpack/assets/javascripts/react_app/components/ChartBox/ChartBox.test.js b/webpack/assets/javascripts/react_app/components/ChartBox/ChartBox.test.js index b81fbcecfb5..c26c8334c76 100644 --- a/webpack/assets/javascripts/react_app/components/ChartBox/ChartBox.test.js +++ b/webpack/assets/javascripts/react_app/components/ChartBox/ChartBox.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import ChartBox from './ChartBox'; import { classFunctionUnitTest } from '../../common/testHelpers'; diff --git a/webpack/assets/javascripts/react_app/components/ConfigReports/ConfigReports.test.js b/webpack/assets/javascripts/react_app/components/ConfigReports/ConfigReports.test.js index 1a17f7e0cc1..48ac9b38a97 100644 --- a/webpack/assets/javascripts/react_app/components/ConfigReports/ConfigReports.test.js +++ b/webpack/assets/javascripts/react_app/components/ConfigReports/ConfigReports.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import ConfigReports from './ConfigReports'; diff --git a/webpack/assets/javascripts/react_app/components/ConfigReports/DiffModal/__tests__/DiffModal.test.js b/webpack/assets/javascripts/react_app/components/ConfigReports/DiffModal/__tests__/DiffModal.test.js index 5fcbeb65bd1..56e809898fe 100644 --- a/webpack/assets/javascripts/react_app/components/ConfigReports/DiffModal/__tests__/DiffModal.test.js +++ b/webpack/assets/javascripts/react_app/components/ConfigReports/DiffModal/__tests__/DiffModal.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import { testComponentSnapshotsWithFixtures } from '../../../../common/testHelpers'; import DiffModal from '../DiffModal'; diff --git a/webpack/assets/javascripts/react_app/components/ConfirmModal/integration.test.js b/webpack/assets/javascripts/react_app/components/ConfirmModal/integration.test.js index 479bf90bb00..52ed9ecaed7 100644 --- a/webpack/assets/javascripts/react_app/components/ConfirmModal/integration.test.js +++ b/webpack/assets/javascripts/react_app/components/ConfirmModal/integration.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { Provider } from 'react-redux'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import { Button } from '@patternfly/react-core'; import store from '../../redux'; import ConfirmModal, { openConfirmModal } from './index'; diff --git a/webpack/assets/javascripts/react_app/components/Editor/__tests__/Editor.test.js b/webpack/assets/javascripts/react_app/components/Editor/__tests__/Editor.test.js index 2e0d6d67e67..30513634beb 100644 --- a/webpack/assets/javascripts/react_app/components/Editor/__tests__/Editor.test.js +++ b/webpack/assets/javascripts/react_app/components/Editor/__tests__/Editor.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import { testComponentSnapshotsWithFixtures } from '../../../common/testHelpers'; import Editor from '../Editor'; import { editorOptions } from '../Editor.fixtures'; diff --git a/webpack/assets/javascripts/react_app/components/Editor/components/__tests__/EditorNavbar.test.js b/webpack/assets/javascripts/react_app/components/Editor/components/__tests__/EditorNavbar.test.js index 527243a1f92..04ca650440c 100644 --- a/webpack/assets/javascripts/react_app/components/Editor/components/__tests__/EditorNavbar.test.js +++ b/webpack/assets/javascripts/react_app/components/Editor/components/__tests__/EditorNavbar.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import { testComponentSnapshotsWithFixtures } from '../../../../common/testHelpers'; import EditorNavbar from '../EditorNavbar'; diff --git a/webpack/assets/javascripts/react_app/components/Editor/components/__tests__/EditorOptions.test.js b/webpack/assets/javascripts/react_app/components/Editor/components/__tests__/EditorOptions.test.js index de6300d14f0..d7b31e68a5a 100644 --- a/webpack/assets/javascripts/react_app/components/Editor/components/__tests__/EditorOptions.test.js +++ b/webpack/assets/javascripts/react_app/components/Editor/components/__tests__/EditorOptions.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import { testComponentSnapshotsWithFixtures } from '../../../../common/testHelpers'; import EditorOptions from '../EditorOptions'; diff --git a/webpack/assets/javascripts/react_app/components/ExternalLogout/__tests__/ExternalLogout.test.js b/webpack/assets/javascripts/react_app/components/ExternalLogout/__tests__/ExternalLogout.test.js index d63b7c29888..eab80f58f7e 100644 --- a/webpack/assets/javascripts/react_app/components/ExternalLogout/__tests__/ExternalLogout.test.js +++ b/webpack/assets/javascripts/react_app/components/ExternalLogout/__tests__/ExternalLogout.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import ExternalLogout from '../ExternalLogout'; import { props } from '../ExternalLogout.fixtures'; diff --git a/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/SubmitOrCancel/SubmitOrCancel.test.js b/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/SubmitOrCancel/SubmitOrCancel.test.js index abaf2ab3882..e32de925747 100644 --- a/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/SubmitOrCancel/SubmitOrCancel.test.js +++ b/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/SubmitOrCancel/SubmitOrCancel.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import SubmitOrCancel from './SubmitOrCancel'; diff --git a/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/__tests__/ForemanModalFooter.test.js b/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/__tests__/ForemanModalFooter.test.js index 8a41647362d..05c5699d75a 100644 --- a/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/__tests__/ForemanModalFooter.test.js +++ b/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/__tests__/ForemanModalFooter.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import { Button, Modal } from 'patternfly-react'; import ForemanModalFooter from '../ForemanModalFooter'; import * as ModalContext from '../../ForemanModalHooks'; // so enzyme test works diff --git a/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/__tests__/ForemanModalHeader.test.js b/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/__tests__/ForemanModalHeader.test.js index 1f3ce92b434..3c6f2c83393 100644 --- a/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/__tests__/ForemanModalHeader.test.js +++ b/webpack/assets/javascripts/react_app/components/ForemanModal/subcomponents/__tests__/ForemanModalHeader.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import { Modal } from 'patternfly-react'; import ForemanModalHeader from '../ForemanModalHeader'; import * as ModalContext from '../../ForemanModalHooks'; // so enzyme test works diff --git a/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIcon.test.js b/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIcon.test.js index d5132cdac71..2f79b894c50 100644 --- a/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIcon.test.js +++ b/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIcon.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import ImpersonateIcon from './ImpersonateIcon'; diff --git a/webpack/assets/javascripts/react_app/components/Layout/components/Toolbar/HeaderToolbar.test.js b/webpack/assets/javascripts/react_app/components/Layout/components/Toolbar/HeaderToolbar.test.js index 6c029c077d8..3896865c879 100644 --- a/webpack/assets/javascripts/react_app/components/Layout/components/Toolbar/HeaderToolbar.test.js +++ b/webpack/assets/javascripts/react_app/components/Layout/components/Toolbar/HeaderToolbar.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import { hasTaxonomiesMock } from '../../Layout.fixtures'; import { noop } from '../../../../common/helpers'; diff --git a/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/__tests__/MemoryAllocationInput.test.js b/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/__tests__/MemoryAllocationInput.test.js index 556e25a393b..9ad986357ef 100644 --- a/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/__tests__/MemoryAllocationInput.test.js +++ b/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/__tests__/MemoryAllocationInput.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import { Provider } from 'react-redux'; import { MEGABYTES } from '../constants'; import MemoryAllocationInput from '../'; diff --git a/webpack/assets/javascripts/react_app/components/PF4/Bookmarks/__tests__/Bookmarks.test.js b/webpack/assets/javascripts/react_app/components/PF4/Bookmarks/__tests__/Bookmarks.test.js index 0f3f43cf44a..e5cacded619 100644 --- a/webpack/assets/javascripts/react_app/components/PF4/Bookmarks/__tests__/Bookmarks.test.js +++ b/webpack/assets/javascripts/react_app/components/PF4/Bookmarks/__tests__/Bookmarks.test.js @@ -1,4 +1,3 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; import React from 'react'; import { Provider } from 'react-redux'; import store from '../../../../redux'; diff --git a/webpack/assets/javascripts/react_app/components/PF4/DocumentationLink/DocumentationLink.test.js b/webpack/assets/javascripts/react_app/components/PF4/DocumentationLink/DocumentationLink.test.js index 7cee3c80b15..905392e36bf 100644 --- a/webpack/assets/javascripts/react_app/components/PF4/DocumentationLink/DocumentationLink.test.js +++ b/webpack/assets/javascripts/react_app/components/PF4/DocumentationLink/DocumentationLink.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import Link from './index'; diff --git a/webpack/assets/javascripts/react_app/components/PasswordStrength/__tests__/PasswordStrength.test.js b/webpack/assets/javascripts/react_app/components/PasswordStrength/__tests__/PasswordStrength.test.js index 71d49e69a78..718a094bcaf 100644 --- a/webpack/assets/javascripts/react_app/components/PasswordStrength/__tests__/PasswordStrength.test.js +++ b/webpack/assets/javascripts/react_app/components/PasswordStrength/__tests__/PasswordStrength.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import { testComponentSnapshotsWithFixtures } from '../../../common/testHelpers'; diff --git a/webpack/assets/javascripts/react_app/components/SettingRecords/__tests__/SettingRecordsReducer.test.js b/webpack/assets/javascripts/react_app/components/SettingRecords/__tests__/SettingRecordsReducer.test.js index 90c20d94482..ae91beb47aa 100644 --- a/webpack/assets/javascripts/react_app/components/SettingRecords/__tests__/SettingRecordsReducer.test.js +++ b/webpack/assets/javascripts/react_app/components/SettingRecords/__tests__/SettingRecordsReducer.test.js @@ -1,4 +1,4 @@ -import { testReducerSnapshotWithFixtures } from '@theforeman/test'; +import { testReducerSnapshotWithFixtures } from 'foremanReact/common/testHelpers'; import { default as reducer, initialState } from '../SettingRecordsReducer'; diff --git a/webpack/assets/javascripts/react_app/components/SettingRecords/__tests__/SettingRecordsSelectors.test.js b/webpack/assets/javascripts/react_app/components/SettingRecords/__tests__/SettingRecordsSelectors.test.js index 706b83f1a14..9f32648a377 100644 --- a/webpack/assets/javascripts/react_app/components/SettingRecords/__tests__/SettingRecordsSelectors.test.js +++ b/webpack/assets/javascripts/react_app/components/SettingRecords/__tests__/SettingRecordsSelectors.test.js @@ -1,4 +1,4 @@ -import { testSelectorsSnapshotWithFixtures } from '@theforeman/test'; +import { testSelectorsSnapshotWithFixtures } from 'foremanReact/common/testHelpers'; import { selectSettings, diff --git a/webpack/assets/javascripts/react_app/components/SettingUpdateModal/SettingUpdateModal.test.js b/webpack/assets/javascripts/react_app/components/SettingUpdateModal/SettingUpdateModal.test.js index 605749ac0e6..d359f0f10db 100644 --- a/webpack/assets/javascripts/react_app/components/SettingUpdateModal/SettingUpdateModal.test.js +++ b/webpack/assets/javascripts/react_app/components/SettingUpdateModal/SettingUpdateModal.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import { arraySetting } from '../SettingRecords/__tests__/SettingRecords.fixtures'; diff --git a/webpack/assets/javascripts/react_app/components/SettingUpdateModal/components/SettingValueField.test.js b/webpack/assets/javascripts/react_app/components/SettingUpdateModal/components/SettingValueField.test.js index c76bf679b65..978be53736d 100644 --- a/webpack/assets/javascripts/react_app/components/SettingUpdateModal/components/SettingValueField.test.js +++ b/webpack/assets/javascripts/react_app/components/SettingUpdateModal/components/SettingValueField.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import SettingValueField from './SettingValueField'; diff --git a/webpack/assets/javascripts/react_app/components/SettingsTable/__tests__/SettingsTable.test.js b/webpack/assets/javascripts/react_app/components/SettingsTable/__tests__/SettingsTable.test.js index 68799862484..9cf4dea3c16 100644 --- a/webpack/assets/javascripts/react_app/components/SettingsTable/__tests__/SettingsTable.test.js +++ b/webpack/assets/javascripts/react_app/components/SettingsTable/__tests__/SettingsTable.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import { groupedSettings } from '../../SettingRecords/__tests__/SettingRecords.fixtures'; diff --git a/webpack/assets/javascripts/react_app/components/SettingsTable/components/__tests__/SettingCell.test.js b/webpack/assets/javascripts/react_app/components/SettingsTable/components/__tests__/SettingCell.test.js index e6cd0b73c83..d766a4b7ee3 100644 --- a/webpack/assets/javascripts/react_app/components/SettingsTable/components/__tests__/SettingCell.test.js +++ b/webpack/assets/javascripts/react_app/components/SettingsTable/components/__tests__/SettingCell.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import { rootPass, diff --git a/webpack/assets/javascripts/react_app/components/SettingsTable/components/__tests__/SettingName.test.js b/webpack/assets/javascripts/react_app/components/SettingsTable/components/__tests__/SettingName.test.js index 19c16153c59..fca1311af45 100644 --- a/webpack/assets/javascripts/react_app/components/SettingsTable/components/__tests__/SettingName.test.js +++ b/webpack/assets/javascripts/react_app/components/SettingsTable/components/__tests__/SettingName.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import { rootPass, diff --git a/webpack/assets/javascripts/react_app/components/ToastsList/__tests__/integration.test.js b/webpack/assets/javascripts/react_app/components/ToastsList/__tests__/integration.test.js index 92c109172ed..d3a7448a5f0 100644 --- a/webpack/assets/javascripts/react_app/components/ToastsList/__tests__/integration.test.js +++ b/webpack/assets/javascripts/react_app/components/ToastsList/__tests__/integration.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { Provider } from 'react-redux'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import store from '../../../redux'; import ToastsList, { addToast, deleteToast } from '../index' diff --git a/webpack/assets/javascripts/react_app/components/common/ActionButtons/ActionButtons.test.js b/webpack/assets/javascripts/react_app/components/common/ActionButtons/ActionButtons.test.js index 45c04779b24..3c97cdd4237 100644 --- a/webpack/assets/javascripts/react_app/components/common/ActionButtons/ActionButtons.test.js +++ b/webpack/assets/javascripts/react_app/components/common/ActionButtons/ActionButtons.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import { ActionButtons } from './ActionButtons'; import { buttons } from './ActionButtons.fixtures'; diff --git a/webpack/assets/javascripts/react_app/components/common/Alert/AlertBody.test.js b/webpack/assets/javascripts/react_app/components/common/Alert/AlertBody.test.js index 27031e8690e..e7dce609455 100644 --- a/webpack/assets/javascripts/react_app/components/common/Alert/AlertBody.test.js +++ b/webpack/assets/javascripts/react_app/components/common/Alert/AlertBody.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import AlertBody from './AlertBody'; diff --git a/webpack/assets/javascripts/react_app/components/common/Alert/AlertLink.test.js b/webpack/assets/javascripts/react_app/components/common/Alert/AlertLink.test.js index faf02a01cde..c2a759c04cd 100644 --- a/webpack/assets/javascripts/react_app/components/common/Alert/AlertLink.test.js +++ b/webpack/assets/javascripts/react_app/components/common/Alert/AlertLink.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import AlertLink from './AlertLink'; diff --git a/webpack/assets/javascripts/react_app/components/common/ComponentWrapper/ComponentWrapper.test.js b/webpack/assets/javascripts/react_app/components/common/ComponentWrapper/ComponentWrapper.test.js index eb2c9f6d045..858281cda00 100644 --- a/webpack/assets/javascripts/react_app/components/common/ComponentWrapper/ComponentWrapper.test.js +++ b/webpack/assets/javascripts/react_app/components/common/ComponentWrapper/ComponentWrapper.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import componentRegistry from '../../componentRegistry'; import ComponentWrapper from './ComponentWrapper'; diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DateInput.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DateInput.test.js index 98c4b6ab193..2a4a564196e 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DateInput.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DateInput.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow, mount } from '@theforeman/test'; +import { shallow, mount } from 'enzyme'; import DateInput from './DateInput'; test('DateInput is working properly', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/Day.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/Day.test.js index 962e50a3c7e..ccee6ef4d7d 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/Day.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/Day.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import Day from './Day'; test('Day is working properly', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeView.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeView.test.js index 051d8a830f4..a45612aec9e 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeView.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeView.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow, mount } from '@theforeman/test'; +import { shallow, mount } from 'enzyme'; import DecadeView from './DecadeView'; test('DecadeView is working properly', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeViewHeader.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeViewHeader.test.js index d193691add4..0fba60bfb15 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeViewHeader.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeViewHeader.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import { DecadeViewHeader } from './DecadeViewHeader'; test('DecadeViewHeader is working properly', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeViewTable.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeViewTable.test.js index 20a72bae885..74dbd93fa9b 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeViewTable.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/DecadeViewTable.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import { DecadeViewTable } from './DecadeViewTable'; test('DecadeViewTable is working properly', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/Header.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/Header.test.js index cc50df728a5..f88d12f8786 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/Header.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/Header.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import Header from './Header'; test('Header is working properly', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/MonthView.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/MonthView.test.js index ca5bf935ed3..23703b6dddb 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/MonthView.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/MonthView.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import MonthView from './MonthView'; test('MonthView is working properly', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/TodayButton.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/TodayButton.test.js index c8a2a7aa963..0d7a4358a93 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/TodayButton.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/TodayButton.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import TodayButton from './TodayButton'; const mockedDate = new Date('2/21/2019 , 3:22:31 PM'); diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/YearView.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/YearView.test.js index 5cd7c691551..92382a3f846 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/YearView.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateComponents/YearView.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import YearView from './YearView'; test('YearView is working properly', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DatePicker.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DatePicker.test.js index 3c8964fcbc7..971498ad680 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DatePicker.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DatePicker.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import DatePicker from './DatePicker'; describe('DatePicker', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateTimePicker.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateTimePicker.test.js index 5b8e713b3e4..b9a0435edd1 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateTimePicker.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/DateTimePicker.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import DateTimePicker from './DateTimePicker'; describe('DateTimePicker', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/PickTimeClock.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/PickTimeClock.test.js index 766a2f3e501..b98ac585b97 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/PickTimeClock.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/PickTimeClock.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow, mount } from '@theforeman/test'; +import { shallow, mount } from 'enzyme'; import PickTimeClock from './PickTimeClock'; import { MINUTE, HOUR } from './TimeConstants'; diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/PickTimeTable.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/PickTimeTable.test.js index cc0f79e9fda..9cbd183db0c 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/PickTimeTable.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/PickTimeTable.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import PickTimeTable from './PickTimeTable'; import { MINUTE, HOUR } from './TimeConstants'; diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/TimeInput.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/TimeInput.test.js index ff463a6bc5b..221fe4803e3 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/TimeInput.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimeComponents/TimeInput.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow, mount } from '@theforeman/test'; +import { shallow, mount } from 'enzyme'; import TimeInput from './TimeInput'; test('TimeInput is working properly', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimePicker.test.js b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimePicker.test.js index e4511a84ebb..11c1d4aec25 100644 --- a/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimePicker.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DateTimePicker/TimePicker.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import TimePicker from './TimePicker'; test('TimePicker is working properly', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/DocumentationLink/DocumentationLink.test.js b/webpack/assets/javascripts/react_app/components/common/DocumentationLink/DocumentationLink.test.js index b47e90902bf..aff30ed02ec 100644 --- a/webpack/assets/javascripts/react_app/components/common/DocumentationLink/DocumentationLink.test.js +++ b/webpack/assets/javascripts/react_app/components/common/DocumentationLink/DocumentationLink.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import Link from './index'; diff --git a/webpack/assets/javascripts/react_app/components/common/Fill/__tests__/FillReducer.test.js b/webpack/assets/javascripts/react_app/components/common/Fill/__tests__/FillReducer.test.js index 4f19db384f1..3eda8463764 100644 --- a/webpack/assets/javascripts/react_app/components/common/Fill/__tests__/FillReducer.test.js +++ b/webpack/assets/javascripts/react_app/components/common/Fill/__tests__/FillReducer.test.js @@ -1,4 +1,4 @@ -import { testReducerSnapshotWithFixtures } from '@theforeman/test'; +import { testReducerSnapshotWithFixtures } from 'foremanReact/common/testHelpers'; import Immutable from 'seamless-immutable'; import reducer from '../FillReducer'; import { REMOVE_FILLED_COMPONENT } from '../FillConstants'; diff --git a/webpack/assets/javascripts/react_app/components/common/Loader/Loader.test.js b/webpack/assets/javascripts/react_app/components/common/Loader/Loader.test.js index 67981863262..370f1d7966c 100644 --- a/webpack/assets/javascripts/react_app/components/common/Loader/Loader.test.js +++ b/webpack/assets/javascripts/react_app/components/common/Loader/Loader.test.js @@ -1,4 +1,4 @@ -import { shallow, mount } from '@theforeman/test'; +import { shallow, mount } from 'enzyme'; import React from 'react'; import { STATUS } from '../../../constants'; diff --git a/webpack/assets/javascripts/react_app/components/common/MessageBox/MessageBox.test.js b/webpack/assets/javascripts/react_app/components/common/MessageBox/MessageBox.test.js index a695222ba9f..3887b509b9a 100644 --- a/webpack/assets/javascripts/react_app/components/common/MessageBox/MessageBox.test.js +++ b/webpack/assets/javascripts/react_app/components/common/MessageBox/MessageBox.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import MessageBox from './index'; diff --git a/webpack/assets/javascripts/react_app/components/common/ModalProgressBar/__tests__/ModalProgressBar.test.js b/webpack/assets/javascripts/react_app/components/common/ModalProgressBar/__tests__/ModalProgressBar.test.js index 6573b1ecd70..acdd062e93c 100644 --- a/webpack/assets/javascripts/react_app/components/common/ModalProgressBar/__tests__/ModalProgressBar.test.js +++ b/webpack/assets/javascripts/react_app/components/common/ModalProgressBar/__tests__/ModalProgressBar.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import ModalProgressBar from '../ModalProgressBar'; describe('ModalProgressBar', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/RedirectCancelButton/RedirectCancelButton.test.js b/webpack/assets/javascripts/react_app/components/common/RedirectCancelButton/RedirectCancelButton.test.js index 211a92a5fbc..f6a523afb8d 100644 --- a/webpack/assets/javascripts/react_app/components/common/RedirectCancelButton/RedirectCancelButton.test.js +++ b/webpack/assets/javascripts/react_app/components/common/RedirectCancelButton/RedirectCancelButton.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import RedirectCancelButton from './RedirectCancelButton'; diff --git a/webpack/assets/javascripts/react_app/components/common/SearchInput/SearchInput.test.js b/webpack/assets/javascripts/react_app/components/common/SearchInput/SearchInput.test.js index 74a4fa0a154..d2788a082b3 100644 --- a/webpack/assets/javascripts/react_app/components/common/SearchInput/SearchInput.test.js +++ b/webpack/assets/javascripts/react_app/components/common/SearchInput/SearchInput.test.js @@ -1,4 +1,4 @@ -import { shallow, mount } from '@theforeman/test'; +import { shallow, mount } from 'enzyme'; import React from 'react'; import SearchInput from './'; diff --git a/webpack/assets/javascripts/react_app/components/common/SkeletonLoader/SkeletonLoader.test.js b/webpack/assets/javascripts/react_app/components/common/SkeletonLoader/SkeletonLoader.test.js index 18957adc4ba..0b37bf7713b 100644 --- a/webpack/assets/javascripts/react_app/components/common/SkeletonLoader/SkeletonLoader.test.js +++ b/webpack/assets/javascripts/react_app/components/common/SkeletonLoader/SkeletonLoader.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import SkeletonLoader from '.'; import { STATUS } from '../../../constants'; const fixtures = { diff --git a/webpack/assets/javascripts/react_app/components/common/charts/BarChart/BarChart.test.js b/webpack/assets/javascripts/react_app/components/common/charts/BarChart/BarChart.test.js index 847f6cfbca1..560dbaa9555 100644 --- a/webpack/assets/javascripts/react_app/components/common/charts/BarChart/BarChart.test.js +++ b/webpack/assets/javascripts/react_app/components/common/charts/BarChart/BarChart.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import BarChart from './'; import * as chartService from '../../../../../services/charts/BarChartService'; diff --git a/webpack/assets/javascripts/react_app/components/common/charts/DonutChart/DonutChart.test.js b/webpack/assets/javascripts/react_app/components/common/charts/DonutChart/DonutChart.test.js index f82921cb624..33bda555cf8 100644 --- a/webpack/assets/javascripts/react_app/components/common/charts/DonutChart/DonutChart.test.js +++ b/webpack/assets/javascripts/react_app/components/common/charts/DonutChart/DonutChart.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import { mockData, emptyData } from './DonutChart.fixtures'; import DonutChart from './'; diff --git a/webpack/assets/javascripts/react_app/components/common/charts/LineChart/LineChart.test.js b/webpack/assets/javascripts/react_app/components/common/charts/LineChart/LineChart.test.js index 9262129308d..df6e5b5751a 100644 --- a/webpack/assets/javascripts/react_app/components/common/charts/LineChart/LineChart.test.js +++ b/webpack/assets/javascripts/react_app/components/common/charts/LineChart/LineChart.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import { data, timeseriesData } from './LineChart.fixtures'; import LineChart from './index'; diff --git a/webpack/assets/javascripts/react_app/components/common/dates/IsoDate.test.js b/webpack/assets/javascripts/react_app/components/common/dates/IsoDate.test.js index 8e48da64bb5..5afa3a6e377 100644 --- a/webpack/assets/javascripts/react_app/components/common/dates/IsoDate.test.js +++ b/webpack/assets/javascripts/react_app/components/common/dates/IsoDate.test.js @@ -1,6 +1,6 @@ /* eslint-disable promise/prefer-await-to-then */ // Configure Enzyme -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import React from 'react'; import IsoDate from './IsoDate'; import { i18nProviderWrapperFactory } from '../../../common/i18nProviderWrapperFactory'; diff --git a/webpack/assets/javascripts/react_app/components/common/dates/LongDateTime.test.js b/webpack/assets/javascripts/react_app/components/common/dates/LongDateTime.test.js index c4f096b10e9..8c5096f24b6 100644 --- a/webpack/assets/javascripts/react_app/components/common/dates/LongDateTime.test.js +++ b/webpack/assets/javascripts/react_app/components/common/dates/LongDateTime.test.js @@ -1,6 +1,6 @@ /* eslint-disable promise/prefer-await-to-then */ // Configure Enzyme -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import React from 'react'; import LongDateTime from './LongDateTime'; import { i18nProviderWrapperFactory } from '../../../common/i18nProviderWrapperFactory'; diff --git a/webpack/assets/javascripts/react_app/components/common/dates/RelativeDateTime.test.js b/webpack/assets/javascripts/react_app/components/common/dates/RelativeDateTime.test.js index 8a8b0f406d9..5bb5c2d8449 100644 --- a/webpack/assets/javascripts/react_app/components/common/dates/RelativeDateTime.test.js +++ b/webpack/assets/javascripts/react_app/components/common/dates/RelativeDateTime.test.js @@ -1,6 +1,6 @@ /* eslint-disable promise/prefer-await-to-then */ // Configure Enzyme -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import React from 'react'; import RelativeDateTime from './RelativeDateTime'; import { i18nProviderWrapperFactory } from '../../../common/i18nProviderWrapperFactory'; diff --git a/webpack/assets/javascripts/react_app/components/common/dates/ShortDateTime.test.js b/webpack/assets/javascripts/react_app/components/common/dates/ShortDateTime.test.js index d1f9c23e95d..ede7e7f046a 100644 --- a/webpack/assets/javascripts/react_app/components/common/dates/ShortDateTime.test.js +++ b/webpack/assets/javascripts/react_app/components/common/dates/ShortDateTime.test.js @@ -1,6 +1,6 @@ /* eslint-disable promise/prefer-await-to-then */ // Configure Enzyme -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import React from 'react'; import ShortDateTime from './ShortDateTime'; import { i18nProviderWrapperFactory } from '../../../common/i18nProviderWrapperFactory'; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/Actions.test.js b/webpack/assets/javascripts/react_app/components/common/forms/Actions.test.js index c59a8f79871..631e557dc73 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/Actions.test.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/Actions.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import Actions from './Actions'; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/CommonForm.test.js b/webpack/assets/javascripts/react_app/components/common/forms/CommonForm.test.js index 499d62a5050..7ced1ba0862 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/CommonForm.test.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/CommonForm.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import { FieldLevelHelp } from 'patternfly-react'; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/CounterInput/__tests__/CounterInput.test.js b/webpack/assets/javascripts/react_app/components/common/forms/CounterInput/__tests__/CounterInput.test.js index c4c5f7ad739..0804dd8ae32 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/CounterInput/__tests__/CounterInput.test.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/CounterInput/__tests__/CounterInput.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import CounterInput from '../'; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/ForemanForm/ForemanForm.test.js b/webpack/assets/javascripts/react_app/components/common/forms/ForemanForm/ForemanForm.test.js index 69376501234..9ffe1032921 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/ForemanForm/ForemanForm.test.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/ForemanForm/ForemanForm.test.js @@ -1,7 +1,7 @@ import { testComponentSnapshotsWithFixtures, testSelectorsSnapshotWithFixtures, -} from '@theforeman/test'; +} from 'foremanReact/common/testHelpers'; import * as Yup from 'yup'; import { prepareErrors } from '../../../../redux/actions/common/forms'; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/ForemanForm/integration.test.js b/webpack/assets/javascripts/react_app/components/common/forms/ForemanForm/integration.test.js index 8f2aac4a75e..0cb262d0b42 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/ForemanForm/integration.test.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/ForemanForm/integration.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { IntegrationTestHelper } from '@theforeman/test'; +import IntegrationTestHelper from 'foremanReact/common/IntegrationTestHelper'; import { submitForm } from '../../../../redux/actions/common/forms'; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/Form.test.js b/webpack/assets/javascripts/react_app/components/common/forms/Form.test.js index 104c6bca864..7e119ef5704 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/Form.test.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/Form.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import Form from './Form'; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/OrderableSelect/__tests__/OrderableSelect.test.js b/webpack/assets/javascripts/react_app/components/common/forms/OrderableSelect/__tests__/OrderableSelect.test.js index 8e6d3370bee..c56603d92b5 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/OrderableSelect/__tests__/OrderableSelect.test.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/OrderableSelect/__tests__/OrderableSelect.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { DndProvider } from 'react-dnd'; import TestBackend from 'react-dnd-test-backend/dist/cjs/TestBackend'; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/RadioButtonGroup/RadioButtonGroup.test.js b/webpack/assets/javascripts/react_app/components/common/forms/RadioButtonGroup/RadioButtonGroup.test.js index fa976d91cad..465df746196 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/RadioButtonGroup/RadioButtonGroup.test.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/RadioButtonGroup/RadioButtonGroup.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import RadioButtonGroup from './RadioButtonGroup'; const radios = [ diff --git a/webpack/assets/javascripts/react_app/components/common/forms/Select.test.js b/webpack/assets/javascripts/react_app/components/common/forms/Select.test.js index 34bee4e78c6..962810eaaf4 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/Select.test.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/Select.test.js @@ -1,16 +1,15 @@ import 'select2'; -import { mount } from '@theforeman/test'; +import { mount } from 'enzyme'; import React from 'react'; import Select from './Select'; jest.unmock('jquery'); -beforeEach(() => { - document.body.innerHTML = '
\n \n
'; -}); - describe('Select', () => { + beforeEach(() => { + document.body.innerHTML = '
\n \n
'; + }); it('onChange called exactly once even after update', () => { const options = { one: '1', two: '2' }; const onChangeMock = jest.fn(); diff --git a/webpack/assets/javascripts/react_app/components/common/table/actions/selectionActions.test.js b/webpack/assets/javascripts/react_app/components/common/table/actions/selectionActions.test.js index 1a86916c2e1..a0062be8fc6 100644 --- a/webpack/assets/javascripts/react_app/components/common/table/actions/selectionActions.test.js +++ b/webpack/assets/javascripts/react_app/components/common/table/actions/selectionActions.test.js @@ -1,4 +1,4 @@ -import { testActionSnapshotWithFixtures } from '@theforeman/test'; +import { testActionSnapshotWithFixtures } from 'foremanReact/common/testHelpers'; import { selectPage, selectAllRows, diff --git a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/DeleteButton.test.js b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/DeleteButton.test.js index 6f3d3cf0451..74f77175333 100644 --- a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/DeleteButton.test.js +++ b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/DeleteButton.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import DeleteButton from '../DeleteButton'; const baseProps = { diff --git a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/HostsCountCell.test.js b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/HostsCountCell.test.js index 9abb4b68c56..39b2dbe2319 100644 --- a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/HostsCountCell.test.js +++ b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/HostsCountCell.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import HostsCountCell from '../HostsCountCell'; describe('HostsCountCell', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/NameCell.test.js b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/NameCell.test.js index 16abf01ce5b..97e1c4aff30 100644 --- a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/NameCell.test.js +++ b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/NameCell.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import NameCell from '../NameCell'; const fixtures = { diff --git a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/SortableHeader.test.js b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/SortableHeader.test.js index c71bc99a951..ef99b250276 100644 --- a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/SortableHeader.test.js +++ b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/SortableHeader.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import SortalbeHeader from '../SortableHeader'; describe('SortalbeHeader', () => { diff --git a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/TableSelectionCell.test.js b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/TableSelectionCell.test.js index 33cc20505fa..036069e352a 100644 --- a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/TableSelectionCell.test.js +++ b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/TableSelectionCell.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import TableSelectionCell from '../TableSelectionCell'; diff --git a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/TableSelectionHeaderCell.test.js b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/TableSelectionHeaderCell.test.js index c1156239134..a8670b93e09 100644 --- a/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/TableSelectionHeaderCell.test.js +++ b/webpack/assets/javascripts/react_app/components/common/table/components/__tests__/TableSelectionHeaderCell.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import TableSelectionHeaderCell from '../TableSelectionHeaderCell'; diff --git a/webpack/assets/javascripts/react_app/components/common/table/reducers/selectionReducer.test.js b/webpack/assets/javascripts/react_app/components/common/table/reducers/selectionReducer.test.js index 1969d7b5739..9ebd4dfb038 100644 --- a/webpack/assets/javascripts/react_app/components/common/table/reducers/selectionReducer.test.js +++ b/webpack/assets/javascripts/react_app/components/common/table/reducers/selectionReducer.test.js @@ -1,5 +1,5 @@ import Immutable from 'seamless-immutable'; -import { testReducerSnapshotWithFixtures } from '@theforeman/test'; +import { testReducerSnapshotWithFixtures } from 'foremanReact/common/testHelpers'; import { SELECT_ROWS, UNSELECT_ROWS, diff --git a/webpack/assets/javascripts/react_app/components/hosts/powerStatus/__tests__/PowerStatus.test.js b/webpack/assets/javascripts/react_app/components/hosts/powerStatus/__tests__/PowerStatus.test.js index 9d675419380..b7d77304916 100644 --- a/webpack/assets/javascripts/react_app/components/hosts/powerStatus/__tests__/PowerStatus.test.js +++ b/webpack/assets/javascripts/react_app/components/hosts/powerStatus/__tests__/PowerStatus.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import PowerStatus from '../PowerStatus'; import { pendingProps, diff --git a/webpack/assets/javascripts/react_app/components/hosts/storage/vmware/controller/controller.test.js b/webpack/assets/javascripts/react_app/components/hosts/storage/vmware/controller/controller.test.js index 17047e500aa..1104d403c1d 100644 --- a/webpack/assets/javascripts/react_app/components/hosts/storage/vmware/controller/controller.test.js +++ b/webpack/assets/javascripts/react_app/components/hosts/storage/vmware/controller/controller.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import { props } from './controller.fixtures'; diff --git a/webpack/assets/javascripts/react_app/components/hosts/storage/vmware/controller/disk/disk.test.js b/webpack/assets/javascripts/react_app/components/hosts/storage/vmware/controller/disk/disk.test.js index 684aa44e7fb..91357e83526 100644 --- a/webpack/assets/javascripts/react_app/components/hosts/storage/vmware/controller/disk/disk.test.js +++ b/webpack/assets/javascripts/react_app/components/hosts/storage/vmware/controller/disk/disk.test.js @@ -1,4 +1,4 @@ -import { shallow } from '@theforeman/test'; +import { shallow } from 'enzyme'; import React from 'react'; import { props } from './disk.fixtures'; diff --git a/webpack/assets/javascripts/react_app/mockRequests.js b/webpack/assets/javascripts/react_app/mockRequests.js index 954b7cb8518..19cd5b61721 100644 --- a/webpack/assets/javascripts/react_app/mockRequests.js +++ b/webpack/assets/javascripts/react_app/mockRequests.js @@ -1,5 +1,5 @@ import axios from 'axios'; -import { MockAdapter } from '@theforeman/test'; +import MockAdapter from 'axios-mock-adapter'; export const mock = () => new MockAdapter(axios); const methods = { diff --git a/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/helpers.test.js b/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/helpers.test.js index 5f7134be1e2..d7ed1810840 100644 --- a/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/helpers.test.js +++ b/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/helpers.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow, render } from '@theforeman/test'; +import { shallow, render } from 'enzyme' import { FormSelectOption } from '@patternfly/react-core'; import { emptyOption, validatedOS, osHelperText } from '../RegistrationCommandsPageHelpers' diff --git a/webpack/assets/javascripts/react_app/routes/__test__/Routes.test.js b/webpack/assets/javascripts/react_app/routes/__test__/Routes.test.js index 386cb612b81..413e2cd5d3c 100644 --- a/webpack/assets/javascripts/react_app/routes/__test__/Routes.test.js +++ b/webpack/assets/javascripts/react_app/routes/__test__/Routes.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import AppSwitcher from '../'; import { children } from './ForemanSwitcher.fixtures' diff --git a/webpack/assets/javascripts/react_app/routes/common/PageLayout/components/ExportButton/ExportButton.test.js b/webpack/assets/javascripts/react_app/routes/common/PageLayout/components/ExportButton/ExportButton.test.js index d9178abcb93..903bf388f25 100644 --- a/webpack/assets/javascripts/react_app/routes/common/PageLayout/components/ExportButton/ExportButton.test.js +++ b/webpack/assets/javascripts/react_app/routes/common/PageLayout/components/ExportButton/ExportButton.test.js @@ -1,4 +1,4 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; +import { testComponentSnapshotsWithFixtures } from 'foremanReact/common/testHelpers'; import ExportButton from './ExportButton'; diff --git a/webpack/assets/javascripts/services/charts/LineChartService.test.js b/webpack/assets/javascripts/services/charts/LineChartService.test.js index 60d51c31a9a..55962aca57d 100644 --- a/webpack/assets/javascripts/services/charts/LineChartService.test.js +++ b/webpack/assets/javascripts/services/charts/LineChartService.test.js @@ -1,4 +1,4 @@ -import { testActionSnapshotWithFixtures } from '@theforeman/test'; +import { testActionSnapshotWithFixtures } from 'foremanReact/common/testHelpers'; import { getLineChartConfig } from './LineChartService'; import { From ac507a03840353622dc9a32183053ce953d275da Mon Sep 17 00:00:00 2001 From: MariaAga Date: Tue, 9 Jul 2024 19:39:18 +0100 Subject: [PATCH 2/7] Fixes #37637 - Test plugins from foreman core --- .eslintrc | 6 +- .github/workflows/plugins_react_tests.yml | 30 +++- babel.config.js | 3 + package-exclude.json | 1 + package.json | 23 ++- script/npm_test_plugin.js | 140 ++++++++++++++++++ script/plugin_webpack_directories.js | 18 +++ .../TemplateGeneratorActions.test.js | 12 +- webpack/{test_setup.js => core_test_setup.js} | 7 + webpack/global_test_setup.js | 19 +++ webpack/jest.config.js | 79 ++++++++++ webpack/resolveNodeModule.js | 61 ++++++++ webpack/theforeman_test_dependencies.js | 36 +++++ 13 files changed, 421 insertions(+), 14 deletions(-) create mode 100644 babel.config.js create mode 100755 script/npm_test_plugin.js rename webpack/{test_setup.js => core_test_setup.js} (73%) create mode 100644 webpack/global_test_setup.js create mode 100644 webpack/jest.config.js create mode 100644 webpack/resolveNodeModule.js create mode 100644 webpack/theforeman_test_dependencies.js diff --git a/.eslintrc b/.eslintrc index 0f541f19ff3..76cae0d39af 100644 --- a/.eslintrc +++ b/.eslintrc @@ -24,6 +24,7 @@ "auditable", "Autocompletion", "autogenerated", + "axios", "bool", "bootable", "Borderless", @@ -107,6 +108,7 @@ "noopener", "noreferrer", "nowrap", + "npx", "num", "numpad", "operatingsystem", @@ -161,6 +163,7 @@ "textarea", "textfield", "tfm", + "theforeman", "timepicker", "timerdelay", "timeseries", @@ -195,6 +198,7 @@ "minLength": 3 } ], - "@theforeman/rules/require-ouiaid": ["error"] + "@theforeman/rules/require-ouiaid": ["error"], + "import/no-extraneous-dependencies": "off", } } diff --git a/.github/workflows/plugins_react_tests.yml b/.github/workflows/plugins_react_tests.yml index 7d0f7184b7c..551b3e9c710 100644 --- a/.github/workflows/plugins_react_tests.yml +++ b/.github/workflows/plugins_react_tests.yml @@ -16,6 +16,9 @@ concurrency: group: ${{ github.ref_name }}-${{ github.workflow }} cancel-in-progress: true +env: + BUNDLE_WITHOUT: "console:development:journald:libvirt" + jobs: setup_matrix: name: Setup matrix @@ -45,11 +48,11 @@ jobs: uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - # We could update the postinstall action for foreman to look for an environment variable for plugin webpack dirs - # before kicking off the ruby script to find them, this would eliminate the ruby dep and running `npm install` in plugins. - - uses: ruby/setup-ruby@v1 + - name: "Set up Ruby ${{ matrix.ruby }}" + uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} + bundler-cache: true - name: Checkout Foreman uses: actions/checkout@v4 with: @@ -65,12 +68,29 @@ jobs: with: repository: ${{ matrix.plugin }} path: ${{ github.workspace }}/projects/plugin + - name: store plugin name + run: echo "PLUGIN_NAME=$(echo ${{ matrix.plugin }} | awk -F'/' '{print $NF}')" >> "${GITHUB_ENV}" + - name: Set up plugin in Foreman + run: | + echo "gemspec name: '$PLUGIN_NAME', path: '${{ github.workspace }}/projects/plugin'" > "bundler.d/$PLUGIN_NAME.local.rb" + if [ -d $PLUGIN_NAME/gemfile.d ] ; then + cat $PLUGIN_NAME/gemfile.d/*.rb >> bundler.d/$PLUGIN_NAME.local.rb + fi + working-directory: ${{ github.workspace }}/projects/foreman - name: Generate ${{ matrix.plugin }} npm dependencies package-lock run: npm install --package-lock-only --no-audit --legacy-peer-deps working-directory: ${{ github.workspace }}/projects/plugin - name: Install ${{ matrix.plugin }} npm dependencies run: npm ci --no-audit --legacy-peer-deps working-directory: ${{ github.workspace }}/projects/plugin + - run: sudo apt-get update + - run: sudo apt-get -qq -y install build-essential libcurl4-openssl-dev zlib1g-dev libpq-dev libvirt-dev + - name: Install gems + run: bundle install + working-directory: ${{ github.workspace }}/projects/foreman + - name: Run plugin webpack dir to test + run: ./script/plugin_webpack_directories.rb + working-directory: ${{ github.workspace }}/projects/foreman - name: Run ${{ matrix.plugin }} tests - run: npm test - working-directory: ${{ github.workspace }}/projects/plugin + run: npm run test:plugins $(echo ${{ matrix.plugin }} | awk -F'/' '{print $NF}') + working-directory: ${{ github.workspace }}/projects/foreman diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000000..773205911e8 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@theforeman/builder/babel')], +}; diff --git a/package-exclude.json b/package-exclude.json index 3b9dabad042..747d37d055f 100644 --- a/package-exclude.json +++ b/package-exclude.json @@ -1,5 +1,6 @@ { "EXCLUDE_NPM_PACKAGES": [ + "@apollo/react-testing", "@sheerun/mutationobserver-shim", "@theforeman/env", "@theforeman/eslint-plugin-foreman", diff --git a/package.json b/package.json index 7ae5676471f..ab646babe27 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,10 @@ "lint:custom": "eslint ./webpack", "foreman-js:link": "./script/npm_link_foreman_js.sh", "postlint": "./script/npm_lint_plugins.js", - "test": "tfm-test", + "test": "npx jest --setupFilesAfterEnv ./global_test_setup.js ./core_test_setup.js --testPathIgnorePatterns '/node_modules/' '/.+fixtures.+' --config ./webpack/jest.config.js", "test:watch": "tfm-test --watchAll", "test:current": "tfm-test --watch", + "test:plugins": "./script/npm_test_plugin.js", "publish-coverage": "tfm-publish-coverage", "postinstall": "./script/npm_install_plugins.js", "analyze": "./script/webpack-analyze" @@ -29,28 +30,45 @@ "react-intl": "^2.8.0" }, "devDependencies": { + "@apollo/react-testing": "^4.0.0", "@babel/core": "^7.7.0", + "@testing-library/jest-dom": "^5.3.0", + "@testing-library/react": "^10.0.2", + "@testing-library/react-hooks": "^3.4.2", "@theforeman/builder": "^13.1.0", "@theforeman/eslint-plugin-foreman": "^13.1.0", "@theforeman/eslint-plugin-rules": "^13.1.0", - "@theforeman/test": "^13.1.0", + "@theforeman/vendor-core": "^13.1.0", "@theforeman/vendor-dev": "^13.1.0", "@types/jest": "<27.0.0", "argv-parse": "^1.0.1", + "axios-mock-adapter": "^1.1.7", "babel-eslint": "^10.0.0", + "babel-jest": "^26.3.0", "babel-loader": "^8.0.0", "buffer": "^5.7.1", + "cheerio": "1.0.0-rc.10", "compression-webpack-plugin": "^10.0.0", "cross-env": "^5.2.0", "css-loader": "^6.8.1", "dotenv": "^5.0.0", + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.2", + "enzyme-to-json": "^3.4.3", "eslint": "^6.7.2", "eslint-plugin-spellcheck": "0.0.17", "graphql": "^15.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^26.4.0", + "jest-prop-type-error": "^1.1.0", + "jest-svg-transformer": "^1.0.0", + "jest-transform-graphql": "^2.1.0", "path-browserify": "^1.0.1", "prettier": "^1.19.1", "pretty-format": "26.6.2", "react-dnd-test-backend": "^9.4.0", + "react-redux-test-utils": "^0.2.0", + "react-test-renderer": "^17.0.1", "redux-mock-store": "^1.2.2", "sass": "~1.60.0", "sass-loader": "^13.3.2", @@ -59,6 +77,7 @@ "stylelint-config-standard": "^18.0.0", "tabbable": "~5.2.0", "victory-core": "~36.8.6", + "victory-legend": "~36.8.6", "victory-pie": "~36.8.6", "webpack": "^5.75.0", "webpack-bundle-analyzer": "^4.5.0", diff --git a/script/npm_test_plugin.js b/script/npm_test_plugin.js new file mode 100755 index 00000000000..cf3f59a7a3a --- /dev/null +++ b/script/npm_test_plugin.js @@ -0,0 +1,140 @@ +#!/usr/bin/env node +/* eslint-disable import/no-dynamic-require */ +/* eslint-disable no-console */ +/* eslint-disable no-var */ + +/* This script is used to run tests for all plugins that have a `lint` script defined in their package.json + To run tests for an individual plugin, pass the plugin name as the first argument to the script + For example, to run tests for the `foreman-tasks` plugin, run: `npm run test-plugin foreman-tasks` + To pass arguments to jest, pass them after the plugin name like so: `npm run test-plugin foreman-tasks -- --debug` +*/ + +var fs = require('fs'); +var path = require('path'); +var lodash = require('lodash'); +var childProcess = require('child_process'); +var { packageJsonDirsObject } = require('./plugin_webpack_directories'); + +const passedArgs = process.argv.slice(2); +const coreConfigPath = path.resolve(__dirname, '../webpack/jest.config.js'); +const coreConfig = require(coreConfigPath); + +function runChildProcess(args, pluginPath) { + return new Promise((resolve, reject) => { + const child = childProcess.spawn('npx', args, { + shell: true, + }); + // this is needed to make sure the output is not cut + let stdoutBuffer = ''; + child.stdout.on('data', data => { + stdoutBuffer += data.toString(); + const lines = stdoutBuffer.split('\n'); + stdoutBuffer = lines.pop(); + }); + + let stderrBuffer = `${pluginPath}: \n`; + child.stderr.on('data', data => { + stderrBuffer += data.toString(); + const lines = stderrBuffer.split('\n'); + stderrBuffer = lines.pop(); + lines.forEach(line => console.error(line)); + }); + child.on('close', code => { + if (stdoutBuffer) console.log(stdoutBuffer); + if (stderrBuffer) console.error(stderrBuffer); + if (code === 0) { + resolve(); + } else { + reject(new Error(`Child process exited with code ${code}`)); + } + }); + }); +} +const runTests = async () => { + var dirs = packageJsonDirsObject(); + var dirsKeys = Object.keys(dirs); + function pluginDefinesLint(pluginPath) { + var packageHasNodeModules = fs.existsSync(`${pluginPath}/node_modules`); // skip gems + var packageData = JSON.parse(fs.readFileSync(`${pluginPath}/package.json`)); + + return ( + packageHasNodeModules && packageData.scripts && packageData.scripts.lint + ); + } + if (passedArgs[0] && passedArgs[0][0] !== '-') { + // if the argument is --debug and not a plugin name npm test:plugins katello --debug + dirsKeys = dirsKeys.filter(dir => dir.endsWith(passedArgs[0])); + passedArgs.shift(); + } + function customizer(objValue, srcValue) { + if (lodash.isArray(objValue)) { + return lodash.uniq(objValue.concat(srcValue)); + } + return undefined; + } + // eslint-disable-next-line no-unused-vars + for (const dirsKey of dirsKeys) { + const pluginPath = dirs[dirsKey]; + if (pluginDefinesLint(pluginPath)) { + const testSetupFiles = [ + path.resolve(__dirname, '../webpack/global_test_setup.js'), + ]; + const testSetupPath = path.join(pluginPath, 'webpack', 'test_setup.js'); + if (fs.existsSync(testSetupPath)) { + testSetupFiles.unshift(testSetupPath); + } + const pluginConfigPath = path.join(pluginPath, 'jest.config.js'); + const combinedConfigPath = path.join( + pluginPath, + 'combined.jest.config.js' + ); + + if (fs.existsSync(pluginConfigPath)) { + // eslint-disable-next-line global-require + const pluginConfig = require(pluginConfigPath); + + const combinedConfig = lodash.mergeWith( + pluginConfig, + { + ...coreConfig, + setupFilesAfterEnv: [ + path.resolve(__dirname, '../webpack/global_test_setup.js'), + ], + }, + customizer + ); + combinedConfig.snapshotSerializers = coreConfig.snapshotSerializers; + fs.writeFileSync( + combinedConfigPath, + `module.exports = ${JSON.stringify(combinedConfig, null, 2)};`, + 'utf8' + ); + } + const pluginConfigOverride = fs.existsSync(pluginConfigPath); + const configPath = pluginConfigOverride + ? combinedConfigPath + : coreConfigPath; + const corePath = path.resolve(__dirname, '../'); + const args = [ + 'jest', + '--roots', + pluginPath, + corePath, + `--config=${configPath}`, + pluginConfigOverride + ? '' + : `--setupFilesAfterEnv ${testSetupFiles.join(' ')}`, + '--color', + ...passedArgs, + ]; + + // eslint-disable-next-line no-await-in-loop + await runChildProcess(args, pluginPath); // Run every plugin test in a separate process + if (fs.existsSync(combinedConfigPath)) { + fs.unlinkSync(combinedConfigPath); + } + } + } +}; + +runTests(); diff --git a/script/plugin_webpack_directories.js b/script/plugin_webpack_directories.js index 08d006e9c10..32bbed9a7aa 100644 --- a/script/plugin_webpack_directories.js +++ b/script/plugin_webpack_directories.js @@ -15,6 +15,19 @@ var sanitizeWebpackDirs = pluginDirs => { return splitDirs.length > 2 ? splitDirs[1] : pluginDirs; }; +var pluginPathObject = file => pluginsObj => { + var paths = {}; + Object.keys(pluginsObj.plugins).forEach(entryKey => { + if (!entryKey.includes(':')) { + const pluginPath = pluginsObj.plugins[entryKey].root; + if (fs.existsSync(path.join(pluginPath, file))) { + paths[entryKey] = pluginPath; + } + } + }); + return paths; +}; + // Get paths that have a specific file or folder var pluginPath = file => pluginsObj => { var paths = []; @@ -53,11 +66,16 @@ var getPluginDirs = stderr => var packageJsonDirs = stderr => pluginPath('package.json')(getPluginDirs(stderr)).map(path.dirname); +// Get plugin paths with the plugin name, dont assume the plugin path will have the plugin name +var packageJsonDirsObject = stderr => + pluginPathObject('package.json')(getPluginDirs(stderr)); + module.exports = { getPluginDirs, pluginNodeModules: pluginPath('node_modules'), aliasPlugins, packageJsonDirs, + packageJsonDirsObject, sanitizeWebpackDirs, pluginPath, }; diff --git a/webpack/assets/javascripts/react_app/components/TemplateGenerator/__tests__/TemplateGeneratorActions.test.js b/webpack/assets/javascripts/react_app/components/TemplateGenerator/__tests__/TemplateGeneratorActions.test.js index a3554f42fdb..05e8fba8f40 100644 --- a/webpack/assets/javascripts/react_app/components/TemplateGenerator/__tests__/TemplateGeneratorActions.test.js +++ b/webpack/assets/javascripts/react_app/components/TemplateGenerator/__tests__/TemplateGeneratorActions.test.js @@ -21,15 +21,16 @@ import * as actions from '../TemplateGeneratorActions'; jest.mock('file-saver'); jest.mock('../../../redux/API'); -beforeEach(() => { - API.post.mockImplementation(async () => scheduleResponse); - API.get.mockImplementation(async () => noContentResponse); -}); - describe('TemplateGeneratorActions', () => { + beforeAll(() => { + jest.useFakeTimers(); + }); beforeEach(() => { API.post.mockClear(); API.get.mockClear(); + + API.post.mockImplementation(async () => scheduleResponse); + API.get.mockImplementation(async () => noContentResponse); }); describe('generateTemplate', () => { @@ -55,7 +56,6 @@ describe('TemplateGeneratorActions', () => { API.get .mockImplementationOnce(async () => noContentResponse) .mockImplementationOnce(async () => generatedReportResponse); - runActionInDepth(() => actions.generateTemplate(), 3).then(callTree => { const successAction = callTree[1][1][1]; expect(successAction).toHaveProperty('type', TEMPLATE_GENERATE_SUCCESS); diff --git a/webpack/test_setup.js b/webpack/core_test_setup.js similarity index 73% rename from webpack/test_setup.js rename to webpack/core_test_setup.js index c7158276891..d22b70ab381 100644 --- a/webpack/test_setup.js +++ b/webpack/core_test_setup.js @@ -6,13 +6,20 @@ ace.config.set('themePath', ''); jest.mock('jed'); jest.mock('./assets/javascripts/react_app/Root/Context/ForemanContext', () => ({ + getForemanContext: () => ({ + context: { metadata: { version: 'mocked_version' } }, + }), + useForemanContext: () => ({ metadata: { version: 'mocked_version' } }), + useForemanSetContext: () => {}, useForemanVersion: () => 'mocked_version', useForemanSettings: () => ({ perPage: 5 }), useForemanDocUrl: () => '/url', useForemanLocation: () => ({ title: 'location' }), useForemanOrganization: () => ({ title: 'organization' }), + useForemanUser: () => ({ login: 'user' }), getHostsPageUrl: displayNewHostsPage => displayNewHostsPage ? '/new/hosts' : '/hosts', + useForemanHostsPageUrl: () => '/hosts', })); jest.mock('./assets/javascripts/react_app/common/I18n'); jest.mock('./assets/javascripts/foreman_tools', () => ({ diff --git a/webpack/global_test_setup.js b/webpack/global_test_setup.js new file mode 100644 index 00000000000..de6724309e2 --- /dev/null +++ b/webpack/global_test_setup.js @@ -0,0 +1,19 @@ +// eslint-disable-next-line import/no-unresolved, import/extensions +import 'core-js/shim'; +// eslint-disable-next-line import/no-extraneous-dependencies +import 'regenerator-runtime/runtime'; + +const { configure } = require('enzyme'); +const Adapter = require('enzyme-adapter-react-16'); + +configure({ adapter: new Adapter() }); + +// https://github.com/facebook/jest/issues/6121 +// eslint-disable-next-line no-console +const { error } = console; +// eslint-disable-next-line no-console +console.error = (message, ...args) => { + error.apply(console, args); // keep default behaviour + const err = message instanceof Error ? message : new Error(message); + throw err; +}; diff --git a/webpack/jest.config.js b/webpack/jest.config.js new file mode 100644 index 00000000000..b1c5e8a4b80 --- /dev/null +++ b/webpack/jest.config.js @@ -0,0 +1,79 @@ +/* eslint-disable spellcheck/spell-checker */ +const fs = require('fs'); +const path = require('path'); + +const nodeModules = path.resolve(__dirname, '..', 'node_modules'); +const packageJsonPath = path.resolve(__dirname, '..', 'package.json'); +const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); +const vendorCorePackageJsonPath = path.resolve( + nodeModules, + '@theforeman/vendor-core', + 'package.json' +); +const vendorCorePackageJson = JSON.parse( + fs.readFileSync(vendorCorePackageJsonPath, 'utf8') +); + +const dependencies = { + ...packageJson.dependencies, + ...packageJson.devDependencies, + ...vendorCorePackageJson.dependencies, + '@apollo/client/testing': '@apollo/client/testing', +}; // Use shared dependencies from foreman node_modules and not plugin node_modules to avoid jest errors due to multiple instances of same package + +const moduleNameMapper = {}; +Object.keys(dependencies).forEach(dep => { + moduleNameMapper[`^${dep}$`] = path.resolve(nodeModules, dep); +}); + +const foremanReactFull = path.resolve( + __dirname, + 'assets/javascripts/react_app' +); +const foremanTest = path.resolve(__dirname, 'theforeman_test_dependencies.js'); + +module.exports = { + verbose: true, + logHeapUsage: true, + maxWorkers: 2, + collectCoverage: true, + coverageReporters: ['lcov'], + coverageDirectory: `../coverage`, + setupFiles: [require.resolve('jest-prop-type-error')], + testRegex: '.*\\.test\\.js$', + testPathIgnorePatterns: [ + '/node_modules/', + '/foreman/', + '/.+fixtures.+', + 'foreman/webpack', // dont test foreman core in plugins + ], + moduleDirectories: [ + `node_modules`, + `/node_modules/@theforeman/vendor-core/node_modules`, + `node_modules/@theforeman/vendor-core/node_modules`, + '/node_modules', + ], + transform: { + '^.+\\.js?$': 'babel-jest', + '\\.(gql|graphql)$': require.resolve('jest-transform-graphql'), // for graphql-tag + }, + snapshotSerializers: [require.resolve('enzyme-to-json/serializer')], + moduleNameMapper: { + '^.+\\.(png|gif|css|scss)$': 'identity-obj-proxy', + ...moduleNameMapper, + '^dnd-core$': `${nodeModules}/dnd-core/dist/cjs`, + '^react-dnd$': `${nodeModules}/react-dnd/dist/cjs`, + '^react-dnd-html5-backend$': `${nodeModules}/react-dnd-html5-backend/dist/cjs`, + '^react-dnd-touch-backend$': `${nodeModules}/react-dnd-touch-backend/dist/cjs`, + '^react-dnd-test-backend$': `${nodeModules}/react-dnd-test-backend/dist/cjs`, + '^react-dnd-test-utils$': `${nodeModules}/react-dnd-test-utils/dist/cjs`, + '^foremanReact(.*)$': `${foremanReactFull}/$1`, + '^@theforeman/test$': foremanTest, + '^victory(.*)$': `${nodeModules}/victory$1`, + }, + globals: { + __testing__: true, + URL_PREFIX: '', + }, + resolver: require.resolve('./resolveNodeModule'), +}; diff --git a/webpack/resolveNodeModule.js b/webpack/resolveNodeModule.js new file mode 100644 index 00000000000..8acba3b6474 --- /dev/null +++ b/webpack/resolveNodeModule.js @@ -0,0 +1,61 @@ +const { modules } = require('@theforeman/vendor-core'); + +const isRequestedByVendorCore = currentFileDirectory => + (currentFileDirectory.includes('foreman-js/packages/vendor-core') || + currentFileDirectory.includes('@theforeman/vendor-core')) && + !currentFileDirectory.includes( + 'foreman-js/packages/vendor-core/node_modules' + ) && + !currentFileDirectory.includes('@theforeman/vendor-core/node_modules'); + +const getModuleToResolve = ({ sourcePath, currentFileDirectory }) => { + // map the custom foreman js module to the correct path + const requestPath = sourcePath === '.' ? './index' : sourcePath; + const sourcePathSplit = sourcePath.split('/'); + const name = sourcePathSplit[sourcePathSplit.length - 1]; + const vendorModule = modules.find(m => m.name === name); + const requestedByVendorCore = isRequestedByVendorCore(currentFileDirectory); + + const shouldResolveCustomVendorModule = modules.find( + m => m.name === name && m.hasCustomPath && !requestedByVendorCore + ); + + return shouldResolveCustomVendorModule ? vendorModule.path : requestPath; +}; + +/** + * resolve a import/require of a node module + * this method should be calld by the jest-resolver + * to resolve every require statement + * This cannot be done with changing the paths with moduleNameMapper + */ + +const resolveNodeModule = (sourcePath, currentFile) => { + const { basedir, rootDir } = currentFile; + const moduleToResolve = getModuleToResolve({ + sourcePath, + currentFileDirectory: basedir, + }); + if (sourcePath.includes('theforeman_test_dependencies')) { + console.warn( + 'import from @theforeman/test is deprecated, please remove the package and import from enzyme, axios-mock-adapter, foremanReact/testHelpers, foremanReact/common/IntegrationTestHelper directly instead.' + ); + } + let results; + try { + results = require.resolve(moduleToResolve, { + paths: [basedir], + }); + } catch (error) { + results = currentFile.defaultResolver(moduleToResolve, currentFile); + } + + return rootDir + ? results.replace( + /.*\/foreman-js\/packages/, + `${rootDir}/node_modules/@theforeman` + ) + : results; +}; + +module.exports = resolveNodeModule; diff --git a/webpack/theforeman_test_dependencies.js b/webpack/theforeman_test_dependencies.js new file mode 100644 index 00000000000..eb747effd53 --- /dev/null +++ b/webpack/theforeman_test_dependencies.js @@ -0,0 +1,36 @@ +// replaces @theforeman/test.js +import { shallow, mount, render, configure } from 'enzyme'; +import MockAdapter from 'axios-mock-adapter'; + +import { + mockWindowLocation, + classFunctionUnitTest, + shallowRenderComponentWithFixtures, + testComponentSnapshotsWithFixtures, + runActionInDepth, + testActionSnapshot, + testActionSnapshotWithFixtures, + testReducerSnapshotWithFixtures, + testSelectorsSnapshotWithFixtures, + initMockStore, +} from './assets/javascripts/react_app/common/testHelpers'; +import IntegrationTestHelper from './assets/javascripts/react_app/common/IntegrationTestHelper'; + +export { + mockWindowLocation, + classFunctionUnitTest, + shallowRenderComponentWithFixtures, + testComponentSnapshotsWithFixtures, + runActionInDepth, + testActionSnapshot, + testActionSnapshotWithFixtures, + testReducerSnapshotWithFixtures, + testSelectorsSnapshotWithFixtures, + initMockStore, + IntegrationTestHelper, + shallow, + mount, + render, + configure, + MockAdapter, +}; From 727a769853dc9e0a639493de9c0ffcafeeede6a4 Mon Sep 17 00:00:00 2001 From: MariaAga Date: Thu, 24 Oct 2024 12:46:46 +0100 Subject: [PATCH 3/7] Fixes #37639 - Use own lint instead of @theforeman --- .eslintrc | 204 ---------------- .eslintrc.js | 21 ++ .github/workflows/js_tests.yml | 2 - package.json | 12 +- .../@foreman/eslint-plugin-custom/index.js | 7 + .../eslint-plugin-custom/require-ouiaid.js | 84 +++++++ script/lint/link-eslint-plugin.js | 33 +++ script/lint/lint_core_config.js | 218 ++++++++++++++++++ script/lint/lint_generic_config.js | 66 ++++++ script/npm_lint_plugins.js | 53 ++++- webpack/resolveNodeModule.js | 1 + 11 files changed, 486 insertions(+), 215 deletions(-) delete mode 100644 .eslintrc create mode 100644 .eslintrc.js create mode 100644 script/lint/@foreman/eslint-plugin-custom/index.js create mode 100644 script/lint/@foreman/eslint-plugin-custom/require-ouiaid.js create mode 100644 script/lint/link-eslint-plugin.js create mode 100644 script/lint/lint_core_config.js create mode 100644 script/lint/lint_generic_config.js diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 76cae0d39af..00000000000 --- a/.eslintrc +++ /dev/null @@ -1,204 +0,0 @@ -{ - "plugins": [ - "@theforeman/foreman", - "spellcheck", - "@theforeman/rules" - ], - "extends": "plugin:@theforeman/foreman/core", - "rules": { - "spellcheck/spell-checker": [ - "warn", - { - "comments": false, - "identifiers": false, - "strings": true, - "lang": "en_US", - "ignoreRequire": false, - "skipWords": [ - "2xl", - "45vh", - "4xl", - "ampm", - "Ansible", - "ascii", - "auditable", - "Autocompletion", - "autogenerated", - "axios", - "bool", - "bootable", - "Borderless", - "btns", - "candlepin", - "centos", - "checkbox", - "clearbutton", - "clearfix", - "comms", - "consts", - "cpu", - "csrf", - "csv", - "datacenter", - "datastore", - "datastores", - "datepicker", - "datetime", - "datetimepicker", - "debian", - "decrement", // should be removed once https://github.com/aotaduy/eslint-plugin-spellcheck/issues/67 is resolved. - "devs", - "dgettext", - "dngettext", - "donut", - "dow", - "dropdown", - "dropdowns", - "ec2", - "erb", - "fieldset", - "fnc", - "formatter", - "fqdn", - "func", - "gettext", - "glyphicon", - "gpg", - "graphql", - "gridster", - "hostdetails", - "hostgroup", - "hostgroups", - "href", - "hypervisor", - "i386", - "internets", - "ip6", - "IPv4", - "IPv6", - "javascript", - "javascripts", - "jed", - "katello", - "keybind", - "keydown", - "keypress", - "klasses", - "labelledby", - "lang", - "ldap", - "loc", - "locs", - "lsi", - "matcher", - "menuitem", - "monokai", - "mousedown", - "mouseup", - "msg", - "nailgun", - "nat", - "navitem", - "netgroups", - "networksurl", - "ngettext", - "nic", - "nfs", - "nonpersistent", - "noopener", - "noreferrer", - "nowrap", - "npx", - "num", - "numpad", - "operatingsystem", - "operatingsystems", - "orderable", - "orgs", - "ownfield", - "paravirtual", - "patternfly", - "pficon", - "poolsurl", - "popstate", - "posinset", - "pqr", - "ptable", - "puppetclass", - "puppetclasses", - "pxe_loader", - "Pv", - "qcow2", - "rbt", - "readonly", - "redhat", - "redux", - "refetches", - "rendering", - "repo", - "resize", - "rex", - "rhel", - "safemode", - "sbs", - "scrollable", - "scsi", - "securityfailure", - "setsize", - "sizex", - "sizey", - "Solaris", - "sparc", - "storages", - "stringified", - "subcomponent", - "subcomponents", - "subnav", - "subnet", - "subnets", - "substate", - "svg", - "testoption", - "testoption", - "textarea", - "textfield", - "tfm", - "theforeman", - "timepicker", - "timerdelay", - "timeseries", - "tlv", - "tooltip", - "turbolinks", - "twipsy", - "txt", - "typeahead", - "ubuntu", - "uncheck", - "unencrypted", - "unmount", - "unordered", - "unprocessable", - "unselect", - "unstyled", - "virtualization", - "vms", - "vmware", - "vnc", - "vnic", - "webpack", - "wget", - "wss", - "x86_64", - "xml", - "xpi", - "xyz", - "yaml" - ], - "minLength": 3 - } - ], - "@theforeman/rules/require-ouiaid": ["error"], - "import/no-extraneous-dependencies": "off", - } -} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000000..f3452815619 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,21 @@ +const lintCoreConfig = require('./script/lint/lint_core_config.js'); +const lintGenericConfig = require('./script/lint/lint_generic_config.js'); + +const combinedConfig = { + ...lintCoreConfig, + ...lintGenericConfig, + rules: { + ...lintCoreConfig.rules, + ...lintGenericConfig.rules, + }, + plugins: [ + ...(lintCoreConfig.plugins || []), + ...(lintGenericConfig.plugins || []), + ], + extends: [ + ...(lintCoreConfig.extends || []), + ...(lintGenericConfig.extends || []), + ], +}; + +module.exports = combinedConfig; diff --git a/.github/workflows/js_tests.yml b/.github/workflows/js_tests.yml index 7501009fb3e..cddfe11b63e 100644 --- a/.github/workflows/js_tests.yml +++ b/.github/workflows/js_tests.yml @@ -52,8 +52,6 @@ jobs: run: npm ci --no-audit - name: Run linter run: npm run lint - - name: Run custom eslint rules Spellcheck (only warnings) and missing ouia-ids - run: npm run lint:custom - name: Run tests run: npm run test - name: Publish Coveralls diff --git a/package.json b/package.json index ab646babe27..2815f3dce8e 100644 --- a/package.json +++ b/package.json @@ -8,14 +8,15 @@ "node": ">=14.0.0 <21.0.0" }, "scripts": { - "lint": "tfm-lint", - "lint:custom": "eslint ./webpack", + "lint": "eslint ./webpack ./script", + "prelint": "node ./script/lint/link-eslint-plugin.js", "foreman-js:link": "./script/npm_link_foreman_js.sh", "postlint": "./script/npm_lint_plugins.js", "test": "npx jest --setupFilesAfterEnv ./global_test_setup.js ./core_test_setup.js --testPathIgnorePatterns '/node_modules/' '/.+fixtures.+' --config ./webpack/jest.config.js", "test:watch": "tfm-test --watchAll", "test:current": "tfm-test --watch", "test:plugins": "./script/npm_test_plugin.js", + "lint:plugins": "./script/npm_lint_plugins.js", "publish-coverage": "tfm-publish-coverage", "postinstall": "./script/npm_install_plugins.js", "analyze": "./script/webpack-analyze" @@ -36,8 +37,6 @@ "@testing-library/react": "^10.0.2", "@testing-library/react-hooks": "^3.4.2", "@theforeman/builder": "^13.1.0", - "@theforeman/eslint-plugin-foreman": "^13.1.0", - "@theforeman/eslint-plugin-rules": "^13.1.0", "@theforeman/vendor-core": "^13.1.0", "@theforeman/vendor-dev": "^13.1.0", "@types/jest": "<27.0.0", @@ -57,12 +56,17 @@ "enzyme-to-json": "^3.4.3", "eslint": "^6.7.2", "eslint-plugin-spellcheck": "0.0.17", + "eslint-plugin-patternfly-react": "0.2.0", + "eslint-plugin-jquery": "^1.5.1", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-react-hooks": "^2.1.1", "graphql": "^15.5.0", "identity-obj-proxy": "^3.0.0", "jest": "^26.4.0", "jest-prop-type-error": "^1.1.0", "jest-svg-transformer": "^1.0.0", "jest-transform-graphql": "^2.1.0", + "jsx-ast-utils": "^3.3.3", "path-browserify": "^1.0.1", "prettier": "^1.19.1", "pretty-format": "26.6.2", diff --git a/script/lint/@foreman/eslint-plugin-custom/index.js b/script/lint/@foreman/eslint-plugin-custom/index.js new file mode 100644 index 00000000000..337fc704241 --- /dev/null +++ b/script/lint/@foreman/eslint-plugin-custom/index.js @@ -0,0 +1,7 @@ +const requireOuiaidRule = require('./require-ouiaid'); + +module.exports = { + rules: { + 'require-ouiaid': requireOuiaidRule, + }, +}; diff --git a/script/lint/@foreman/eslint-plugin-custom/require-ouiaid.js b/script/lint/@foreman/eslint-plugin-custom/require-ouiaid.js new file mode 100644 index 00000000000..2254b202a99 --- /dev/null +++ b/script/lint/@foreman/eslint-plugin-custom/require-ouiaid.js @@ -0,0 +1,84 @@ +const getProp = require('jsx-ast-utils/getProp'); + +module.exports = { + create(context) { + const patternflyImports = new Set(); + const options = context.options.length + ? context.options + : [ + 'Alert', + 'Breadcrumb', + 'Button', + 'Card', + 'Checkbox', + 'Chip', + 'ChipGroup', + 'ContextSelector', + 'Dropdown', + 'DropdownItem', + 'DropdownSeparator', + 'DropdownToggle', + 'DropdownToggleCheckbox', + 'FormSelect', + 'Menu', + 'Modal', + 'ModalBoxCloseButton', + 'ModalContent', + 'Nav', + 'NavExpandable', + 'NavItem', + 'OptionsMenu', + 'Pagination', + 'Radio', + 'RowWrapper', + 'Select', + 'Switch', + 'TabButton', + 'TabContent', + 'Tab', + 'Tabs', + 'Text', + 'TextInput', + 'Title', + 'Toolbar', + 'Table', + 'TableComposable', + 'Tr', + ]; + + function addPatternflyImport(node) { + if ( + node.type === 'ImportDeclaration' && + node.source.value.startsWith('@patternfly/react') + ) { + node.specifiers.forEach(specifier => { + if (specifier.type === 'ImportSpecifier') { + patternflyImports.add(specifier.local.name); + } + }); + } + } + + function checkPatternflyComponent(node) { + if (!options.includes(node.name.name)) { + return; + } + if ( + node.type === 'JSXOpeningElement' && + patternflyImports.has(node.name.name) + ) { + const ouiaIdProp = getProp(node.attributes, 'ouiaId'); + if (!ouiaIdProp) { + context.report({ + node, + message: `ouiaId property is missing in PatternFly component '${node.name.name}'`, + }); + } + } + } + return { + ImportDeclaration: addPatternflyImport, + JSXOpeningElement: checkPatternflyComponent, + }; + }, +}; diff --git a/script/lint/link-eslint-plugin.js b/script/lint/link-eslint-plugin.js new file mode 100644 index 00000000000..c196235f9ad --- /dev/null +++ b/script/lint/link-eslint-plugin.js @@ -0,0 +1,33 @@ +/* eslint-disable no-console */ +const fs = require('fs'); +const path = require('path'); + +function linkEslintPlugin(runPath = process.cwd()) { + // instead of creating an npm package for the custom eslint plugin, we symlink it + // eslint will only search for plugins in node_modules, so we need to symlink it there + const sourceDir = path.join(__dirname, '@foreman'); + const destinationDir = path.join(runPath, 'node_modules', '@foreman'); + function createSymlink() { + fs.symlink(sourceDir, destinationDir, 'dir', err => { + if (err) { + console.error('Error creating symlink:', err); + } + }); + } + + // Check if the symlink exists and remove it if it does + fs.lstat(destinationDir, (err, stats) => { + if (!err && stats.isSymbolicLink()) { + fs.unlink(destinationDir, unlinkErr => { + if (unlinkErr) { + console.error('Error removing existing symlink:', unlinkErr); + return; + } + createSymlink(); + }); + } else { + createSymlink(); + } + }); +} +linkEslintPlugin(); diff --git a/script/lint/lint_core_config.js b/script/lint/lint_core_config.js new file mode 100644 index 00000000000..c1b3d84e16b --- /dev/null +++ b/script/lint/lint_core_config.js @@ -0,0 +1,218 @@ +module.exports = { + plugins: ['spellcheck', '@foreman/custom'], + rules: { + 'spellcheck/spell-checker': [ + 'warn', + { + comments: false, + identifiers: false, + strings: true, + lang: 'en_US', + ignoreRequire: false, + skipWords: [ + '2xl', + '45vh', + '4xl', + 'ampm', + 'Ansible', + 'ascii', + 'auditable', + 'Autocompletion', + 'autogenerated', + 'axios', + 'bool', + 'bootable', + 'Borderless', + 'btns', + 'candlepin', + 'centos', + 'checkbox', + 'clearbutton', + 'clearfix', + 'comms', + 'Composable', + 'consts', + 'cpu', + 'csrf', + 'csv', + 'datacenter', + 'datastore', + 'datastores', + 'datepicker', + 'datetime', + 'datetimepicker', + 'debian', + 'decrement', // should be removed once https://github.com/aotaduy/eslint-plugin-spellcheck/issues/67 is resolved. + 'devs', + 'dgettext', + 'dngettext', + 'donut', + 'dow', + 'dropdown', + 'dropdowns', + 'ec2', + 'erb', + 'fieldset', + 'fnc', + 'formatter', + 'fqdn', + 'func', + 'gettext', + 'glyphicon', + 'gpg', + 'graphql', + 'gridster', + 'hostdetails', + 'hostgroup', + 'hostgroups', + 'href', + 'hypervisor', + 'i386', + 'internets', + 'ip6', + 'IPv4', + 'IPv6', + 'javascript', + 'javascripts', + 'jed', + 'katello', + 'keybind', + 'keydown', + 'keypress', + 'klasses', + 'labelledby', + 'lang', + 'ldap', + 'loc', + 'locs', + 'lsi', + 'matcher', + 'menuitem', + 'monokai', + 'mousedown', + 'mouseup', + 'msg', + 'nailgun', + 'nat', + 'navitem', + 'netgroups', + 'networksurl', + 'ngettext', + 'nic', + 'nfs', + 'nonpersistent', + 'noopener', + 'noreferrer', + 'nowrap', + 'npx', + 'num', + 'numpad', + 'operatingsystem', + 'operatingsystems', + 'orderable', + 'orgs', + 'ouia', + 'ouiaid', + 'ownfield', + 'paravirtual', + 'patternfly', + 'pficon', + 'poolsurl', + 'popstate', + 'posinset', + 'pqr', + 'ptable', + 'puppetclass', + 'puppetclasses', + 'pxe_loader', + 'Pv', + 'qcow2', + 'rbt', + 'readonly', + 'redhat', + 'redux', + 'refetches', + 'rendering', + 'repo', + 'resize', + 'rex', + 'rhel', + 'safemode', + 'sbs', + 'scrollable', + 'scsi', + 'securityfailure', + 'setsize', + 'sizex', + 'sizey', + 'Solaris', + 'sparc', + 'storages', + 'stringified', + 'subcomponent', + 'subcomponents', + 'subnav', + 'subnet', + 'subnets', + 'substate', + 'svg', + 'symlink', + 'Symlink', + 'testoption', + 'testoption', + 'textarea', + 'textfield', + 'tfm', + 'theforeman', + 'timepicker', + 'timerdelay', + 'timeseries', + 'tlv', + 'tooltip', + 'turbolinks', + 'twipsy', + 'txt', + 'typeahead', + 'ubuntu', + 'uncheck', + 'unencrypted', + 'unmount', + 'unordered', + 'unprocessable', + 'unselect', + 'unstyled', + 'utf8', + 'virtualization', + 'vms', + 'vmware', + 'vnc', + 'vnic', + 'webpack', + 'wget', + 'wss', + 'x86_64', + 'xml', + 'xpi', + 'xyz', + 'yaml', + ], + minLength: 3, + }, + ], + + 'import/no-extraneous-dependencies': 'off', + 'import/no-unresolved': [ + 'error', + { + ignore: ['foremanReact/.*'], + }, + ], + 'import/extensions': [ + 'error', + { + ignore: ['foremanReact/.*'], + }, + ], + '@foreman/custom/require-ouiaid': 'error', + }, +}; diff --git a/script/lint/lint_generic_config.js b/script/lint/lint_generic_config.js new file mode 100644 index 00000000000..f0bd8c4eaa4 --- /dev/null +++ b/script/lint/lint_generic_config.js @@ -0,0 +1,66 @@ +module.exports = { + plugins: [ + 'patternfly-react', + 'promise', + 'jquery', + 'react-hooks', + // '@foreman/custom', + ], + extends: [ + 'plugin:patternfly-react/recommended', + require.resolve('@theforeman/vendor-dev/eslint.extends.js'), + 'plugin:jquery/deprecated', + ], + rules: { + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'warn', + 'max-lines': [ + 'error', + { + max: 300, + skipBlankLines: true, + skipComments: true, + }, + ], + 'no-restricted-syntax': [ + 'error', + { + selector: 'ForInStatement', + message: + 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.', + }, + { + selector: 'LabeledStatement', + message: + 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.', + }, + { + selector: 'WithStatement', + message: + '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.', + }, + ], + 'promise/prefer-await-to-then': 'error', + 'prettier/prettier': [ + 'error', + { + singleQuote: true, + trailingComma: 'es5', + }, + ], + 'import/no-unresolved': [ + 'error', + { + ignore: ['foremanReact/.*'], + }, + ], + 'import/extensions': [ + 'error', + { + ignore: ['foremanReact/.*'], + }, + ], + 'import/no-extraneous-dependencies': 'off', + // '@foreman/custom/require-ouiaid': 'error', TODO: uncomment when the plugins are ready + }, +}; diff --git a/script/npm_lint_plugins.js b/script/npm_lint_plugins.js index d98421123db..b181d42e81b 100755 --- a/script/npm_lint_plugins.js +++ b/script/npm_lint_plugins.js @@ -1,20 +1,63 @@ #!/usr/bin/env node /* eslint-disable no-var */ +/* eslint-disable no-console */ var fs = require('fs'); -var childProcess = require('child_process'); -var { packageJsonDirs } = require('./plugin_webpack_directories'); +const { spawn, execSync } = require('child_process'); +const path = require('path'); + +var { packageJsonDirsObject } = require('./plugin_webpack_directories'); + +var dirs = packageJsonDirsObject(); +var dirsKeys = Object.keys(dirs); +var passedArgs = process.argv.slice(2); function pluginDefinesLint(pluginPath) { var packageData = JSON.parse(fs.readFileSync(`${pluginPath}/package.json`)); return packageData.scripts && packageData.scripts.lint; } +if (passedArgs[0] && passedArgs[0][0] !== '-') { + // if the argument is --debug and not a plugin name npm test:plugins katello --debug + dirsKeys = dirsKeys.filter(dir => dir.endsWith(passedArgs[0])); + passedArgs.shift(); +} +try { + const scriptPath = path.join(__dirname, 'lint', 'link-eslint-plugin.js'); + execSync(`node ${scriptPath}`, { stdio: 'inherit' }); +} catch (error) { + console.error(`Error: ${error.message}`); +} +dirsKeys.forEach(dirsKey => { + const pluginPath = dirs[dirsKey]; + const pluginLintScript = pluginDefinesLint(pluginPath); + if (pluginLintScript?.includes('tfm-lint')) { + const eslintConfigPath = path.join( + __dirname, + 'lint', + '/lint_generic_config.js' + ); + const eslint = spawn( + 'npx', + ['eslint', path.join(pluginPath, 'webpack'), '-c', eslintConfigPath], + { + cwd: path.join(__dirname, '..'), + stdio: 'inherit', + } + ); + eslint.on('error', error => { + console.error(`Error: ${error.message}`); + }); -packageJsonDirs().forEach(pluginPath => { - if (pluginDefinesLint(pluginPath)) { - childProcess.spawn('npm', ['run', 'lint'], { + eslint.on('close', code => { + if (code !== 0) { + console.error(`ESLint process exited with code ${code}`); + } + }); + } else if (pluginLintScript.length) { + // Dont run foreman config lint for plugins with custom lint + spawn('npm', ['run', 'lint'], { env: process.env, cwd: pluginPath, stdio: 'inherit', diff --git a/webpack/resolveNodeModule.js b/webpack/resolveNodeModule.js index 8acba3b6474..30f3d22b315 100644 --- a/webpack/resolveNodeModule.js +++ b/webpack/resolveNodeModule.js @@ -37,6 +37,7 @@ const resolveNodeModule = (sourcePath, currentFile) => { currentFileDirectory: basedir, }); if (sourcePath.includes('theforeman_test_dependencies')) { + // eslint-disable-next-line no-console console.warn( 'import from @theforeman/test is deprecated, please remove the package and import from enzyme, axios-mock-adapter, foremanReact/testHelpers, foremanReact/common/IntegrationTestHelper directly instead.' ); From d3ff1732d80a249ab7d4fab8f0096145a0b5051f Mon Sep 17 00:00:00 2001 From: MariaAga Date: Fri, 4 Oct 2024 15:33:18 +0100 Subject: [PATCH 4/7] Refs #37882 - seperate javascript and react app imports --- webpack/assets/javascripts/react_app/common/helpers.js | 9 +++++++++ .../assets/javascripts/react_app/common/urlHelpers.js | 2 +- .../components/HostDetails/ActionsBar/actions.js | 3 +-- .../react_app/components/HostDetails/ActionsBar/index.js | 3 +-- .../react_app/components/HostStatuses/index.js | 2 +- .../components/HostsIndex/BulkActions/bulkDelete.js | 3 +-- .../components/ImpersonateIcon/ImpersonateIconActions.js | 2 +- webpack/assets/javascripts/react_app/redux/API/API.js | 2 +- .../react_app/redux/actions/notifications/index.js | 2 +- .../RegistrationCommandsPageActions.js | 2 +- .../RegistrationCommandsPageHelpers.js | 2 +- .../RegistrationCommandsPage/components/Actions.js | 2 +- .../javascripts/react_app/routes/RoutingService.js | 2 +- .../routes/common/EmptyPage/RedirectedEmptyPage.js | 2 +- 14 files changed, 22 insertions(+), 16 deletions(-) diff --git a/webpack/assets/javascripts/react_app/common/helpers.js b/webpack/assets/javascripts/react_app/common/helpers.js index f9853e6b069..e5ad1a91ca9 100644 --- a/webpack/assets/javascripts/react_app/common/helpers.js +++ b/webpack/assets/javascripts/react_app/common/helpers.js @@ -202,6 +202,13 @@ export const formatDateTime = date => { // generates an absolute, needed in case of running Foreman from a subpath export const foremanUrl = path => `${window.URL_PREFIX}${path}`; +export const visit = url => { + window.location.href = url; +}; + +export const reloadPage = () => { + window.location.reload(); +}; export default { isoCompatibleDate, bindMethods, @@ -222,4 +229,6 @@ export default { formatDateTime, foremanUrl, getWikiURL, + visit, + reloadPage, }; diff --git a/webpack/assets/javascripts/react_app/common/urlHelpers.js b/webpack/assets/javascripts/react_app/common/urlHelpers.js index 8d15d9dda87..de5e54227f7 100644 --- a/webpack/assets/javascripts/react_app/common/urlHelpers.js +++ b/webpack/assets/javascripts/react_app/common/urlHelpers.js @@ -1,6 +1,6 @@ import URI from 'urijs'; -import { visit } from '../../foreman_navigation'; +import { visit } from './helpers'; /** * Build a url from given controller, action and id diff --git a/webpack/assets/javascripts/react_app/components/HostDetails/ActionsBar/actions.js b/webpack/assets/javascripts/react_app/components/HostDetails/ActionsBar/actions.js index 5c161a7e11e..85a374b3454 100644 --- a/webpack/assets/javascripts/react_app/components/HostDetails/ActionsBar/actions.js +++ b/webpack/assets/javascripts/react_app/components/HostDetails/ActionsBar/actions.js @@ -1,7 +1,6 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; -import { visit } from '../../../../foreman_navigation'; -import { foremanUrl } from '../../../common/helpers'; +import { visit, foremanUrl } from '../../../common/helpers'; import { sprintf, translate as __ } from '../../../common/I18n'; import { openConfirmModal } from '../../ConfirmModal'; import { APIActions } from '../../../redux/API'; diff --git a/webpack/assets/javascripts/react_app/components/HostDetails/ActionsBar/index.js b/webpack/assets/javascripts/react_app/components/HostDetails/ActionsBar/index.js index 4570a2f249d..f5f307a505f 100644 --- a/webpack/assets/javascripts/react_app/components/HostDetails/ActionsBar/index.js +++ b/webpack/assets/javascripts/react_app/components/HostDetails/ActionsBar/index.js @@ -18,10 +18,9 @@ import { BuildIcon, TerminalIcon, } from '@patternfly/react-icons'; -import { visit } from '../../../../foreman_navigation'; import { translate as __ } from '../../../common/I18n'; import { selectKebabItems } from './Selectors'; -import { foremanUrl } from '../../../common/helpers'; +import { visit, foremanUrl } from '../../../common/helpers'; import { cancelBuild, deleteHost, isHostTurnOn } from './actions'; import { useForemanSettings } from '../../../Root/Context/ForemanContext'; import BuildModal from './BuildModal'; diff --git a/webpack/assets/javascripts/react_app/components/HostStatuses/index.js b/webpack/assets/javascripts/react_app/components/HostStatuses/index.js index 3849896ca11..afd5dd7886d 100644 --- a/webpack/assets/javascripts/react_app/components/HostStatuses/index.js +++ b/webpack/assets/javascripts/react_app/components/HostStatuses/index.js @@ -1,7 +1,7 @@ import React, { Fragment } from 'react'; import { useSelector } from 'react-redux'; import { PageSection, Grid, GridItem, Title } from '@patternfly/react-core'; -import { foremanUrl } from '../../../foreman_tools'; +import { foremanUrl } from '../../common/helpers'; import { useAPI } from '../../common/hooks/API/APIHooks'; import Status from './Status'; import StatusSkeleton from './Status/StatusSkeleton'; diff --git a/webpack/assets/javascripts/react_app/components/HostsIndex/BulkActions/bulkDelete.js b/webpack/assets/javascripts/react_app/components/HostsIndex/BulkActions/bulkDelete.js index e6d04bff2a8..be546dc3372 100644 --- a/webpack/assets/javascripts/react_app/components/HostsIndex/BulkActions/bulkDelete.js +++ b/webpack/assets/javascripts/react_app/components/HostsIndex/BulkActions/bulkDelete.js @@ -1,7 +1,6 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; -import { visit } from '../../../../foreman_navigation'; -import { foremanUrl } from '../../../common/helpers'; +import { visit, foremanUrl } from '../../../common/helpers'; import { sprintf, translate as __ } from '../../../common/I18n'; import { openConfirmModal } from '../../ConfirmModal'; import { APIActions } from '../../../redux/API'; diff --git a/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIconActions.js b/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIconActions.js index 0a8e01050fe..cca7c5d4c2f 100644 --- a/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIconActions.js +++ b/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIconActions.js @@ -1,5 +1,5 @@ import { API } from '../../../../redux/API'; -import { foremanUrl } from '../../../../../foreman_tools'; +import { foremanUrl } from '../../../../common/helpers'; import { addToast } from '../../../ToastsList'; diff --git a/webpack/assets/javascripts/react_app/redux/API/API.js b/webpack/assets/javascripts/react_app/redux/API/API.js index cf766e7039c..1a21cf3df54 100644 --- a/webpack/assets/javascripts/react_app/redux/API/API.js +++ b/webpack/assets/javascripts/react_app/redux/API/API.js @@ -1,6 +1,6 @@ import axios from 'axios'; import './APITestSetup'; -import { foremanUrl } from '../../../foreman_tools'; +import { foremanUrl } from '../../common/helpers'; const getcsrfToken = () => { const token = document.querySelector('meta[name="csrf-token"]'); diff --git a/webpack/assets/javascripts/react_app/redux/actions/notifications/index.js b/webpack/assets/javascripts/react_app/redux/actions/notifications/index.js index 7b340e4bf95..9373901024b 100644 --- a/webpack/assets/javascripts/react_app/redux/actions/notifications/index.js +++ b/webpack/assets/javascripts/react_app/redux/actions/notifications/index.js @@ -10,7 +10,7 @@ import { } from '../../consts'; import * as sessionStorage from '../../../components/notifications/NotificationDrawerSessionStorage'; import { API, get } from '../../API'; -import { reloadPage } from '../../../../foreman_navigation'; +import { reloadPage } from '../../../common/helpers'; import { stopInterval, withInterval, diff --git a/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPageActions.js b/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPageActions.js index c98599ca324..84ea051c9e5 100644 --- a/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPageActions.js +++ b/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPageActions.js @@ -1,4 +1,4 @@ -import { foremanUrl } from '../../../../foreman_tools'; +import { foremanUrl } from '../../../common/helpers'; import { get, post } from '../../../redux/API'; import { diff --git a/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPageHelpers.js b/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPageHelpers.js index 44849b41ade..e81b3adb28e 100644 --- a/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPageHelpers.js +++ b/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPageHelpers.js @@ -2,7 +2,7 @@ import React from 'react'; import { FormSelectOption } from '@patternfly/react-core'; -import { foremanUrl } from '../../../../foreman_tools'; +import { foremanUrl } from '../../../common/helpers'; import { sprintf, translate as __ } from '../../../common/I18n'; // Form helpers diff --git a/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/components/Actions.js b/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/components/Actions.js index c77c78cf51c..e76aada4e7d 100644 --- a/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/components/Actions.js +++ b/webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/components/Actions.js @@ -5,7 +5,7 @@ import { Link } from 'react-router-dom'; import { ActionGroup, Button } from '@patternfly/react-core'; import { translate as __ } from '../../../../common/I18n'; -import { foremanUrl } from '../../../../../foreman_tools'; +import { foremanUrl } from '../../../../common/helpers'; const Actions = ({ isLoading, isGenerating, handleSubmit, invalidFields }) => ( <> diff --git a/webpack/assets/javascripts/react_app/routes/RoutingService.js b/webpack/assets/javascripts/react_app/routes/RoutingService.js index 9f463dcc070..ac7bd65ea68 100644 --- a/webpack/assets/javascripts/react_app/routes/RoutingService.js +++ b/webpack/assets/javascripts/react_app/routes/RoutingService.js @@ -1,6 +1,6 @@ import { Route } from 'react-router-dom'; import React from 'react'; -import { visit } from '../../foreman_navigation'; +import { visit } from '../common/helpers'; import { addGlobalFill } from '../components/common/Fill/GlobalFill'; let currentPath = window.location.href; diff --git a/webpack/assets/javascripts/react_app/routes/common/EmptyPage/RedirectedEmptyPage.js b/webpack/assets/javascripts/react_app/routes/common/EmptyPage/RedirectedEmptyPage.js index d1f1b7014c8..1407501d96f 100644 --- a/webpack/assets/javascripts/react_app/routes/common/EmptyPage/RedirectedEmptyPage.js +++ b/webpack/assets/javascripts/react_app/routes/common/EmptyPage/RedirectedEmptyPage.js @@ -4,7 +4,7 @@ import { Button } from '@patternfly/react-core'; import { useHistory } from 'react-router-dom'; import { SearchIcon } from '@patternfly/react-icons'; import { translate as __ } from '../../../common/I18n'; -import { visit } from '../../../../foreman_navigation'; +import { visit } from '../../../common/helpers'; import { EmptyStatePattern } from '../../../components/common/EmptyState'; const RedirectedEmptyPage = ({ location: { state = {} } }) => { From e3af1c6f53defc0b1c3294500dd91f913a2e8bc1 Mon Sep 17 00:00:00 2001 From: MariaAga Date: Fri, 4 Oct 2024 15:35:41 +0100 Subject: [PATCH 5/7] Refs #37882 - move css from vendor to foreman --- app/views/layouts/base.html.erb | 1 - developer_docs/adding-dependencies.asciidoc | 32 ------------------- .../javascripts/react_app/Root/ReactApp.js | 1 + .../react_app/common/scss/mixins.scss | 21 ++++++++++++ .../react_app/common/scss/vendor-core.scss | 22 +++++++++++++ .../react_app/common/variables.scss | 23 +++++++++++-- .../ImpersonateIcon/ImpersonateIcon.scss | 2 +- .../TaxonomySwitcher/TaxonomyDropdown.scss | 2 +- .../components/LoginPage/LoginPage.scss | 2 +- .../components/PF4/Bookmarks/bookmarks.scss | 2 +- .../PasswordStrength/PasswordStrength.scss | 2 +- .../components/SearchBar/SearchBar.scss | 2 +- .../forms/DateTime/DateTimeOverrides.scss | 2 +- .../components/common/forms/NumericInput.scss | 4 +-- 14 files changed, 74 insertions(+), 44 deletions(-) delete mode 100644 developer_docs/adding-dependencies.asciidoc create mode 100644 webpack/assets/javascripts/react_app/common/scss/mixins.scss create mode 100644 webpack/assets/javascripts/react_app/common/scss/vendor-core.scss diff --git a/app/views/layouts/base.html.erb b/app/views/layouts/base.html.erb index 7099e4d458f..1fe19a38a5c 100644 --- a/app/views/layouts/base.html.erb +++ b/app/views/layouts/base.html.erb @@ -10,7 +10,6 @@ <%= favicon_link_tag "favicon.ico"%> - <%= get_webpack_foreman_vendor_css %> <%= stylesheet_link_tag 'application' %> <%= yield(:stylesheets) %> diff --git a/developer_docs/adding-dependencies.asciidoc b/developer_docs/adding-dependencies.asciidoc deleted file mode 100644 index 9cbaeea321b..00000000000 --- a/developer_docs/adding-dependencies.asciidoc +++ /dev/null @@ -1,32 +0,0 @@ -[[adding-js-dependencies]] -= NPM dependencies -:toc: right -:toclevels: 5 - -## Using/Adding/updating NPM dependencies - -Foreman manage npm dependencies with a seperate project called `@theforeman/vendor` which responsible to deliver 3rd-party modules to foreman and its plugins. -Foreman and its plugins consumes `@theforeman/vendor` project from `npm` in development and from `rpm` in production. - -`@theforeman/vendor` lives inside a monorepo together with other foreman javascript tools in a project called https://github.com/theforeman/foreman-js[foreman-js] - - -https://github.com/theforeman/foreman-js/tree/master/packages/vendor[Read more about @theforeman/vendor] - -## Consuming `foreman-js` projects from source (locally) - -Clone, install, build and link the `foreman-js` project to foreman: - -```sh -git clone git@github.com:theforeman/foreman-js.git -cd foreman-js -npm install -npm run build -npm run link -- --location ../foreman -``` - -To read to full documentation, please go to `foreman-js` contribution guide: -https://github.com/theforeman/foreman-js/blob/master/CONTRIBUTING.md - -**NOTICE: You must remove `./node_modules/@theforeman` before running `npm install`. -If not, it will destroy your `foreman-js` copy.** diff --git a/webpack/assets/javascripts/react_app/Root/ReactApp.js b/webpack/assets/javascripts/react_app/Root/ReactApp.js index 4af38571a2a..0f3d70fd532 100644 --- a/webpack/assets/javascripts/react_app/Root/ReactApp.js +++ b/webpack/assets/javascripts/react_app/Root/ReactApp.js @@ -11,6 +11,7 @@ import apolloClient from './apollo'; import ToastsList from '../components/ToastsList'; import ErrorBoundary from '../components/common/ErrorBoundary'; import ConfirmModal from '../components/ConfirmModal'; +import '../common/scss/vendor-core.scss'; const ReactApp = ({ layout, metadata, toasts }) => { const [context, setContext] = useState({ metadata }); diff --git a/webpack/assets/javascripts/react_app/common/scss/mixins.scss b/webpack/assets/javascripts/react_app/common/scss/mixins.scss new file mode 100644 index 00000000000..f106521f856 --- /dev/null +++ b/webpack/assets/javascripts/react_app/common/scss/mixins.scss @@ -0,0 +1,21 @@ +// Mixins - Bootstrap overrides +// ------------------- +@mixin box-shadow($shadow...) { + -webkit-box-shadow: $shadow; // iOS <4.3 & Android <4.1 + box-shadow: $shadow; +} + +// Form control outline +@mixin form-control-outline($color: $input-border-focus){ + $color-rgba: rgba(red($color), green($color), blue($color), .6); + &:focus { + border-color: $color; + outline: 0 !important; + @include box-shadow(unquote("inset 0 1px 1px rgba(3, 3, 3, 0.075), 0 0 8px #{$color-rgba}")); + } +} +/** + Third Party mixins imports here +*/ +@import '~patternfly/dist/sass/patternfly/bootstrap-mixin-overrides'; +@import '~patternfly/dist/sass/patternfly/mixins'; diff --git a/webpack/assets/javascripts/react_app/common/scss/vendor-core.scss b/webpack/assets/javascripts/react_app/common/scss/vendor-core.scss new file mode 100644 index 00000000000..a4c432652c5 --- /dev/null +++ b/webpack/assets/javascripts/react_app/common/scss/vendor-core.scss @@ -0,0 +1,22 @@ +/** + Third Party libraries imports here +*/ +@import '../variables'; +@import './mixins'; + +@import '~multiselect/css/multi-select.css'; +@import '~react-diff-view/style/index.css'; +@import '~select2/select2-bootstrap.css'; +@import '~select2/select2.css'; +@import "~dsmorse-gridster/dist/jquery.gridster"; +@import "~datatables.net-bs/css/dataTables.bootstrap.css"; +// @import "~@redhat-cloud-services/frontend-components/index.css"; + +// patternfly v3 +@import '~patternfly-react/dist/sass/_patternfly-react.scss'; +@import '~patternfly-react-extensions/dist/sass/_select.scss'; +@import '~patternfly/dist/sass/patternfly/_loading-state'; + +// patternfly v4 +@import '~@patternfly/patternfly/patternfly'; +@import '~@patternfly/patternfly/patternfly-addons'; diff --git a/webpack/assets/javascripts/react_app/common/variables.scss b/webpack/assets/javascripts/react_app/common/variables.scss index f7485b1fc2b..37f34808fe3 100644 --- a/webpack/assets/javascripts/react_app/common/variables.scss +++ b/webpack/assets/javascripts/react_app/common/variables.scss @@ -1,3 +1,22 @@ -@import '~@theforeman/vendor/scss/variables.scss'; +/** + Third Party variables imports here +*/ +// patternfly v3 +$font-path: '~patternfly/dist/fonts/'; +$img-path: '~patternfly/dist/img/'; +$icon-font-path: '~patternfly/dist/fonts/'; -$header-max-width: calc(#{$pf-global--breakpoint--lg} + 70px); //TODO move into @theforeman/vendor/scss/variables +// patternfly v4 +$pf-global--font-path: '~@patternfly/patternfly/assets/fonts'; +$fa-font-path: '~@patternfly/patternfly/assets/fonts/webfonts'; +$pf-global--fonticon-path: '~@patternfly/patternfly/assets/pficon'; +$pf-global--image-path: '~@patternfly/patternfly/assets/images'; + +// patternfly v3 +@import '~bootstrap-sass/assets/stylesheets/bootstrap/variables'; +@import '~patternfly/dist/sass/patternfly/variables'; + +// patternfly v4 +@import '~@patternfly/patternfly/base/patternfly-variables'; + +$header-max-width: calc(#{$pf-global--breakpoint--lg} + 70px); diff --git a/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIcon.scss b/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIcon.scss index fee44434dbc..7b6b05a1fb1 100644 --- a/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIcon.scss +++ b/webpack/assets/javascripts/react_app/components/Layout/components/ImpersonateIcon/ImpersonateIcon.scss @@ -1,4 +1,4 @@ -@import "~@theforeman/vendor/scss/variables"; +@import "../../../../common/variables"; @keyframes blink { 0% { diff --git a/webpack/assets/javascripts/react_app/components/Layout/components/TaxonomySwitcher/TaxonomyDropdown.scss b/webpack/assets/javascripts/react_app/components/Layout/components/TaxonomySwitcher/TaxonomyDropdown.scss index 5f7e814d201..2f8ea071f87 100644 --- a/webpack/assets/javascripts/react_app/components/Layout/components/TaxonomySwitcher/TaxonomyDropdown.scss +++ b/webpack/assets/javascripts/react_app/components/Layout/components/TaxonomySwitcher/TaxonomyDropdown.scss @@ -1,4 +1,4 @@ -@import '~@theforeman/vendor/scss/variables'; +@import '../../../../common/variables.scss'; .pf-c-masthead .pf-c-toolbar { .pf-c-context-selector__menu-search { diff --git a/webpack/assets/javascripts/react_app/components/LoginPage/LoginPage.scss b/webpack/assets/javascripts/react_app/components/LoginPage/LoginPage.scss index c0567e34b7c..5827565ddaa 100644 --- a/webpack/assets/javascripts/react_app/components/LoginPage/LoginPage.scss +++ b/webpack/assets/javascripts/react_app/components/LoginPage/LoginPage.scss @@ -1,4 +1,4 @@ -@import '~@theforeman/vendor/scss/variables'; +@import '../../common/variables.scss'; $caption_font_weight: 600; $background_image: url('../LoginPage/background.svg'); diff --git a/webpack/assets/javascripts/react_app/components/PF4/Bookmarks/bookmarks.scss b/webpack/assets/javascripts/react_app/components/PF4/Bookmarks/bookmarks.scss index b41b45aad74..5fdad1912c7 100644 --- a/webpack/assets/javascripts/react_app/components/PF4/Bookmarks/bookmarks.scss +++ b/webpack/assets/javascripts/react_app/components/PF4/Bookmarks/bookmarks.scss @@ -1,4 +1,4 @@ -@import '~@theforeman/vendor/scss/variables'; +@import '../../../common/variables.scss'; .bookmarks-dropdown-item { word-break: break-word; diff --git a/webpack/assets/javascripts/react_app/components/PasswordStrength/PasswordStrength.scss b/webpack/assets/javascripts/react_app/components/PasswordStrength/PasswordStrength.scss index db05e547a3c..a133d6176cf 100644 --- a/webpack/assets/javascripts/react_app/components/PasswordStrength/PasswordStrength.scss +++ b/webpack/assets/javascripts/react_app/components/PasswordStrength/PasswordStrength.scss @@ -1,5 +1,5 @@ -@import "~@theforeman/vendor/scss/variables"; @import '../../common/colors.scss'; +@import '../../common/variables.scss'; .ReactPasswordStrength { .ReactPasswordStrength-input { diff --git a/webpack/assets/javascripts/react_app/components/SearchBar/SearchBar.scss b/webpack/assets/javascripts/react_app/components/SearchBar/SearchBar.scss index 1d3c880ace0..9a82d5fa94b 100644 --- a/webpack/assets/javascripts/react_app/components/SearchBar/SearchBar.scss +++ b/webpack/assets/javascripts/react_app/components/SearchBar/SearchBar.scss @@ -1,4 +1,4 @@ -@import '~@theforeman/vendor/scss/variables'; +@import '../../common//variables.scss'; .autocomplete-search { width: 100%; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/DateTime/DateTimeOverrides.scss b/webpack/assets/javascripts/react_app/components/common/forms/DateTime/DateTimeOverrides.scss index 31c6f3a6c93..4fd50975cce 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/DateTime/DateTimeOverrides.scss +++ b/webpack/assets/javascripts/react_app/components/common/forms/DateTime/DateTimeOverrides.scss @@ -1,4 +1,4 @@ -@import "~@theforeman/vendor/scss/variables"; +@import "../../../../common/variables.scss"; $screen-md: 992px !default; $screen-md-min: $screen-md !default; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/NumericInput.scss b/webpack/assets/javascripts/react_app/components/common/forms/NumericInput.scss index 1e06824d4cd..305999c1489 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/NumericInput.scss +++ b/webpack/assets/javascripts/react_app/components/common/forms/NumericInput.scss @@ -1,5 +1,5 @@ -@import "~@theforeman/vendor/scss/variables"; -@import "~@theforeman/vendor/scss/mixins"; +@import "../../../common/variables"; +@import "../../../common/scss/mixins"; .foreman-numeric-input { position: relative; From e3a26fc46a77e2c51edf8a0d49dabdb23040ddc5 Mon Sep 17 00:00:00 2001 From: MariaAga Date: Tue, 8 Oct 2024 16:03:49 +0100 Subject: [PATCH 6/7] Fixes #37882 - Remove @theforeman/vendor --- .npmrc | 1 - app/assets/javascripts/application.js | 2 +- app/assets/javascripts/host_edit.js | 6 +- app/assets/javascripts/subnets.js | 2 +- app/helpers/reactjs_helper.rb | 7 +- app/views/layouts/base.html.erb | 5 +- config/webpack.config.js | 53 ++++++-- config/webpack.vendor.js | 123 +++++++++++++++++- package.json | 92 ++++++++++++- webpack/assets/javascripts/bundle.js | 4 + webpack/assets/javascripts/exportAll.js | 7 +- webpack/assets/javascripts/jquery.js | 15 +++ .../javascripts/react_app/Root/ReactApp.js | 1 - .../common/forms/OrderableSelect/index.js | 2 +- 14 files changed, 290 insertions(+), 30 deletions(-) create mode 100644 webpack/assets/javascripts/jquery.js diff --git a/.npmrc b/.npmrc index d5831dd5188..b6f27f13595 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1 @@ engine-strict=true -legacy-peer-deps=true diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 25babb1b055..582ed1bb9c0 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -80,7 +80,7 @@ function onContentLoad() { password_caps_lock_hint(); tfm.i18n.intl.ready.then(function() { - var tz = jstz.determine(); + var tz = tfm.jstz.determine(); $.cookie('timezone', tz.name(), { path: '/', secure: location.protocol === 'https:', diff --git a/app/assets/javascripts/host_edit.js b/app/assets/javascripts/host_edit.js index 7c2f18ab8b6..19eeb147e13 100644 --- a/app/assets/javascripts/host_edit.js +++ b/app/assets/javascripts/host_edit.js @@ -402,12 +402,12 @@ function serializeForm() { } function subnet_contains(network, cidr, ip) { - if (!ip || 0 === ip.length || !ipaddr.isValid(ip)) { + if (!ip || 0 === ip.length || !tfm.ipaddr.isValid(ip)) { return; } - var addr = ipaddr.parse(ip); - var range = ipaddr.parse(network); + var addr = tfm.ipaddr.parse(ip); + var range = tfm.ipaddr.parse(network); return addr.match(range, cidr); } diff --git a/app/assets/javascripts/subnets.js b/app/assets/javascripts/subnets.js index 19db0e569cd..943e67bd430 100644 --- a/app/assets/javascripts/subnets.js +++ b/app/assets/javascripts/subnets.js @@ -69,7 +69,7 @@ function subnetMaskChanged(field) { } if ($('input[id^=subnet_type_]:checked').val() === 'Subnet::Ipv4') { try { - var cidr = ipaddr.IPv4.parse(mask).prefixLengthFromSubnetMask(); + var cidr = tfm.ipaddr.IPv4.parse(mask).prefixLengthFromSubnetMask(); } catch (err) { var cidr = ''; } diff --git a/app/helpers/reactjs_helper.rb b/app/helpers/reactjs_helper.rb index a09381c2372..6afdc4f5ec4 100644 --- a/app/helpers/reactjs_helper.rb +++ b/app/helpers/reactjs_helper.rb @@ -36,13 +36,8 @@ def get_webpack_chunk(name, extension) data['assetsByChunkName'][name]&.find { |value| value.end_with?(".#{extension}") } end - def get_webpack_foreman_vendor_js - foreman_vendor_js = get_webpack_chunk('foreman-vendor', 'js') - javascript_include_tag("/webpack/#{foreman_vendor_js}") - end - def get_webpack_foreman_vendor_css - foreman_vendor_css = get_webpack_chunk('foreman-vendor', 'css') + foreman_vendor_css = get_webpack_chunk('vendorStyles', 'css') stylesheet_link_tag("/webpack/#{foreman_vendor_css}") end diff --git a/app/views/layouts/base.html.erb b/app/views/layouts/base.html.erb index 1fe19a38a5c..e94f1e5df54 100644 --- a/app/views/layouts/base.html.erb +++ b/app/views/layouts/base.html.erb @@ -10,6 +10,7 @@ <%= favicon_link_tag "favicon.ico"%> + <%= get_webpack_foreman_vendor_css %> <%= stylesheet_link_tag 'application' %> <%= yield(:stylesheets) %> @@ -35,10 +36,10 @@ - <%= get_webpack_foreman_vendor_js %> + <%= javascript_include_tag("/webpack/#{get_webpack_chunk('vendor', 'js')}") %> - <%= javascript_include_tag("/webpack/#{get_webpack_chunk('bundle', 'js')}") %> <%= javascript_include_tag("/webpack/#{get_webpack_chunk('reactExports', 'js')}") %> + <%= javascript_include_tag("/webpack/#{get_webpack_chunk('bundle', 'js')}") %> <%= javascript_include_tag 'application' %> <%= webpacked_plugins_with_global_js %> diff --git a/config/webpack.config.js b/config/webpack.config.js index 17c8186432e..cac3f52b391 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -4,9 +4,10 @@ var path = require('path'); var webpack = require('webpack'); const dotenv = require('dotenv'); +const root = path.resolve(__dirname, '..'); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); + dotenv.config(); -var ForemanVendorPlugin = require('@theforeman/vendor') - .WebpackForemanVendorPlugin; var StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin; var vendorEntry = require('./webpack.vendor'); var fs = require('fs'); @@ -15,6 +16,18 @@ var pluginUtils = require('../script/plugin_webpack_directories'); var { generateExportsFile }= require('../webpack/assets/javascripts/exportAll'); var CompressionPlugin = require('compression-webpack-plugin'); +const packageJsonPath = path.resolve(__dirname,'..', 'package.json'); +const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); +const dependencies = packageJson.dependencies || {}; +const devDependencies = packageJson.devDependencies || {}; +const allDependencies = { ...dependencies, ...devDependencies }; +const shared = isPlugin => Object.keys(allDependencies).map(dep => ({ + [dep]: { + eager: !isPlugin, // core should load all dependencies eagerly so they will be available for plugins + singleton: true, + requiredVersion: allDependencies[dep], + }})); + class AddRuntimeRequirement { // to avoid "webpackRequire.l is not a function" error // enables use of webpack require inside promise new promise @@ -79,11 +92,18 @@ const commonConfig = function() { os: require.resolve('os-browserify'), }, alias: { + 'patternfly-react$': path.resolve(__dirname,'..', 'node_modules/patternfly-react/dist/js/index.js'), // to avoid circular dependency in dist/esm + '/node_modules/jquery': path.resolve(__dirname, '..', 'webpack/assets/javascripts/jquery.js'), + 'jquery': path.resolve(__dirname, '..', 'webpack/assets/javascripts/jquery.js'), foremanReact: path.join( __dirname, '../webpack/assets/javascripts/react_app' ), + 'react/jsx-runtime': 'react/jsx-runtime.js', // for react-dnd + 'react/jsx-dev-runtime': 'react/jsx-dev-runtime.js', // for react-dnd + }, + }, resolveLoader: { modules: [path.resolve(__dirname, '..', 'node_modules')], @@ -117,9 +137,6 @@ const commonConfig = function() { ], }, plugins: [ - new ForemanVendorPlugin({ - mode, - }), new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify(mode), @@ -160,13 +177,18 @@ const coreConfig = function() { } config.entry = { + /* keep bundle entry files and reactExports seperate to avoid late loading issues of mixed files, import in react_app only from react_app and node_modules */ bundle: { import: bundleEntry, dependOn: ['vendor', 'reactExports'] }, - vendor: vendorEntry, - reactExports: path.join( + reactExports: { + import: path.join( __dirname, '..', 'webpack/assets/javascripts/all_react_app_exports.js' - ), + ), + dependOn: 'vendor', + }, + vendor: vendorEntry, + vendorStyles: path.join(__dirname, '..', 'webpack/assets/javascripts/react_app/common/scss/vendor-core.scss'), }; config.output = { path: path.join(__dirname, '..', 'public', 'webpack'), @@ -179,9 +201,12 @@ const coreConfig = function() { }; var plugins = config.plugins; + plugins.push( + new MiniCssExtractPlugin()); plugins.push( new ModuleFederationPlugin({ name: 'foremanReact', + shared: shared(false), }) ); plugins.push( @@ -191,8 +216,10 @@ const coreConfig = function() { ); config.plugins = plugins; var rules = config.module.rules; + rules.push({ test: /\.(sa|sc|c)ss$/, + exclude: /vendor-core/i, use: [ { loader: 'style-loader', @@ -205,6 +232,14 @@ const coreConfig = function() { 'sass-loader', ], }); + rules.push({ + test: /vendor-core/i, + use: [ + MiniCssExtractPlugin.loader, + 'css-loader', + 'sass-loader', + ], + }); config.module.rules = rules; return config; }; @@ -276,8 +311,10 @@ const pluginConfig = function(plugin) { name: pluginName, filename: pluginName + '_remoteEntry.js', exposes: pluginEntries, + shared: shared(true), }) ); + config.plugins = plugins; var rules = config.module.rules; rules.push({ diff --git a/config/webpack.vendor.js b/config/webpack.vendor.js index d6f31b32227..25f29718e8c 100644 --- a/config/webpack.vendor.js +++ b/config/webpack.vendor.js @@ -1 +1,122 @@ -module.exports = ['react-intl', 'intl']; +/* eslint-disable */ + +module.exports = [ + 'intl', + /** + * React related + */ + '@apollo/client', + '@apollo/client/link/batch-http', + '@reduxjs/toolkit', + 'core-js/shim', + 'regenerator-runtime/runtime', + 'formik', + 'rc-input-number', + 'react', + 'react-ace', + 'react-dom', + 'react-dnd', + 'react-dnd-html5-backend', + 'react-debounce-input', + 'react-diff-view', + 'react-ellipsis-with-tooltip', + 'react-onclickoutside', + 'react-password-strength', + 'react-router-dom', + 'react-router-bootstrap', + 'react-loading-skeleton', + 'react-redux', + 'redux', + 'redux-logger', + 'redux-thunk', + 'reselect', + 'prop-types', + 'classnames', + 'seamless-immutable', + 'connected-react-router', + 'react-helmet', + 'react-intl', + + /** + * Patternfly related + */ + 'patternfly-react', + 'patternfly-react-extensions', + '@patternfly/react-core', + '@patternfly/react-icons', + '@patternfly/react-table', + '@patternfly/react-tokens', + '@patternfly/react-styles', + '@patternfly/react-charts', + // '@redhat-cloud-services/frontend-components', + + /** + * ace-builds related + */ + 'ace-builds', + 'ace-builds/src-noconflict/ace', + 'ace-builds/src-noconflict/ext-language_tools', + 'ace-builds/src-noconflict/mode-ruby', + 'ace-builds/src-noconflict/mode-json', + 'ace-builds/src-noconflict/mode-sh', + 'ace-builds/src-noconflict/mode-html_ruby', + 'ace-builds/src-noconflict/mode-xml', + 'ace-builds/src-noconflict/mode-yaml', + 'ace-builds/src-noconflict/theme-github', + 'ace-builds/src-noconflict/theme-monokai', + 'ace-builds/src-noconflict/keybinding-vim', + 'ace-builds/src-noconflict/keybinding-emacs', + 'ace-builds/src-min-noconflict/ext-searchbox', + + /** + * UUID + */ + 'uuid', + 'uuid/v1', + 'uuid/v3', + 'uuid/v4', + 'uuid/v5', + + 'jstz', + 'diff', + /** + * Custom modules + */ + // { + // name: 'jquery', + // path: '@theforeman/vendor-core/lib/customModules/jquery.js', + // }, + // { + // name: 'jstz', + // window: 'jstz', + // }, + // { + // name: 'ipaddr.js', + // window: 'ipaddr', + // }, + // { + // name: 'diff', + // window: 'diff', + // }, + + /** + * Other packages + */ + 'history', + 'number_helpers', + 'lodash', + 'axios', + 'file-saver', + 'humanize-duration', + 'unidiff', + 'urijs', + 'yup', + 'select2', + 'multiselect', + '@novnc/novnc/core/rfb', + '@novnc/novnc', + + // '@spice-project/spice-html5', + // '@webcomponents/webcomponentsjs/webcomponents-bundle', + // '@webcomponents/webcomponentsjs/custom-elements-es5-adapter', +]; diff --git a/package.json b/package.json index 2815f3dce8e..693a5fc4eec 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "description": "Foreman isn't really a node module, these are just dependencies needed to build the webpack bundle. 'dependencies' are the asset libraries in use and 'devDependencies' are used for the build process.", "private": true, "engines": { - "node": ">=14.0.0 <21.0.0" + "node": ">=14.0.0 <21.0.0", + "npm": ">=8.0.0" }, "scripts": { "lint": "eslint ./webpack ./script", @@ -22,13 +23,79 @@ "analyze": "./script/webpack-analyze" }, "dependencies": { + "@apollo/client": "^3.3.7", "@module-federation/utilities": "^1.7.0", - "@theforeman/vendor": "^13.1.0", + "@novnc/novnc": "1.3", + "@patternfly/patternfly": "^4.171.1", + "@patternfly/react-charts": "~6.94.15", + "@patternfly/react-core": "~4.271.2", + "@patternfly/react-icons": "~4.93.3", + "@patternfly/react-styles": "~4.92.3", + "@patternfly/react-table": "~4.112.6", + "@patternfly/react-tokens": "~4.94.3", + "@reduxjs/toolkit": "^1.6.0", + "@spice-project/spice-html5": "^0.2.1", + "@webcomponents/webcomponentsjs": "^2.2.10", + "ace-builds": "^1.4.13", + "axios": "^0.21.1", + "bootstrap-sass": "^3.3.7", + "classnames": "^2.2.5", + "connected-react-router": "6.6.1", + "core-js": "^2.5.7", + "datatables.net": "~1.10.12", + "datatables.net-bs": "~1.10.12", + "diff": "^4.0.1", + "dsmorse-gridster": "^0.8.0", + "file-saver": "^2.0.1", + "formik": "^1.5.8", + "graphql": "^15.5.0", "graphql-tag": "^2.11.0", + "history": "^4.7.2", + "humanize-duration": "3.27.0", "intl": "~1.2.5", + "ipaddr.js": "~1.2.0", "jed": "^1.1.1", + "jquery": "~2.2.4", + "jquery-ujs": "~1.2.0", + "jquery.cookie": "~1.4.1", + "jstz": "~1.0.7", + "lodash": "^4.17.14", + "multiselect": "~0.9.12", + "number_helpers": "^0.1.1", "os-browserify": "^0.3.0", - "react-intl": "^2.8.0" + "patternfly": "^3.58.0", + "patternfly-react": "^2.39.17", + "patternfly-react-extensions": "^3.0.12", + "prop-types": "^15.6.0", + "rc-input-number": "^6.0.0", + "react": "^16.9.0", + "react-ace": "^9.5.0", + "react-debounce-input": "^3.2.0", + "react-diff-view": "^2.4.5", + "react-dnd": "^14.0.2", + "react-dnd-html5-backend": "^14.0.0", + "react-dom": "^16.8.1", + "react-ellipsis-with-tooltip": "^1.0.8", + "react-helmet": "^6.1.0", + "react-intl": "^2.8.0", + "react-loading-skeleton": "^1.1.2", + "react-onclickoutside": "^6.6.2", + "react-password-strength": "^2.4.0", + "react-redux": "^7.1.0", + "react-router-bootstrap": "^0.25.0", + "react-router-dom": "^5.1.2", + "redux": "^4.0.4", + "redux-logger": "^2.8.1", + "redux-thunk": "^2.2.0", + "regenerator-runtime": "^0.13.3", + "reselect": "^3.0.1", + "sanitize-html": "2.3.2", + "seamless-immutable": "^7.1.2", + "select2": "~3.5.2-browserify", + "unidiff": "^1.0.0", + "urijs": "^1.19.4", + "uuid": "^3.3.2", + "yup": "^0.29.3" }, "devDependencies": { "@apollo/react-testing": "^4.0.0", @@ -73,6 +140,7 @@ "react-dnd-test-backend": "^9.4.0", "react-redux-test-utils": "^0.2.0", "react-test-renderer": "^17.0.1", + "mini-css-extract-plugin": "^2.9.1", "redux-mock-store": "^1.2.2", "sass": "~1.60.0", "sass-loader": "^13.3.2", @@ -87,5 +155,23 @@ "webpack-bundle-analyzer": "^4.5.0", "webpack-cli": "^5.0.1", "webpack-stats-plugin": "^1.0.3" + }, + "overrides": { + "victory-core": "36.8.6", + "victory-pie": "36.8.6", + "victory-area": "36.8.6", + "victory-axis": "36.8.6", + "victory-bar": "36.8.6", + "victory-chart": "36.8.6", + "victory-create-container": "36.8.6", + "victory-cursor-container": "36.8.6", + "victory-group": "36.8.6", + "victory-legend": "36.8.6", + "victory-line": "36.8.6", + "victory-scatter": "36.8.6", + "victory-stack": "36.8.6", + "victory-tooltip": "36.8.6", + "victory-voronoi-container": "36.8.6", + "victory-zoom-container": "36.8.6" } } diff --git a/webpack/assets/javascripts/bundle.js b/webpack/assets/javascripts/bundle.js index 397994b337c..045cc5a8969 100644 --- a/webpack/assets/javascripts/bundle.js +++ b/webpack/assets/javascripts/bundle.js @@ -1,5 +1,7 @@ import 'core-js/shim'; import 'regenerator-runtime/runtime'; +import jstz from 'jstz'; +import ipaddr from 'ipaddr.js'; import compute from './foreman_compute_resource'; import componentRegistry from './react_app/components/componentRegistry'; @@ -56,4 +58,6 @@ window.tfm = Object.assign(window.tfm || {}, { componentRegistry, store, lookupKeys, + jstz, + ipaddr, }); diff --git a/webpack/assets/javascripts/exportAll.js b/webpack/assets/javascripts/exportAll.js index d56a6497401..8062a11bbf6 100644 --- a/webpack/assets/javascripts/exportAll.js +++ b/webpack/assets/javascripts/exportAll.js @@ -19,9 +19,11 @@ function generateExports(directoryPath, exportFileContent = '') { !dirent.name.endsWith('.test.js') && !dirent.name.endsWith('.fixtures.js') && !dirent.name.endsWith('mockRequests.js') && + !dirent.name.endsWith('jquery.js') && + !dirent.name.endsWith('jquery.js') && !fileNameWithoutExtension.includes('TestHelper') && !fileNameWithoutExtension.includes('testHelper') && - !fileNameWithoutExtension.includes('APITestSetup') + !fileNameWithoutExtension.includes('vendor-core.scss') ) { let relativeFilePath = path.relative( __dirname, @@ -51,7 +53,8 @@ function generateExports(directoryPath, exportFileContent = '') { const generateExportsFile = () => { let exportFileContent = generateExports(path.join(__dirname, 'react_app')); - exportFileContent = `/* eslint-disable */\n// This file is autogenerated by the webpack/assets/javascripts/exportAll.js script\n// Please do not modify this file directly\n\n${exportFileContent}`; + exportFileContent = `/* eslint-disable */\n// This file is autogenerated by the webpack/assets/javascripts/exportAll.js script\n// Please do not modify this file directly\n\n + console.log('all_react_export');\n\n${exportFileContent}`; fs.writeFileSync( path.join(__dirname, 'all_react_app_exports.js'), diff --git a/webpack/assets/javascripts/jquery.js b/webpack/assets/javascripts/jquery.js new file mode 100644 index 00000000000..be613eadabc --- /dev/null +++ b/webpack/assets/javascripts/jquery.js @@ -0,0 +1,15 @@ +// to avoid webpack alias loop +const jquery = require('../../../node_modules/jquery'); + +window.$ = jquery; +window.jQuery = jquery; +window.jquery = jquery; + +module.exports = jquery; + +require('jquery.cookie'); +require('jquery-ujs'); +require('multiselect'); +require('select2'); +require('datatables.net-bs'); +require('dsmorse-gridster/dist/jquery.dsmorse-gridster'); diff --git a/webpack/assets/javascripts/react_app/Root/ReactApp.js b/webpack/assets/javascripts/react_app/Root/ReactApp.js index 0f3d70fd532..4af38571a2a 100644 --- a/webpack/assets/javascripts/react_app/Root/ReactApp.js +++ b/webpack/assets/javascripts/react_app/Root/ReactApp.js @@ -11,7 +11,6 @@ import apolloClient from './apollo'; import ToastsList from '../components/ToastsList'; import ErrorBoundary from '../components/common/ErrorBoundary'; import ConfirmModal from '../components/ConfirmModal'; -import '../common/scss/vendor-core.scss'; const ReactApp = ({ layout, metadata, toasts }) => { const [context, setContext] = useState({ metadata }); diff --git a/webpack/assets/javascripts/react_app/components/common/forms/OrderableSelect/index.js b/webpack/assets/javascripts/react_app/components/common/forms/OrderableSelect/index.js index 533ab841ae3..fc39637c90b 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/OrderableSelect/index.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/OrderableSelect/index.js @@ -1,6 +1,6 @@ import React from 'react'; import { DndProvider } from 'react-dnd'; -import HTML5Backend from 'react-dnd-html5-backend'; +import { HTML5Backend } from 'react-dnd-html5-backend'; import OrderableSelect from './OrderableSelect'; From 005f580e14a0e745bf75adf74743552dc7e0d0e9 Mon Sep 17 00:00:00 2001 From: MariaAga Date: Wed, 30 Oct 2024 16:54:01 +0000 Subject: [PATCH 7/7] Refs #37882 - update tests to npm8 --- .github/workflows/foreman.yml | 2 ++ .github/workflows/js_tests.yml | 2 ++ .github/workflows/plugins_react_tests.yml | 2 ++ package.json | 9 ++++----- .../javascripts/react_app/common/urlHelpers.test.js | 2 +- webpack/core_test_setup.js | 11 +++++++++++ 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.github/workflows/foreman.yml b/.github/workflows/foreman.yml index 7a5c845604d..07862bb1d39 100644 --- a/.github/workflows/foreman.yml +++ b/.github/workflows/foreman.yml @@ -93,6 +93,8 @@ jobs: uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} + - name: use npm 8 + run: npm i -g npm@8 --registry=https://registry.npmjs.org - name: Setup NPM Cache uses: actions/cache@v4 with: diff --git a/.github/workflows/js_tests.yml b/.github/workflows/js_tests.yml index cddfe11b63e..5d8980fd24f 100644 --- a/.github/workflows/js_tests.yml +++ b/.github/workflows/js_tests.yml @@ -46,6 +46,8 @@ jobs: uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} + - name: use npm 8 + run: npm i -g npm@8 --registry=https://registry.npmjs.org - name: Generate npm dependencies package-lock run: npm install --package-lock-only --no-audit - name: Install npm dependencies diff --git a/.github/workflows/plugins_react_tests.yml b/.github/workflows/plugins_react_tests.yml index 551b3e9c710..ce1d1baeb42 100644 --- a/.github/workflows/plugins_react_tests.yml +++ b/.github/workflows/plugins_react_tests.yml @@ -48,6 +48,8 @@ jobs: uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} + - name: use npm 8 + run: npm i -g npm@8 --registry=https://registry.npmjs.org - name: "Set up Ruby ${{ matrix.ruby }}" uses: ruby/setup-ruby@v1 with: diff --git a/package.json b/package.json index 693a5fc4eec..0de2a5bfbe4 100644 --- a/package.json +++ b/package.json @@ -138,8 +138,7 @@ "prettier": "^1.19.1", "pretty-format": "26.6.2", "react-dnd-test-backend": "^9.4.0", - "react-redux-test-utils": "^0.2.0", - "react-test-renderer": "^17.0.1", + "react-test-renderer": "^16.9.0", "mini-css-extract-plugin": "^2.9.1", "redux-mock-store": "^1.2.2", "sass": "~1.60.0", @@ -148,9 +147,9 @@ "stylelint": "^9.3.0", "stylelint-config-standard": "^18.0.0", "tabbable": "~5.2.0", - "victory-core": "~36.8.6", - "victory-legend": "~36.8.6", - "victory-pie": "~36.8.6", + "victory-core": "36.8.6", + "victory-legend": "36.8.6", + "victory-pie": "36.8.6", "webpack": "^5.75.0", "webpack-bundle-analyzer": "^4.5.0", "webpack-cli": "^5.0.1", diff --git a/webpack/assets/javascripts/react_app/common/urlHelpers.test.js b/webpack/assets/javascripts/react_app/common/urlHelpers.test.js index efd5e446164..34ffab09bcb 100644 --- a/webpack/assets/javascripts/react_app/common/urlHelpers.test.js +++ b/webpack/assets/javascripts/react_app/common/urlHelpers.test.js @@ -1,5 +1,5 @@ import { mockWindowLocation } from './testHelpers'; -import { visit } from '../../foreman_navigation'; +import { visit } from './helpers'; import { urlBuilder, urlWithSearch, diff --git a/webpack/core_test_setup.js b/webpack/core_test_setup.js index d22b70ab381..6940d453554 100644 --- a/webpack/core_test_setup.js +++ b/webpack/core_test_setup.js @@ -26,3 +26,14 @@ jest.mock('./assets/javascripts/foreman_tools', () => ({ foremanUrl: url => url, })); jest.mock('./assets/javascripts/foreman_navigation'); + +jest.mock('./assets/javascripts/react_app/common/helpers', () => { + const helpers = jest.requireActual( + './assets/javascripts/react_app/common/helpers' + ); + return { + ...helpers, + visit: jest.fn(), + reloadPage: jest.fn(), + }; +});