From 61e484af1f564c9a0cbb36159581d7f8224da7fd Mon Sep 17 00:00:00 2001 From: Ben Warzeski Date: Tue, 25 Oct 2022 15:36:33 -0400 Subject: [PATCH] fix: Bug-doc fixes (#52) Co-authored-by: Leangseu Kim --- src/App.jsx | 28 ++++- src/App.test.jsx | 93 ++++++++++++--- src/__snapshots__/App.test.jsx.snap | 60 +++++++++- .../CourseCardActions/ViewCourseButton.jsx | 3 +- .../ViewCourseButton.test.jsx | 67 +++++------ .../ViewCourseButton.test.jsx.snap | 22 ++-- .../CourseCardBanners/CertificateBanner.jsx | 4 +- .../CourseCardBanners/CourseBanner.jsx | 4 +- .../CourseCardBanners/EntitlementBanner.jsx | 7 +- .../components/CourseCardDetails/hooks.js | 4 +- .../__snapshots__/index.test.jsx.snap | 13 +-- .../components/CourseCardMenu/index.jsx | 17 +-- .../components/CourseCardMenu/index.test.jsx | 107 +++++++++++------- src/containers/CourseList/hooks.test.js | 2 - src/containers/Dashboard/index.jsx | 2 +- src/containers/Dashboard/index.test.jsx | 4 +- src/containers/UnenrollConfirmModal/hooks.js | 6 +- .../UnenrollConfirmModal/hooks.test.js | 28 ++++- src/data/redux/app/selectors/courseCard.js | 11 +- .../redux/app/selectors/courseCard.test.js | 26 +++-- src/data/redux/hooks.js | 3 +- src/data/services/lms/urls.js | 6 +- src/messages.js | 5 + src/setupTest.jsx | 14 +++ src/test/app.test.jsx | 15 ++- src/utils/dateFormatter.js | 6 +- src/utils/hooks.js | 12 ++ 27 files changed, 404 insertions(+), 165 deletions(-) create mode 100644 src/utils/hooks.js diff --git a/src/App.jsx b/src/App.jsx index f10ea78..4876318 100755 --- a/src/App.jsx +++ b/src/App.jsx @@ -4,14 +4,23 @@ import { useDispatch } from 'react-redux'; import { Helmet } from 'react-helmet'; import { useIntl } from '@edx/frontend-platform/i18n'; -import { AppContext } from '@edx/frontend-platform/react'; +import { ErrorPage, AppContext } from '@edx/frontend-platform/react'; import Footer from '@edx/frontend-component-footer'; +import { Alert } from '@edx/paragon'; +import { RequestKeys } from 'data/constants/requests'; import store from 'data/store'; -import { selectors, actions, thunkActions } from 'data/redux'; -import fakeData from 'data/services/lms/fakeData/courses'; +import { + selectors, + actions, + thunkActions, + hooks as appHooks, +} from 'data/redux'; import LearnerDashboardHeader from 'containers/LearnerDashboardHeader'; import Dashboard from 'containers/Dashboard'; + +import fakeData from 'data/services/lms/fakeData/courses'; + import messages from './messages'; import './App.scss'; @@ -21,6 +30,12 @@ export const App = () => { // TODO: made development-only const { authenticatedUser } = React.useContext(AppContext); const { formatMessage } = useIntl(); + const isFailed = { + initialize: appHooks.useRequestIsFailed(RequestKeys.initialize), + refreshList: appHooks.useRequestIsFailed(RequestKeys.refreshList), + }; + const hasNetworkFailure = isFailed.initialize || isFailed.refreshList; + const { supportEmail } = appHooks.usePlatformSettingsData(); React.useEffect(() => { if (authenticatedUser?.administrator || process.env.NODE_ENV === 'development') { window.loadEmptyData = () => { @@ -49,7 +64,12 @@ export const App = () => {
- + {hasNetworkFailure + ? ( + + + + ) : ()}
diff --git a/src/App.test.jsx b/src/App.test.jsx index 775e196..b9873ae 100644 --- a/src/App.test.jsx +++ b/src/App.test.jsx @@ -1,41 +1,104 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { Helmet } from 'react-helmet'; +import { ErrorPage } from '@edx/frontend-platform/react'; -import { BrowserRouter } from 'react-router-dom'; +import { BrowserRouter as Router } from 'react-router-dom'; import Footer from '@edx/frontend-component-footer'; +import { useIntl } from '@edx/frontend-platform/i18n'; +import { Alert } from '@edx/paragon'; +import { RequestKeys } from 'data/constants/requests'; +import { hooks as appHooks } from 'data/redux'; import Dashboard from 'containers/Dashboard'; +import LearnerDashboardHeader from 'containers/LearnerDashboardHeader'; import { App } from './App'; +import messages from './messages'; jest.mock('@edx/frontend-component-footer', () => 'Footer'); jest.mock('containers/Dashboard', () => 'Dashboard'); jest.mock('containers/LearnerDashboardHeader', () => 'LearnerDashboardHeader'); +jest.mock('data/redux', () => ({ + selectors: 'redux.selectors', + actions: 'redux.actions', + thunkActions: 'redux.thunkActions', + hooks: { + useRequestIsFailed: jest.fn(), + usePlatformSettingsData: jest.fn(), + }, +})); +jest.mock('data/store', () => 'data/store'); const logo = 'fakeLogo.png'; let el; -let router; + +const supportEmail = 'test-support-url'; +appHooks.usePlatformSettingsData.mockReturnValue({ supportEmail }); describe('App router component', () => { - test('snapshot: enabled', () => { - expect(shallow()).toMatchSnapshot(); - }); + process.env.LOGO_POWERED_BY_OPEN_EDX_URL_SVG = logo; + const { formatMessage } = useIntl(); describe('component', () => { - beforeEach(() => { - process.env.LOGO_POWERED_BY_OPEN_EDX_URL_SVG = logo; - el = shallow(); - router = el.find(BrowserRouter); - }); - describe('Router', () => { - test('Routing - ListView is only route', () => { - expect(router.find('main')).toEqual(shallow( + const runBasicTests = () => { + test('snapshot', () => { expect(el).toMatchSnapshot(); }); + it('displays title in helmet component', () => { + expect(el.find(Helmet).find('title').text()).toEqual(useIntl().formatMessage(messages.pageTitle)); + }); + it('displays learner dashboard header', () => { + expect(el.find(LearnerDashboardHeader).length).toEqual(1); + }); + it('wraps the page in a browser router', () => { + expect(el.find(Router)).toMatchObject(el); + }); + test('Footer logo drawn from env variable', () => { + expect(el.find(Footer).props().logo).toEqual(logo); + }); + }; + describe('no network failure', () => { + beforeAll(() => { + appHooks.useRequestIsFailed.mockReturnValue(false); + el = shallow(); + }); + runBasicTests(); + it('loads dashboard', () => { + expect(el.find('main')).toMatchObject(shallow(
, )); }); }); - test('Footer logo drawn from env variable', () => { - expect(router.find(Footer).props().logo).toEqual(logo); + describe('initialize failure', () => { + beforeAll(() => { + appHooks.useRequestIsFailed.mockImplementation((key) => key === RequestKeys.initialize); + el = shallow(); + }); + runBasicTests(); + it('loads error page', () => { + expect(el.find('main')).toEqual(shallow( +
+ + + +
, + )); + }); + }); + describe('refresh failure', () => { + beforeAll(() => { + appHooks.useRequestIsFailed.mockImplementation((key) => key === RequestKeys.refreshList); + el = shallow(); + }); + runBasicTests(); + it('loads error page', () => { + expect(el.find('main')).toEqual(shallow( +
+ + + +
, + )); + }); }); }); }); diff --git a/src/__snapshots__/App.test.jsx.snap b/src/__snapshots__/App.test.jsx.snap index 59c2da2..74e9246 100644 --- a/src/__snapshots__/App.test.jsx.snap +++ b/src/__snapshots__/App.test.jsx.snap @@ -1,6 +1,34 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`App router component snapshot: enabled 1`] = ` +exports[`App router component component initialize failure snapshot 1`] = ` + + + + Learner Home + + +
+ +
+ + + +
+
+
+
+`; + +exports[`App router component component no network failure snapshot 1`] = `