Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Ankush1oo8 authored Mar 3, 2025
2 parents 825032f + e764e9c commit 12ffc5c
Show file tree
Hide file tree
Showing 23 changed files with 1,477 additions and 826 deletions.
1,813 changes: 1,049 additions & 764 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"devDependencies": {
"@edx/browserslist-config": "^1.3.0",
"@edx/reactifex": "^2.1.1",
"@openedx/frontend-build": "14.2.2",
"@openedx/frontend-build": "14.3.1",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.1.0",
"copy-webpack-plugin": "^12.0.0",
Expand Down
7 changes: 3 additions & 4 deletions src/containers/Dashboard/__snapshots__/index.test.jsx.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Dashboard snapshots courses loaded, show select session modal snapshot 1`] = `
exports[`Dashboard snapshots courses loaded, show select session modal, no available dashboards snapshot 1`] = `
<div
className="d-flex flex-column p-2 pt-0"
id="dashboard-container"
Expand All @@ -11,7 +11,6 @@ exports[`Dashboard snapshots courses loaded, show select session modal snapshot
test-page-title
</h1>
<Fragment>
<DashboardModalSlot />
<SelectSessionModal />
</Fragment>
<div
Expand Down Expand Up @@ -44,7 +43,7 @@ exports[`Dashboard snapshots courses still loading snapshot 1`] = `
</div>
`;

exports[`Dashboard snapshots there are no courses snapshot 1`] = `
exports[`Dashboard snapshots there are no courses, there ARE available dashboards snapshot 1`] = `
<div
className="d-flex flex-column p-2 pt-0"
id="dashboard-container"
Expand All @@ -55,7 +54,7 @@ exports[`Dashboard snapshots there are no courses snapshot 1`] = `
test-page-title
</h1>
<Fragment>
<DashboardModalSlot />
<EnterpriseDashboardModal />
</Fragment>
<div
data-testid="dashboard-content"
Expand Down
5 changes: 3 additions & 2 deletions src/containers/Dashboard/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from 'react';

import { reduxHooks } from 'hooks';
import { RequestKeys } from 'data/constants/requests';
import EnterpriseDashboardModal from 'containers/EnterpriseDashboardModal';
import SelectSessionModal from 'containers/SelectSessionModal';
import CoursesPanel from 'containers/CoursesPanel';
import DashboardModalSlot from 'plugin-slots/DashboardModalSlot';

import LoadingView from './LoadingView';
import DashboardLayout from './DashboardLayout';
Expand All @@ -15,6 +15,7 @@ export const Dashboard = () => {
hooks.useInitializeDashboard();
const { pageTitle } = hooks.useDashboardMessages();
const hasCourses = reduxHooks.useHasCourses();
const hasAvailableDashboards = reduxHooks.useHasAvailableDashboards();
const initIsPending = reduxHooks.useRequestIsPending(RequestKeys.initialize);
const showSelectSessionModal = reduxHooks.useShowSelectSessionModal();

Expand All @@ -23,7 +24,7 @@ export const Dashboard = () => {
<h1 className="sr-only">{pageTitle}</h1>
{!initIsPending && (
<>
<DashboardModalSlot />
{hasAvailableDashboards && <EnterpriseDashboardModal />}
{(hasCourses && showSelectSessionModal) && <SelectSessionModal />}
</>
)}
Expand Down
21 changes: 18 additions & 3 deletions src/containers/Dashboard/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { shallow } from '@edx/react-unit-test-utils';

import { reduxHooks } from 'hooks';

import EnterpriseDashboardModal from 'containers/EnterpriseDashboardModal';
import SelectSessionModal from 'containers/SelectSessionModal';
import CoursesPanel from 'containers/CoursesPanel';

Expand All @@ -13,12 +14,13 @@ import Dashboard from '.';
jest.mock('hooks', () => ({
reduxHooks: {
useHasCourses: jest.fn(),
useHasAvailableDashboards: jest.fn(),
useShowSelectSessionModal: jest.fn(),
useRequestIsPending: jest.fn(),
},
}));

jest.mock('plugin-slots/DashboardModalSlot', () => 'DashboardModalSlot');
jest.mock('containers/EnterpriseDashboardModal', () => 'EnterpriseDashboardModal');
jest.mock('containers/CoursesPanel', () => 'CoursesPanel');
jest.mock('./LoadingView', () => 'LoadingView');
jest.mock('./DashboardLayout', () => 'DashboardLayout');
Expand All @@ -36,10 +38,12 @@ describe('Dashboard', () => {
});
const createWrapper = ({
hasCourses,
hasAvailableDashboards,
initIsPending,
showSelectSessionModal,
}) => {
reduxHooks.useHasCourses.mockReturnValueOnce(hasCourses);
reduxHooks.useHasAvailableDashboards.mockReturnValueOnce(hasAvailableDashboards);
reduxHooks.useRequestIsPending.mockReturnValueOnce(initIsPending);
reduxHooks.useShowSelectSessionModal.mockReturnValueOnce(showSelectSessionModal);
return shallow(<Dashboard />);
Expand Down Expand Up @@ -67,6 +71,7 @@ describe('Dashboard', () => {
const testView = ({
props,
content: [contentName, contentEl],
showEnterpriseModal,
showSelectSessionModal,
}) => {
beforeEach(() => { wrapper = createWrapper(props); });
Expand All @@ -75,6 +80,10 @@ describe('Dashboard', () => {
it(`renders ${contentName}`, () => {
testContent(contentEl);
});
it(`${renderString(showEnterpriseModal)} dashbaord modal`, () => {
expect(wrapper.instance.findByType(EnterpriseDashboardModal).length)
.toEqual(showEnterpriseModal ? 1 : 0);
});
it(`${renderString(showSelectSessionModal)} select session modal`, () => {
expect(wrapper.instance.findByType(SelectSessionModal).length).toEqual(showSelectSessionModal ? 1 : 0);
});
Expand All @@ -83,38 +92,44 @@ describe('Dashboard', () => {
testView({
props: {
hasCourses: false,
hasAvailableDashboards: false,
initIsPending: true,
showSelectSessionModal: false,
},
content: ['LoadingView', <LoadingView />],
showEnterpriseModal: false,
showSelectSessionModal: false,
});
});

describe('courses loaded, show select session modal', () => {
describe('courses loaded, show select session modal, no available dashboards', () => {
testView({
props: {
hasCourses: true,
hasAvailableDashboards: false,
initIsPending: false,
showSelectSessionModal: true,
},
content: ['LoadedView', (
<DashboardLayout><CoursesPanel /></DashboardLayout>
)],
showEnterpriseModal: false,
showSelectSessionModal: true,
});
});

describe('there are no courses', () => {
describe('there are no courses, there ARE available dashboards', () => {
testView({
props: {
hasCourses: false,
hasAvailableDashboards: true,
initIsPending: false,
showSelectSessionModal: false,
},
content: ['Dashboard layout with no courses sidebar and content', (
<DashboardLayout><CoursesPanel /></DashboardLayout>
)],
showEnterpriseModal: true,
showSelectSessionModal: false,
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EnterpriseDashboard empty snapshot 1`] = `null`;

