Skip to content

Commit

Permalink
feat: more experimenting with changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ilee2u committed Feb 6, 2024
1 parent 7fee083 commit 586ff0a
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 11 deletions.
6 changes: 6 additions & 0 deletions src/core/ExamStateProvider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand Down
35 changes: 24 additions & 11 deletions src/core/OuterExamTimer.jsx
Original file line number Diff line number Diff line change
@@ -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';

Check failure on line 9 in src/core/OuterExamTimer.jsx

View workflow job for this annotation

GitHub Actions / tests

Expected a line break after this opening brace

Check failure on line 9 in src/core/OuterExamTimer.jsx

View workflow job for this annotation

GitHub Actions / tests

Expected a line break before this closing brace

Check failure on line 9 in src/core/OuterExamTimer.jsx

View workflow job for this annotation

GitHub Actions / tests

Expected a line break after this opening brace

Check failure on line 9 in src/core/OuterExamTimer.jsx

View workflow job for this annotation

GitHub Actions / tests

Expected a line break before this closing brace
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.

Check failure on line 25 in src/core/OuterExamTimer.jsx

View workflow job for this annotation

GitHub Actions / tests

Expected exception block, space or tab after '//' in comment

Check failure on line 25 in src/core/OuterExamTimer.jsx

View workflow job for this annotation

GitHub Actions / tests

Expected exception block, space or tab after '//' in comment
const showTimer = !!(activeAttempt && IS_STARTED_STATUS(activeAttempt.attempt_status));
// console.log(showTimer);
console.log(activeAttempt);

Check warning on line 28 in src/core/OuterExamTimer.jsx

View workflow job for this annotation

GitHub Actions / tests

Unexpected console statement

Check warning on line 28 in src/core/OuterExamTimer.jsx

View workflow job for this annotation

GitHub Actions / tests

Unexpected console statement
const apiErrorMsg = useSelector(selectors.apiErrorMsg);

useEffect(() => {
getLatestAttemptData(courseId);
Expand Down Expand Up @@ -53,9 +66,9 @@ ExamTimer.propTypes = {
* will be shown.
*/
const OuterExamTimer = ({ courseId }) => (
<ExamStateProvider>
<ExamTimer courseId={courseId} />
</ExamStateProvider>
// <ExamStateProvider>
<ExamTimer courseId={courseId} />
// </ExamStateProvider>
);

OuterExamTimer.propTypes = {
Expand Down
29 changes: 29 additions & 0 deletions src/data/selectors.js
Original file line number Diff line number Diff line change
@@ -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,

Check failure on line 4 in src/data/selectors.js

View workflow job for this annotation

GitHub Actions / tests

This line has a length of 124. Maximum allowed is 120

Check failure on line 4 in src/data/selectors.js

View workflow job for this annotation

GitHub Actions / tests

This line has a length of 124. Maximum allowed is 120
*/

// 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;

Check failure on line 29 in src/data/selectors.js

View workflow job for this annotation

GitHub Actions / tests

Too many blank lines at the end of file. Max of 0 allowed

Check failure on line 29 in src/data/selectors.js

View workflow job for this annotation

GitHub Actions / tests

Too many blank lines at the end of file. Max of 0 allowed
1 change: 1 addition & 0 deletions src/data/slice.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 }) => {
Expand Down
10 changes: 10 additions & 0 deletions src/exam/ExamWrapper.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down

0 comments on commit 586ff0a

Please sign in to comment.