Skip to content

Commit

Permalink
fix: submit exam right away if user click end my exam button when tim…
Browse files Browse the repository at this point in the history
…er reached 00:00
  • Loading branch information
viktorrusakov committed Jul 5, 2021
1 parent ca23071 commit 41bebf6
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
26 changes: 22 additions & 4 deletions src/data/thunks.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,18 +287,36 @@ export function resetExam() {
export function submitExam() {
return async (dispatch, getState) => {
const { exam, activeAttempt } = getState().examState;
const attemptId = exam.attempt.attempt_id;
const { desktop_application_js_url: workerUrl } = activeAttempt || {};
const useWorker = window.Worker && activeAttempt && workerUrl;

if (!attemptId) {
logError('Failed to submit exam. No attempt id.');
if (!activeAttempt) {
logError('Failed to submit exam. No active attempt.');
handleAPIError(
{ message: 'Failed to submit exam. No attempt id was found.' },
{ message: 'Failed to submit exam. No active attempt was found.' },
dispatch,
);
return;
}

const { attempt_id: attemptId, exam_url_path: examUrl } = activeAttempt;
if (!exam.attempt || attemptId !== exam.attempt.attempt_id) {
try {
await submitAttempt(attemptId);
window.location.href = examUrl;
if (useWorker) {
workerPromiseForEventNames(actionToMessageTypesMap.submit, workerUrl)()
.catch(() => handleAPIError(
{ message: 'Something has gone wrong submitting your exam. Please double-check that the application is running.' },
dispatch,
));
}
} catch (error) {
handleAPIError(error, dispatch);
}
return;
}

await updateAttemptAfter(exam.course_id, exam.content_id, submitAttempt(attemptId))(dispatch);

if (useWorker) {
Expand Down
3 changes: 2 additions & 1 deletion src/exam/Exam.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const Exam = ({ isTimeLimited, children }) => {
const {
isLoading, activeAttempt, showTimer, stopExam, exam,
expireExam, pollAttempt, apiErrorMsg, pingAttempt,
getVerificationData, getProctoringSettings,
getVerificationData, getProctoringSettings, submitExam,
} = state;

const { type: examType, id: examId } = exam || {};
Expand Down Expand Up @@ -55,6 +55,7 @@ const Exam = ({ isTimeLimited, children }) => {
<ExamTimerBlock
attempt={activeAttempt}
stopExamAttempt={stopExam}
submitExam={submitExam}
expireExamAttempt={expireExam}
pollExamAttempt={pollAttempt}
pingAttempt={pingAttempt}
Expand Down
21 changes: 19 additions & 2 deletions src/timer/ExamTimerBlock.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,49 @@ import {
TIMER_IS_CRITICALLY_LOW,
TIMER_IS_LOW,
TIMER_LIMIT_REACHED,
TIMER_REACHED_NULL,
} from './events';

/**
* Exam timer block component.
*/
const ExamTimerBlock = injectIntl(({
attempt, stopExamAttempt, expireExamAttempt, pollExamAttempt, intl, pingAttempt,
attempt, stopExamAttempt, expireExamAttempt,
pollExamAttempt, intl, pingAttempt, submitExam,
}) => {
const [isShowMore, showMore, showLess] = useToggle(false);
const [alertVariant, setAlertVariant] = useState('info');
const [timeReachedNull, setTimeReachedNull] = useState(false);

if (!attempt || !IS_STARTED_STATUS(attempt.attempt_status)) {
return null;
}

const onLowTime = () => setAlertVariant('warning');
const onCriticalLowTime = () => setAlertVariant('danger');
const onTimeReachedNull = () => setTimeReachedNull(true);

const handleEndExamClick = () => {
// if timer reached 00:00 submit exam right away
// instead of trying to move user to ready_to_submit page
if (timeReachedNull) {
submitExam();
} else {
stopExamAttempt();
}
};

useEffect(() => {
Emitter.once(TIMER_IS_LOW, onLowTime);
Emitter.once(TIMER_IS_CRITICALLY_LOW, onCriticalLowTime);
Emitter.once(TIMER_LIMIT_REACHED, expireExamAttempt);
Emitter.once(TIMER_REACHED_NULL, onTimeReachedNull);

return () => {
Emitter.off(TIMER_IS_LOW, onLowTime);
Emitter.off(TIMER_IS_CRITICALLY_LOW, onCriticalLowTime);
Emitter.off(TIMER_LIMIT_REACHED, expireExamAttempt);
Emitter.off(TIMER_REACHED_NULL, onTimeReachedNull);
};
}, []);

Expand Down Expand Up @@ -95,7 +111,7 @@ const ExamTimerBlock = injectIntl(({

{attempt.attempt_status !== ExamStatus.READY_TO_SUBMIT
&& (
<Button className="mr-3" variant="outline-primary" onClick={stopExamAttempt}>
<Button className="mr-3" variant="outline-primary" onClick={handleEndExamClick}>
<FormattedMessage
id="exam.examTimer.endExamBtn"
defaultMessage="End My Exam"
Expand Down Expand Up @@ -123,6 +139,7 @@ ExamTimerBlock.propTypes = {
}),
stopExamAttempt: PropTypes.func.isRequired,
expireExamAttempt: PropTypes.func.isRequired,
submitExam: PropTypes.func.isRequired,
};

export default ExamTimerBlock;

0 comments on commit 41bebf6

Please sign in to comment.