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 = [