diff --git a/src/constants.js b/src/constants.js
index 6d975d6b..0358e2ed 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -43,6 +43,7 @@ export const ExamAction = Object.freeze({
ERROR: 'error',
RESET: 'reset_attempt',
CLICK_DOWNLOAD_SOFTWARE: 'click_download_software',
+ DECLINE: 'decline',
});
export const VerificationStatus = Object.freeze({
diff --git a/src/data/api.js b/src/data/api.js
index 5cd6f610..1aa603c5 100644
--- a/src/data/api.js
+++ b/src/data/api.js
@@ -62,6 +62,10 @@ export async function softwareDownloadAttempt(attemptId) {
return updateAttemptStatus(attemptId, ExamAction.CLICK_DOWNLOAD_SOFTWARE);
}
+export async function declineAttempt(attemptId) {
+ return updateAttemptStatus(attemptId, ExamAction.DECLINE);
+}
+
export async function fetchExamReviewPolicy(examId) {
const url = new URL(
`${getConfig().LMS_BASE_URL}/api/edx_proctoring/v1/proctored_exam/review_policy/exam_id/${examId}/`,
diff --git a/src/data/thunks.js b/src/data/thunks.js
index 4d64a405..827dbce3 100644
--- a/src/data/thunks.js
+++ b/src/data/thunks.js
@@ -11,6 +11,7 @@ import {
fetchVerificationStatus,
fetchExamReviewPolicy,
resetAttempt,
+ declineAttempt,
} from './api';
import { isEmpty } from '../helpers';
import {
@@ -167,9 +168,16 @@ export function skipProctoringExam() {
logError('Failed to skip proctored exam. No exam id.');
return;
}
- await updateAttemptAfter(
- exam.course_id, exam.content_id, createExamAttempt(exam.id, true, false),
- )(dispatch);
+ const attemptId = exam.attempt.attempt_id;
+ if (attemptId) {
+ await updateAttemptAfter(
+ exam.course_id, exam.content_id, declineAttempt(attemptId),
+ )(dispatch);
+ } else {
+ await updateAttemptAfter(
+ exam.course_id, exam.content_id, createExamAttempt(exam.id, true, false),
+ )(dispatch);
+ }
};
}
diff --git a/src/exam/Exam.jsx b/src/exam/Exam.jsx
index 66476893..a09bf267 100644
--- a/src/exam/Exam.jsx
+++ b/src/exam/Exam.jsx
@@ -21,10 +21,10 @@ const Exam = ({ isTimeLimited, children }) => {
const {
isLoading, activeAttempt, showTimer, stopExam, exam,
expireExam, pollAttempt, apiErrorMsg, pingAttempt,
- getVerificationData, getAllowProctoringOptOut, getProctoringSettings,
+ getVerificationData, getProctoringSettings,
} = state;
- const { type: examType, content_id: sequenceId, id: examId } = exam || {};
+ const { type: examType, id: examId } = exam || {};
useEffect(() => {
if (examId) {
@@ -32,7 +32,6 @@ const Exam = ({ isTimeLimited, children }) => {
}
if (examType === ExamType.PROCTORED) {
getVerificationData();
- getAllowProctoringOptOut(sequenceId);
}
// this makes sure useEffect gets called only one time after the exam has been fetched
diff --git a/src/instructions/index.jsx b/src/instructions/index.jsx
index 356d55db..5d083c2f 100644
--- a/src/instructions/index.jsx
+++ b/src/instructions/index.jsx
@@ -41,12 +41,8 @@ const Instructions = ({ children }) => {
const renderEmptyAttemptInstructions = () => {
let component =