import React from 'react'; import { Factory } from 'rosie'; import MockAdapter from 'axios-mock-adapter'; import { getConfig } from '@edx/frontend-platform'; import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; import { fetchCourse } from '../data'; import { render, initializeMockApp, screen, fireEvent, waitFor, } from '../../setupTest'; import initializeStore from '../../store'; import { appendBrowserTimezoneToUrl, executeThunk } from '../../utils'; import NotificationTray from './NotificationTray'; import useWindowSize from '../../generic/tabs/useWindowSize'; initializeMockApp(); jest.mock('../../generic/tabs/useWindowSize'); jest.mock('@edx/frontend-platform/analytics'); describe('NotificationTray', () => { let mockData; let axiosMock; let store; const courseId = 'course-v1:edX+DemoX+Demo_Course'; const defaultMetadata = Factory.build('courseMetadata', { id: courseId }); let courseMetadataUrl = `${getConfig().LMS_BASE_URL}/api/courseware/course/${defaultMetadata.id}`; courseMetadataUrl = appendBrowserTimezoneToUrl(courseMetadataUrl); function setMetadata(attributes, options) { const courseMetadata = Factory.build('courseMetadata', { id: courseId, ...attributes }, options); axiosMock.onGet(courseMetadataUrl).reply(200, courseMetadata); } async function fetchAndRender(component) { await executeThunk(fetchCourse(defaultMetadata.id), store.dispatch); render(component, { store }); } beforeEach(async () => { store = initializeStore(); axiosMock = new MockAdapter(getAuthenticatedHttpClient()); axiosMock.onGet(courseMetadataUrl).reply(200, defaultMetadata); mockData = { toggleNotificationTray: () => {}, }; }); it('renders notification tray and close tray button', async () => { useWindowSize.mockReturnValue({ width: 1200 }); const toggleNotificationTray = jest.fn(); const testData = { ...mockData, toggleNotificationTray, }; await fetchAndRender(); 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(); 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(); expect(screen.queryByText('You have no new notifications at this time.')).toBeInTheDocument(); }); it('renders notification tray with full screen "Back to course" at responsive view', async () => { useWindowSize.mockReturnValue({ width: 991 }); const toggleNotificationTray = jest.fn(); const testData = { ...mockData, toggleNotificationTray, }; await fetchAndRender(); const responsiveCloseButton = screen.getByRole('button', { name: 'Back to course' }); await waitFor(() => expect(responsiveCloseButton).toBeInTheDocument()); fireEvent.click(responsiveCloseButton); expect(toggleNotificationTray).toHaveBeenCalledTimes(1); }); });