= {
diff --git a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.tsx b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.tsx
index 8b822c82..50644782 100644
--- a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.tsx
+++ b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.tsx
@@ -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';
@@ -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;
@@ -83,23 +76,7 @@ const NotificationsWidget = () => {
setNotificationCurrentState: setUpgradeNotificationCurrentState,
toggleSidebar: onToggleSidebar,
}}
- >
-
-
+ />
);
};
diff --git a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx
index 1fbc8301..ef01e13e 100644
--- a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx
+++ b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx
@@ -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';
@@ -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;
@@ -90,23 +83,7 @@ const NotificationTray = ({ intl }) => {
notificationCurrentState: upgradeNotificationCurrentState,
setNotificationCurrentState: setUpgradeNotificationCurrentState,
}}
- >
-
-
+ />
) : (
{intl.formatMessage(messages.noNotificationsMessage)}
)}
diff --git a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.test.jsx b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.test.jsx
index 79a75663..269a35f7 100644
--- a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.test.jsx
+++ b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.test.jsx
@@ -94,26 +94,6 @@ describe('NotificationTray', () => {
expect(screen.getByTestId('notification_tray_slot')).toBeInTheDocument();
});
- it('renders upgrade card', async () => {
- await fetchAndRender(
-
-
- ,
- );
-
- 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(
diff --git a/src/generic/upgrade-notification/UpgradeNotification.jsx b/src/generic/upgrade-notification/UpgradeNotification.jsx
deleted file mode 100644
index 13e785c8..00000000
--- a/src/generic/upgrade-notification/UpgradeNotification.jsx
+++ /dev/null
@@ -1,573 +0,0 @@
-import React, { useEffect } from 'react';
-import PropTypes from 'prop-types';
-import classNames from 'classnames';
-import { useIntl, FormattedDate, FormattedMessage } from '@edx/frontend-platform/i18n';
-import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/analytics';
-import { Button, Icon, IconButton } from '@openedx/paragon';
-import { Close, Launch } from '@openedx/paragon/icons';
-import { setLocalStorage } from '../../data/localStorage';
-import { UpgradeButton } from '../upgrade-button';
-import {
- VerifiedCertBullet,
- UnlockGradedBullet,
- FullAccessBullet,
- SupportMissionBullet,
-} from '../upsell-bullets/UpsellBullets';
-import messages from '../messages';
-
-const UpsellNoFBECardContent = () => (
-
-);
-
-const UpsellFBEFarAwayCardContent = () => (
-
-);
-
-const UpsellFBESoonCardContent = ({ accessExpirationDate, timezoneFormatArgs }) => {
- const includingAnyProgress = (
-
-
-
- );
-
- const date = (
-
- );
-
- const benefitsOfUpgrading = (
-
-
-
-
-
-
- );
-
- return (
-
- );
-};
-
-UpsellFBESoonCardContent.propTypes = {
- accessExpirationDate: PropTypes.PropTypes.instanceOf(Date).isRequired,
- timezoneFormatArgs: PropTypes.shape({
- timeZone: PropTypes.string,
- }),
-};
-
-UpsellFBESoonCardContent.defaultProps = {
- timezoneFormatArgs: {},
-};
-
-const PastExpirationCardContent = () => (
-
-);
-
-const ExpirationCountdown = ({
- courseId, hoursToExpiration, setupgradeNotificationCurrentState, type,
-}) => {
- let expirationText;
- if (hoursToExpiration >= 24) { // More than 1 day left
- // setupgradeNotificationCurrentState is available in NotificationTray (not course home)
- if (setupgradeNotificationCurrentState) {
- if (type === 'access') {
- setupgradeNotificationCurrentState('accessDaysLeft');
- setLocalStorage(`upgradeNotificationCurrentState.${courseId}`, 'accessDaysLeft');
- }
- if (type === 'offer') {
- setupgradeNotificationCurrentState('FPDdaysLeft');
- setLocalStorage(`upgradeNotificationCurrentState.${courseId}`, 'FPDdaysLeft');
- }
- }
- expirationText = (
-
- );
- } else if (hoursToExpiration >= 1) { // More than 1 hour left
- // setupgradeNotificationCurrentState is available in NotificationTray (not course home)
- if (setupgradeNotificationCurrentState) {
- if (type === 'access') {
- setupgradeNotificationCurrentState('accessHoursLeft');
- setLocalStorage(`upgradeNotificationCurrentState.${courseId}`, 'accessHoursLeft');
- }
- if (type === 'offer') {
- setupgradeNotificationCurrentState('FPDHoursLeft');
- setLocalStorage(`upgradeNotificationCurrentState.${courseId}`, 'FPDHoursLeft');
- }
- }
- expirationText = (
-
- );
- } else { // Less than 1 hour
- // setupgradeNotificationCurrentState is available in NotificationTray (not course home)
- if (setupgradeNotificationCurrentState) {
- if (type === 'access') {
- setupgradeNotificationCurrentState('accessLastHour');
- setLocalStorage(`upgradeNotificationCurrentState.${courseId}`, 'accessLastHour');
- }
- if (type === 'offer') {
- setupgradeNotificationCurrentState('FPDLastHour');
- setLocalStorage(`upgradeNotificationCurrentState.${courseId}`, 'FPDLastHour');
- }
- }
- expirationText = (
-
- );
- }
- return ({expirationText}
);
-};
-
-ExpirationCountdown.propTypes = {
- courseId: PropTypes.string.isRequired,
- hoursToExpiration: PropTypes.number.isRequired,
- setupgradeNotificationCurrentState: PropTypes.func,
- type: PropTypes.string,
-};
-ExpirationCountdown.defaultProps = {
- setupgradeNotificationCurrentState: null,
- type: null,
-};
-
-const AccessExpirationDateBanner = ({
- courseId, accessExpirationDate, timezoneFormatArgs, setupgradeNotificationCurrentState,
-}) => {
- if (setupgradeNotificationCurrentState) {
- setupgradeNotificationCurrentState('accessDateView');
- setLocalStorage(`upgradeNotificationCurrentState.${courseId}`, 'accessDateView');
- }
- return (
-
-
- ),
- }}
- />
-
- );
-};
-
-AccessExpirationDateBanner.propTypes = {
- courseId: PropTypes.string.isRequired,
- accessExpirationDate: PropTypes.PropTypes.instanceOf(Date).isRequired,
- timezoneFormatArgs: PropTypes.shape({
- timeZone: PropTypes.string,
- }),
- setupgradeNotificationCurrentState: PropTypes.func,
-};
-
-AccessExpirationDateBanner.defaultProps = {
- timezoneFormatArgs: {},
- setupgradeNotificationCurrentState: null,
-};
-
-const PastExpirationDateBanner = ({
- courseId, accessExpirationDate, timezoneFormatArgs, setupgradeNotificationCurrentState,
-}) => {
- if (setupgradeNotificationCurrentState) {
- setupgradeNotificationCurrentState('PastExpirationDate');
- setLocalStorage(`upgradeNotificationCurrentState.${courseId}`, 'PastExpirationDate');
- }
- return (
-
-
- ),
- }}
- />
-
- );
-};
-
-PastExpirationDateBanner.propTypes = {
- courseId: PropTypes.string.isRequired,
- accessExpirationDate: PropTypes.PropTypes.instanceOf(Date).isRequired,
- timezoneFormatArgs: PropTypes.shape({
- timeZone: PropTypes.string,
- }),
- setupgradeNotificationCurrentState: PropTypes.func,
-};
-
-PastExpirationDateBanner.defaultProps = {
- timezoneFormatArgs: {},
- setupgradeNotificationCurrentState: null,
-};
-
-const UpgradeNotification = ({
- accessExpiration,
- contentTypeGatingEnabled,
- marketingUrl,
- courseId,
- offer,
- org,
- setupgradeNotificationCurrentState,
- shouldDisplayBorder,
- timeOffsetMillis,
- upsellPageName,
- userTimezone,
- verifiedMode,
- toggleSidebar,
-}) => {
- const intl = useIntl();
- const dateNow = Date.now();
- const timezoneFormatArgs = userTimezone ? { timeZone: userTimezone } : {};
- const correctedTime = new Date(dateNow + timeOffsetMillis);
- const accessExpirationDate = accessExpiration ? new Date(accessExpiration.expirationDate) : null;
- const pastExpirationDeadline = accessExpiration ? new Date(dateNow) > accessExpirationDate : false;
-
- const eventProperties = {
- org_key: org,
- courserun_key: courseId,
- };
-
- const promotionEventProperties = {
- creative: 'sidebarupsell',
- name: 'In-Course Verification Prompt',
- position: 'sidebar-message',
- promotion_id: 'courseware_verified_certificate_upsell',
- ...eventProperties,
- };
-
- useEffect(() => {
- sendTrackingLogEvent('edx.bi.course.upgrade.sidebarupsell.displayed', eventProperties);
- sendTrackEvent('Promotion Viewed', promotionEventProperties);
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
-
- if (!verifiedMode) {
- return null;
- }
-
- const logClick = () => {
- sendTrackingLogEvent('edx.bi.course.upgrade.sidebarupsell.clicked', eventProperties);
- sendTrackingLogEvent('edx.course.enrollment.upgrade.clicked', {
- ...eventProperties,
- location: 'sidebar-message',
- });
- sendTrackEvent('Promotion Clicked', promotionEventProperties);
- sendTrackEvent('edx.bi.ecommerce.upsell_links_clicked', {
- ...eventProperties,
- linkCategory: 'green_upgrade',
- linkName: `${upsellPageName}_green`,
- linkType: 'button',
- pageName: upsellPageName,
- });
- };
-
- const logClickPastExpiration = () => {
- sendTrackEvent('edx.bi.ecommerce.upgrade_notification.past_expiration.button_clicked', {
- ...eventProperties,
- linkCategory: 'upgrade_notification',
- linkName: `${upsellPageName}_course_details`,
- linkType: 'button',
- pageName: upsellPageName,
- });
- };
-
- /*
- There are 5 parts that change in the upgrade card:
- upgradeNotificationHeaderText
- expirationBanner
- upsellMessage
- callToActionButton
- offerCode
- */
- let upgradeNotificationHeaderText;
- let expirationBanner;
- let upsellMessage;
- let callToActionButton;
- let offerCode;
-
- if (!!accessExpiration && !!contentTypeGatingEnabled) {
- const hoursToAccessExpiration = Math.floor((accessExpirationDate - correctedTime) / 1000 / 60 / 60);
-
- if (hoursToAccessExpiration >= (7 * 24)) {
- if (offer) { // countdown to the first purchase discount if there is one
- const hoursToDiscountExpiration = Math.floor((new Date(offer.expirationDate) - correctedTime) / 1000 / 60 / 60);
- upgradeNotificationHeaderText = (
-
- );
- expirationBanner = (
-
- );
- } else {
- upgradeNotificationHeaderText = (
-
- );
- expirationBanner = (
-
- );
- }
- upsellMessage = ;
- } else if (hoursToAccessExpiration < (7 * 24) && hoursToAccessExpiration >= 0) {
- // more urgent messaging if there's less than 7 days left to access expiration
- upgradeNotificationHeaderText = (
-
- );
- expirationBanner = (
-
- );
- upsellMessage = (
-
- );
- } else { // access expiration deadline has passed
- upgradeNotificationHeaderText = (
-
- );
- expirationBanner = (
-
- );
- upsellMessage = (
-
- );
- }
- } else { // FBE is turned off
- upgradeNotificationHeaderText = (
-
- );
- upsellMessage = ();
- }
-
- if (pastExpirationDeadline) {
- callToActionButton = (
-
- );
- } else {
- callToActionButton = (
-
- );
- }
-
- if (offer) { // if there's a first purchase discount, message the code at the bottom
- offerCode = (
-
- {offer.code}),
- }}
- />
-
- );
- }
-
- return (
-
-
-
- {expirationBanner}
-
- {upsellMessage}
-
-
- {callToActionButton}
-
- {offerCode}
-
-
- );
-};
-
-UpgradeNotification.propTypes = {
- courseId: PropTypes.string.isRequired,
- org: PropTypes.string.isRequired,
- accessExpiration: PropTypes.shape({
- expirationDate: PropTypes.string,
- }),
- contentTypeGatingEnabled: PropTypes.bool,
- marketingUrl: PropTypes.string,
- offer: PropTypes.shape({
- expirationDate: PropTypes.string,
- percentage: PropTypes.number,
- code: PropTypes.string,
- }),
- toggleSidebar: PropTypes.func,
- shouldDisplayBorder: PropTypes.bool,
- setupgradeNotificationCurrentState: PropTypes.func,
- timeOffsetMillis: PropTypes.number,
- upsellPageName: PropTypes.string.isRequired,
- userTimezone: PropTypes.string,
- verifiedMode: PropTypes.shape({
- currencySymbol: PropTypes.string.isRequired,
- price: PropTypes.number.isRequired,
- upgradeUrl: PropTypes.string.isRequired,
- }),
-};
-
-UpgradeNotification.defaultProps = {
- accessExpiration: null,
- contentTypeGatingEnabled: false,
- marketingUrl: null,
- offer: null,
- setupgradeNotificationCurrentState: null,
- shouldDisplayBorder: null,
- timeOffsetMillis: 0,
- userTimezone: null,
- verifiedMode: null,
- toggleSidebar: null,
-};
-
-export default UpgradeNotification;
diff --git a/src/generic/upgrade-notification/UpgradeNotification.scss b/src/generic/upgrade-notification/UpgradeNotification.scss
deleted file mode 100644
index ee706438..00000000
--- a/src/generic/upgrade-notification/UpgradeNotification.scss
+++ /dev/null
@@ -1,46 +0,0 @@
-.upgrade-notification {
- border-radius: 0 !important;
-}
-
-.upgrade-notification-header {
- margin: 1.25rem;
-}
-
-.upsell-warning {
- background-color: $danger-100;
-}
-
-.upsell-warning-light {
- background-color: $warning-100;
-}
-
-.upsell-warning, .upsell-warning-light {
- padding: 0.5rem 1.25rem;
-}
-
-// .fa-ul added so specificity is higher than Font Awesome's .fa-ul.
-// An additional Font Awesome stylesheet is imported by Braze in
-// stage/production but not devstack.
-.upgrade-notification-ul.fa-ul {
- padding: 0.875rem 1.25rem 0;
- margin: 0 0 1rem 2.5rem;
-}
-
-.upgrade-notification-text {
- padding: 0.875rem 1.25rem 0 1.25rem;
-}
-
-.upgrade-notification-button {
- padding: 1.25rem;
- padding-top: 0;
-}
-
-.discount-info {
- border-top: 1px solid $light-400;
- padding-top: .75rem;
- padding-bottom: .75rem;
-}
-
-.font-size-18 {
- font-size: 18px !important;
-}
diff --git a/src/generic/upgrade-notification/UpgradeNotification.test.jsx b/src/generic/upgrade-notification/UpgradeNotification.test.jsx
deleted file mode 100644
index 17d38f00..00000000
--- a/src/generic/upgrade-notification/UpgradeNotification.test.jsx
+++ /dev/null
@@ -1,322 +0,0 @@
-import React from 'react';
-import { Factory } from 'rosie';
-import { sendTrackEvent } from '@edx/frontend-platform/analytics';
-
-import {
- fireEvent,
- initializeMockApp,
- render,
- screen,
- waitFor,
-} from '../../setupTest';
-import UpgradeNotification from './UpgradeNotification';
-
-initializeMockApp();
-jest.mock('@edx/frontend-platform/analytics');
-const dateNow = new Date('2021-04-13T11:01:58.000Z');
-jest
- .spyOn(global.Date, 'now')
- .mockImplementation(() => dateNow.valueOf());
-
-describe('Upgrade Notification', () => {
- function buildAndRender(attributes) {
- const upgradeNotificationData = Factory.build('upgradeNotificationData', { ...attributes });
- render();
- }
-
- it('sends upgrade click info to segment', async () => {
- sendTrackEvent.mockClear();
- buildAndRender({ pageName: 'test' });
-
- const upgradeButton = await waitFor(() => screen.queryByRole('link', { name: 'Upgrade for $149' }));
- fireEvent.click(upgradeButton);
-
- expect(sendTrackEvent).toHaveBeenCalledTimes(3);
- expect(sendTrackEvent).toHaveBeenNthCalledWith(3, 'edx.bi.ecommerce.upsell_links_clicked', {
- org_key: 'edX',
- courserun_key: 'course-v1:edX+DemoX+Demo_Course',
- linkCategory: 'green_upgrade',
- linkName: 'test_green',
- linkType: 'button',
- pageName: 'test',
- });
- });
-
- it('does not render when there is no verified mode', async () => {
- buildAndRender({ verifiedMode: null });
- expect(screen.queryByRole('link', { name: 'Upgrade for $149' })).not.toBeInTheDocument();
- });
-
- it('renders non-FBE when there is a verified mode but no FBE', async () => {
- buildAndRender();
- expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument();
- expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé');
- expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX');
- expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument();
- });
-
- it('renders non-FBE when there is a verified mode and access expiration, but no content gating', async () => {
- const expirationDate = new Date(dateNow);
- expirationDate.setMinutes(expirationDate.getMinutes() + 45);
- buildAndRender({
- accessExpiration: {
- expirationDate: expirationDate.toString(),
- },
- });
- expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument();
- expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé');
- expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX');
- expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument();
- });
-
- it('renders non-FBE when there is a verified mode and content gating, but no access expiration', async () => {
- buildAndRender({
- contentTypeGatingEnabled: true,
- accessExpiration: null,
- });
- expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument();
- expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé');
- expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX');
- expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument();
- });
-
- it('renders non-FBE with a discount properly', async () => {
- const discountExpirationDate = new Date(dateNow);
- discountExpirationDate.setDate(discountExpirationDate.getDate() + 6);
- buildAndRender({
- offer: {
- expirationDate: discountExpirationDate.toString(),
- percentage: 15,
- code: 'Welcome15',
- discountedPrice: '$126.65',
- originalPrice: '$149',
- upgradeUrl: 'www.exampleUpgradeUrl.com',
- },
- });
- expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument();
- expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé');
- expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX');
- expect(screen.getByText(/Upgrade for/).textContent).toMatch('$126.65 ($149)');
- expect(screen.getByText(/Use code.*?at checkout/s).textContent).toMatch('Use code Welcome15 at checkout');
- });
-
- it('renders FBE expiration within an hour properly', async () => {
- const expirationDate = new Date(dateNow);
- expirationDate.setMinutes(expirationDate.getMinutes() + 45);
- buildAndRender({
- accessExpiration: {
- expirationDate: expirationDate.toString(),
- },
- contentTypeGatingEnabled: true,
- });
- expect(screen.getByRole('heading', { name: 'Course Access Expiration' })).toBeInTheDocument();
- expect(screen.getByText('Less than 1 hour left')).toBeInTheDocument();
- expect(screen.getByText(/You will lose all access to this course.*?on/s).textContent).toMatch('You will lose all access to this course, including any progress, on April 13.');
- expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading in a new tab.');
- expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument();
- });
-
- it('renders FBE expiration within 24 hours properly', async () => {
- const expirationDate = new Date(dateNow);
- expirationDate.setHours(expirationDate.getHours() + 12);
- buildAndRender({
- accessExpiration: {
- expirationDate: expirationDate.toString(),
- },
- contentTypeGatingEnabled: true,
- });
- expect(screen.getByRole('heading', { name: 'Course Access Expiration' })).toBeInTheDocument();
- expect(screen.getByText('12 hours left')).toBeInTheDocument();
- expect(screen.getByText(/You will lose all access to this course.*?on/s)).toHaveTextContent('You will lose all access to this course, including any progress, on April 13.');
- expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading in a new tab.');
- expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument();
- });
-
- it('renders FBE expiration within 7 days properly', async () => {
- const expirationDate = new Date(dateNow);
- expirationDate.setDate(expirationDate.getDate() + 6);
- buildAndRender({
- accessExpiration: {
- expirationDate: expirationDate.toString(),
- },
- contentTypeGatingEnabled: true,
- });
- expect(screen.getByRole('heading', { name: 'Course Access Expiration' })).toBeInTheDocument();
- expect(screen.getByText('6 days left')).toBeInTheDocument(); // setting the time to 12 will mean that it's slightly less than 12
- expect(screen.getByText(/You will lose all access to this course.*?on/s).textContent).toMatch('You will lose all access to this course, including any progress, on April 19.');
- expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading in a new tab.');
- expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument();
- });
-
- it('renders FBE expiration greater than 7 days properly', async () => {
- const expirationDate = new Date(dateNow);
- expirationDate.setDate(expirationDate.getDate() + 14);
- buildAndRender({
- accessExpiration: {
- expirationDate: expirationDate.toString(),
- },
- contentTypeGatingEnabled: true,
- });
- expect(screen.getByRole('heading', { name: 'Upgrade your course today' })).toBeInTheDocument();
- expect(screen.getByText(/Course access will expire/s).textContent).toMatch('Course access will expire April 27');
- expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé');
- expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments');
- expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends');
- expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX');
- expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument();
- });
-
- it('renders discount less than an hour properly', async () => {
- const accessExpirationDate = new Date(dateNow);
- accessExpirationDate.setDate(accessExpirationDate.getDate() + 21);
- const discountExpirationDate = new Date(dateNow);
- discountExpirationDate.setMinutes(discountExpirationDate.getMinutes() + 30);
- buildAndRender({
- accessExpiration: {
- expirationDate: accessExpirationDate.toString(),
- },
- contentTypeGatingEnabled: true,
- offer: {
- expirationDate: discountExpirationDate.toString(),
- percentage: 15,
- code: 'Welcome15',
- discountedPrice: '$126.65',
- originalPrice: '$149',
- upgradeUrl: 'www.exampleUpgradeUrl.com',
- },
- });
- expect(screen.getByRole('heading', { name: '15% First-Time Learner Discount' })).toBeInTheDocument();
- expect(screen.getByText('Less than 1 hour left')).toBeInTheDocument();
- expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé');
- expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments');
- expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends');
- expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX');
- expect(screen.getByText(/Upgrade for/).textContent).toMatch('$126.65 ($149)');
- expect(screen.getByText(/Use code.*?at checkout/s).textContent).toMatch('Use code Welcome15 at checkout');
- });
-
- it('renders discount less than a day properly', async () => {
- const accessExpirationDate = new Date(dateNow);
- accessExpirationDate.setDate(accessExpirationDate.getDate() + 21);
- const discountExpirationDate = new Date(dateNow);
- discountExpirationDate.setHours(discountExpirationDate.getHours() + 12);
- buildAndRender({
- accessExpiration: {
- expirationDate: accessExpirationDate.toString(),
- },
- contentTypeGatingEnabled: true,
- offer: {
- expirationDate: discountExpirationDate.toString(),
- percentage: 15,
- code: 'Welcome15',
- discountedPrice: '$126.65',
- originalPrice: '$149',
- upgradeUrl: 'www.exampleUpgradeUrl.com',
- },
- });
- expect(screen.getByRole('heading', { name: '15% First-Time Learner Discount' })).toBeInTheDocument();
- expect(screen.getByText(/hours left/s).textContent).toMatch('12 hours left');
- expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé');
- expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments');
- expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends');
- expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX');
- expect(screen.getByText(/Upgrade for/).textContent).toMatch('$126.65 ($149)');
- expect(screen.getByText(/Use code.*?at checkout/s).textContent).toMatch('Use code Welcome15 at checkout');
- });
-
- it('renders discount less a week properly', async () => {
- const accessExpirationDate = new Date(dateNow);
- accessExpirationDate.setDate(accessExpirationDate.getDate() + 21);
- const discountExpirationDate = new Date(dateNow);
- discountExpirationDate.setDate(discountExpirationDate.getDate() + 6);
- buildAndRender({
- accessExpiration: {
- expirationDate: accessExpirationDate.toString(),
- },
- contentTypeGatingEnabled: true,
- offer: {
- expirationDate: discountExpirationDate.toString(),
- percentage: 15,
- code: 'Welcome15',
- discountedPrice: '$126.65',
- originalPrice: '$149',
- upgradeUrl: 'www.exampleUpgradeUrl.com',
- },
- });
- expect(screen.getByRole('heading', { name: '15% First-Time Learner Discount' })).toBeInTheDocument();
- expect(screen.getByText(/days left/s).textContent).toMatch('6 days left');
- expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé');
- expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments');
- expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends');
- expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX');
- expect(screen.getByText(/Upgrade for/).textContent).toMatch('$126.65 ($149)');
- expect(screen.getByText(/Use code.*?at checkout/s).textContent).toMatch('Use code Welcome15 at checkout');
- });
-
- it('renders discount less a week access expiration less than a week properly', async () => {
- const accessExpirationDate = new Date(dateNow);
- accessExpirationDate.setDate(accessExpirationDate.getDate() + 5);
- const discountExpirationDate = new Date(dateNow);
- discountExpirationDate.setDate(discountExpirationDate.getDate() + 6);
- buildAndRender({
- accessExpiration: {
- expirationDate: accessExpirationDate.toString(),
- },
- contentTypeGatingEnabled: true,
- offer: {
- expirationDate: discountExpirationDate.toString(),
- percentage: 15,
- code: 'Welcome15',
- discountedPrice: '$126.65',
- originalPrice: '$149',
- upgradeUrl: 'www.exampleUpgradeUrl.com',
- },
- });
- expect(screen.getByRole('heading', { name: 'Course Access Expiration' })).toBeInTheDocument();
- expect(screen.getByText('5 days left')).toBeInTheDocument(); // setting the time to 12 will mean that it's slightly less than 12
- expect(screen.getByText(/You will lose all access to this course.*?on/s).textContent).toMatch('You will lose all access to this course, including any progress, on April 18.');
- expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading in a new tab.');
- expect(screen.getByText(/Upgrade for/).textContent).toMatch('$126.65 ($149)');
- expect(screen.getByText(/Use code.*?at checkout/s).textContent).toMatch('Use code Welcome15 at checkout');
- });
-
- it('renders past access expiration message properly', async () => {
- const expirationDate = new Date(dateNow);
- expirationDate.setDate(expirationDate.getDate() - 1);
- buildAndRender({
- contentTypeGatingEnabled: true,
- accessExpiration: {
- expirationDate: expirationDate.toString(),
- },
- });
- expect(screen.getByRole('heading', { name: 'Course Access Expiration' })).toBeInTheDocument();
- expect(screen.getByText(/The upgrade deadline/s).textContent).toMatch('The upgrade deadline for this course passed');
- expect(screen.getByText(/To upgrade/s).textContent).toMatch('To upgrade, enroll in the next available session');
- expect(screen.getByRole('button', { name: 'View Course Details' })).toBeInTheDocument();
- });
-
- it('sends course details click info to segment if past access expiration', async () => {
- const expirationDate = new Date(dateNow);
- expirationDate.setDate(expirationDate.getDate() - 1);
- sendTrackEvent.mockClear();
- buildAndRender({
- pageName: 'test',
- contentTypeGatingEnabled: true,
- accessExpiration: {
- expirationDate: expirationDate.toString(),
- },
- });
-
- const courseDetailsLink = await waitFor(() => screen.queryByRole('button', { name: 'View Course Details' }));
- fireEvent.click(courseDetailsLink);
- expect(sendTrackEvent).toHaveBeenCalledTimes(2);
- expect(sendTrackEvent).toHaveBeenNthCalledWith(2, 'edx.bi.ecommerce.upgrade_notification.past_expiration.button_clicked', {
- org_key: 'edX',
- courserun_key: 'course-v1:edX+DemoX+Demo_Course',
- linkCategory: 'upgrade_notification',
- linkName: 'test_course_details',
- linkType: 'button',
- pageName: 'test',
- });
- });
-});
diff --git a/src/index.scss b/src/index.scss
index 205d12a3..f4ae867e 100755
--- a/src/index.scss
+++ b/src/index.scss
@@ -462,13 +462,10 @@
@import "courseware/course/celebration/CelebrationModal.scss";
@import "courseware/course/sidebar/sidebars/discussions/Discussions.scss";
@import "courseware/course/sidebar/sidebars/notifications/NotificationIcon.scss";
-@import "courseware/course/sequence/lock-paywall/LockPaywall.scss";
@import "shared/streak-celebration/StreakCelebrationModal.scss";
@import "courseware/course/content-tools/calculator/calculator.scss";
@import "courseware/course/content-tools/contentTools.scss";
@import "course-home/dates-tab/timeline/Day.scss";
-@import "generic/upgrade-notification/UpgradeNotification.scss";
-@import "generic/upsell-bullets/UpsellBullets.scss";
@import "course-home/outline-tab/widgets/ProctoringInfoPanel.scss";
@import "course-home/outline-tab/widgets/FlagButton.scss";
@import "course-home/progress-tab/course-completion/CompletionDonutChart.scss";