Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 1 addition & 26 deletions src/course-home/outline-tab/OutlineTab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import CourseTools from './widgets/CourseTools';
import { fetchOutlineTab } from '../data';
import messages from './messages';
import ShiftDatesAlert from '../suggested-schedule-messaging/ShiftDatesAlert';
import UpgradeNotification from '../../generic/upgrade-notification/UpgradeNotification';
import UpgradeToShiftDatesAlert from '../suggested-schedule-messaging/UpgradeToShiftDatesAlert';
import useCertificateAvailableAlert from './alerts/certificate-status-alert';
import useCourseEndAlert from './alerts/course-end-alert';
Expand All @@ -40,13 +39,11 @@ const OutlineTab = () => {
isSelfPaced,
org,
title,
userTimezone,
} = useModel('courseHomeMeta', courseId);

const expandButtonRef = useRef();

const {
accessExpiration,
courseBlocks: {
courses,
sections,
Expand All @@ -55,20 +52,12 @@ const OutlineTab = () => {
selectedGoal,
weeklyLearningGoalEnabled,
} = {},
datesBannerInfo,
datesWidget: {
courseDateBlocks,
},
enableProctoredExams,
offer,
timeOffsetMillis,
verifiedMode,
} = useModel('outline', courseId);

const {
marketingUrl,
} = useModel('coursewareMeta', courseId);

const [expandAll, setExpandAll] = useState(false);
const navigate = useNavigate();

Expand Down Expand Up @@ -198,21 +187,7 @@ const OutlineTab = () => {
courseId,
model: 'outline',
}}
>
<UpgradeNotification
offer={offer}
verifiedMode={verifiedMode}
accessExpiration={accessExpiration}
contentTypeGatingEnabled={datesBannerInfo.contentTypeGatingEnabled}
marketingUrl={marketingUrl}
upsellPageName="course_home"
userTimezone={userTimezone}
shouldDisplayBorder
timeOffsetMillis={timeOffsetMillis}
courseId={courseId}
org={org}
/>
</PluginSlot>
/>
<CourseDates />
<CourseHandouts />
</div>
Expand Down
76 changes: 1 addition & 75 deletions src/course-home/outline-tab/OutlineTab.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { Factory } from 'rosie';
import { getConfig } from '@edx/frontend-platform';
import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/analytics';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import MockAdapter from 'axios-mock-adapter';
import Cookies from 'js-cookie';
Expand Down Expand Up @@ -1190,80 +1190,6 @@ describe('Outline Tab', () => {
});
});

