From 377da5719105de8a5a3853decc894cc6557ff908 Mon Sep 17 00:00:00 2001 From: Alison Langston <46360176+alangsto@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:38:28 -0400 Subject: [PATCH 1/7] feat: add plugin slot for fbe lock paywall (#1347) --- .../course/sequence/Unit/UnitSuspense.jsx | 22 ++++++++++++------- .../sequence/Unit/UnitSuspense.test.jsx | 7 +++--- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/courseware/course/sequence/Unit/UnitSuspense.jsx b/src/courseware/course/sequence/Unit/UnitSuspense.jsx index 59e34333ce..0e1871ec68 100644 --- a/src/courseware/course/sequence/Unit/UnitSuspense.jsx +++ b/src/courseware/course/sequence/Unit/UnitSuspense.jsx @@ -2,6 +2,7 @@ import React, { Suspense } from 'react'; import PropTypes from 'prop-types'; import { useIntl } from '@edx/frontend-platform/i18n'; +import { PluginSlot } from '@openedx/frontend-plugin-framework'; import { useModel } from '@src/generic/model-store'; import PageLoading from '@src/generic/PageLoading'; @@ -24,19 +25,24 @@ const UnitSuspense = ({ meta.contentTypeGatingEnabled && unit.containsContentTypeGatedContent ); - const suspenseComponent = (message, Component) => ( - }> - - - ); - return ( <> {shouldDisplayContentGating && ( - suspenseComponent(messages.loadingLockedContent, LockPaywall) + }> + + + + )} {shouldDisplayHonorCode && ( - suspenseComponent(messages.loadingHonorCode, HonorCode) + }> + + )} ); diff --git a/src/courseware/course/sequence/Unit/UnitSuspense.test.jsx b/src/courseware/course/sequence/Unit/UnitSuspense.test.jsx index 34bc21c073..f47ee6b241 100644 --- a/src/courseware/course/sequence/Unit/UnitSuspense.test.jsx +++ b/src/courseware/course/sequence/Unit/UnitSuspense.test.jsx @@ -64,7 +64,7 @@ describe('UnitSuspense component', () => { describe('output', () => { describe('LockPaywall', () => { const testNoPaywall = () => { - it('does not display LockPaywal', () => { + it('does not display LockPaywall', () => { el = shallow(); expect(el.instance.findByType(LockPaywall).length).toEqual(0); }); @@ -79,8 +79,9 @@ describe('UnitSuspense component', () => { it('displays LockPaywall in Suspense wrapper with PageLoading fallback', () => { el = shallow(); const [component] = el.instance.findByType(LockPaywall); - expect(component.parent.type).toEqual('Suspense'); - expect(component.parent.props.fallback) + expect(component.parent.type).toEqual('PluginSlot'); + expect(component.parent.parent.type).toEqual('Suspense'); + expect(component.parent.parent.props.fallback) .toEqual(); expect(component.props.courseId).toEqual(props.courseId); }); From d3ef3065870c929f4be675895608a2a193f43950 Mon Sep 17 00:00:00 2001 From: Marcos Rigoli Date: Fri, 19 Apr 2024 14:49:46 -0300 Subject: [PATCH 2/7] feat: Added PluginSlot wrapping UpgradeNotification components (#1366) * chore: Updated PluginSlot mock to support children and test ids * chore: Updated mocked PluginSlot * chore: Added unit test for MockedPluginSlot * fix: Updated slot name ids --- src/course-home/outline-tab/OutlineTab.jsx | 35 +++++++++------ .../outline-tab/OutlineTab.test.jsx | 15 +++++++ .../notifications/NotificationsWidget.jsx | 41 +++++++++++------- .../NotificationsWidget.test.jsx | 7 ++- src/setupTest.js | 3 +- src/tests/MockedPluginSlot.jsx | 25 +++++++++++ src/tests/MockedPluginSlot.test.jsx | 43 +++++++++++++++++++ 7 files changed, 138 insertions(+), 31 deletions(-) create mode 100644 src/tests/MockedPluginSlot.jsx create mode 100644 src/tests/MockedPluginSlot.test.jsx diff --git a/src/course-home/outline-tab/OutlineTab.jsx b/src/course-home/outline-tab/OutlineTab.jsx index 15ac5dd605..2ea019d972 100644 --- a/src/course-home/outline-tab/OutlineTab.jsx +++ b/src/course-home/outline-tab/OutlineTab.jsx @@ -5,6 +5,7 @@ import { sendTrackEvent } from '@edx/frontend-platform/analytics'; import { getAuthenticatedUser } from '@edx/frontend-platform/auth'; import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; import { Button } from '@openedx/paragon'; +import { PluginSlot } from '@openedx/frontend-plugin-framework'; import { AlertList } from '../../generic/user-messages'; import CourseDates from './widgets/CourseDates'; @@ -123,6 +124,20 @@ const OutlineTab = ({ intl }) => { } }, [location.search]); + const upgradeNotificationProps = { + offer, + verifiedMode, + accessExpiration, + contentTypeGatingEnabled: datesBannerInfo.contentTypeGatingEnabled, + marketingUrl, + upsellPageName: 'course_home', + userTimezone, + timeOffsetMillis, + courseId, + org, + shouldDisplayBorder: true, + }; + return ( <>
@@ -194,19 +209,13 @@ const OutlineTab = ({ intl }) => { /> )} - + + +
diff --git a/src/course-home/outline-tab/OutlineTab.test.jsx b/src/course-home/outline-tab/OutlineTab.test.jsx index 47ceed621d..5395da4506 100644 --- a/src/course-home/outline-tab/OutlineTab.test.jsx +++ b/src/course-home/outline-tab/OutlineTab.test.jsx @@ -132,6 +132,21 @@ describe('Outline Tab', () => { expect(expandedSectionNode).toHaveAttribute('aria-expanded', 'true'); }); + it('renders the Notification wrapper', async () => { + const { courseBlocks } = await buildMinimalCourseBlocks(courseId, 'Title', { resumeBlock: true }); + setTabData({ + course_blocks: { blocks: courseBlocks.blocks }, + }); + await fetchAndRender(); + + const pluginSlot = screen.getByTestId('outline-tab-slot'); + expect(pluginSlot).toBeInTheDocument(); + + // The Upgrade Notification should be inside the PluginSlot. + const UpgradeNotification = pluginSlot.querySelector('.upgrade-notification'); + expect(UpgradeNotification).toBeInTheDocument(); + }); + it('handles expand/collapse all button click', async () => { await fetchAndRender(); // Button renders as "Expand All" diff --git a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx index 3f8ab62bbc..3c61332db6 100644 --- a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx +++ b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx @@ -1,6 +1,7 @@ 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'; @@ -66,24 +67,32 @@ const NotificationsWidget = () => { if (hideNotificationbar || !isNotificationbarAvailable) { return null; } + const upgradeNotificationProps = { + offer, + verifiedMode, + accessExpiration, + contentTypeGatingEnabled, + marketingUrl, + upsellPageName: 'in_course', + userTimezone, + timeOffsetMillis, + courseId, + org, + upgradeNotificationCurrentState, + setupgradeNotificationCurrentState: setUpgradeNotificationCurrentState, // TODO: Check typo in component? + shouldDisplayBorder: false, + toggleSidebar: () => toggleSidebar(currentSidebar, WIDGETS.NOTIFICATIONS), + }; + return (
- toggleSidebar(currentSidebar, WIDGETS.NOTIFICATIONS)} - /> + + +
); }; diff --git a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.test.jsx b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.test.jsx index 74d12a8ebe..b72b4f90b1 100644 --- a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.test.jsx +++ b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.test.jsx @@ -92,9 +92,14 @@ describe('NotificationsWidget', () => { , ); - const UpgradeNotification = document.querySelector('.upgrade-notification'); + const pluginSlot = screen.getByTestId('notification-widget-slot'); + expect(pluginSlot).toBeInTheDocument(); + + // The Upgrade Notification should be inside the PluginSlot. + const UpgradeNotification = pluginSlot.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(); }); diff --git a/src/setupTest.js b/src/setupTest.js index b3039f6e10..3f999b8744 100755 --- a/src/setupTest.js +++ b/src/setupTest.js @@ -28,11 +28,12 @@ import { fetchCourse, fetchSequence } from './courseware/data'; import { appendBrowserTimezoneToUrl, executeThunk } from './utils'; import buildSimpleCourseAndSequenceMetadata from './courseware/data/__factories__/sequenceMetadata.factory'; import { buildOutlineFromBlocks } from './courseware/data/__factories__/learningSequencesOutline.factory'; +import MockedPluginSlot from './tests/MockedPluginSlot'; jest.mock('@openedx/frontend-plugin-framework', () => ({ ...jest.requireActual('@openedx/frontend-plugin-framework'), Plugin: () => 'Plugin', - PluginSlot: () => 'PluginSlot', + PluginSlot: MockedPluginSlot, })); jest.mock('@src/generic/plugin-store', () => ({ diff --git a/src/tests/MockedPluginSlot.jsx b/src/tests/MockedPluginSlot.jsx new file mode 100644 index 0000000000..e1409ca88b --- /dev/null +++ b/src/tests/MockedPluginSlot.jsx @@ -0,0 +1,25 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +const MockedPluginSlot = ({ children, testId }) => { + if (!testId) { return children ?? 'PluginSlot'; } // Return its content if PluginSlot slot is wrapping any. + + return
{children}
; +}; + +MockedPluginSlot.displayName = 'PluginSlot'; + +MockedPluginSlot.propTypes = { + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node, + ]), + testId: PropTypes.string, +}; + +MockedPluginSlot.defaultProps = { + children: undefined, + testId: undefined, +}; + +export default MockedPluginSlot; diff --git a/src/tests/MockedPluginSlot.test.jsx b/src/tests/MockedPluginSlot.test.jsx new file mode 100644 index 0000000000..cc492a0d11 --- /dev/null +++ b/src/tests/MockedPluginSlot.test.jsx @@ -0,0 +1,43 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import MockedPluginSlot from './MockedPluginSlot'; + +describe('MockedPluginSlot', () => { + it('renders as plain "PluginSlot" text node if no clildren nor testId is', () => { + render(); + + const component = screen.getByText('PluginSlot'); + expect(component).toBeInTheDocument(); + }); + + it('renders as the slot children directly if there is content within and no testId', () => { + render( +
+ + How much wood could a woodchuck chuck if a woodchuck could chuck wood? + +
, + ); + + const component = screen.getByRole('article'); + expect(component).toBeInTheDocument(); + + // Direct children + const quote = component.querySelector(':scope > q'); + expect(quote.getAttribute('role')).toBe('note'); + }); + + it('renders a div when a testId is provided ', () => { + render( + + I am selling these fine leather jackets. + , + ); + + const component = screen.getByTestId('guybrush'); + expect(component).toBeInTheDocument(); + + const quote = component.querySelector('[role=note]'); + expect(quote).toBeInTheDocument(); + }); +}); From 1b5337a7ce5e543954b8bba6a06066e8e13ce74a Mon Sep 17 00:00:00 2001 From: Marcos Rigoli Date: Mon, 22 Apr 2024 16:09:48 -0300 Subject: [PATCH 3/7] feat: Added Plugin Slot wrapping UpgradeNotification in NotificationTray (#1367) --- .../notifications/NotificationTray.jsx | 39 ++++++++++++------- .../notifications/NotificationTray.test.jsx | 10 +++-- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx index 76f1e38f94..6adb7b3e32 100644 --- a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx +++ b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx @@ -2,6 +2,7 @@ import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; import classNames from 'classnames'; 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'; @@ -65,6 +66,22 @@ const NotificationTray = ({ intl }) => { sendTrackEvent('edx.ui.course.upgrade.old_sidebar.notifications', notificationTrayEventProperties); }, []); + const upgradeNotificationProps = { + offer, + verifiedMode, + accessExpiration, + contentTypeGatingEnabled, + marketingUrl, + upsellPageName: 'in_course', + userTimezone, + shouldDisplayBorder: false, + timeOffsetMillis, + courseId, + org, + upgradeNotificationCurrentState, + setupgradeNotificationCurrentState: setUpgradeNotificationCurrentState, // TODO: Check typo in component? + }; + return ( { >
{verifiedMode ? ( - + + + ) : (

{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 666874d75c..3e353fbfb2 100644 --- a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.test.jsx +++ b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.test.jsx @@ -91,10 +91,14 @@ describe('NotificationTray', () => { , ); - const UpgradeNotification = document.querySelector('.upgrade-notification'); - expect(UpgradeNotification) - .toBeInTheDocument(); + const pluginSlot = screen.getByTestId('notification-tray-slot'); + expect(pluginSlot).toBeInTheDocument(); + + // The Upgrade Notification should be inside the PluginSlot. + const UpgradeNotification = pluginSlot.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.')) From 1e29715f9ba1db10be689f983ab31578c5af1601 Mon Sep 17 00:00:00 2001 From: Marcos Rigoli Date: Tue, 23 Apr 2024 13:36:59 -0300 Subject: [PATCH 4/7] fix: Removed PluginSlot prop scoping for UpgradeNotification (#1369) --- src/course-home/outline-tab/OutlineTab.jsx | 2 +- .../notifications/NotificationsWidget.jsx | 2 +- .../course/sidebar/sidebars/notifications/NotificationTray.jsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/course-home/outline-tab/OutlineTab.jsx b/src/course-home/outline-tab/OutlineTab.jsx index 2ea019d972..9b79479517 100644 --- a/src/course-home/outline-tab/OutlineTab.jsx +++ b/src/course-home/outline-tab/OutlineTab.jsx @@ -211,7 +211,7 @@ const OutlineTab = ({ intl }) => { diff --git a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx index 3c61332db6..d7e6b5e064 100644 --- a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx +++ b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx @@ -88,7 +88,7 @@ const NotificationsWidget = () => {
diff --git a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx index 6adb7b3e32..5c133bc60b 100644 --- a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx +++ b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx @@ -94,7 +94,7 @@ const NotificationTray = ({ intl }) => { ? ( From 098955957ca1bccfc505207491e765dd7f680ca8 Mon Sep 17 00:00:00 2001 From: Zachary Hancock Date: Tue, 7 May 2024 14:22:39 -0400 Subject: [PATCH 5/7] feat: generic sidebar notification plugin (#1379) * feat: make notification plugin api generic * feat: include new sidebar and tests * feat: tweak sidebar toggle --- src/course-home/outline-tab/OutlineTab.jsx | 33 ++++++------- .../outline-tab/OutlineTab.test.jsx | 9 +--- .../notifications/NotificationsWidget.jsx | 48 +++++++++++-------- .../NotificationsWidget.test.jsx | 20 ++++++-- .../notifications/NotificationTray.jsx | 41 ++++++++-------- .../notifications/NotificationTray.test.jsx | 20 +++++--- src/tests/MockedPluginSlot.jsx | 15 +++--- src/tests/MockedPluginSlot.test.jsx | 12 ++--- 8 files changed, 109 insertions(+), 89 deletions(-) diff --git a/src/course-home/outline-tab/OutlineTab.jsx b/src/course-home/outline-tab/OutlineTab.jsx index 9b79479517..de900251be 100644 --- a/src/course-home/outline-tab/OutlineTab.jsx +++ b/src/course-home/outline-tab/OutlineTab.jsx @@ -124,20 +124,6 @@ const OutlineTab = ({ intl }) => { } }, [location.search]); - const upgradeNotificationProps = { - offer, - verifiedMode, - accessExpiration, - contentTypeGatingEnabled: datesBannerInfo.contentTypeGatingEnabled, - marketingUrl, - upsellPageName: 'course_home', - userTimezone, - timeOffsetMillis, - courseId, - org, - shouldDisplayBorder: true, - }; - return ( <>
@@ -210,11 +196,22 @@ const OutlineTab = ({ intl }) => { )} - + diff --git a/src/course-home/outline-tab/OutlineTab.test.jsx b/src/course-home/outline-tab/OutlineTab.test.jsx index 5395da4506..7bb8544d96 100644 --- a/src/course-home/outline-tab/OutlineTab.test.jsx +++ b/src/course-home/outline-tab/OutlineTab.test.jsx @@ -132,19 +132,14 @@ describe('Outline Tab', () => { expect(expandedSectionNode).toHaveAttribute('aria-expanded', 'true'); }); - it('renders the Notification wrapper', async () => { + it('includes outline_tab_notifications_plugin slot', async () => { const { courseBlocks } = await buildMinimalCourseBlocks(courseId, 'Title', { resumeBlock: true }); setTabData({ course_blocks: { blocks: courseBlocks.blocks }, }); await fetchAndRender(); - const pluginSlot = screen.getByTestId('outline-tab-slot'); - expect(pluginSlot).toBeInTheDocument(); - - // The Upgrade Notification should be inside the PluginSlot. - const UpgradeNotification = pluginSlot.querySelector('.upgrade-notification'); - expect(UpgradeNotification).toBeInTheDocument(); + expect(screen.getByTestId('outline_tab_notifications_plugin')).toBeInTheDocument(); }); it('handles expand/collapse all button click', async () => { diff --git a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx index d7e6b5e064..c926c1468d 100644 --- a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx +++ b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx @@ -59,6 +59,10 @@ const NotificationsWidget = () => { verification_status: verificationStatus, }; + const onToggleSidebar = () => { + toggleSidebar(currentSidebar, WIDGETS.NOTIFICATIONS); + }; + // After three seconds, update notificationSeen (to hide red dot) useEffect(() => { setTimeout(onNotificationSeen, 3000); @@ -67,31 +71,33 @@ const NotificationsWidget = () => { if (hideNotificationbar || !isNotificationbarAvailable) { return null; } - const upgradeNotificationProps = { - offer, - verifiedMode, - accessExpiration, - contentTypeGatingEnabled, - marketingUrl, - upsellPageName: 'in_course', - userTimezone, - timeOffsetMillis, - courseId, - org, - upgradeNotificationCurrentState, - setupgradeNotificationCurrentState: setUpgradeNotificationCurrentState, // TODO: Check typo in component? - shouldDisplayBorder: false, - toggleSidebar: () => toggleSidebar(currentSidebar, WIDGETS.NOTIFICATIONS), - }; - return (
- +
); diff --git a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.test.jsx b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.test.jsx index b72b4f90b1..cc19bb64c4 100644 --- a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.test.jsx +++ b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.test.jsx @@ -80,7 +80,7 @@ describe('NotificationsWidget', () => { }); }); - it('renders upgrade card', async () => { + it('includes notification_widget_plugin slot', async () => { await fetchAndRender( { , ); + expect(screen.getByTestId('notification_widget_plugin')).toBeInTheDocument(); + }); - const pluginSlot = screen.getByTestId('notification-widget-slot'); - expect(pluginSlot).toBeInTheDocument(); + it('renders upgrade card', async () => { + await fetchAndRender( + + + , + ); // The Upgrade Notification should be inside the PluginSlot. - const UpgradeNotification = pluginSlot.querySelector('.upgrade-notification'); + const UpgradeNotification = document.querySelector('.upgrade-notification'); expect(UpgradeNotification).toBeInTheDocument(); expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument(); diff --git a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx index 5c133bc60b..4cda479759 100644 --- a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx +++ b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx @@ -66,22 +66,6 @@ const NotificationTray = ({ intl }) => { sendTrackEvent('edx.ui.course.upgrade.old_sidebar.notifications', notificationTrayEventProperties); }, []); - const upgradeNotificationProps = { - offer, - verifiedMode, - accessExpiration, - contentTypeGatingEnabled, - marketingUrl, - upsellPageName: 'in_course', - userTimezone, - shouldDisplayBorder: false, - timeOffsetMillis, - courseId, - org, - upgradeNotificationCurrentState, - setupgradeNotificationCurrentState: setUpgradeNotificationCurrentState, // TODO: Check typo in component? - }; - return ( {
{verifiedMode ? ( - + ) : (

{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 3e353fbfb2..2e1815f7be 100644 --- a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.test.jsx +++ b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.test.jsx @@ -81,7 +81,7 @@ describe('NotificationTray', () => { .toBeInTheDocument(); }); - it('renders upgrade card', async () => { + it('includes notification_tray_plugin slot', async () => { await fetchAndRender( { , ); + expect(screen.getByTestId('notification_tray_plugin')).toBeInTheDocument(); + }); - const pluginSlot = screen.getByTestId('notification-tray-slot'); - expect(pluginSlot).toBeInTheDocument(); + it('renders upgrade card', async () => { + await fetchAndRender( + + + , + ); - // The Upgrade Notification should be inside the PluginSlot. - const UpgradeNotification = pluginSlot.querySelector('.upgrade-notification'); - expect(UpgradeNotification).toBeInTheDocument(); + expect(document.querySelector('.upgrade-notification')).toBeInTheDocument(); expect(screen.getByRole('link', { name: 'Upgrade for $149' })) .toBeInTheDocument(); diff --git a/src/tests/MockedPluginSlot.jsx b/src/tests/MockedPluginSlot.jsx index e1409ca88b..e86952ee0b 100644 --- a/src/tests/MockedPluginSlot.jsx +++ b/src/tests/MockedPluginSlot.jsx @@ -1,11 +1,12 @@ import React from 'react'; import PropTypes from 'prop-types'; -const MockedPluginSlot = ({ children, testId }) => { - if (!testId) { return children ?? 'PluginSlot'; } // Return its content if PluginSlot slot is wrapping any. - - return
{children}
; -}; +const MockedPluginSlot = ({ children, id }) => ( +
+ PluginSlot_{id} + { children &&
{children}
} +
+); MockedPluginSlot.displayName = 'PluginSlot'; @@ -14,12 +15,12 @@ MockedPluginSlot.propTypes = { PropTypes.arrayOf(PropTypes.node), PropTypes.node, ]), - testId: PropTypes.string, + id: PropTypes.string, }; MockedPluginSlot.defaultProps = { children: undefined, - testId: undefined, + id: undefined, }; export default MockedPluginSlot; diff --git a/src/tests/MockedPluginSlot.test.jsx b/src/tests/MockedPluginSlot.test.jsx index cc492a0d11..b830b68fbf 100644 --- a/src/tests/MockedPluginSlot.test.jsx +++ b/src/tests/MockedPluginSlot.test.jsx @@ -3,14 +3,14 @@ import { render, screen } from '@testing-library/react'; import MockedPluginSlot from './MockedPluginSlot'; describe('MockedPluginSlot', () => { - it('renders as plain "PluginSlot" text node if no clildren nor testId is', () => { - render(); + it('renders mock plugin with "PluginSlot" text', () => { + render(); - const component = screen.getByText('PluginSlot'); + const component = screen.getByText('PluginSlot_test_plugin'); expect(component).toBeInTheDocument(); }); - it('renders as the slot children directly if there is content within and no testId', () => { + it('renders as the slot children directly if there is content within', () => { render(
@@ -27,9 +27,9 @@ describe('MockedPluginSlot', () => { expect(quote.getAttribute('role')).toBe('note'); }); - it('renders a div when a testId is provided ', () => { + it('renders mock plugin with a data-testid ', () => { render( - + I am selling these fine leather jackets. , ); From af3eaf6271c718eb1bd8cb68527c331281c3c826 Mon Sep 17 00:00:00 2001 From: Zacharis278 Date: Tue, 7 May 2024 14:36:50 -0400 Subject: [PATCH 6/7] style: fix extra space from merge --- .../course/sidebar/sidebars/notifications/NotificationTray.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx index 0b78c0210e..9fe8d1ad21 100644 --- a/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx +++ b/src/courseware/course/sidebar/sidebars/notifications/NotificationTray.jsx @@ -6,7 +6,6 @@ import { PluginSlot } from '@openedx/frontend-plugin-framework'; import { useModel } from '../../../../../generic/model-store'; import UpgradeNotification from '../../../../../generic/upgrade-notification/UpgradeNotification'; - import messages from '../../../messages'; import SidebarBase from '../../common/SidebarBase'; import SidebarContext from '../../SidebarContext'; From 71a23d28d89833cc16dd73d74b801b81396aff6a Mon Sep 17 00:00:00 2001 From: Zacharis278 Date: Mon, 13 May 2024 16:25:32 -0400 Subject: [PATCH 7/7] feat: rename plugin slots --- .../notifications/NotificationsWidget.jsx | 2 +- .../notifications/NotificationsWidget.test.jsx | 4 ++-- src/courseware/course/sequence/Unit/UnitSuspense.jsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx index c926c1468d..7e7087ac5b 100644 --- a/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx +++ b/src/courseware/course/new-sidebar/sidebars/discussions-notifications/notifications/NotificationsWidget.jsx @@ -74,7 +74,7 @@ const NotificationsWidget = () => { return (
{ }); }); - it('includes notification_widget_plugin slot', async () => { + it('includes notification_widget_slot', async () => { await fetchAndRender( { , ); - expect(screen.getByTestId('notification_widget_plugin')).toBeInTheDocument(); + expect(screen.getByTestId('notification_widget_slot')).toBeInTheDocument(); }); it('renders upgrade card', async () => { diff --git a/src/courseware/course/sequence/Unit/UnitSuspense.jsx b/src/courseware/course/sequence/Unit/UnitSuspense.jsx index 0e1871ec68..09843a7164 100644 --- a/src/courseware/course/sequence/Unit/UnitSuspense.jsx +++ b/src/courseware/course/sequence/Unit/UnitSuspense.jsx @@ -30,7 +30,7 @@ const UnitSuspense = ({ {shouldDisplayContentGating && ( }>