From 193a184142f3ffdea89b1324068b6efbd59c85f1 Mon Sep 17 00:00:00 2001 From: Shafqat Farhan Date: Tue, 26 Jul 2022 09:07:55 +0500 Subject: [PATCH] feat: [VAN-1000] - Set weekly goal through welcome email via query param (#956) --- .../outline-tab/OutlineTab.test.jsx | 31 +++++++++++++++++-- .../widgets/WeeklyLearningGoalCard.jsx | 23 ++++++++++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/course-home/outline-tab/OutlineTab.test.jsx b/src/course-home/outline-tab/OutlineTab.test.jsx index d21193f8..f36ac523 100644 --- a/src/course-home/outline-tab/OutlineTab.test.jsx +++ b/src/course-home/outline-tab/OutlineTab.test.jsx @@ -2,6 +2,7 @@ * @jest-environment jsdom */ import React from 'react'; +import { MemoryRouter } from 'react-router-dom'; import { Factory } from 'rosie'; import { getConfig } from '@edx/frontend-platform'; import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/analytics'; @@ -51,9 +52,14 @@ describe('Outline Tab', () => { axiosMock.onGet(outlineUrl).reply(200, outlineTabData); } - async function fetchAndRender() { + async function fetchAndRender(path = '') { await executeThunk(thunks.fetchOutlineTab(courseId), store.dispatch); - await act(async () => render(, { store })); + await act(async () => render( + + + , + { store }, + )); } beforeEach(async () => { @@ -338,6 +344,27 @@ describe('Outline Tab', () => { expect(spy).toHaveBeenCalledTimes(0); }); + it('post goal via query param', async () => { + setTabData({ + course_goals: { + weekly_learning_goal_enabled: true, + }, + }); + const spy = jest.spyOn(thunks, 'saveWeeklyLearningGoal'); + sendTrackEvent.mockClear(); + + await fetchAndRender('http://localhost/?weekly_goal=3'); + expect(spy).toHaveBeenCalledTimes(1); + expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.goal.days-per-week.changed', { + org_key: 'edX', + courserun_key: courseId, + is_staff: false, + num_days: 3, + reminder_selected: true, + triggeredFromEmail: true, + }); + }); + describe('weekly learning goal is not set', () => { beforeEach(async () => { setTabData({ diff --git a/src/course-home/outline-tab/widgets/WeeklyLearningGoalCard.jsx b/src/course-home/outline-tab/widgets/WeeklyLearningGoalCard.jsx index 08ae5e4e..fef6f46c 100644 --- a/src/course-home/outline-tab/widgets/WeeklyLearningGoalCard.jsx +++ b/src/course-home/outline-tab/widgets/WeeklyLearningGoalCard.jsx @@ -1,7 +1,9 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; +import { useLocation } from 'react-router-dom'; import PropTypes from 'prop-types'; import { Form, Card, Icon } from '@edx/paragon'; +import { history } from '@edx/frontend-platform'; import { sendTrackEvent } from '@edx/frontend-platform/analytics'; import { getAuthenticatedUser } from '@edx/frontend-platform/auth'; import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; @@ -32,8 +34,9 @@ function WeeklyLearningGoalCard({ const [daysPerWeekGoal, setDaysPerWeekGoal] = useState(daysPerWeek); // eslint-disable-next-line react/prop-types const [isGetReminderSelected, setGetReminderSelected] = useState(subscribedToReminders); + const location = useLocation(); - function handleSelect(days) { + function handleSelect(days, triggeredFromEmail = false) { // Set the subscription button if this is the first time selecting a goal const selectReminders = daysPerWeekGoal === null ? true : isGetReminderSelected; setGetReminderSelected(selectReminders); @@ -46,6 +49,7 @@ function WeeklyLearningGoalCard({ is_staff: administrator, num_days: days, reminder_selected: selectReminders, + triggeredFromEmail, }); } } @@ -65,6 +69,21 @@ function WeeklyLearningGoalCard({ } } + useEffect(() => { + const currentParams = new URLSearchParams(location.search); + const weeklyGoal = Number(currentParams.get('weekly_goal')); + if ([1, 3, 5].includes(weeklyGoal)) { + handleSelect(weeklyGoal, true); + + // Deleting the weekly_goal query param as it only needs to be set once + // whenever passed in query params. + currentParams.delete('weekly_goal'); + history.replace({ + search: currentParams.toString(), + }); + } + }, [location.search]); + return (