diff --git a/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.jsx b/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.jsx index 6d05caa..b7dd658 100644 --- a/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.jsx +++ b/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.jsx @@ -5,6 +5,7 @@ import { Locked } from '@edx/paragon/icons'; import { useIntl } from '@edx/frontend-platform/i18n'; import { hooks } from 'data/redux'; +import useTrackUpgradeData from './hooks'; import ActionButton from './ActionButton'; import messages from './messages'; @@ -14,11 +15,14 @@ export const UpgradeButton = ({ cardId }) => { const { isMasquerading } = hooks.useMasqueradeData(); const { formatMessage } = useIntl(); const isEnabled = (!isMasquerading && canUpgrade); + const { trackUpgradeClick } = useTrackUpgradeData(); + return ( {formatMessage(messages.upgrade)} diff --git a/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.test.jsx b/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.test.jsx index 5d88fc7..b28c69f 100644 --- a/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.test.jsx +++ b/src/containers/CourseCard/components/CourseCardActions/UpgradeButton.test.jsx @@ -12,6 +12,9 @@ jest.mock('data/redux', () => ({ }, })); jest.mock('./ActionButton', () => 'ActionButton'); +jest.mock('./hooks', () => () => ({ + trackUpgradeClick: jest.fn().mockName('trackUpgradeClick'), +})); describe('UpgradeButton', () => { const props = { diff --git a/src/containers/CourseCard/components/CourseCardActions/__snapshots__/UpgradeButton.test.jsx.snap b/src/containers/CourseCard/components/CourseCardActions/__snapshots__/UpgradeButton.test.jsx.snap index 0277bc1..b5b2077 100644 --- a/src/containers/CourseCard/components/CourseCardActions/__snapshots__/UpgradeButton.test.jsx.snap +++ b/src/containers/CourseCard/components/CourseCardActions/__snapshots__/UpgradeButton.test.jsx.snap @@ -6,6 +6,7 @@ exports[`UpgradeButton snapshot can upgrade 1`] = ` disabled={false} href="upgradeUrl" iconBefore={[MockFunction icons.Locked]} + onClick={[MockFunction trackUpgradeClick]} variant="outline-primary" > Upgrade @@ -16,6 +17,7 @@ exports[`UpgradeButton snapshot cannot upgrade 1`] = ` Upgrade @@ -26,6 +28,7 @@ exports[`UpgradeButton snapshot masquerading 1`] = ` Upgrade diff --git a/src/containers/CourseCard/components/CourseCardActions/hooks.js b/src/containers/CourseCard/components/CourseCardActions/hooks.js new file mode 100644 index 0000000..c05c94e --- /dev/null +++ b/src/containers/CourseCard/components/CourseCardActions/hooks.js @@ -0,0 +1,18 @@ +import { handleEvent } from 'data/services/segment/utils'; +import { eventNames } from 'data/services/segment/constants'; + +export const useTrackUpgradeData = () => { + const trackUpgradeClick = () => { + handleEvent(eventNames.upgradeCourse, { + pageName: 'learner_home', + linkType: 'button', + linkCategory: 'green_upgrade', + }); + }; + + return { + trackUpgradeClick, + }; +}; + +export default useTrackUpgradeData; diff --git a/src/containers/CourseCard/components/CourseCardActions/hooks.test.js b/src/containers/CourseCard/components/CourseCardActions/hooks.test.js new file mode 100644 index 0000000..26b5e4e --- /dev/null +++ b/src/containers/CourseCard/components/CourseCardActions/hooks.test.js @@ -0,0 +1,21 @@ +import { handleEvent } from 'data/services/segment/utils'; +import { eventNames } from 'data/services/segment/constants'; +import * as hooks from './hooks'; + +jest.mock('data/services/segment/utils', () => ({ + handleEvent: jest.fn(), +})); + +describe('CourseCardActions hooks', () => { + describe('useTrackUpgradeData', () => { + it('calls handleEvent with correct params', () => { + const out = hooks.useTrackUpgradeData(); + out.trackUpgradeClick(); + expect(handleEvent).toHaveBeenCalledWith(eventNames.upgradeCourse, { + pageName: 'learner_home', + linkType: 'button', + linkCategory: 'green_upgrade', + }); + }); + }); +}); diff --git a/src/data/services/segment/constants.js b/src/data/services/segment/constants.js index a6a39c3..807e774 100644 --- a/src/data/services/segment/constants.js +++ b/src/data/services/segment/constants.js @@ -5,10 +5,12 @@ export const events = StrictDict({ entitlementUnenroll: 'entitlementUnenroll', sessionChange: 'sessionChange', unenrollReason: 'unenrollReason', + upgradeCourse: 'upgradeCourse', }); export const eventNames = StrictDict({ [events.courseEnroll]: 'edx.bi.user.program-details.enrollment', + [events.upgradeCourse]: 'learner_home.course_card.upgrade', [events.entitlementUnenroll]: 'entitlement_unenrollment_reason.selected', [events.sessionChange]: ({ action }) => `course-dashboard.${action}-session`, // 'switch', 'new', 'leave' [events.unenrollReason]: 'unenrollment_reason.selected', diff --git a/src/widgets/LookingForChallengeWidget/__snapshots__/index.test.jsx.snap b/src/widgets/LookingForChallengeWidget/__snapshots__/index.test.jsx.snap index f13ad67..733e816 100644 --- a/src/widgets/LookingForChallengeWidget/__snapshots__/index.test.jsx.snap +++ b/src/widgets/LookingForChallengeWidget/__snapshots__/index.test.jsx.snap @@ -19,6 +19,7 @@ exports[`LookingForChallengeWidget snapshots default 1`] = ` ); -export const LookingForChallengeWidget = () => { - const { formatMessage } = useIntl(); +export const LookingForChallengeWidget = ({ + courseSearchClickTracker, +}) => { const { courseSearchUrl } = hooks.usePlatformSettingsData(); + const { formatMessage } = useIntl(); return ( { {formatMessage(messages.lookingForChallengePrompt)}
- + {formatMessage(messages.findCoursesButton, { arrow: arrowIcon })}
@@ -34,4 +43,8 @@ export const LookingForChallengeWidget = () => { ); }; +LookingForChallengeWidget.propTypes = { + courseSearchClickTracker: PropTypes.func.isRequired, +}; + export default LookingForChallengeWidget; diff --git a/src/widgets/LookingForChallengeWidget/index.test.jsx b/src/widgets/LookingForChallengeWidget/index.test.jsx index f3055ae..10f2d0a 100644 --- a/src/widgets/LookingForChallengeWidget/index.test.jsx +++ b/src/widgets/LookingForChallengeWidget/index.test.jsx @@ -11,9 +11,12 @@ jest.mock('data/redux', () => ({ })); describe('LookingForChallengeWidget', () => { + const props = { + courseSearchClickTracker: jest.fn().mockName('courseSearchClickTracker'), + }; describe('snapshots', () => { test('default', () => { - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); }); diff --git a/src/widgets/RecommendationsPanel/LoadedView.jsx b/src/widgets/RecommendationsPanel/LoadedView.jsx index 463db1f..36cdbb8 100644 --- a/src/widgets/RecommendationsPanel/LoadedView.jsx +++ b/src/widgets/RecommendationsPanel/LoadedView.jsx @@ -13,6 +13,7 @@ import './index.scss'; export const LoadedView = ({ courses, + courseSearchClickTracker, }) => { const { courseSearchUrl } = hooks.usePlatformSettingsData(); const { formatMessage } = useIntl(); @@ -31,6 +32,7 @@ export const LoadedView = ({ iconBefore={Search} as="a" href={courseSearchUrl} + onClick={courseSearchClickTracker} > {formatMessage(messages.exploreCoursesButton)} @@ -46,6 +48,7 @@ LoadedView.propTypes = { logoImageUrl: PropTypes.string, marketingUrl: PropTypes.string, })).isRequired, + courseSearchClickTracker: PropTypes.func.isRequired, }; export default LoadedView; diff --git a/src/widgets/RecommendationsPanel/LoadedView.test.jsx b/src/widgets/RecommendationsPanel/LoadedView.test.jsx index 5606ef0..6289313 100644 --- a/src/widgets/RecommendationsPanel/LoadedView.test.jsx +++ b/src/widgets/RecommendationsPanel/LoadedView.test.jsx @@ -1,22 +1,24 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { hooks } from 'data/redux'; import LoadedView from './LoadedView'; import mockData from './mockData'; jest.mock('./components/CourseCard', () => 'CourseCard'); jest.mock('data/redux', () => ({ hooks: { - usePlatformSettingsData: jest.fn(), + usePlatformSettingsData: () => ({ + courseSearchUrl: 'course-search-url', + }), }, })); -const courseSearchUrl = 'test-course-search-url'; -hooks.usePlatformSettingsData.mockReturnValue(courseSearchUrl); - describe('RecommendationsPanel LoadedView', () => { + const props = { + courses: mockData.courses, + courseSearchClickTracker: jest.fn().mockName('courseSearchClickTracker'), + }; test('snapshot', () => { - expect(shallow()).toMatchSnapshot(); + expect(shallow()).toMatchSnapshot(); }); }); diff --git a/src/widgets/RecommendationsPanel/__snapshots__/LoadedView.test.jsx.snap b/src/widgets/RecommendationsPanel/__snapshots__/LoadedView.test.jsx.snap index 5469b2a..4510129 100644 --- a/src/widgets/RecommendationsPanel/__snapshots__/LoadedView.test.jsx.snap +++ b/src/widgets/RecommendationsPanel/__snapshots__/LoadedView.test.jsx.snap @@ -60,6 +60,8 @@ exports[`RecommendationsPanel LoadedView snapshot 1`] = ` >