Skip to content

Commit 7957533

Browse files
authored
feat: Add redirect to enterprise learner dashboard (#1251)
When a learner tries to load the B2C course page for a course that starts in the future (error_code="course_not_started"), normally the learning MFE automatically redirects to the B2C dashboard. This change supports an alternate error_code "course_not_started_enterprise_learner" to trigger an alternative redirect to the B2B (enterprise) learner dashboard. This does two main things: 1. When the course metadata API response indicates course_access.error_code = "course_not_started_enterprise_learner" then redirect to "/redirect/enterprise-learner-dashboard". 2. When the top-level router matches path "/redirect/enterprise-learner-dashboard" then redirec to to the value of config `ENTERPRISE_LEARNER_PORTAL_URL`. ENT-8078
1 parent 2bf326f commit 7957533

8 files changed

+46
-5
lines changed

global-setup.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Force all tests to run in UTC to prevent tests from being sensitive to host timezone.
2+
module.exports = async () => {
3+
process.env.TZ = 'UTC';
4+
};

jest.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ module.exports = createConfig('jest', {
1616
'react-markdown': '<rootDir>/node_modules/react-markdown/react-markdown.min.js',
1717
},
1818
testTimeout: 30000,
19-
testEnvironment: 'jsdom'
19+
testEnvironment: 'jsdom',
20+
globalSetup: "./global-setup.js"
2021
});

src/constants.js

+2
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ export const ROUTES = {
2222
UNSUBSCRIBE: '/goal-unsubscribe/:token',
2323
REDIRECT: '/redirect/*',
2424
DASHBOARD: 'dashboard',
25+
ENTERPRISE_LEARNER_DASHBOARD: 'enterprise-learner-dashboard',
2526
CONSENT: 'consent',
2627
};
2728

2829
export const REDIRECT_MODES = {
2930
DASHBOARD_REDIRECT: 'dashboard-redirect',
31+
ENTERPRISE_LEARNER_DASHBOARD_REDIRECT: 'enterprise-learner-dashboard-redirect',
3032
CONSENT_REDIRECT: 'consent-redirect',
3133
HOME_REDIRECT: 'home-redirect',
3234
SURVEY_REDIRECT: 'survey-redirect',

src/courseware/CoursewareContainer.test.jsx

+7
Original file line numberDiff line numberDiff line change
@@ -515,5 +515,12 @@ describe('CoursewareContainer', () => {
515515
const startDate = '2/5/2013'; // This date is based on our courseMetadata factory's sample data.
516516
expect(global.location.href).toEqual(`http://localhost/redirect/dashboard?notlive=${startDate}`);
517517
});
518+
519+
it('should go to the enterprise learner dashboard for a course_not_started_enterprise_learner error code', async () => {
520+
setUpWithDeniedStatus('course_not_started_enterprise_learner');
521+
await loadContainer();
522+
523+
expect(global.location.href).toEqual('http://localhost/redirect/enterprise-learner-dashboard');
524+
});
518525
});
519526
});

src/courseware/CoursewareRedirectLandingPage.jsx

+4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ const CoursewareRedirectLandingPage = () => (
2929
path={ROUTES.DASHBOARD}
3030
element={<PageWrap><RedirectPage pattern="/dashboard" mode={REDIRECT_MODES.DASHBOARD_REDIRECT} /></PageWrap>}
3131
/>
32+
<Route
33+
path={ROUTES.ENTERPRISE_LEARNER_DASHBOARD}
34+
element={<PageWrap><RedirectPage mode={REDIRECT_MODES.ENTERPRISE_LEARNER_DASHBOARD_REDIRECT} /></PageWrap>}
35+
/>
3236
<Route
3337
path={ROUTES.CONSENT}
3438
element={<PageWrap><RedirectPage mode={REDIRECT_MODES.CONSENT_REDIRECT} /></PageWrap>}

src/courseware/CoursewareRedirectLandingPage.test.jsx

+14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import { MemoryRouter as Router } from 'react-router-dom';
3+
import { mergeConfig } from '@edx/frontend-platform';
34
import { render, initializeMockApp } from '../setupTest';
45
import CoursewareRedirectLandingPage from './CoursewareRedirectLandingPage';
56

@@ -11,6 +12,9 @@ jest.mock('../decode-page-route', () => jest.fn(({ children }) => <div>{children
1112
describe('CoursewareRedirectLandingPage', () => {
1213
beforeEach(async () => {
1314
await initializeMockApp();
15+
mergeConfig({
16+
ENTERPRISE_LEARNER_PORTAL_URL: 'http://localhost:8734',
17+
}, 'Add configs for URLs');
1418
delete global.location;
1519
global.location = { assign: redirectUrl };
1620
});
@@ -34,4 +38,14 @@ describe('CoursewareRedirectLandingPage', () => {
3438

3539
expect(redirectUrl).toHaveBeenCalledWith('/course/course-v1:edX+DemoX+Demo_Course/home');
3640
});
41+
42+
it('Redirects to correct enterprise dashboard URL', () => {
43+
render(
44+
<Router initialEntries={['/enterprise-learner-dashboard']}>
45+
<CoursewareRedirectLandingPage />
46+
</Router>,
47+
);
48+
49+
expect(redirectUrl).toHaveBeenCalledWith('http://localhost:8734');
50+
});
3751
});

src/courseware/RedirectPage.jsx

+10-4
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,26 @@ const RedirectPage = ({
1414
const location = useLocation();
1515
const { consentPath } = queryString.parse(location?.search);
1616

17-
const BASE_URL = getConfig().LMS_BASE_URL;
17+
const {
18+
LMS_BASE_URL,
19+
ENTERPRISE_LEARNER_PORTAL_URL,
20+
} = getConfig();
1821

1922
switch (mode) {
2023
case REDIRECT_MODES.DASHBOARD_REDIRECT:
21-
global.location.assign(`${BASE_URL}${pattern}${location?.search}`);
24+
global.location.assign(`${LMS_BASE_URL}${pattern}${location?.search}`);
25+
break;
26+
case REDIRECT_MODES.ENTERPRISE_LEARNER_DASHBOARD_REDIRECT:
27+
global.location.assign(ENTERPRISE_LEARNER_PORTAL_URL);
2228
break;
2329
case REDIRECT_MODES.CONSENT_REDIRECT:
24-
global.location.assign(`${BASE_URL}${consentPath}`);
30+
global.location.assign(`${LMS_BASE_URL}${consentPath}`);
2531
break;
2632
case REDIRECT_MODES.HOME_REDIRECT:
2733
global.location.assign(generatePath(pattern, { courseId }));
2834
break;
2935
default:
30-
global.location.assign(`${BASE_URL}${generatePath(pattern, { courseId })}`);
36+
global.location.assign(`${LMS_BASE_URL}${generatePath(pattern, { courseId })}`);
3137
}
3238

3339
return null;

src/shared/access.js

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ export function getAccessDeniedRedirectUrl(courseId, activeTabSlug, courseAccess
1515
const startDate = (new Intl.DateTimeFormat(getLocale())).format(new Date(start));
1616
url = `/redirect/dashboard?notlive=${startDate}`;
1717
break;
18+
case 'course_not_started_enterprise_learner':
19+
url = '/redirect/enterprise-learner-dashboard';
20+
break;
1821
case 'survey_required':
1922
url = `/redirect/survey/${courseId}`;
2023
break;

0 commit comments

Comments
 (0)