diff --git a/src/courseware/course/chat/Chat.jsx b/src/courseware/course/chat/Chat.jsx index cddfbc1ddf..e5dde8886c 100644 --- a/src/courseware/course/chat/Chat.jsx +++ b/src/courseware/course/chat/Chat.jsx @@ -1,4 +1,5 @@ import { createPortal } from 'react-dom'; +import { useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import { Xpert } from '@edx/frontend-lib-learning-assistant'; @@ -13,6 +14,10 @@ const Chat = ({ unitId, endDate, }) => { + const { + activeAttempt, exam, + } = useSelector(state => state.specialExams); + const VERIFIED_MODES = [ 'professional', 'verified', @@ -41,6 +46,10 @@ const Chat = ({ enabled && (hasVerifiedEnrollment || isStaff) // display only to verified learners or staff && !endDatePassed() + // it is necessary to check both whether the user is in an exam, and whether or not they are viewing an exam + // this will prevent the learner from interacting with the tool at any point of the exam flow, even at the + // entrance interstitial. + && !(activeAttempt?.attempt_id || exam?.id) ); return ( diff --git a/src/courseware/course/chat/Chat.test.jsx b/src/courseware/course/chat/Chat.test.jsx index 581948037f..75f7a208ea 100644 --- a/src/courseware/course/chat/Chat.test.jsx +++ b/src/courseware/course/chat/Chat.test.jsx @@ -1,10 +1,12 @@ import { BrowserRouter } from 'react-router-dom'; -import { configureStore } from '@reduxjs/toolkit'; import React from 'react'; -import { reducer as learningAssistantReducer } from '@edx/frontend-lib-learning-assistant'; - -import { initializeMockApp, render, screen } from '../../../setupTest'; +import { + initializeMockApp, + initializeTestStore, + render, + screen, +} from '../../../setupTest'; import Chat from './Chat'; @@ -39,6 +41,21 @@ const disabledModes = [null, undefined, 'xyz', 'audit', 'honor', 'unpaid-executi const currentTime = new Date(); describe('Chat', () => { + let store; + + beforeAll(async () => { + store = await initializeTestStore({ + specialExams: { + activeAttempt: { + attempt_id: null, + }, + exam: { + id: null, + }, + }, + }); + }); + // Generate test cases. enabledTestCases = enabledModes.map((mode) => ({ enrollmentMode: mode, isVisible: true })); disabledTestCases = disabledModes.map((mode) => ({ enrollmentMode: mode, isVisible: false })); @@ -48,12 +65,6 @@ describe('Chat', () => { it( `visibility determined by ${test.enrollmentMode} enrollment mode when enabled and not isStaff`, async () => { - const store = configureStore({ - reducer: { - learningAssistant: learningAssistantReducer, - }, - }); - render( { testCases = enabledModes.concat(disabledModes).map((mode) => ({ enrollmentMode: mode, isVisible: true })); testCases.forEach(test => { it('visibility determined by isStaff when enabled and any enrollment mode', async () => { - const store = configureStore({ - reducer: { - learningAssistant: learningAssistantReducer, - }, - }); - render( { `visibility determined by ${test.enabled} enabled when ${test.isStaff} isStaff and ${test.enrollmentMode} enrollment mode`, async () => { - const store = configureStore({ - reducer: { - learningAssistant: learningAssistantReducer, - }, - }); - render( { }); it('if course end date has passed, component should not be visible', async () => { - const store = configureStore({ - reducer: { - learningAssistant: learningAssistantReducer, - }, - }); - render( { }); it('if course has no end date, component should be visible', async () => { - const store = configureStore({ - reducer: { - learningAssistant: learningAssistantReducer, + render( + + + , + { store }, + ); + + const chat = screen.queryByTestId('toggle-button'); + expect(chat).toBeInTheDocument(); + }); + + it('if learner has active exam attempt, component should not be visible', async () => { + store = await initializeTestStore({ + specialExams: { + activeAttempt: { + attempt_id: 1, + }, }, }); diff --git a/src/store.js b/src/store.js index d44f5be864..6776558323 100644 --- a/src/store.js +++ b/src/store.js @@ -1,6 +1,6 @@ import { reducer as learningAssistantReducer } from '@edx/frontend-lib-learning-assistant'; -import { configureStore } from '@reduxjs/toolkit'; import { reducer as specialExamsReducer } from '@edx/frontend-lib-special-exams'; +import { configureStore } from '@reduxjs/toolkit'; import { reducer as courseHomeReducer } from './course-home/data'; import { reducer as coursewareReducer } from './courseware/data/slice'; import { reducer as recommendationsReducer } from './courseware/course/course-exit/data/slice';