From 777d3aa45c1a3eb88c254ab395a843436910b043 Mon Sep 17 00:00:00 2001
From: Maxwell Frank <92897870+MaxFrank13@users.noreply.github.com>
Date: Mon, 13 Jan 2025 13:50:50 -0500
Subject: [PATCH 1/4] feat!: remove UpgradeButton (#536)
---
.../BeginCourseButton.test.jsx | 2 +-
.../CourseCardActions/ResumeButton.test.jsx | 2 +-
.../CourseCardActions/UpgradeButton.test.jsx | 49 -------------------
.../ViewCourseButton.test.jsx | 2 +-
.../BeginCourseButton.test.jsx.snap | 4 +-
.../__snapshots__/ResumeButton.test.jsx.snap | 4 +-
.../__snapshots__/UpgradeButton.test.jsx.snap | 32 ------------
.../ViewCourseButton.test.jsx.snap | 4 +-
.../components/CourseCardActions/messages.js | 5 --
.../components/CourseCardImage.test.jsx | 4 +-
.../components/CourseCardTitle.test.jsx | 4 +-
.../CourseCardImage.test.jsx.snap | 2 +-
.../CourseCardTitle.test.jsx.snap | 2 +-
src/containers/CourseCard/components/hooks.js | 6 +--
.../CourseCard/components/hooks.test.js | 21 --------
src/data/redux/app/selectors/courseCard.js | 1 -
.../redux/app/selectors/courseCard.test.js | 4 +-
src/data/services/lms/api.js | 7 ---
src/data/services/lms/api.test.js | 7 ---
src/data/services/lms/fakeData/courses.js | 3 --
.../CourseCardActionSlot/index.jsx | 29 +++--------
src/tracking/constants.js | 7 ---
src/tracking/trackers/course.js | 24 ---------
src/tracking/trackers/course.test.js | 45 -----------------
24 files changed, 26 insertions(+), 244 deletions(-)
delete mode 100644 src/containers/CourseCard/components/CourseCardActions/UpgradeButton.test.jsx
delete mode 100644 src/containers/CourseCard/components/CourseCardActions/__snapshots__/UpgradeButton.test.jsx.snap
diff --git a/src/containers/CourseCard/components/CourseCardActions/BeginCourseButton.test.jsx b/src/containers/CourseCard/components/CourseCardActions/BeginCourseButton.test.jsx
index f34a534c3..1559d4edf 100644
--- a/src/containers/CourseCard/components/CourseCardActions/BeginCourseButton.test.jsx
+++ b/src/containers/CourseCard/components/CourseCardActions/BeginCourseButton.test.jsx
@@ -27,7 +27,7 @@ reduxHooks.useCardCourseRunData.mockReturnValue({ homeUrl });
const execEdPath = (cardId) => `exec-ed-tracking-path=${cardId}`;
reduxHooks.useCardExecEdTrackingParam.mockImplementation(execEdPath);
reduxHooks.useTrackCourseEvent.mockImplementation(
- (eventName, cardId, upgradeUrl) => ({ trackCourseEvent: { eventName, cardId, upgradeUrl } }),
+ (eventName, cardId, url) => ({ trackCourseEvent: { eventName, cardId, url } }),
);
describe('BeginCourseButton', () => {
diff --git a/src/containers/CourseCard/components/CourseCardActions/ResumeButton.test.jsx b/src/containers/CourseCard/components/CourseCardActions/ResumeButton.test.jsx
index c4ca41e57..a96fc1aa2 100644
--- a/src/containers/CourseCard/components/CourseCardActions/ResumeButton.test.jsx
+++ b/src/containers/CourseCard/components/CourseCardActions/ResumeButton.test.jsx
@@ -26,7 +26,7 @@ reduxHooks.useCardCourseRunData.mockReturnValue({ resumeUrl });
const execEdPath = (cardId) => `exec-ed-tracking-path=${cardId}`;
reduxHooks.useCardExecEdTrackingParam.mockImplementation(execEdPath);
reduxHooks.useTrackCourseEvent.mockImplementation(
- (eventName, cardId, upgradeUrl) => ({ trackCourseEvent: { eventName, cardId, upgradeUrl } }),
+ (eventName, cardId, url) => ({ trackCourseEvent: { eventName, cardId, url } }),
);
let wrapper;
diff --git a/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.test.jsx b/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.test.jsx
deleted file mode 100644
index a539278cc..000000000
--- a/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.test.jsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import { shallow } from '@edx/react-unit-test-utils';
-
-import track from 'tracking';
-import { reduxHooks } from 'hooks';
-import useActionDisabledState from '../hooks';
-import UpgradeButton from './UpgradeButton';
-
-jest.mock('tracking', () => ({
- course: {
- upgradeClicked: jest.fn().mockName('segment.trackUpgradeClicked'),
- },
-}));
-
-jest.mock('hooks', () => ({
- reduxHooks: {
- useCardCourseRunData: jest.fn(),
- useTrackCourseEvent: jest.fn(
- (eventName, cardId, upgradeUrl) => ({ trackCourseEvent: { eventName, cardId, upgradeUrl } }),
- ),
- },
-}));
-jest.mock('../hooks', () => jest.fn(() => ({ disableUpgradeCourse: false })));
-jest.mock('./ActionButton', () => 'ActionButton');
-
-describe('UpgradeButton', () => {
- const props = {
- cardId: 'cardId',
- };
- const upgradeUrl = 'upgradeUrl';
- reduxHooks.useCardCourseRunData.mockReturnValue({ upgradeUrl });
- describe('snapshot', () => {
- test('can upgrade', () => {
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- expect(wrapper.instance.props.disabled).toEqual(false);
- expect(wrapper.instance.props.onClick).toEqual(reduxHooks.useTrackCourseEvent(
- track.course.upgradeClicked,
- props.cardId,
- upgradeUrl,
- ));
- });
- test('cannot upgrade', () => {
- useActionDisabledState.mockReturnValueOnce({ disableUpgradeCourse: true });
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- expect(wrapper.instance.props.disabled).toEqual(true);
- });
- });
-});
diff --git a/src/containers/CourseCard/components/CourseCardActions/ViewCourseButton.test.jsx b/src/containers/CourseCard/components/CourseCardActions/ViewCourseButton.test.jsx
index 712f81032..186f40bde 100644
--- a/src/containers/CourseCard/components/CourseCardActions/ViewCourseButton.test.jsx
+++ b/src/containers/CourseCard/components/CourseCardActions/ViewCourseButton.test.jsx
@@ -15,7 +15,7 @@ jest.mock('hooks', () => ({
reduxHooks: {
useCardCourseRunData: jest.fn(() => ({ homeUrl: 'homeUrl' })),
useTrackCourseEvent: jest.fn(
- (eventName, cardId, upgradeUrl) => ({ trackCourseEvent: { eventName, cardId, upgradeUrl } }),
+ (eventName, cardId, url) => ({ trackCourseEvent: { eventName, cardId, url } }),
),
},
}));
diff --git a/src/containers/CourseCard/components/CourseCardActions/__snapshots__/BeginCourseButton.test.jsx.snap b/src/containers/CourseCard/components/CourseCardActions/__snapshots__/BeginCourseButton.test.jsx.snap
index 4604ab60b..0cbfdb62e 100644
--- a/src/containers/CourseCard/components/CourseCardActions/__snapshots__/BeginCourseButton.test.jsx.snap
+++ b/src/containers/CourseCard/components/CourseCardActions/__snapshots__/BeginCourseButton.test.jsx.snap
@@ -10,7 +10,7 @@ exports[`BeginCourseButton snapshot disabled snapshot 1`] = `
"trackCourseEvent": {
"cardId": "cardId",
"eventName": [MockFunction segment.enterCourseClicked],
- "upgradeUrl": "home-urlexec-ed-tracking-path=cardId",
+ "url": "home-urlexec-ed-tracking-path=cardId",
},
}
}
@@ -29,7 +29,7 @@ exports[`BeginCourseButton snapshot enabled snapshot 1`] = `
"trackCourseEvent": {
"cardId": "cardId",
"eventName": [MockFunction segment.enterCourseClicked],
- "upgradeUrl": "home-urlexec-ed-tracking-path=cardId",
+ "url": "home-urlexec-ed-tracking-path=cardId",
},
}
}
diff --git a/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ResumeButton.test.jsx.snap b/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ResumeButton.test.jsx.snap
index e0c348400..c9c7e5e60 100644
--- a/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ResumeButton.test.jsx.snap
+++ b/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ResumeButton.test.jsx.snap
@@ -10,7 +10,7 @@ exports[`ResumeButton snapshot disabled snapshot 1`] = `
"trackCourseEvent": {
"cardId": "cardId",
"eventName": [MockFunction segment.enterCourseClicked],
- "upgradeUrl": "resume-urlexec-ed-tracking-path=cardId",
+ "url": "resume-urlexec-ed-tracking-path=cardId",
},
}
}
@@ -29,7 +29,7 @@ exports[`ResumeButton snapshot enabled snapshot 1`] = `
"trackCourseEvent": {
"cardId": "cardId",
"eventName": [MockFunction segment.enterCourseClicked],
- "upgradeUrl": "resume-urlexec-ed-tracking-path=cardId",
+ "url": "resume-urlexec-ed-tracking-path=cardId",
},
}
}
diff --git a/src/containers/CourseCard/components/CourseCardActions/__snapshots__/UpgradeButton.test.jsx.snap b/src/containers/CourseCard/components/CourseCardActions/__snapshots__/UpgradeButton.test.jsx.snap
deleted file mode 100644
index d6718302a..000000000
--- a/src/containers/CourseCard/components/CourseCardActions/__snapshots__/UpgradeButton.test.jsx.snap
+++ /dev/null
@@ -1,32 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`UpgradeButton snapshot can upgrade 1`] = `
-
- Upgrade
-
-`;
-
-exports[`UpgradeButton snapshot cannot upgrade 1`] = `
-
- Upgrade
-
-`;
diff --git a/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ViewCourseButton.test.jsx.snap b/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ViewCourseButton.test.jsx.snap
index d777595e4..3274270fc 100644
--- a/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ViewCourseButton.test.jsx.snap
+++ b/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ViewCourseButton.test.jsx.snap
@@ -10,7 +10,7 @@ exports[`ViewCourseButton learner can view course 1`] = `
"trackCourseEvent": {
"cardId": "cardId",
"eventName": [MockFunction segment.enterCourseClicked],
- "upgradeUrl": "homeUrl",
+ "url": "homeUrl",
},
}
}
@@ -29,7 +29,7 @@ exports[`ViewCourseButton learner cannot view course 1`] = `
"trackCourseEvent": {
"cardId": "cardId",
"eventName": [MockFunction segment.enterCourseClicked],
- "upgradeUrl": "homeUrl",
+ "url": "homeUrl",
},
}
}
diff --git a/src/containers/CourseCard/components/CourseCardActions/messages.js b/src/containers/CourseCard/components/CourseCardActions/messages.js
index 6c14f9b0c..309842977 100644
--- a/src/containers/CourseCard/components/CourseCardActions/messages.js
+++ b/src/containers/CourseCard/components/CourseCardActions/messages.js
@@ -1,11 +1,6 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
- upgrade: {
- id: 'learner-dash.courseCard.actions.upgrade',
- description: 'Course card upgrade button text',
- defaultMessage: 'Upgrade',
- },
beginCourse: {
id: 'learner-dash.courseCard.actions.beginCourse',
description: 'Course card begin-course button text',
diff --git a/src/containers/CourseCard/components/CourseCardImage.test.jsx b/src/containers/CourseCard/components/CourseCardImage.test.jsx
index 278b20d08..05d0636e2 100644
--- a/src/containers/CourseCard/components/CourseCardImage.test.jsx
+++ b/src/containers/CourseCard/components/CourseCardImage.test.jsx
@@ -18,8 +18,8 @@ jest.mock('hooks', () => ({
useCardCourseData: jest.fn(() => ({ bannerImgSrc: 'banner-img-src' })),
useCardCourseRunData: jest.fn(() => ({ homeUrl })),
useCardEnrollmentData: jest.fn(() => ({ isVerified: true })),
- useTrackCourseEvent: jest.fn((eventName, cardId, upgradeUrl) => ({
- trackCourseEvent: { eventName, cardId, upgradeUrl },
+ useTrackCourseEvent: jest.fn((eventName, cardId, url) => ({
+ trackCourseEvent: { eventName, cardId, url },
})),
},
}));
diff --git a/src/containers/CourseCard/components/CourseCardTitle.test.jsx b/src/containers/CourseCard/components/CourseCardTitle.test.jsx
index a71dd7e74..aa3dcdd30 100644
--- a/src/containers/CourseCard/components/CourseCardTitle.test.jsx
+++ b/src/containers/CourseCard/components/CourseCardTitle.test.jsx
@@ -17,8 +17,8 @@ jest.mock('hooks', () => ({
reduxHooks: {
useCardCourseData: jest.fn(() => ({ courseName: 'course-name' })),
useCardCourseRunData: jest.fn(() => ({ homeUrl })),
- useTrackCourseEvent: jest.fn((eventName, cardId, upgradeUrl) => ({
- trackCourseEvent: { eventName, cardId, upgradeUrl },
+ useTrackCourseEvent: jest.fn((eventName, cardId, url) => ({
+ trackCourseEvent: { eventName, cardId, url },
})),
},
}));
diff --git a/src/containers/CourseCard/components/__snapshots__/CourseCardImage.test.jsx.snap b/src/containers/CourseCard/components/__snapshots__/CourseCardImage.test.jsx.snap
index 2a0bc9258..a0d357c7c 100644
--- a/src/containers/CourseCard/components/__snapshots__/CourseCardImage.test.jsx.snap
+++ b/src/containers/CourseCard/components/__snapshots__/CourseCardImage.test.jsx.snap
@@ -9,7 +9,7 @@ exports[`CourseCardImage snapshot renders clickable link course Image 1`] = `
"trackCourseEvent": {
"cardId": "cardId",
"eventName": [MockFunction segment.courseImageClicked],
- "upgradeUrl": "home-url",
+ "url": "home-url",
},
}
}
diff --git a/src/containers/CourseCard/components/__snapshots__/CourseCardTitle.test.jsx.snap b/src/containers/CourseCard/components/__snapshots__/CourseCardTitle.test.jsx.snap
index c35f852c1..34446ade0 100644
--- a/src/containers/CourseCard/components/__snapshots__/CourseCardTitle.test.jsx.snap
+++ b/src/containers/CourseCard/components/__snapshots__/CourseCardTitle.test.jsx.snap
@@ -11,7 +11,7 @@ exports[`CourseCardTitle snapshot renders clickable link course title 1`] = `
"trackCourseEvent": {
"cardId": "cardId",
"eventName": [MockFunction segment.courseTitleClicked],
- "upgradeUrl": "home-url",
+ "url": "home-url",
},
}
}
diff --git a/src/containers/CourseCard/components/hooks.js b/src/containers/CourseCard/components/hooks.js
index 2a3020142..9d80c0ae9 100644
--- a/src/containers/CourseCard/components/hooks.js
+++ b/src/containers/CourseCard/components/hooks.js
@@ -3,19 +3,18 @@ import { reduxHooks } from 'hooks';
export const useActionDisabledState = (cardId) => {
const { isMasquerading } = reduxHooks.useMasqueradeData();
const {
- canUpgrade, hasAccess, isAudit, isAuditAccessExpired,
+ hasAccess, isAudit, isAuditAccessExpired,
} = reduxHooks.useCardEnrollmentData(cardId);
const {
isEntitlement, isFulfilled, canChange, hasSessions,
} = reduxHooks.useCardEntitlementData(cardId);
- const { resumeUrl, homeUrl, upgradeUrl } = reduxHooks.useCardCourseRunData(cardId);
+ const { resumeUrl, homeUrl } = reduxHooks.useCardCourseRunData(cardId);
const disableBeginCourse = !homeUrl || (isMasquerading || !hasAccess || (isAudit && isAuditAccessExpired));
const disableResumeCourse = !resumeUrl || (isMasquerading || !hasAccess || (isAudit && isAuditAccessExpired));
const disableViewCourse = !hasAccess || (isAudit && isAuditAccessExpired);
const disableSelectSession = !isEntitlement || isMasquerading || !hasAccess || (!canChange || !hasSessions);
- const disableUpgradeCourse = !upgradeUrl || (isMasquerading && !canUpgrade);
const disableCourseTitle = (isEntitlement && !isFulfilled) || disableViewCourse;
@@ -23,7 +22,6 @@ export const useActionDisabledState = (cardId) => {
disableBeginCourse,
disableResumeCourse,
disableViewCourse,
- disableUpgradeCourse,
disableSelectSession,
disableCourseTitle,
};
diff --git a/src/containers/CourseCard/components/hooks.test.js b/src/containers/CourseCard/components/hooks.test.js
index f389ef40e..50d2ccc25 100644
--- a/src/containers/CourseCard/components/hooks.test.js
+++ b/src/containers/CourseCard/components/hooks.test.js
@@ -16,7 +16,6 @@ const cardId = 'my-test-course-number';
describe('useActionDisabledState', () => {
const defaultData = {
isMasquerading: false,
- canUpgrade: false,
isEntitlement: false,
isFulfilled: false,
canChange: false,
@@ -26,12 +25,10 @@ describe('useActionDisabledState', () => {
isAuditAccessExpired: false,
resumeUrl: 'resume.url',
homeUrl: 'home.url',
- upgradeUrl: 'upgrade.url',
};
const mockHooksData = (args) => {
const {
isMasquerading,
- canUpgrade,
isEntitlement,
isFulfilled,
canChange,
@@ -41,11 +38,9 @@ describe('useActionDisabledState', () => {
isAuditAccessExpired,
resumeUrl,
homeUrl,
- upgradeUrl,
} = { ...defaultData, ...args };
reduxHooks.useMasqueradeData.mockReturnValueOnce({ isMasquerading });
reduxHooks.useCardEnrollmentData.mockReturnValueOnce({
- canUpgrade,
hasAccess,
isAudit,
isAuditAccessExpired,
@@ -59,7 +54,6 @@ describe('useActionDisabledState', () => {
reduxHooks.useCardCourseRunData.mockReturnValueOnce({
resumeUrl,
homeUrl,
- upgradeUrl,
});
};
@@ -121,21 +115,6 @@ describe('useActionDisabledState', () => {
testDisabled({ hasAccess: true }, false);
});
});
- describe('disableUpgradeCourse', () => {
- const testDisabled = (data, expected) => {
- mockHooksData(data);
- expect(runHook().disableUpgradeCourse).toBe(expected);
- };
- it('disable when upgradeUrl is invalid', () => {
- testDisabled({ upgradeUrl: null }, true);
- });
- it('disable when isMasquerading is true and canUpgrade is false', () => {
- testDisabled({ isMasquerading: true, canUpgrade: false }, true);
- });
- it('enable when all conditions are met', () => {
- testDisabled({ canUpgrade: true }, false);
- });
- });
describe('disableSelectSession', () => {
const testDisabled = (data, expected) => {
mockHooksData(data);
diff --git a/src/data/redux/app/selectors/courseCard.js b/src/data/redux/app/selectors/courseCard.js
index 742c5f000..080ad37ef 100644
--- a/src/data/redux/app/selectors/courseCard.js
+++ b/src/data/redux/app/selectors/courseCard.js
@@ -52,7 +52,6 @@ export const courseCard = StrictDict({
homeUrl: courseRun.homeUrl,
marketingUrl: courseRun.marketingUrl,
- upgradeUrl: courseRun.upgradeUrl,
progressUrl: baseAppUrl(courseRun.progressUrl),
resumeUrl: baseAppUrl(courseRun.resumeUrl), // resume will route this to learning mfe.
diff --git a/src/data/redux/app/selectors/courseCard.test.js b/src/data/redux/app/selectors/courseCard.test.js
index 5f042c53c..84c6da654 100644
--- a/src/data/redux/app/selectors/courseCard.test.js
+++ b/src/data/redux/app/selectors/courseCard.test.js
@@ -156,7 +156,6 @@ describe('courseCard selectors module', () => {
homeUrl: 'test-home-url',
marketingUrl: 'test-marketing-url',
- upgradeUrl: 'test-upgrade-url',
progressUrl: 'test-progress-url',
resumeUrl: 'test-resume-url',
@@ -181,10 +180,9 @@ describe('courseCard selectors module', () => {
it('passes minPassingGrade floored from float to a percentage value', () => {
expect(selected.minPassingGrade).toEqual(93);
});
- it('passes [homeUrl, marketingUrl, upgradeUrl]', () => {
+ it('passes [homeUrl, marketingUrl]', () => {
expect(selected.homeUrl).toEqual(testData.homeUrl);
expect(selected.marketingUrl).toEqual(testData.marketingUrl);
- expect(selected.upgradeUrl).toEqual(testData.upgradeUrl);
});
it('passes [progressUrl, unenrollUrl, resumeUrl], converted to baseAppUrl', () => {
expect(selected.progressUrl).toEqual(baseAppUrl(testData.progressUrl));
diff --git a/src/data/services/lms/api.js b/src/data/services/lms/api.js
index 6f9acd560..e2d477181 100644
--- a/src/data/services/lms/api.js
+++ b/src/data/services/lms/api.js
@@ -50,12 +50,6 @@ export const logEvent = ({ eventName, data, courseId }) => post(urls.event(), {
event: JSON.stringify(data),
});
-export const logUpgrade = ({ courseId }) => module.logEvent({
- eventName: eventNames.upgradeButtonClickedEnrollment,
- courseId,
- data: { location: 'learner-dashboard' },
-});
-
export const logShare = ({ courseId, site }) => module.logEvent({
eventName: eventNames.shareClicked,
courseId,
@@ -78,7 +72,6 @@ export default {
updateEntitlementEnrollment,
deleteEntitlementEnrollment,
logEvent,
- logUpgrade,
logShare,
createCreditRequest,
};
diff --git a/src/data/services/lms/api.test.js b/src/data/services/lms/api.test.js
index 8f83a3791..af24aad9f 100644
--- a/src/data/services/lms/api.test.js
+++ b/src/data/services/lms/api.test.js
@@ -130,13 +130,6 @@ describe('lms api methods', () => {
beforeEach(() => {
jest.spyOn(api, moduleKeys.logEvent).mockImplementation(logEvent);
});
- test('logUpgrade sends enrollment upgrade click event with learner dashboard location', () => {
- expect(api.logUpgrade({ courseId })).toEqual(logEvent({
- eventName: eventNames.upgradeButtonClickedEnrollment,
- courseId,
- data: { location: 'learner-dashboard' },
- }));
- });
test('logShare sends share clicke vent with course id, side and location', () => {
const site = 'test-site';
expect(api.logShare({ courseId, site })).toEqual(logEvent({
diff --git a/src/data/services/lms/fakeData/courses.js b/src/data/services/lms/fakeData/courses.js
index 0fec065b2..31911a969 100644
--- a/src/data/services/lms/fakeData/courses.js
+++ b/src/data/services/lms/fakeData/courses.js
@@ -779,9 +779,6 @@ export const compileCourseRunData = ({ courseName, ...data }, index) => {
courseProvider: getOption(providerOptions, index),
programs: getOption(programsOptions, index),
};
- if (out.enrollment.canUpgrade) {
- out.courseRun.upgradeUrl = 'test-upgrade-url';
- }
return out;
};
diff --git a/src/plugin-slots/CourseCardActionSlot/index.jsx b/src/plugin-slots/CourseCardActionSlot/index.jsx
index 6747ee185..7a95b675b 100644
--- a/src/plugin-slots/CourseCardActionSlot/index.jsx
+++ b/src/plugin-slots/CourseCardActionSlot/index.jsx
@@ -2,27 +2,14 @@ import React from 'react';
import PropTypes from 'prop-types';
import { PluginSlot } from '@openedx/frontend-plugin-framework';
-import { reduxHooks } from 'hooks';
-import UpgradeButton from 'containers/CourseCard/components/CourseCardActions/UpgradeButton';
-
-const CourseCardActionSlot = ({ cardId }) => {
- const { isEntitlement } = reduxHooks.useCardEntitlementData(cardId);
- const {
- isVerified,
- isExecEd2UCourse,
- } = reduxHooks.useCardEnrollmentData(cardId);
-
- return (
-
- {!(isEntitlement || isVerified || isExecEd2UCourse) && }
-
- );
-};
+const CourseCardActionSlot = ({ cardId }) => (
+
+);
CourseCardActionSlot.propTypes = {
cardId: PropTypes.string.isRequired,
diff --git a/src/tracking/constants.js b/src/tracking/constants.js
index 8c439a9bb..4683019cc 100644
--- a/src/tracking/constants.js
+++ b/src/tracking/constants.js
@@ -2,7 +2,6 @@ import { StrictDict } from 'utils';
export const categories = StrictDict({
dashboard: 'dashboard',
- upgrade: 'upgrade',
userEngagement: 'user-engagement',
searchButton: 'search_button',
credit: 'credit',
@@ -14,9 +13,6 @@ export const events = StrictDict({
courseImageClicked: 'courseImageClicked',
courseTitleClicked: 'courseTitleClicked',
courseOptionsDropdownClicked: 'courseOptionsDropdownClicked',
- upgradeButtonClicked: 'upgradeButtonClicked',
- upgradeButtonClickedEnrollment: 'upgradeButtonClickedEnrollment',
- upgradeButtonClickedUpsell: 'upgradeButtonClickedUpsell',
shareClicked: 'shareClicked',
userSettingsChanged: 'userSettingsChanged',
newSession: 'newSession',
@@ -36,9 +32,6 @@ export const eventNames = StrictDict({
courseImageClicked: 'edx.bi.dashboard.course_image.clicked',
courseTitleClicked: 'edx.bi.dashboard.course_title.clicked',
courseOptionsDropdownClicked: 'edx.bi.dashboard.course_options_dropdown.clicked',
- upgradeButtonClicked: 'edx.bi.dashboard.upgrade_button.clicked',
- upgradeButtonClickedEnrollment: 'edx.course.enrollment.upgrade.clicked',
- upgradeButtonClickedUpsell: 'edx.bi.ecommerce.upsell_links_clicked',
shareClicked: 'edx.course.share_clicked',
userSettingsChanged: 'edx.user.settings.changed',
newSession: 'course-dashboard.new-session',
diff --git a/src/tracking/trackers/course.js b/src/tracking/trackers/course.js
index aa5262c54..1edba2678 100644
--- a/src/tracking/trackers/course.js
+++ b/src/tracking/trackers/course.js
@@ -1,4 +1,3 @@
-import api from 'data/services/lms/api';
import { createEventTracker, createLinkTracker } from 'data/services/segment/utils';
import { categories, eventNames } from '../constants';
import * as module from './course';
@@ -31,20 +30,6 @@ export const courseLinkTracker = (eventName) => (courseId, href) => (
createLinkTracker(module.courseEventTracker(eventName, courseId), href)
);
-// Upgrade Events
-/**
- * There are currently multiple tracked api events for the upgrade event, with different targets.
- * Goal here is to split out the tracked events for easier testing.
- */
-export const upgradeButtonClicked = (courseId) => createEventTracker(
- eventNames.upgradeButtonClicked,
- { category: categories.upgrade, label: courseId },
-);
-export const upgradeButtonClickedUpsell = (courseId) => createEventTracker(
- eventNames.upgradeButtonClickedUpsell,
- { ...upsellOptions, courseId },
-);
-
// Non-Link events
export const courseOptionsDropdownClicked = (courseId) => (
module.courseEventTracker(eventNames.courseOptionsDropdownClicked, courseId)
@@ -57,19 +42,10 @@ export const courseTitleClicked = (...args) => (
module.courseLinkTracker(eventNames.courseTitleClicked)(...args));
export const enterCourseClicked = (...args) => (
module.courseLinkTracker(eventNames.enterCourseClicked)(...args));
-export const upgradeClicked = (courseId, href) => createLinkTracker(
- () => {
- module.upgradeButtonClicked(courseId)();
- module.upgradeButtonClickedUpsell(courseId)();
- api.logUpgrade({ courseId });
- },
- href,
-);
export default {
courseImageClicked,
courseOptionsDropdownClicked,
courseTitleClicked,
enterCourseClicked,
- upgradeClicked,
};
diff --git a/src/tracking/trackers/course.test.js b/src/tracking/trackers/course.test.js
index a8c8c391b..7715b1133 100644
--- a/src/tracking/trackers/course.test.js
+++ b/src/tracking/trackers/course.test.js
@@ -1,13 +1,8 @@
import { keyStore } from 'utils';
-import api from 'data/services/lms/api';
import { createEventTracker, createLinkTracker } from 'data/services/segment/utils';
import { categories, eventNames } from '../constants';
import * as trackers from './course';
-jest.mock('data/services/lms/api', () => ({
- logUpgrade: jest.fn(),
-}));
-
jest.mock('data/services/segment/utils', () => ({
createEventTracker: jest.fn(args => ({ createEventTracker: args })),
createLinkTracker: jest.fn((cb, href) => ({ createLinkTracker: { cb, href } })),
@@ -44,26 +39,6 @@ describe('course trackers', () => {
});
});
});
- describe('Upgrade Events', () => {
- describe('upgradeButtonClicked', () => {
- it('creates an event tracker for upgradeButtonClicked event with category and label', () => {
- expect(trackers.upgradeButtonClicked(courseId)).toEqual(createEventTracker(
- eventNames.upgradeButtonClicked,
- { category: categories.upgrade, label: courseId },
- ));
- });
- });
- describe('upgradeButtonClickedUpsell', () => {
- it('creates an event tracker for upgradeButtonClickedUpsell eventwith upsellOptions', () => {
- expect(trackers.upgradeButtonClickedUpsell(courseId)).toEqual(
- createEventTracker(
- eventNames.upgradeButtonClickedUpsell,
- { ...trackers.upsellOptions, courseId },
- ),
- );
- });
- });
- });
describe('Non-link events', () => {
describe('courseOptionsDropdownClicked', () => {
it('creates course event tracker for courseOptionsDropdownClicked event', () => {
@@ -101,25 +76,5 @@ describe('course trackers', () => {
);
});
});
- describe('upgradeClicked', () => {
- it('triggers upgrade actions and api.logUpgrade with courseId', () => {
- const upgradeButtonClicked = jest.fn();
- const upgradeButtonClickedUpsell = jest.fn();
- const trackUpgradeButtonClicked = jest.fn(() => upgradeButtonClicked);
- const trackUpgradeButtonClickedUpsell = jest.fn(() => upgradeButtonClickedUpsell);
- jest.spyOn(trackers, moduleKeys.upgradeButtonClicked)
- .mockImplementationOnce(trackUpgradeButtonClicked);
- jest.spyOn(trackers, moduleKeys.upgradeButtonClickedUpsell)
- .mockImplementationOnce(trackUpgradeButtonClickedUpsell);
- const out = trackers.upgradeClicked(courseId, href).createLinkTracker;
- expect(out.href).toEqual(href);
- out.cb();
- expect(trackUpgradeButtonClicked).toHaveBeenCalledWith(courseId);
- expect(trackUpgradeButtonClickedUpsell).toHaveBeenCalledWith(courseId);
- expect(upgradeButtonClicked).toHaveBeenCalledWith();
- expect(upgradeButtonClickedUpsell).toHaveBeenCalledWith();
- expect(api.logUpgrade).toHaveBeenCalledWith({ courseId });
- });
- });
});
});
From abae82b507c5204915f72ec5d62f2f4a7de8545a Mon Sep 17 00:00:00 2001
From: Maxwell Frank <92897870+MaxFrank13@users.noreply.github.com>
Date: Tue, 14 Jan 2025 14:36:38 -0500
Subject: [PATCH 2/4] fix: remove remaining UpgradeButton definition and tests
(#548)
---
.../CourseCardActions/UpgradeButton.jsx | 45 -------------------
.../CourseCardActions/index.test.jsx | 27 ++---------
src/tracking/trackers/course.js | 7 ---
3 files changed, 3 insertions(+), 76 deletions(-)
delete mode 100644 src/containers/CourseCard/components/CourseCardActions/UpgradeButton.jsx
diff --git a/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.jsx b/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.jsx
deleted file mode 100644
index ca55ec9a4..000000000
--- a/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.jsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import { Locked } from '@openedx/paragon/icons';
-import { useIntl } from '@edx/frontend-platform/i18n';
-
-import track from 'tracking';
-import { reduxHooks } from 'hooks';
-import useActionDisabledState from '../hooks';
-
-import ActionButton from './ActionButton';
-import messages from './messages';
-
-export const UpgradeButton = ({ cardId }) => {
- const { formatMessage } = useIntl();
-
- const { upgradeUrl } = reduxHooks.useCardCourseRunData(cardId);
- const { disableUpgradeCourse } = useActionDisabledState(cardId);
-
- const trackUpgradeClick = reduxHooks.useTrackCourseEvent(
- track.course.upgradeClicked,
- cardId,
- upgradeUrl,
- );
-
- const enabledProps = {
- as: 'a',
- href: upgradeUrl,
- onClick: trackUpgradeClick,
- };
- return (
-
- {formatMessage(messages.upgrade)}
-
- );
-};
-UpgradeButton.propTypes = {
- cardId: PropTypes.string.isRequired,
-};
-export default UpgradeButton;
diff --git a/src/containers/CourseCard/components/CourseCardActions/index.test.jsx b/src/containers/CourseCard/components/CourseCardActions/index.test.jsx
index 5819a9b6e..329467238 100644
--- a/src/containers/CourseCard/components/CourseCardActions/index.test.jsx
+++ b/src/containers/CourseCard/components/CourseCardActions/index.test.jsx
@@ -3,7 +3,6 @@ import { shallow } from '@edx/react-unit-test-utils';
import { reduxHooks } from 'hooks';
import CourseCardActionSlot from 'plugin-slots/CourseCardActionSlot';
-import UpgradeButton from './UpgradeButton';
import SelectSessionButton from './SelectSessionButton';
import BeginCourseButton from './BeginCourseButton';
import ResumeButton from './ResumeButton';
@@ -21,7 +20,6 @@ jest.mock('hooks', () => ({
}));
jest.mock('plugin-slots/CourseCardActionSlot', () => 'CustomActionButton');
-jest.mock('./UpgradeButton', () => 'UpgradeButton');
jest.mock('./SelectSessionButton', () => 'SelectSessionButton');
jest.mock('./ViewCourseButton', () => 'ViewCourseButton');
jest.mock('./BeginCourseButton', () => 'BeginCourseButton');
@@ -59,19 +57,7 @@ describe('CourseCardActions', () => {
});
});
describe('output', () => {
- describe('Exec Ed course', () => {
- it('does not render upgrade button', () => {
- mockHooks({ isExecEd2UCourse: true });
- render();
- expect(el.instance.findByType(UpgradeButton).length).toEqual(0);
- });
- });
describe('entitlement course', () => {
- it('does not render upgrade button', () => {
- mockHooks({ isEntitlement: true });
- render();
- expect(el.instance.findByType(UpgradeButton).length).toEqual(0);
- });
it('renders ViewCourseButton if fulfilled', () => {
mockHooks({ isEntitlement: true, isFulfilled: true });
render();
@@ -83,22 +69,15 @@ describe('CourseCardActions', () => {
expect(el.instance.findByType(SelectSessionButton)[0].props.cardId).toEqual(cardId);
});
});
- describe('verified course', () => {
- it('does not render upgrade button', () => {
- mockHooks({ isVerified: true });
- render();
- expect(el.instance.findByType(UpgradeButton).length).toEqual(0);
- });
- });
describe('not entitlement, verified, or exec ed', () => {
- it('renders UpgradeButton and ViewCourseButton for archived courses', () => {
+ it('renders CourseCardActionSlot and ViewCourseButton for archived courses', () => {
mockHooks({ isArchived: true });
render();
expect(el.instance.findByType(CourseCardActionSlot)[0].props.cardId).toEqual(cardId);
expect(el.instance.findByType(ViewCourseButton)[0].props.cardId).toEqual(cardId);
});
describe('unstarted courses', () => {
- it('renders UpgradeButton and BeginCourseButton', () => {
+ it('renders CourseCardActionSlot and BeginCourseButton', () => {
mockHooks();
render();
expect(el.instance.findByType(CourseCardActionSlot)[0].props.cardId).toEqual(cardId);
@@ -106,7 +85,7 @@ describe('CourseCardActions', () => {
});
});
describe('active courses (started, and not archived)', () => {
- it('renders UpgradeButton and ResumeButton', () => {
+ it('renders CourseCardActionSlot and ResumeButton', () => {
mockHooks({ hasStarted: true });
render();
expect(el.instance.findByType(CourseCardActionSlot)[0].props.cardId).toEqual(cardId);
diff --git a/src/tracking/trackers/course.js b/src/tracking/trackers/course.js
index 1edba2678..8513692ae 100644
--- a/src/tracking/trackers/course.js
+++ b/src/tracking/trackers/course.js
@@ -2,13 +2,6 @@ import { createEventTracker, createLinkTracker } from 'data/services/segment/uti
import { categories, eventNames } from '../constants';
import * as module from './course';
-export const upsellOptions = {
- linkName: 'course_dashboard_green',
- linkType: 'button',
- pageName: 'course_dashboard',
- linkCategory: 'green_update',
-};
-
// Utils/Helpers
/**
* Generate a segement event tracker for a given course event.
From 8b67abd304e49faf4cc69e5916bb52fcb485a9dc Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 20 Jan 2025 05:03:34 +0000
Subject: [PATCH 3/4] fix(deps): update dependency react-router-dom to v6.28.2
(#551)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
package-lock.json | 26 +++++++++++++-------------
package.json | 2 +-
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 7ce1ea1a9..61a118d02 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -38,7 +38,7 @@
"react-helmet": "^6.1.0",
"react-intl": "6.8.9",
"react-redux": "^7.2.4",
- "react-router-dom": "6.28.1",
+ "react-router-dom": "6.28.2",
"react-share": "^4.4.0",
"redux": "4.2.1",
"redux-logger": "3.0.6",
@@ -3982,9 +3982,9 @@
"license": "MIT"
},
"node_modules/@remix-run/router": {
- "version": "1.21.0",
- "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz",
- "integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==",
+ "version": "1.21.1",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.1.tgz",
+ "integrity": "sha512-KeBYSwohb8g4/wCcnksvKTYlg69O62sQeLynn2YE+5z7JWEj95if27kclW9QqbrlsQ2DINI8fjbV3zyuKfwjKg==",
"license": "MIT",
"engines": {
"node": ">=14.0.0"
@@ -15106,12 +15106,12 @@
}
},
"node_modules/react-router": {
- "version": "6.28.1",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.1.tgz",
- "integrity": "sha512-2omQTA3rkMljmrvvo6WtewGdVh45SpL9hGiCI9uUrwGGfNFDIvGK4gYJsKlJoNVi6AQZcopSCballL+QGOm7fA==",
+ "version": "6.28.2",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.2.tgz",
+ "integrity": "sha512-BgFY7+wEGVjHCiqaj2XiUBQ1kkzfg6UoKYwEe0wv+FF+HNPCxtS/MVPvLAPH++EsuCMReZl9RYVGqcHLk5ms3A==",
"license": "MIT",
"dependencies": {
- "@remix-run/router": "1.21.0"
+ "@remix-run/router": "1.21.1"
},
"engines": {
"node": ">=14.0.0"
@@ -15121,13 +15121,13 @@
}
},
"node_modules/react-router-dom": {
- "version": "6.28.1",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.1.tgz",
- "integrity": "sha512-YraE27C/RdjcZwl5UCqF/ffXnZDxpJdk9Q6jw38SZHjXs7NNdpViq2l2c7fO7+4uWaEfcwfGCv3RSg4e1By/fQ==",
+ "version": "6.28.2",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.2.tgz",
+ "integrity": "sha512-O81EWqNJWqvlN/a7eTudAdQm0TbI7hw+WIi7OwwMcTn5JMyZ0ibTFNGz+t+Lju0df4LcqowCegcrK22lB1q9Kw==",
"license": "MIT",
"dependencies": {
- "@remix-run/router": "1.21.0",
- "react-router": "6.28.1"
+ "@remix-run/router": "1.21.1",
+ "react-router": "6.28.2"
},
"engines": {
"node": ">=14.0.0"
diff --git a/package.json b/package.json
index b95180369..b608fa9e4 100755
--- a/package.json
+++ b/package.json
@@ -59,7 +59,7 @@
"react-helmet": "^6.1.0",
"react-intl": "6.8.9",
"react-redux": "^7.2.4",
- "react-router-dom": "6.28.1",
+ "react-router-dom": "6.28.2",
"react-share": "^4.4.0",
"redux": "4.2.1",
"redux-logger": "3.0.6",
From 2b287c63327546e9867c4173853ed02ce73e7a62 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 20 Jan 2025 09:40:34 +0000
Subject: [PATCH 4/4] chore(deps): update dependency @edx/browserslist-config
to v1.5.0 (#552)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
package-lock.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 61a118d02..d2ce3cd7f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2039,9 +2039,9 @@
"integrity": "sha512-Dn9CtpC8fovh++Xi4NF5NJoeR9yU2yXZnV9IujxIyGd/dn0Phq5t6dzJVfupwq09mpDnzJv7egA8Znz/3ljO+w=="
},
"node_modules/@edx/browserslist-config": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@edx/browserslist-config/-/browserslist-config-1.4.0.tgz",
- "integrity": "sha512-/nUVlFuri0N6R9jaU6ah39FGosUcGhJyH+7a6Sg9fkjzqDHIRpS6PB7OFM91i8UvHJQs4iQ3qZ8yHw7ianzPCw==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@edx/browserslist-config/-/browserslist-config-1.5.0.tgz",
+ "integrity": "sha512-d2ggwi5j4DOBJOwhWZxBWQSDR0DhT4ke/1PbzRauICdFkuOyax+PsFjK8GUh443K2OaQpy9PGfiCzZ1Yg37AUA==",
"license": "AGPL-3.0"
},
"node_modules/@edx/eslint-config": {