From c73ef26d8e6d452f1d582ce00f7e809598a1463a Mon Sep 17 00:00:00 2001 From: alangsto <46360176+alangsto@users.noreply.github.com> Date: Thu, 13 Jul 2023 13:56:25 -0400 Subject: [PATCH] feat: add segment event for lti modal launch (#1140) --- src/courseware/course/Course.jsx | 1 + src/courseware/course/lti-modal/ChatTrigger.jsx | 13 ++++++++++++- .../course/lti-modal/ChatTrigger.test.jsx | 16 +++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/courseware/course/Course.jsx b/src/courseware/course/Course.jsx index 4cba7e27..99dbbb46 100644 --- a/src/courseware/course/Course.jsx +++ b/src/courseware/course/Course.jsx @@ -97,6 +97,7 @@ const Course = ({ enrollmentMode={course.enrollmentMode} isStaff={isStaff} launchUrl={course.learningAssistantLaunchUrl} + courseId={courseId} /> diff --git a/src/courseware/course/lti-modal/ChatTrigger.jsx b/src/courseware/course/lti-modal/ChatTrigger.jsx index e62c1569..97784829 100644 --- a/src/courseware/course/lti-modal/ChatTrigger.jsx +++ b/src/courseware/course/lti-modal/ChatTrigger.jsx @@ -1,4 +1,6 @@ import React, { useState } from 'react'; +import { getAuthenticatedUser } from '@edx/frontend-platform/auth'; +import { sendTrackEvent } from '@edx/frontend-platform/analytics'; import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; import { ModalDialog, @@ -17,9 +19,11 @@ const ChatTrigger = ({ enrollmentMode, isStaff, launchUrl, + courseId, }) => { const [isOpen, open, close] = useToggle(false); const [hasOpenedChat, setHasOpenedChat] = useState(false); + const { userId } = getAuthenticatedUser(); const VERIFIED_MODES = [ 'professional', @@ -46,6 +50,11 @@ const ChatTrigger = ({ setHasOpenedChat(true); } open(); + sendTrackEvent('edx.ui.lms.lti_modal.opened', { + course_id: courseId, + user_id: userId, + is_staff: isStaff, + }); }; return ( @@ -111,12 +120,14 @@ const ChatTrigger = ({ ChatTrigger.propTypes = { intl: intlShape.isRequired, isStaff: PropTypes.bool.isRequired, - enrollmentMode: PropTypes.string.isRequired, + enrollmentMode: PropTypes.string, launchUrl: PropTypes.string, + courseId: PropTypes.string.isRequired, }; ChatTrigger.defaultProps = { launchUrl: null, + enrollmentMode: null, }; export default injectIntl(ChatTrigger); diff --git a/src/courseware/course/lti-modal/ChatTrigger.test.jsx b/src/courseware/course/lti-modal/ChatTrigger.test.jsx index 7e1aff9c..a496e381 100644 --- a/src/courseware/course/lti-modal/ChatTrigger.test.jsx +++ b/src/courseware/course/lti-modal/ChatTrigger.test.jsx @@ -1,12 +1,19 @@ import { render } from '@testing-library/react'; +import { sendTrackEvent } from '@edx/frontend-platform/analytics'; import { IntlProvider } from '@edx/frontend-platform/i18n'; import { BrowserRouter } from 'react-router-dom'; import React from 'react'; import ChatTrigger from './ChatTrigger'; import { act, fireEvent, screen } from '../../../setupTest'; +jest.mock('@edx/frontend-platform/auth', () => ({ + getAuthenticatedUser: jest.fn(() => ({ userId: 1 })), +})); +jest.mock('@edx/frontend-platform/analytics'); + describe('ChatTrigger', () => { it('handles click to open/close chat modal', async () => { + sendTrackEvent.mockClear(); render( @@ -14,6 +21,7 @@ describe('ChatTrigger', () => { enrollmentMode={null} isStaff launchUrl="https://testurl.org" + courseId="course-edX" /> , , @@ -28,12 +36,18 @@ describe('ChatTrigger', () => { }); const modalCloseButton = screen.getByRole('button', { name: /Close/i }); await expect(modalCloseButton).toBeInTheDocument(); + expect(sendTrackEvent).toHaveBeenCalledTimes(1); + expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.lti_modal.opened', { + course_id: 'course-edX', + user_id: 1, + is_staff: true, + }); await act(async () => { fireEvent.click(modalCloseButton); }); await expect(modalCloseButton).not.toBeInTheDocument(); - expect(screen.queryByText('Holy guacamole!')).not.toBeInTheDocument(); + expect(screen.queryByText('Need help understanding course content?')).not.toBeInTheDocument(); }); const testCases = [