diff --git a/src/core/ExamStateProvider.jsx b/src/core/ExamStateProvider.jsx
index ced1d07c..8519a822 100644
--- a/src/core/ExamStateProvider.jsx
+++ b/src/core/ExamStateProvider.jsx
@@ -13,6 +13,12 @@ import { IS_STARTED_STATUS } from '../constants';
// eslint-disable-next-line react/prop-types
const StateProvider = ({ children, ...state }) => {
+ // This is bizzare and unecessary maybe, or maybe it wasn't documented as to why
+ // They took stuff out of redux and put it in a context, but they could have just used the redux store???
+ // This was meant to only make "showTimer" change when the state would change.
+ // useMemo is used when computations are expensive
+ // But this isn't so why use it here?
+ // Idk why this is optimal
const contextValue = useMemo(() => ({
...state,
showTimer: !!(state.activeAttempt && IS_STARTED_STATUS(state.activeAttempt.attempt_status)),
diff --git a/src/core/OuterExamTimer.jsx b/src/core/OuterExamTimer.jsx
index f5ef7fbf..0393b7f9 100644
--- a/src/core/OuterExamTimer.jsx
+++ b/src/core/OuterExamTimer.jsx
@@ -1,19 +1,32 @@
import React, { useEffect, useContext } from 'react';
+import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { AppContext } from '@edx/frontend-platform/react';
-import ExamStateContext from '../context';
+
+// new imports
+// import ExamStateContext from '../context';
+import { IS_STARTED_STATUS } from '../constants';
+import { stopExam, submitExam, expireExam, pollAttempt, pingAttempt, getLatestAttemptData } from '../data/thunks';
+import * as selectors from '../data/selectors';
+
import { ExamTimerBlock } from '../timer';
import ExamAPIError from '../exam/ExamAPIError';
-import ExamStateProvider from './ExamStateProvider';
+// import ExamStateProvider from './ExamStateProvider';
const ExamTimer = ({ courseId }) => {
- const state = useContext(ExamStateContext);
+ // const state = useContext(ExamStateContext);
const { authenticatedUser } = useContext(AppContext);
- const {
- activeAttempt, showTimer, stopExam, submitExam,
- expireExam, pollAttempt, apiErrorMsg, pingAttempt,
- getLatestAttemptData,
- } = state;
+
+ // const {
+ // activeAttempt, showTimer, apiErrorMsg,
+ // } = state;
+ const activeAttempt = useSelector(selectors.activeAttempt);
+ // TODO: The logic surrounding this showTimer var is WEIRD.
+ //TODO:Move this boolean to some file to encapsulate. Probably best in constants also there's no hooks file.
+ const showTimer = !!(activeAttempt && IS_STARTED_STATUS(activeAttempt.attempt_status));
+ // console.log(showTimer);
+ console.log(activeAttempt);
+ const apiErrorMsg = useSelector(selectors.apiErrorMsg);
useEffect(() => {
getLatestAttemptData(courseId);
@@ -53,9 +66,9 @@ ExamTimer.propTypes = {
* will be shown.
*/
const OuterExamTimer = ({ courseId }) => (
-
-
-
+ //
+
+ //
);
OuterExamTimer.propTypes = {
diff --git a/src/data/selectors.js b/src/data/selectors.js
new file mode 100644
index 00000000..a5499820
--- /dev/null
+++ b/src/data/selectors.js
@@ -0,0 +1,29 @@
+/*
+Slice: activeAttempt, apiErrorMsg
+In ExamStateProviders, needs to be moved to slice: showTimer,
+Thunks, which need to be imported instead: stopExam, submitExam, expireExam, pollAttempt, pingAttempt, getLatestAttemptData,
+*/
+
+// TODO: Perhaps name the slice 'name:' var to 'currentExam',
+// or change the one in frontend-app-exams-dashboard to 'examsList' or something.
+
+/*
+I got this error:
+
+ OuterExamTimer › is successfully rendered and shows timer if there is an exam in progress
+
+ TypeError: Cannot read properties of undefined (reading 'activeAttempt')
+
+ 7 | // TODO: Perhaps name the slice 'name:' var to 'currentExam',
+ 8 | // or change the one in frontend-app-exams-dashboard to 'examsList' or something.
+ > 9 | export const activeAttempt = state => state.exam.activeAttempt;
+ | ^
+ 10 | export const apiErrorMsg = state => state.exam.apiErrorMsg;
+ 11 | export const showTimer = state => state.exam.showTimer;
+
+Why isn't the selector working?
+*/
+export const activeAttempt = state => state.examState.activeAttempt;
+export const apiErrorMsg = state => state.examState.apiErrorMsg;
+export const showTimer = state => state.examState.showTimer;
+
diff --git a/src/data/slice.js b/src/data/slice.js
index c049b536..7e1f890f 100644
--- a/src/data/slice.js
+++ b/src/data/slice.js
@@ -66,6 +66,7 @@ export const examSlice = createSlice({
exam_access_token: '',
exam_access_token_expiration: '',
},
+ // showTimer: !!(state.activeAttempt && IS_STARTED_STATUS(state.activeAttempt.attempt_status)),
},
reducers: {
setAllowProctoringOptOut: (state, { payload }) => {
diff --git a/src/exam/ExamWrapper.test.jsx b/src/exam/ExamWrapper.test.jsx
index bee6ed74..e44d9f79 100644
--- a/src/exam/ExamWrapper.test.jsx
+++ b/src/exam/ExamWrapper.test.jsx
@@ -24,9 +24,19 @@ jest.mock('../data/thunks', () => {
};
});
+// TODO: Make changes to what's mocked. should only be API functions and react/redux initialState stuff.
+
+// When we mock out the thunks below, we stamp out a lot of the non-async stuff
+// Like loading states and other redux goodness. We can't ever change the loading state if
+// The function it's in has been mocked away.
+// The ONLY thing we should need to mock out in this app are API REST calls.
getExamAttemptsData.mockReturnValue(jest.fn());
startTimedExam.mockReturnValue(jest.fn());
+// No idea what "subscribe" does but it probably shouldn't be mocked
store.subscribe = jest.fn();
+// We should not mock this. This makes the dispatch function useless. It just needs the right setup to work.
+// Things were mocked, then broke, then they mocked other things that didn't need to be mocked.
+// This all can work out of the box with the right set up
store.dispatch = jest.fn();
describe('SequenceExamWrapper', () => {