diff --git a/src/data/slice.js b/src/data/slice.js index d6348da6..39c038ed 100644 --- a/src/data/slice.js +++ b/src/data/slice.js @@ -56,6 +56,7 @@ export const examSlice = createSlice({ ping_interval: null, attempt_code: '', external_id: '', + use_legacy_attempt_api: true, }, type: '', }, diff --git a/src/instructions/proctored_exam/ProctoredExamInstructions.test.jsx b/src/instructions/proctored_exam/ProctoredExamInstructions.test.jsx index 1994cc11..063ad89f 100644 --- a/src/instructions/proctored_exam/ProctoredExamInstructions.test.jsx +++ b/src/instructions/proctored_exam/ProctoredExamInstructions.test.jsx @@ -1,11 +1,11 @@ import '@testing-library/jest-dom'; import { Factory } from 'rosie'; import React from 'react'; -import { fireEvent } from '@testing-library/dom'; +import { fireEvent, waitFor } from '@testing-library/dom'; import Instructions from '../index'; import { store, getExamAttemptsData } from '../../data'; import { submitExam } from '../../data/thunks'; -import { render, screen } from '../../setupTest'; +import { initializeMockApp, render, screen } from '../../setupTest'; import ExamStateProvider from '../../core/ExamStateProvider'; import { ExamType, @@ -27,6 +27,11 @@ store.subscribe = jest.fn(); store.dispatch = jest.fn(); describe('SequenceExamWrapper', () => { + beforeEach(() => { + initializeMockApp(); + jest.clearAllMocks(); + }); + it('Start exam instructions can be successfully rendered', () => { store.getState = () => ({ examState: Factory.build('examState', { @@ -164,6 +169,7 @@ describe('SequenceExamWrapper', () => { it('Shows correct instructions when attempt status is ready_to_submit ', () => { const attempt = Factory.build('attempt', { attempt_status: ExamStatus.READY_TO_SUBMIT, + use_legacy_attempt_api: true, }); store.getState = () => ({ examState: Factory.build('examState', { @@ -190,6 +196,39 @@ describe('SequenceExamWrapper', () => { expect(submitExam).toHaveBeenCalled(); }); + it('Initiates an LTI launch in a new window when the user clicks the submit button', async () => { + const windowSpy = jest.spyOn(window, 'open'); + windowSpy.mockImplementation(() => ({})); + const attempt = Factory.build('attempt', { + attempt_status: ExamStatus.READY_TO_SUBMIT, + use_legacy_attempt_api: false, + attempt_id: 1, + }); + store.getState = () => ({ + examState: Factory.build('examState', { + activeAttempt: attempt, + exam: Factory.build('exam', { + is_proctored: true, + type: ExamType.PROCTORED, + attempt, + }), + }), + }); + + const { queryByTestId } = render( + + +
Sequence
+
+
, + { store }, + ); + + expect(queryByTestId('proctored-exam-instructions-title')).toHaveTextContent('Are you sure you want to end your proctored exam?'); + fireEvent.click(queryByTestId('end-exam-button')); + await waitFor(() => { expect(windowSpy).toHaveBeenCalledWith('http://localhost:18740/lti/end_assessment/1', '_blank'); }); + }); + it('Instructions are shown when attempt status is verified', () => { store.getState = () => ({ examState: Factory.build('examState', { diff --git a/src/instructions/proctored_exam/SubmitProctoredExamInstructions.jsx b/src/instructions/proctored_exam/SubmitProctoredExamInstructions.jsx index ca99f02a..1413d04d 100644 --- a/src/instructions/proctored_exam/SubmitProctoredExamInstructions.jsx +++ b/src/instructions/proctored_exam/SubmitProctoredExamInstructions.jsx @@ -1,4 +1,5 @@ import React, { useContext } from 'react'; +import { getConfig } from '@edx/frontend-platform'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; import { Button } from '@edx/paragon'; import ExamStateContext from '../../context'; @@ -11,8 +12,18 @@ const SubmitProctoredExamInstructions = () => { exam, activeAttempt, } = state; - const { type: examType } = exam || {}; + const { type: examType, attempt } = exam || {}; const { exam_display_name: examName } = activeAttempt; + const examHasLtiProvider = !attempt.use_legacy_attempt_api; + const submitLtiAttemptUrl = `${getConfig().EXAMS_BASE_URL}/lti/end_assessment/${attempt.attempt_id}`; + + const handleSubmitClick = () => { + if (examHasLtiProvider) { + window.open(submitLtiAttemptUrl, '_blank'); + } else { + submitExam(); + } + }; return ( <> @@ -48,7 +59,7 @@ const SubmitProctoredExamInstructions = () => { />

)} -