describe('Upgrade Card', () => {
it('renders title when upgrade is available', async () => {
await fetchAndRender();
expect(screen.queryByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument();
});

it('displays link to upgrade', async () => {
await fetchAndRender();
expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument();
});

it('viewing upgrade card sends analytics', async () => {
sendTrackEvent.mockClear();
sendTrackingLogEvent.mockClear();
await fetchAndRender();

expect(sendTrackEvent).toHaveBeenCalledTimes(1);
expect(sendTrackEvent).toHaveBeenCalledWith('Promotion Viewed', {
org_key: 'edX',
courserun_key: courseId,
creative: 'sidebarupsell',
name: 'In-Course Verification Prompt',
position: 'sidebar-message',
promotion_id: 'courseware_verified_certificate_upsell',
});

expect(sendTrackingLogEvent).toHaveBeenCalledTimes(1);
expect(sendTrackingLogEvent).toHaveBeenCalledWith('edx.bi.course.upgrade.sidebarupsell.displayed', {
org_key: 'edX',
courserun_key: courseId,
});
});

it('clicking upgrade link sends analytics', async () => {
await fetchAndRender();

// Clearing after render to remove any events sent on view (ex. 'Promotion Viewed')
sendTrackEvent.mockClear();
sendTrackingLogEvent.mockClear();
const upgradeButton = screen.getByRole('link', { name: 'Upgrade for $149' });

fireEvent.click(upgradeButton);

expect(sendTrackEvent).toHaveBeenCalledTimes(2);
expect(sendTrackEvent).toHaveBeenNthCalledWith(1, 'Promotion Clicked', {
org_key: 'edX',
courserun_key: courseId,
creative: 'sidebarupsell',
name: 'In-Course Verification Prompt',
position: 'sidebar-message',
promotion_id: 'courseware_verified_certificate_upsell',
});
expect(sendTrackEvent).toHaveBeenNthCalledWith(2, 'edx.bi.ecommerce.upsell_links_clicked', {
org_key: 'edX',
courserun_key: courseId,
linkCategory: 'green_upgrade',
linkName: 'course_home_green',
linkType: 'button',
pageName: 'course_home',
});

expect(sendTrackingLogEvent).toHaveBeenCalledTimes(2);
expect(sendTrackingLogEvent).toHaveBeenNthCalledWith(1, 'edx.bi.course.upgrade.sidebarupsell.clicked', {
org_key: 'edX',
courserun_key: courseId,
});
expect(sendTrackingLogEvent).toHaveBeenNthCalledWith(2, 'edx.course.enrollment.upgrade.clicked', {
org_key: 'edX',
courserun_key: courseId,
location: 'sidebar-message',
});
});
});

describe('Account Activation Alert', () => {
beforeEach(() => {
const intersectionObserverMock = () => ({
Expand Down
12 changes: 0 additions & 12 deletions src/courseware/course/Course.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,18 +148,6 @@ describe('Course', () => {
});
});

it('displays notification trigger and toggles active class on click', async () => {
render(<Course {...mockData} />, { wrapWithRouter: true });

waitFor(() => {
const notificationTrigger = screen.getByRole('button', { name: /Show notification tray/i });
expect(notificationTrigger).toBeInTheDocument();
expect(notificationTrigger.parentNode).not.toHaveClass('sidebar-active', { exact: true });
fireEvent.click(notificationTrigger);
expect(notificationTrigger.parentNode).toHaveClass('sidebar-active');
});
});

it('handles click to open/close discussions sidebar', async () => {
await setupDiscussionSidebar();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { breakpoints } from '@openedx/paragon';

import {
initializeMockApp, render, screen, within, act, fireEvent, waitFor,
initializeMockApp, render, screen, act, fireEvent, waitFor,
} from '../../../../../../setupTest';
import initializeStore from '../../../../../../store';
import { appendBrowserTimezoneToUrl, executeThunk } from '../../../../../../utils';
Expand Down Expand Up @@ -93,27 +93,6 @@ describe('NotificationsWidget', () => {
expect(screen.getByTestId('notification_widget_slot')).toBeInTheDocument();
});

it('renders upgrade card', async () => {
const contextData: Partial<SidebarContextData> = {
currentSidebar: ID,
courseId,
hideNotificationbar: false,
isNotificationbarAvailable: true,
};
await fetchAndRender(
<SidebarContext.Provider value={contextData as SidebarContextData}>
<NotificationsWidget />
</SidebarContext.Provider>,
);

// The Upgrade Notification should be inside the PluginSlot.
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 bar if no verified mode', async () => {
setMetadata({ verified_mode: null });
const contextData: Partial<SidebarContextData> = {
Expand All @@ -130,44 +109,6 @@ describe('NotificationsWidget', () => {
expect(screen.queryByText('Notifications')).not.toBeInTheDocument();
});

it.each([
{
description: 'close the notification widget.',
enabledInContext: true,
testId: 'notification-widget',
},
{
description: 'close the sidebar when the notification widget is closed, and the discussion widget is unavailable.',
enabledInContext: false,
testId: 'sidebar-DISCUSSIONS_NOTIFICATIONS',
},
])('successfully %s', async ({ enabledInContext, testId }) => {
const userVerifiedMode = Factory.build('verifiedMode');

await setupDiscussionSidebar({
verifiedMode: userVerifiedMode,
enabledInContext,
isNewDiscussionSidebarViewEnabled: true,
});

const sidebarButton = screen.getByRole('button', { name: /Show sidebar tray/i });

await act(async () => {
fireEvent.click(sidebarButton);
});

const notificationWidget = await waitFor(() => screen.getByTestId('notification-widget'));
const closeNotificationButton = within(notificationWidget).getByRole('button', { name: /Close/i });

await act(async () => {
fireEvent.click(closeNotificationButton);
});

await waitFor(() => {
expect(screen.queryByTestId(testId)).not.toBeInTheDocument();
});
});

Copy link
Copy Markdown
Contributor Author

@arbrandes arbrandes Apr 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests can no longer run because they rely on a "Close" button that can now only be provided by a plugin.

(I don't approve of the way this NotificationsWidget was implemented in the first place. It should not have relied on an optional widget for an apparently essential feature. But it's beyond the scope of this PR to fix the architecture here.)

it('marks notification as seen 3 seconds later', async () => {
const onNotificationSeen = jest.fn();
const contextData: Partial<SidebarContextData> = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React, { useContext, useEffect, useMemo } from 'react';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { PluginSlot } from '@openedx/frontend-plugin-framework';
import { useModel } from '../../../../../../generic/model-store';
import UpgradeNotification from '../../../../../../generic/upgrade-notification/UpgradeNotification';
import { WIDGETS } from '../../../../../../constants';
import SidebarContext from '../../../SidebarContext';

Expand All @@ -21,17 +20,11 @@ const NotificationsWidget = () => {
const course = useModel('coursewareMeta', courseId);

const {
accessExpiration,
contentTypeGatingEnabled,
end,
enrollmentEnd,
enrollmentMode,
enrollmentStart,
marketingUrl,
offer,
start,
timeOffsetMillis,
userTimezone,
verificationStatus,
} = course;

Expand Down Expand Up @@ -83,23 +76,7 @@ const NotificationsWidget = () => {
setNotificationCurrentState: setUpgradeNotificationCurrentState,
toggleSidebar: onToggleSidebar,
}}
>
<UpgradeNotification
offer={offer}
verifiedMode={verifiedMode}
accessExpiration={accessExpiration}
contentTypeGatingEnabled={contentTypeGatingEnabled}
marketingUrl={marketingUrl}
upsellPageName="in_course"
userTimezone={userTimezone}
shouldDisplayBorder={false}
timeOffsetMillis={timeOffsetMillis}
courseId={courseId}
org={org}
setupgradeNotificationCurrentState={setUpgradeNotificationCurrentState}
toggleSidebar={onToggleSidebar}
/>
</PluginSlot>
/>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { PluginSlot } from '@openedx/frontend-plugin-framework';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { useModel } from '@src/generic/model-store';
import UpgradeNotification from '../../../../../generic/upgrade-notification/UpgradeNotification';

import messages from '../../../messages';
import SidebarBase from '../../common/SidebarBase';
Expand All @@ -23,17 +22,11 @@ const NotificationTray = ({ intl }) => {
const course = useModel('coursewareMeta', courseId);

const {
accessExpiration,
contentTypeGatingEnabled,
end,
enrollmentEnd,
enrollmentMode,
enrollmentStart,
marketingUrl,
offer,
start,
timeOffsetMillis,
userTimezone,
verificationStatus,
} = course;

Expand Down Expand Up @@ -90,23 +83,7 @@ const NotificationTray = ({ intl }) => {
notificationCurrentState: upgradeNotificationCurrentState,
setNotificationCurrentState: setUpgradeNotificationCurrentState,
}}
>
<UpgradeNotification
offer={offer}
verifiedMode={verifiedMode}
accessExpiration={accessExpiration}
contentTypeGatingEnabled={contentTypeGatingEnabled}
marketingUrl={marketingUrl}
upsellPageName="in_course"
userTimezone={userTimezone}
shouldDisplayBorder={false}
timeOffsetMillis={timeOffsetMillis}
courseId={courseId}
org={org}
upgradeNotificationCurrentState={upgradeNotificationCurrentState}
setupgradeNotificationCurrentState={setUpgradeNotificationCurrentState}
/>
</PluginSlot>
/>
) : (
<p className="p-3 small">{intl.formatMessage(messages.noNotificationsMessage)}</p>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,26 +94,6 @@ describe('NotificationTray', () => {
expect(screen.getByTestId('notification_tray_slot')).toBeInTheDocument();
});

it('renders upgrade card', async () => {
await fetchAndRender(
<SidebarContext.Provider value={{
currentSidebar: ID,
courseId,
}}
>
<NotificationTray />
</SidebarContext.Provider>,
);

expect(document.querySelector('.upgrade-notification')).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(
Expand Down
Loading
Loading