diff --git a/package-lock.json b/package-lock.json index 2f63b85ded..b03944eb08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,8 +15,8 @@ "@edx/frontend-enterprise-hotjar": "1.2.0", "@edx/frontend-enterprise-logistration": "2.1.0", "@edx/frontend-enterprise-utils": "2.1.0", - "@edx/frontend-platform": "2.3.0", - "@edx/paragon": "19.25.3", + "@edx/frontend-platform": "2.4.0", + "@edx/paragon": "20.2.0", "@fortawesome/fontawesome-svg-core": "1.2.35", "@fortawesome/free-brands-svg-icons": "5.15.3", "@fortawesome/free-regular-svg-icons": "5.15.3", @@ -3591,9 +3591,9 @@ } }, "node_modules/@edx/frontend-platform": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-2.3.0.tgz", - "integrity": "sha512-vZAw3eKJgUvD3wu8QOlCbNvuhe9YOGhdVuiTiFGMJKsYagJNMuQZxTJ2DwPCr7/gprJ65mboisJ3BF5IoFzVJA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-2.4.0.tgz", + "integrity": "sha512-i5z6cg+A+OLHgpvqPzU2jd7VM2soHsOAb8Jk6t4ddAtN1gLDad/pFhty3+aBEPIsnTuGDmrtUl5Yl/hP8Muc+w==", "dependencies": { "@cospired/i18n-iso-languages": "2.2.0", "@formatjs/intl-pluralrules": "^4.3.3", @@ -3619,7 +3619,7 @@ "transifex-utils.js": "i18n/scripts/transifex-utils.js" }, "peerDependencies": { - "@edx/paragon": ">= 10.0.0 < 20.0.0", + "@edx/paragon": ">= 10.0.0 < 21.0.0", "prop-types": "^15.7.2", "react": "^16.9.0", "react-dom": "^16.9.0", @@ -3665,9 +3665,9 @@ } }, "node_modules/@edx/paragon": { - "version": "19.25.3", - "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-19.25.3.tgz", - "integrity": "sha512-5YaZKiHeQdst/wyzmZZQsXb8apvLd185+iRV9fwV8/P7qxgxgIoLarFaDsU+jPJpjzL/Y17Fo1U6+IhGb155ew==", + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.2.0.tgz", + "integrity": "sha512-zOTBIH5LUpSWxrkWHpcEBN1/XIx6lf2mfd7K5TKX/zGB6Rbd35MkLUm1wZrNVaoFlemNIisixjxh7NpGKnv6rA==", "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/react-fontawesome": "^0.1.18", @@ -3676,6 +3676,7 @@ "classnames": "^2.3.1", "email-prop-type": "^3.0.0", "font-awesome": "^4.7.0", + "glob": "^8.0.3", "lodash.uniqby": "^4.7.0", "mailto-link": "^1.0.0", "prop-types": "^15.8.1", @@ -3691,7 +3692,8 @@ }, "peerDependencies": { "react": "^16.8.6 || ^17.0.0", - "react-dom": "^16.8.6 || ^17.0.0" + "react-dom": "^16.8.6 || ^17.0.0", + "react-intl": "^5.25.0" } }, "node_modules/@edx/paragon/node_modules/@fortawesome/fontawesome-svg-core": { @@ -3718,11 +3720,48 @@ "react": ">=16.x" } }, + "node_modules/@edx/paragon/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/@edx/paragon/node_modules/classnames": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" }, + "node_modules/@edx/paragon/node_modules/glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@edx/paragon/node_modules/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@edx/paragon/node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -28462,9 +28501,9 @@ } }, "@edx/frontend-platform": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-2.3.0.tgz", - "integrity": "sha512-vZAw3eKJgUvD3wu8QOlCbNvuhe9YOGhdVuiTiFGMJKsYagJNMuQZxTJ2DwPCr7/gprJ65mboisJ3BF5IoFzVJA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-2.4.0.tgz", + "integrity": "sha512-i5z6cg+A+OLHgpvqPzU2jd7VM2soHsOAb8Jk6t4ddAtN1gLDad/pFhty3+aBEPIsnTuGDmrtUl5Yl/hP8Muc+w==", "requires": { "@cospired/i18n-iso-languages": "2.2.0", "@formatjs/intl-pluralrules": "^4.3.3", @@ -28520,9 +28559,9 @@ } }, "@edx/paragon": { - "version": "19.25.3", - "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-19.25.3.tgz", - "integrity": "sha512-5YaZKiHeQdst/wyzmZZQsXb8apvLd185+iRV9fwV8/P7qxgxgIoLarFaDsU+jPJpjzL/Y17Fo1U6+IhGb155ew==", + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.2.0.tgz", + "integrity": "sha512-zOTBIH5LUpSWxrkWHpcEBN1/XIx6lf2mfd7K5TKX/zGB6Rbd35MkLUm1wZrNVaoFlemNIisixjxh7NpGKnv6rA==", "requires": { "@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/react-fontawesome": "^0.1.18", @@ -28531,6 +28570,7 @@ "classnames": "^2.3.1", "email-prop-type": "^3.0.0", "font-awesome": "^4.7.0", + "glob": "^8.0.3", "lodash.uniqby": "^4.7.0", "mailto-link": "^1.0.0", "prop-types": "^15.8.1", @@ -28561,11 +28601,39 @@ "prop-types": "^15.8.1" } }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, "classnames": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" }, + "glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", diff --git a/package.json b/package.json index b14242c519..1d5cce6c5f 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ "@edx/frontend-enterprise-hotjar": "1.2.0", "@edx/frontend-enterprise-logistration": "2.1.0", "@edx/frontend-enterprise-utils": "2.1.0", - "@edx/frontend-platform": "2.3.0", - "@edx/paragon": "19.25.3", + "@edx/frontend-platform": "2.4.0", + "@edx/paragon": "20.2.0", "@fortawesome/fontawesome-svg-core": "1.2.35", "@fortawesome/free-brands-svg-icons": "5.15.3", "@fortawesome/free-regular-svg-icons": "5.15.3", diff --git a/src/components/App/index.jsx b/src/components/App/index.jsx index 37d399d63f..dee1ff521c 100644 --- a/src/components/App/index.jsx +++ b/src/components/App/index.jsx @@ -29,7 +29,7 @@ const AppWrapper = () => { initializeHotjar({ hotjarId: process.env.HOTJAR_APP_ID, hotjarVersion: process.env.HOTJAR_VERSION, - hotjarDebug: process.env.HOTJAR_DEBUG, + hotjarDebug: !!process.env.HOTJAR_DEBUG, }); } catch (error) { logError(error); diff --git a/src/components/BulkEnrollmentPage/CourseSearchResults.test.jsx b/src/components/BulkEnrollmentPage/CourseSearchResults.test.jsx index 437cffa83b..23839f6748 100644 --- a/src/components/BulkEnrollmentPage/CourseSearchResults.test.jsx +++ b/src/components/BulkEnrollmentPage/CourseSearchResults.test.jsx @@ -8,6 +8,7 @@ import userEvent from '@testing-library/user-event'; import thunk from 'redux-thunk'; import { SearchContext, SearchPagination } from '@edx/frontend-enterprise-catalog-search'; import Skeleton from 'react-loading-skeleton'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { Alert } from '@edx/paragon'; import BulkEnrollContextProvider from './BulkEnrollmentContext'; @@ -80,13 +81,15 @@ const refinements = {}; // eslint-disable-next-line react/prop-types const CourseSearchWrapper = ({ value = { refinements }, props = defaultProps }) => ( - - - - - + + + + + + + ); diff --git a/src/components/BulkEnrollmentPage/stepper/AddCoursesStep.test.jsx b/src/components/BulkEnrollmentPage/stepper/AddCoursesStep.test.jsx index 31ecbebd96..8fa73a65a3 100644 --- a/src/components/BulkEnrollmentPage/stepper/AddCoursesStep.test.jsx +++ b/src/components/BulkEnrollmentPage/stepper/AddCoursesStep.test.jsx @@ -1,6 +1,7 @@ import { screen } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; import React from 'react'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { ADD_COURSES_TITLE, WARNING_ALERT_TITLE_TEXT } from './constants'; import { BulkEnrollContext } from '../BulkEnrollmentContext'; @@ -25,10 +26,13 @@ const StepperWrapper = (props) => { emails: [selectedEmails, () => {}], subscription: [{}, () => {}], }; + return ( - - - + + + + + ); }; diff --git a/src/components/CodeManagement/tests/ManageCodesTab.test.jsx b/src/components/CodeManagement/tests/ManageCodesTab.test.jsx index 304735f4d5..5bb5b0c57c 100644 --- a/src/components/CodeManagement/tests/ManageCodesTab.test.jsx +++ b/src/components/CodeManagement/tests/ManageCodesTab.test.jsx @@ -6,6 +6,7 @@ import { MemoryRouter } from 'react-router-dom'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { mount } from 'enzyme'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import ManageCodesTab from '../ManageCodesTab'; @@ -48,21 +49,20 @@ const initialState = { const ManageCodesTabWrapper = ({ store, subsidyRequestConfiguration, ...props }) => ( - - {}, - }} - {...props} - /> - + + + {}, + }} + {...props} + /> + + ); diff --git a/src/components/FeatureAnnouncementBanner/FeatureAnnouncementBanner.test.jsx b/src/components/FeatureAnnouncementBanner/FeatureAnnouncementBanner.test.jsx index 7ca7b79684..3901f27674 100644 --- a/src/components/FeatureAnnouncementBanner/FeatureAnnouncementBanner.test.jsx +++ b/src/components/FeatureAnnouncementBanner/FeatureAnnouncementBanner.test.jsx @@ -1,7 +1,8 @@ import React from 'react'; import { - render, fireEvent, screen, act, + render, fireEvent, screen, } from '@testing-library/react'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import FeatureAnnouncementBanner from './index'; import LmsApiService from '../../data/services/LmsApiService'; @@ -20,41 +21,30 @@ const mockEnterpriseCustomerWithMarkdown = { }, }; -let container = null; -beforeEach(() => { - // setup a DOM element as a render target - container = document.createElement('div'); - document.body.appendChild(container); -}); +const FeatureAnnouncementBannerWrapper = (props) => ( + + + +); describe('', () => { it('renders correctly', async () => { - const flushPromises = () => new Promise(setImmediate); - LmsApiService.fetchEnterpriseBySlug.mockImplementation(() => Promise.resolve({ data: mockEnterpriseCustomer, })); - await act(async () => { - render(, container); - await flushPromises(); - }); + render(); await screen.findByText('This is a test title.'); await screen.findByText('This is a test notification.'); }); it('renders markdown correctly', async () => { - const flushPromises = () => new Promise(setImmediate); - LmsApiService.fetchEnterpriseBySlug.mockImplementation(() => Promise.resolve({ data: mockEnterpriseCustomerWithMarkdown, })); - await act(async () => { - render(, container); - await flushPromises(); - }); + render(); await screen.findByText('This is a test title.'); const selector = (content, element) => content.startsWith('Message') && element.tagName.toLowerCase() === 'p'; @@ -63,33 +53,24 @@ describe('', () => { }); it('does not render if data is not available', async () => { - const flushPromises = () => new Promise(setImmediate); - LmsApiService.fetchEnterpriseBySlug.mockImplementation(() => Promise.resolve({ data: {}, })); - await act(async () => { - render(, container); - await flushPromises(); - }); + render(); - expect(container.textContent).not.toContain('This is a test title.'); - expect(container.textContent).not.toContain('This is a test notification.'); + expect(screen.queryByText('This is a test title.')); + expect(screen.queryByText('This is a test notification.')); }); it('calls markBannerNotificationAsRead on alert dismissal.', async () => { - const flushPromises = () => new Promise(setImmediate); - LmsApiService.fetchEnterpriseBySlug.mockImplementation(() => Promise.resolve({ data: mockEnterpriseCustomer, })); LmsApiService.markBannerNotificationAsRead.mockImplementation(() => Promise.resolve({})); - await act(async () => { - render(, container); - await flushPromises(); - }); + render(); + await screen.findByText('This is a test title.'); await screen.findByText('This is a test notification.'); const closeBtn = await screen.findByText('Dismiss'); diff --git a/src/components/FeatureAnnouncementBanner/index.jsx b/src/components/FeatureAnnouncementBanner/index.jsx index 23019cee6c..7f6958ce55 100644 --- a/src/components/FeatureAnnouncementBanner/index.jsx +++ b/src/components/FeatureAnnouncementBanner/index.jsx @@ -41,15 +41,17 @@ const FeatureAnnouncementBanner = ({ enterpriseSlug }) => { }); }, [enterpriseSlug]); + if (isRead || !enterpriseNotificationBanner.text || !enterpriseNotificationBanner.title) { + return null; + } + return ( - isRead || !enterpriseNotificationBanner.text || !enterpriseNotificationBanner.title ? null : ( -
- - {enterpriseNotificationBanner.title} - {enterpriseNotificationBanner.text} - -
- ) +
+ + {enterpriseNotificationBanner.title} + {enterpriseNotificationBanner.text} + +
); }; diff --git a/src/components/NewFeatureAlertBrowseAndRequest/NewFeatureAlertBrowseAndRequest.test.jsx b/src/components/NewFeatureAlertBrowseAndRequest/NewFeatureAlertBrowseAndRequest.test.jsx index 82178e5302..a0283ebce0 100644 --- a/src/components/NewFeatureAlertBrowseAndRequest/NewFeatureAlertBrowseAndRequest.test.jsx +++ b/src/components/NewFeatureAlertBrowseAndRequest/NewFeatureAlertBrowseAndRequest.test.jsx @@ -9,6 +9,7 @@ import { } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { Router } from 'react-router-dom'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import NewFeatureAlertBrowseAndRequest, { generateBrowseAndRequestAlertCookieName } from './index'; import { @@ -38,10 +39,12 @@ const historyMock = { push: useHistoryPush, location: {}, listen: jest.fn() }; const SETTINGS_PAGE_LOCATION = `/${ENTERPRISE_SLUG}/admin/${ROUTE_NAMES.settings}/${SETTINGS_TABS_VALUES.access}`; -const alertWithContext = () => ( +const NewFeatureAlertBrowseAndRequestWrapper = () => ( - + + + ); @@ -55,7 +58,7 @@ describe('', () => { writable: true, value: `${cookieName}=true`, }); - render(alertWithContext()); + render(); expect(screen.queryByText(BROWSE_AND_REQUEST_ALERT_TEXT)).toBeFalsy(); }); @@ -65,12 +68,12 @@ describe('', () => { writable: true, value: `${wrongCookieName}=true`, }); - render(alertWithContext()); + render(); expect(screen.queryByText(BROWSE_AND_REQUEST_ALERT_TEXT)).toBeTruthy(); }); it(`redirects to settings page at ${SETTINGS_PAGE_LOCATION}`, async () => { - render(alertWithContext()); + render(); const button = screen.getByText(REDIRECT_SETTINGS_BUTTON_TEXT); await act(async () => { userEvent.click(button); }); expect(useHistoryPush).toHaveBeenCalledWith({ @@ -85,7 +88,7 @@ describe('', () => { writable: true, value: `${cookieName}=true`, }); - render(alertWithContext()); + render(); expect(screen.queryByText(BROWSE_AND_REQUEST_ALERT_TEXT)).toBeFalsy(); }); }); diff --git a/src/components/SubsidyRequestManagementTable/tests/SubsidyRequestManagementTable.test.jsx b/src/components/SubsidyRequestManagementTable/tests/SubsidyRequestManagementTable.test.jsx index 1e05468bda..0881ff59fd 100644 --- a/src/components/SubsidyRequestManagementTable/tests/SubsidyRequestManagementTable.test.jsx +++ b/src/components/SubsidyRequestManagementTable/tests/SubsidyRequestManagementTable.test.jsx @@ -1,3 +1,4 @@ +import { IntlProvider } from '@edx/frontend-platform/i18n'; import React from 'react'; import renderer from 'react-test-renderer'; @@ -50,10 +51,16 @@ const defaultProps = { }, }; +const SubsidyRequestManagementTableWrapper = (props) => ( + + + +); + describe('SubsidyRequestManagementTable', () => { test('renders data in a table as expected', () => { const tree = renderer - .create() + .create() .toJSON(); expect(tree).toMatchSnapshot(); }); diff --git a/src/components/SubsidyRequestManagementTable/tests/__snapshots__/SubsidyRequestManagementTable.test.jsx.snap b/src/components/SubsidyRequestManagementTable/tests/__snapshots__/SubsidyRequestManagementTable.test.jsx.snap index 59a94d0637..8973ab0b5f 100644 --- a/src/components/SubsidyRequestManagementTable/tests/__snapshots__/SubsidyRequestManagementTable.test.jsx.snap +++ b/src/components/SubsidyRequestManagementTable/tests/__snapshots__/SubsidyRequestManagementTable.test.jsx.snap @@ -77,11 +77,7 @@ exports[`SubsidyRequestManagementTable renders data in a table as expected 1`] =
- Showing - 3 - of - 24 - . + Showing 3 of 24.
- Showing - 3 - of - 24 - . + Showing 3 of 24.
({ const TEST_INVITE_KEY_UUID = 'test-uuid-1'; +const ActionsTableCellWrapper = (props) => ( + + + +); + describe('ActionsTableCell', () => { jest.spyOn(navigator.clipboard, 'writeText'); @@ -32,7 +39,7 @@ describe('ActionsTableCell', () => { test('renders no actions if invite key is invalid', () => { render( - { test('copies invite URL to clipboard', async () => { render( - { }, }; render( - , diff --git a/src/components/settings/SettingsAccessTab/tests/DisableLinkManagementAlertModal.test.jsx b/src/components/settings/SettingsAccessTab/tests/DisableLinkManagementAlertModal.test.jsx index e10518fffa..ef70f8d886 100644 --- a/src/components/settings/SettingsAccessTab/tests/DisableLinkManagementAlertModal.test.jsx +++ b/src/components/settings/SettingsAccessTab/tests/DisableLinkManagementAlertModal.test.jsx @@ -6,32 +6,43 @@ import { act, } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import DisableLinkManagementAlertModal from '../DisableLinkManagementAlertModal'; -describe('', () => { +const DisableLinkManagementAlertModalWrapper = (props) => ( + + + +); + +describe('', () => { afterEach(() => { cleanup(); jest.clearAllMocks(); }); test('Error message is displayed', () => { - render( {}} - onDisable={() => {}} - error - />); + render(( + {}} + onDisable={() => {}} + error + /> + )); const cancelButton = screen.getByText('Something went wrong'); expect(cancelButton).toBeTruthy(); }); test('Buttons disabled if `isLoadingDisable`', () => { - render( {}} - onDisable={() => {}} - isLoading - />); + render(( + {}} + onDisable={() => {}} + isLoading + /> + )); const disableButton = screen.queryByText('Disabling...').closest('button'); expect(disableButton).toBeTruthy(); expect(disableButton).toHaveProperty('disabled', true); @@ -42,11 +53,13 @@ describe('', () => { }); test('`Disable` button calls `onDisable`', async () => { const onDisableMock = jest.fn(); - render( {}} - onDisable={onDisableMock} - />); + render(( + {}} + onDisable={onDisableMock} + /> + )); const disableButton = screen.getByText('Disable'); await act(async () => { userEvent.click(disableButton); }); expect(onDisableMock).toHaveBeenCalledTimes(1); diff --git a/src/components/settings/SettingsAccessTab/tests/SettingsAccessSSOManagement.test.jsx b/src/components/settings/SettingsAccessTab/tests/SettingsAccessSSOManagement.test.jsx index d463530aad..43315cdd97 100644 --- a/src/components/settings/SettingsAccessTab/tests/SettingsAccessSSOManagement.test.jsx +++ b/src/components/settings/SettingsAccessTab/tests/SettingsAccessSSOManagement.test.jsx @@ -5,6 +5,8 @@ import { waitFor, } from '@testing-library/react'; import '@testing-library/jest-dom'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; + import SettingsAccessSSOManagement from '../SettingsAccessSSOManagement'; import LmsApiService from '../../../../data/services/LmsApiService'; @@ -26,6 +28,12 @@ jest.mock('../SettingsAccessTabSection', () => ({ )), })); +const SettingsAccessSSOManagementWrapper = (props) => ( + + + +); + describe('', () => { const basicProps = { enterpriseId: 'test-enterprise-uuid', @@ -36,7 +44,12 @@ describe('', () => { it('display current configuration value and handle form switch change', async () => { const mockUpdatePortalConfiguration = jest.fn(); - render(); + render(( + + )); const checkbox = screen.getByLabelText('Checkbox'); const { enableIntegratedCustomerLearnerPortalSearch } = basicProps; @@ -55,7 +68,7 @@ describe('', () => { it('should show alert if an error occured', async () => { LmsApiService.updateEnterpriseCustomer.mockRejectedValue(new Error()); - render(); + render(); const checkbox = screen.getByLabelText('Checkbox'); fireEvent.click(checkbox); diff --git a/src/components/settings/SettingsAccessTab/tests/SettingsAccessSubsidyRequestManagement.test.jsx b/src/components/settings/SettingsAccessTab/tests/SettingsAccessSubsidyRequestManagement.test.jsx index a258c0f0b9..4bbcfc5a76 100644 --- a/src/components/settings/SettingsAccessTab/tests/SettingsAccessSubsidyRequestManagement.test.jsx +++ b/src/components/settings/SettingsAccessTab/tests/SettingsAccessSubsidyRequestManagement.test.jsx @@ -5,6 +5,8 @@ import { waitFor, } from '@testing-library/react'; import '@testing-library/jest-dom'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; + import SettingsAccessSubsidyRequestManagement from '../SettingsAccessSubsidyRequestManagement'; import { SUPPORTED_SUBSIDY_TYPES } from '../../../../data/constants/subsidyRequests'; @@ -18,6 +20,12 @@ jest.mock('../SettingsAccessTabSection', () => ({ )), })); +const SettingsAccessSubsidyRequestManagementWrapper = (props) => ( + + + +); + describe('', () => { const basicProps = { subsidyRequestConfiguration: { @@ -34,11 +42,7 @@ describe('', () => { updateSubsidyRequestConfiguration: mockUpdateSubsidyRequestConfiguration, }; - render( - , - ); + render(); const checkbox = screen.getByLabelText('Checkbox'); expect(checkbox.checked).toBe(props.subsidyRequestConfiguration.subsidyRequestsEnabled); @@ -61,20 +65,9 @@ describe('', () => { disabled: true, }; - const { rerender } = render( - , - ); - - rerender( - , - ); + const { rerender } = render(); + + rerender(); await waitFor(() => { expect(mockUpdateSubsidyRequestConfiguration).toHaveBeenCalledWith( @@ -91,11 +84,7 @@ describe('', () => { disabled: true, }; - render( - , - ); + render(); await waitFor(() => { expect(mockUpdateSubsidyRequestConfiguration).toHaveBeenCalledWith( @@ -111,11 +100,7 @@ describe('', () => { updateSubsidyRequestConfiguration: mockUpdateSubsidyRequestConfiguration, }; - render( - , - ); + render(); const checkbox = screen.getByLabelText('Checkbox'); fireEvent.click(checkbox); diff --git a/src/components/settings/SettingsTabs.jsx b/src/components/settings/SettingsTabs.jsx index 5c57befc13..514f6da803 100644 --- a/src/components/settings/SettingsTabs.jsx +++ b/src/components/settings/SettingsTabs.jsx @@ -35,7 +35,7 @@ const SettingsTabs = ({ identityProvider, updatePortalConfiguration, }) => { - const { FEATURE_SSO_SETTINGS_TAB, EXTERNAL_LMS_CONFIGURATION, SETTINGS_PAGE_LMS_TAB } = features; + const { FEATURE_SSO_SETTINGS_TAB, SETTINGS_PAGE_LMS_TAB } = features; const tab = useCurrentSettingsTab(); @@ -78,12 +78,12 @@ const SettingsTabs = ({ /> )} - {FEATURE_SSO_SETTINGS_TAB && ( + {FEATURE_SSO_SETTINGS_TAB && enableSamlConfigurationScreen && ( )} - {EXTERNAL_LMS_CONFIGURATION && SETTINGS_PAGE_LMS_TAB && enableLmsConfigurationsScreen && ( + {SETTINGS_PAGE_LMS_TAB && enableLmsConfigurationsScreen && ( ', () => { }); test.each([ - [false, true, true], - [true, false, true], - [true, true, false], - ])('LMS tab is not rendered if any of EXTERNAL_LMS_CONFIGURATION, SETTINGS_PAGE_LMS_TAB, enableLmsConfigurationsScreen = false', ( - enableExternalLmsConfiguration, + [false, true], + [true, false], + ])('LMS tab is not rendered if either SETTINGS_PAGE_LMS_TAB or enableLmsConfigurationsScreen = false', ( enableSettingsPageLmsTab, enableLmsConfigurationsScreen, ) => { - features.EXTERNAL_LMS_CONFIGURATION = enableExternalLmsConfiguration; features.SETTINGS_PAGE_LMS_TAB = enableSettingsPageLmsTab; render( diff --git a/src/components/subscriptions/licenses/LicenseManagementTable/tests/index.test.jsx b/src/components/subscriptions/licenses/LicenseManagementTable/tests/index.test.jsx index c4516385e5..4b6fa81579 100644 --- a/src/components/subscriptions/licenses/LicenseManagementTable/tests/index.test.jsx +++ b/src/components/subscriptions/licenses/LicenseManagementTable/tests/index.test.jsx @@ -9,6 +9,7 @@ import { import userEvent from '@testing-library/user-event'; import moment from 'moment'; import { sendEnterpriseTrackEvent } from '@edx/frontend-enterprise-utils'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { TEST_ENTERPRISE_CUSTOMER_UUID, @@ -58,10 +59,12 @@ const expiredSubscriptionPlan = ( }; // eslint-disable-next-line react/prop-types -const tableWithContext = ({ subscriptionPlan }) => ( - - - +const LicenseManagementTableWrapper = ({ subscriptionPlan, ...props }) => ( + + + + + ); const singleUserSetup = (status = 'assigned') => { @@ -76,7 +79,7 @@ const singleUserSetup = (status = 'assigned') => { subscriptionPlan, [generateSubscriptionUser({ status })], ); - render(tableWithContext({ subscriptionPlan })); + render(); return refreshFunctions; }; @@ -90,9 +93,7 @@ describe('', () => { it('renders initially loading state', () => { const subscriptionPlan = generateSubscriptionPlan(); mockSubscriptionHooks(subscriptionPlan, [], true); - render(tableWithContext({ - subscriptionPlan, - })); + render(); // assert that the spinner is shown (`isLoading` is properly passed to `DataTable`) // expect(screen.getByRole('Status')); }); @@ -102,9 +103,7 @@ describe('', () => { it('renders zero state message', () => { const subscriptionPlan = generateSubscriptionPlan(); mockSubscriptionHooks(subscriptionPlan, []); - render(tableWithContext({ - subscriptionPlan, - })); + render(); expect(screen.getByText('Get Started')); expect(screen.getByText('No results found')); }); @@ -136,9 +135,7 @@ describe('', () => { }); it('does not allow selection of table rows', () => { - render(tableWithContext({ - subscriptionPlan, - })); + render(); expect(screen.queryByTitle('Toggle Row Selected')).toBeFalsy(); }); }); @@ -158,9 +155,7 @@ describe('', () => { }); it('allows selection of table rows', () => { - render(tableWithContext({ - subscriptionPlan, - })); + render(); expect(screen.getByTitle('Toggle Row Selected')); }); }); @@ -184,9 +179,7 @@ describe('', () => { mockSubscriptionHooks(subscriptionPlan, users); }); it('when clicking status filters', async () => { - render(tableWithContext({ - subscriptionPlan, - })); + render(); // click status checkbox const activeCheckBox = screen.getByText('Active'); @@ -203,9 +196,7 @@ describe('', () => { ); }); it('when typing in to email filter', async () => { - render(tableWithContext({ - subscriptionPlan, - })); + render(); const emailInput = screen.getByPlaceholderText('Search Email address'); // type in 'foo' to email input fireEvent.change(emailInput, { target: { value: 'foo' } }); @@ -221,9 +212,7 @@ describe('', () => { }); it('when changing to the page', async () => { - render(tableWithContext({ - subscriptionPlan, - })); + render(); const nextPageButton = screen.getByLabelText('next', { exact: false }); await act(async () => { userEvent.click(nextPageButton); diff --git a/src/components/subscriptions/tests/MultipleSubscriptionsPage.test.jsx b/src/components/subscriptions/tests/MultipleSubscriptionsPage.test.jsx index 5dcfb9be81..fa8f8d6d34 100644 --- a/src/components/subscriptions/tests/MultipleSubscriptionsPage.test.jsx +++ b/src/components/subscriptions/tests/MultipleSubscriptionsPage.test.jsx @@ -1,3 +1,4 @@ +import React from 'react'; import { screen, } from '@testing-library/react'; @@ -5,12 +6,11 @@ import '@testing-library/jest-dom/extend-expect'; import { Provider } from 'react-redux'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; -import React from 'react'; import { renderWithRouter } from '../../test/testUtils'; import { SubscriptionContext } from '../SubscriptionData'; import { ROUTE_NAMES } from '../../EnterpriseApp/constants'; - import MultipleSubscriptionsPage from '../MultipleSubscriptionsPage'; const fakeSlug = 'sluggo'; @@ -66,14 +66,16 @@ const mockStore = configureMockStore([thunk]); // eslint-disable-next-line react/prop-types const MultipleSubscriptionsPageWrapper = ({ subscriptions = defaultSubscriptions, ...props }) => ( - - - + + + + + ); describe('MultipleSubscriptionsPage', () => { - it('displays a the MultipleSubscriptionPicker when there are multiple subscriptions', () => { + it('displays the MultipleSubscriptionPicker when there are multiple subscriptions', () => { renderWithRouter(, { route: `/${fakeSlug}/admin/${ROUTE_NAMES.subscriptionManagement}`, path: `/:enterpriseSlug/admin/${ROUTE_NAMES.subscriptionManagement}`, diff --git a/src/components/subscriptions/tests/SubscriptionManagementPage.test.jsx b/src/components/subscriptions/tests/SubscriptionManagementPage.test.jsx index 103d02ce1a..290df71043 100644 --- a/src/components/subscriptions/tests/SubscriptionManagementPage.test.jsx +++ b/src/components/subscriptions/tests/SubscriptionManagementPage.test.jsx @@ -2,6 +2,7 @@ import React from 'react'; import { Provider } from 'react-redux'; import moment from 'moment'; import { screen, waitFor } from '@testing-library/react'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import '@testing-library/jest-dom/extend-expect'; import { @@ -62,7 +63,9 @@ describe('SubscriptionManagementPage', () => { return ( - + + + ); }; diff --git a/src/components/subscriptions/tests/expiration/SubscriptionExpirationBanner.test.jsx b/src/components/subscriptions/tests/expiration/SubscriptionExpirationBanner.test.jsx index c3d548ff35..a0dc6aea45 100644 --- a/src/components/subscriptions/tests/expiration/SubscriptionExpirationBanner.test.jsx +++ b/src/components/subscriptions/tests/expiration/SubscriptionExpirationBanner.test.jsx @@ -3,8 +3,9 @@ import { screen, render, waitForElementToBeRemoved, } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; - +import { IntlProvider } from '@edx/frontend-platform/i18n'; import * as enterpriseUtils from '@edx/frontend-enterprise-utils'; + import SubscriptionExpirationBanner from '../../expiration/SubscriptionExpirationBanner'; import { SUBSCRIPTION_DAYS_REMAINING_MODERATE, @@ -27,10 +28,12 @@ jest.mock('@edx/frontend-enterprise-utils', () => { // PropType validation for state is done by SubscriptionManagementContext // eslint-disable-next-line react/prop-types -const ExpirationBannerWithContext = ({ detailState, isSubscriptionPlanDetails = false }) => ( - - - +const ExpirationBannerWrapper = ({ detailState, isSubscriptionPlanDetails = false }) => ( + + + + + ); describe('', () => { @@ -41,7 +44,7 @@ describe('', () => { ...SUBSCRIPTION_PLAN_ZERO_STATE, agreementNetDaysUntilExpiration: 240, }; - render(); + render(); expect(screen.queryByRole('alert')).toBeNull(); }); @@ -54,7 +57,7 @@ describe('', () => { ...SUBSCRIPTION_PLAN_ZERO_STATE, agreementNetDaysUntilExpiration: threshold, }; - render(); + render(); expect(screen.queryByRole('alert')).not.toBeNull(); }); @@ -66,7 +69,7 @@ describe('', () => { ...SUBSCRIPTION_PLAN_ZERO_STATE, agreementNetDaysUntilExpiration: threshold, }; - render(); + render(); expect(screen.queryByRole('alert')).not.toBeNull(); userEvent.click(screen.getByText('Dismiss')); await waitForElementToBeRemoved(screen.queryByRole('alert')); @@ -87,7 +90,7 @@ describe('', () => { agreementNetDaysUntilExpiration: SUBSCRIPTION_DAYS_REMAINING_MODERATE, showExpirationNotifications: false, }; - render(); + render(); expect(screen.queryByRole('alert')).toBeNull(); }); @@ -100,7 +103,7 @@ describe('', () => { agreementNetDaysUntilExpiration: 0, daysUntilExpiration: 0, }; - render(); @@ -121,7 +124,7 @@ describe('', () => { agreementNetDaysUntilExpiration, }; - render(); + render(); userEvent.click(screen.getByText('Contact support')); expect(enterpriseUtils.sendEnterpriseTrackEvent).toHaveBeenCalledWith( TEST_ENTERPRISE_CUSTOMER_UUID, diff --git a/src/components/subsidy-request-management-alerts/tests/NoAvailableCodesBanner.test.jsx b/src/components/subsidy-request-management-alerts/tests/NoAvailableCodesBanner.test.jsx index c62542dac9..f23e00604d 100644 --- a/src/components/subsidy-request-management-alerts/tests/NoAvailableCodesBanner.test.jsx +++ b/src/components/subsidy-request-management-alerts/tests/NoAvailableCodesBanner.test.jsx @@ -5,17 +5,25 @@ import { waitFor, } from '@testing-library/react'; import moment from 'moment'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; + import { NoAvailableCodesBanner } from '../NoAvailableCodesBanner'; +const NoAvailableCodesBannerWrapper = (props) => ( + + + +); + describe('', () => { it('should render null if there are no coupons', () => { - const { container } = render(); + const { container } = render(); expect(container.childElementCount).toEqual(0); }); it('should render alert if all coupons have expired', () => { const { getByText } = render( - ', () => { }); it('should render alert if all active codes have been assigned', () => { - const { getByText } = render(); + const { getByText } = render(( + + )); expect(getByText('Not enough codes')); }); it('should render null if there are available codes', () => { const { container } = render( - ', () => { }); it('should dimiss banner', async () => { - const { getByText, container } = render( - , - ); + /> + )); const dismissBtn = getByText('Dismiss'); fireEvent.click(dismissBtn); await waitFor(() => { diff --git a/src/components/subsidy-request-management-alerts/tests/NoAvailableLicensesBanner.test.jsx b/src/components/subsidy-request-management-alerts/tests/NoAvailableLicensesBanner.test.jsx index d50b66620e..201f2b9786 100644 --- a/src/components/subsidy-request-management-alerts/tests/NoAvailableLicensesBanner.test.jsx +++ b/src/components/subsidy-request-management-alerts/tests/NoAvailableLicensesBanner.test.jsx @@ -4,19 +4,27 @@ import { fireEvent, waitFor, } from '@testing-library/react'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; + import NoAvailableLicensesBanner from '../NoAvailableLicensesBanner'; +const NoAvailableLicensesBannerWrapper = (props) => ( + + + +); + describe('', () => { it('should render null if there are no subscriptions', () => { const { container } = render( - , + , ); expect(container.childElementCount).toEqual(0); }); it('should render alert if all subscriptions have expired', () => { const { getByText } = render( - ', () => { it('should render alert if all licenses in active subscriptions have been assigned', () => { const { getByText } = render( - ', () => { it('should render null if there are available licenses', () => { const { container } = render( - ', () => { it('should dimiss banner', async () => { const { getByText, container } = render( -