exports[`EnterpriseDashboard snapshot 1`] = `
<ModalDialog
hasCloseButton={false}
onClose={[MockFunction useEnterpriseDashboardHook.handleEscape]}
title=""
>
<div
className="bg-white p-3 rounded shadow"
style={
{
"textAlign": "start",
}
}
>
<h4>
You have access to the edX, Inc. dashboard
</h4>
<p>
To access the courses available to you through edX, Inc., visit the edX, Inc. dashboard now.
</p>
<ActionRow>
<Button
onClick={[MockFunction useEnterpriseDashboardHook.handleClose]}
variant="tertiary"
>
Dismiss
</Button>
<Button
href="/edx-dashboard"
onClick={[MockFunction useEnterpriseDashboardHook.handleCTAClick]}
type="a"
>
Go to dashboard
</Button>
</ActionRow>
</div>
</ModalDialog>
`;
48 changes: 48 additions & 0 deletions src/containers/EnterpriseDashboardModal/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';

import { StrictDict } from 'utils';
import track from 'tracking';
import { reduxHooks } from 'hooks';

import * as module from './hooks';

export const state = StrictDict({
showModal: (val) => React.useState(val), // eslint-disable-line
});

const { modalOpened, modalClosed, modalCTAClicked } = track.enterpriseDashboard;

