diff --git a/src/constants.js b/src/constants.js
index df3084e3..7767722f 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -9,6 +9,8 @@ export const ExamStatus = Object.freeze({
TIMED_OUT: 'timed_out',
VERIFIED: 'verified',
REJECTED: 'rejected',
+ ERROR: 'error',
+ READY_TO_RESUME: 'ready_to_resume',
});
export const IS_STARTED_STATUS = (status) => [ExamStatus.STARTED, ExamStatus.READY_TO_SUBMIT].includes(status);
diff --git a/src/instructions/Instructions.test.jsx b/src/instructions/Instructions.test.jsx
index 1c20cf54..0419ea82 100644
--- a/src/instructions/Instructions.test.jsx
+++ b/src/instructions/Instructions.test.jsx
@@ -2,7 +2,7 @@ import '@testing-library/jest-dom';
import React from 'react';
import Instructions from './index';
import { store, getExamAttemptsData, startExam } from '../data';
-import { render } from '../setupTest';
+import { render, screen } from '../setupTest';
import { ExamStateProvider } from '../index';
jest.mock('../data', () => ({
@@ -147,4 +147,74 @@ describe('SequenceExamWrapper', () => {
expect(getByTestId('pending-prerequisites')).toBeInTheDocument();
});
+
+ it('Instructions for error status', () => {
+ store.getState = () => ({
+ examState: {
+ isLoading: false,
+ proctoringSettings: {
+ link_urls: '',
+ },
+ verification: {
+ status: 'none',
+ can_verify: true,
+ },
+ activeAttempt: {
+ attempt_status: 'error',
+ },
+ exam: {
+ time_limit_mins: 30,
+ attempt: {
+ attempt_status: 'error',
+ },
+ },
+ },
+ });
+
+ render(
+
+
+ Sequence
+
+ ,
+ { store },
+ );
+ expect(screen.getByText('Error with proctored exam')).toBeInTheDocument();
+ });
+
+ it('Instructions for ready to resume status', () => {
+ store.getState = () => ({
+ examState: {
+ isLoading: false,
+ proctoringSettings: {
+ link_urls: '',
+ platform_name: 'Platform Name',
+ },
+ verification: {
+ status: 'none',
+ can_verify: true,
+ },
+ activeAttempt: {
+ attempt_status: 'ready_to_resume',
+ },
+ exam: {
+ time_limit_mins: 30,
+ attempt: {
+ attempt_status: 'ready_to_resume',
+ },
+ },
+ },
+ });
+
+ render(
+
+
+ Sequence
+
+ ,
+ { store },
+ );
+ expect(screen.getByText('Your exam is ready to be resumed.')).toBeInTheDocument();
+ expect(screen.getByTestId('start-exam-button')).toHaveTextContent('Continue to my proctored exam.');
+ });
});
diff --git a/src/instructions/index.jsx b/src/instructions/index.jsx
index d54a5ae8..701ed496 100644
--- a/src/instructions/index.jsx
+++ b/src/instructions/index.jsx
@@ -4,6 +4,7 @@ import StartExamInstructions from './StartExamInstructions';
import SubmitExamInstructions from './SubmitExamInstructions';
import SubmittedExamInstructions from './SubmittedExamInstructions';
import {
+ ErrorProctoredExamInstructions,
EntranceProctoredExamInstructions,
VerificationProctoredExamInstructions,
SubmitProctoredExamInstructions,
@@ -61,6 +62,10 @@ const Instructions = ({ children }) => {
return ;
case attempt.attempt_status === ExamStatus.REJECTED:
return ;
+ case attempt.attempt_status === ExamStatus.ERROR:
+ return ;
+ case attempt.attempt_status === ExamStatus.READY_TO_RESUME:
+ return ;
default:
return children;
}
diff --git a/src/instructions/proctored_exam/EntranceProctoredExamInstructions.jsx b/src/instructions/proctored_exam/EntranceProctoredExamInstructions.jsx
index e6508732..36903085 100644
--- a/src/instructions/proctored_exam/EntranceProctoredExamInstructions.jsx
+++ b/src/instructions/proctored_exam/EntranceProctoredExamInstructions.jsx
@@ -1,22 +1,45 @@
import React, { useContext } from 'react';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import { Button, Container } from '@edx/paragon';
+import { ExamStatus } from '../../constants';
import ExamStateContext from '../../context';
import Footer from './Footer';
const EntranceProctoredExamInstructions = () => {
const state = useContext(ExamStateContext);
- const { startProctoringExam } = state;
+ const { exam, startProctoringExam } = state;
+ const { attempt } = exam || {};
+ const { total_time: totalTime = 0 } = attempt;
return (
-
-
-
+ { exam.attempt.attempt_status === ExamStatus.READY_TO_RESUME ? (
+
+ ) : (
+
+
+
+
+
+ )}
{
+ const state = useContext(ExamStateContext);
+ const {
+ link_urls: linkUrls,
+ platform_name: platformName,
+ proctoring_escalation_email: proctoringEscalationEmail,
+ } = state.proctoringSettings || {};
+ const contactUsUrl = linkUrls && linkUrls.contact_us;
+
+ const renderBody = () => {
+ if (proctoringEscalationEmail) {
+ return (
+ {proctoringEscalationEmail} }}
+ />
+ );
+ }
+
+ return (
+ {platformName} Support }}
+ />
+ );
+ };
+
+ return (
+
+
+
+
+
+
+ {renderBody()}
+
+
+
+
+ );
+};
+
+export default ErrorProctoredExamInstructions;
diff --git a/src/instructions/proctored_exam/index.js b/src/instructions/proctored_exam/index.js
index 53cc3c74..dae107cc 100644
--- a/src/instructions/proctored_exam/index.js
+++ b/src/instructions/proctored_exam/index.js
@@ -1,3 +1,4 @@
+export { default as ErrorProctoredExamInstructions } from './ErrorProctoredExamInstructions';
export { default as EntranceProctoredExamInstructions } from './EntranceProctoredExamInstructions';
export { default as RejectedProctoredExamInstructions } from './RejectedProctoredExamInstructions';
export { default as SubmitProctoredExamInstructions } from './SubmitProctoredExamInstructions';