Files
frontend-app-learning/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.test.jsx
Chris Deery 3cba1bbac4 fix: [AA-1207] Remove redundant API fields (#873)
Remove redundant fields from courseware API. These are all found in courseHome: 

- number
- org
- originalUserIsStaff
- isStaff
- verifiedMode
- isMasquerading (virtual field from isStaff and originalUserIsStaff)
2022-03-18 09:20:31 -04:00

161 lines
5.3 KiB
JavaScript

import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { breakpoints } from '@edx/paragon';
import MockAdapter from 'axios-mock-adapter';
import React from 'react';
import { Factory } from 'rosie';
import {
fireEvent, initializeMockApp, render, screen, waitFor,
} from '../../../../../setupTest';
import initializeStore from '../../../../../store';
import { appendBrowserTimezoneToUrl, executeThunk } from '../../../../../utils';
import { fetchCourse } from '../../../../data';
import SidebarContext from '../../SidebarContext';
import { ID } from './index';
import NotificationTray from './NotificationTray';
initializeMockApp();
jest.mock('@edx/frontend-platform/analytics');
describe('NotificationTray', () => {
let axiosMock;
let store;
const defaultMetadata = Factory.build('courseMetadata');
const courseId = defaultMetadata.id;
let courseMetadataUrl = `${getConfig().LMS_BASE_URL}/api/courseware/course/${defaultMetadata.id}`;
courseMetadataUrl = appendBrowserTimezoneToUrl(courseMetadataUrl);
const courseHomeMetadata = Factory.build('courseHomeMetadata');
const courseHomeMetadataUrl = appendBrowserTimezoneToUrl(`${getConfig().LMS_BASE_URL}/api/course_home/course_metadata/${courseId}`);
function setMetadata(attributes, options) {
const updatedCourseHomeMetadata = Factory.build('courseHomeMetadata', attributes, options);
axiosMock.onGet(courseHomeMetadataUrl).reply(200, updatedCourseHomeMetadata);
}
async function fetchAndRender(component) {
await executeThunk(fetchCourse(defaultMetadata.id), store.dispatch);
render(component, { store });
}
beforeEach(async () => {
global.innerWidth = breakpoints.large.minWidth;
store = initializeStore();
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
axiosMock.onGet(courseMetadataUrl).reply(200, defaultMetadata);
axiosMock.onGet(courseHomeMetadataUrl).reply(200, courseHomeMetadata);
});
it('renders notification tray and close tray button', async () => {
global.innerWidth = breakpoints.extraLarge.minWidth;
const toggleNotificationTray = jest.fn();
await fetchAndRender(
<SidebarContext.Provider value={{
currentSidebar: ID,
courseId,
toggleSidebar: toggleNotificationTray,
shouldDisplayFullScreen: false,
}}
>
<NotificationTray />
</SidebarContext.Provider>,
);
expect(screen.getByText('Notifications'))
.toBeInTheDocument();
const notificationCloseIconButton = screen.getByRole('button', { name: /Close notification tray/i });
expect(notificationCloseIconButton)
.toBeInTheDocument();
expect(notificationCloseIconButton)
.toHaveClass('btn-icon-primary');
fireEvent.click(notificationCloseIconButton);
expect(toggleNotificationTray)
.toHaveBeenCalledTimes(1);
// should not render responsive "Back to course" to close the tray
expect(screen.queryByText('Back to course'))
.not
.toBeInTheDocument();
});
it('renders upgrade card', async () => {
await fetchAndRender(
<SidebarContext.Provider value={{
currentSidebar: ID,
courseId,
}}
>
<NotificationTray />
</SidebarContext.Provider>,
);
const UpgradeNotification = document.querySelector('.upgrade-notification');
expect(UpgradeNotification)
.toBeInTheDocument();
expect(screen.getByRole('link', { name: 'Upgrade for $149' }))
.toBeInTheDocument();
expect(screen.queryByText('You have no new notifications at this time.'))
.not
.toBeInTheDocument();
});
it('renders no notifications message if no verified mode', async () => {
setMetadata({ verified_mode: null });
await fetchAndRender(
<SidebarContext.Provider value={{
currentSidebar: ID,
courseId,
}}
>
<NotificationTray />
</SidebarContext.Provider>,
);
expect(screen.queryByText('You have no new notifications at this time.'))
.toBeInTheDocument();
});
it('marks notification as seen 3 seconds later', async () => {
jest.useFakeTimers();
const onNotificationSeen = jest.fn();
await fetchAndRender(
<SidebarContext.Provider value={{
currentSidebar: ID,
courseId,
onNotificationSeen,
}}
>
<NotificationTray />
</SidebarContext.Provider>,
);
expect(onNotificationSeen).toHaveBeenCalledTimes(0);
jest.advanceTimersByTime(3000);
expect(onNotificationSeen).toHaveBeenCalledTimes(1);
});
it('renders notification tray with full screen "Back to course" at responsive view', async () => {
global.innerWidth = breakpoints.medium.maxWidth;
const toggleNotificationTray = jest.fn();
await fetchAndRender(
<SidebarContext.Provider value={{
currentSidebar: ID,
courseId,
shouldDisplayFullScreen: true,
toggleSidebar: toggleNotificationTray,
}}
>
<NotificationTray />
</SidebarContext.Provider>,
);
const responsiveCloseButton = screen.getByRole('button', { name: 'Back to course' });
await waitFor(() => expect(responsiveCloseButton)
.toBeInTheDocument());
fireEvent.click(responsiveCloseButton);
expect(toggleNotificationTray)
.toHaveBeenCalledTimes(1);
});
});