export const useEnterpriseDashboardHook = () => {
const [showModal, setShowModal] = module.state.showModal(true);
const dashboard = reduxHooks.useEnterpriseDashboardData();

const trackOpened = modalOpened(dashboard.enterpriseUUID);
const trackClose = modalClosed(dashboard.enterpriseUUID, 'Cancel button');
const trackEscape = modalClosed(dashboard.enterpriseUUID, 'Escape');

const handleCTAClick = modalCTAClicked(dashboard.enterpriseUUID, dashboard.url);
const handleClose = () => {
trackClose();
setShowModal(false);
};
const handleEscape = () => {
trackEscape();
setShowModal(false);
};

React.useEffect(() => {
if (dashboard && dashboard.label) {
trackOpened();
}
}, []); // eslint-disable-line

return {
showModal,
handleCTAClick,
handleClose,
handleEscape,
dashboard,
};
};

export default useEnterpriseDashboardHook;
75 changes: 75 additions & 0 deletions src/containers/EnterpriseDashboardModal/hooks.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { MockUseState } from 'testUtils';
import { reduxHooks } from 'hooks';
import track from 'tracking';

import * as hooks from './hooks';

jest.mock('hooks', () => ({
reduxHooks: {
useEnterpriseDashboardData: jest.fn(),
},
}));
jest.mock('tracking', () => {
const modalOpenedEvent = jest.fn();
const modalClosedEvent = jest.fn();
const modalCTAClickedEvent = jest.fn();
return {
__esModule: true,
default: {
enterpriseDashboard: {
modalOpenedEvent,
modalClosedEvent,
modalCTAClickedEvent,
modalOpened: jest.fn(() => modalOpenedEvent),
modalClosed: jest.fn(() => modalClosedEvent),
modalCTAClicked: jest.fn(() => modalCTAClickedEvent),
},
},
};
});

const state = new MockUseState(hooks);

const enterpriseDashboardData = { label: 'edX, Inc.', url: '/edx-dashboard' };

describe('EnterpriseDashboard hooks', () => {
reduxHooks.useEnterpriseDashboardData.mockReturnValue({ ...enterpriseDashboardData });

describe('state values', () => {
state.testGetter(state.keys.showModal);
});

describe('behavior', () => {
let out;

beforeEach(() => {
state.mock();
out = hooks.useEnterpriseDashboardHook();
});
afterEach(state.restore);

test('useEnterpriseDashboardHook to return dashboard data from redux hooks', () => {
expect(out.dashboard).toMatchObject(enterpriseDashboardData);
});

test('modal initializes to shown when rendered and closes on click', () => {
state.expectInitializedWith(state.keys.showModal, true);
out.handleClose();
expect(state.values.showModal).toEqual(false);
});

test('modal initializes to shown when rendered and closes on escape', () => {
state.expectInitializedWith(state.keys.showModal, true);
out.handleEscape();
expect(state.values.showModal).toEqual(false);
});

test('CTA click tracks modalCTAClicked', () => {
out.handleCTAClick();
expect(track.enterpriseDashboard.modalCTAClicked).toHaveBeenCalledWith(
enterpriseDashboardData.enterpriseUUID,
enterpriseDashboardData.url,
);
});
});
});
Loading

0 comments on commit 12ffc5c

Please sign in to comment.