From 8e51de4ce7bf852bef20925da5fe8f178c4a60bf Mon Sep 17 00:00:00 2001 From: alangsto <46360176+alangsto@users.noreply.github.com> Date: Mon, 5 Feb 2024 09:47:52 -0500 Subject: [PATCH] feat: refactor non instruction components (#132) --- src/context.jsx | 4 - src/core/ExamStateProvider.jsx | 35 ---- src/core/OuterExamTimer.jsx | 13 +- src/core/OuterExamTimer.test.jsx | 13 +- src/core/SequenceExamWrapper.jsx | 5 +- src/data/index.js | 2 +- src/data/store.js | 8 - src/exam/Exam.jsx | 21 +- src/exam/ExamAPIError.jsx | 7 +- src/exam/ExamAPIError.test.jsx | 36 ++-- src/exam/ExamWrapper.jsx | 18 +- src/exam/ExamWrapper.test.jsx | 180 +++++++----------- src/hocs.jsx | 12 -- src/index.jsx | 1 - src/instructions/Instructions.test.jsx | 14 +- .../ProctoredExamInstructions.test.jsx | 19 +- src/timer/CountDownTimer.test.jsx | 11 -- 17 files changed, 147 insertions(+), 252 deletions(-) delete mode 100644 src/context.jsx delete mode 100644 src/core/ExamStateProvider.jsx delete mode 100644 src/data/store.js delete mode 100644 src/hocs.jsx diff --git a/src/context.jsx b/src/context.jsx deleted file mode 100644 index 3005f5a7..00000000 --- a/src/context.jsx +++ /dev/null @@ -1,4 +0,0 @@ -import React from 'react'; - -const ExamStateContext = React.createContext({}); -export default ExamStateContext; diff --git a/src/core/ExamStateProvider.jsx b/src/core/ExamStateProvider.jsx deleted file mode 100644 index 174a2b61..00000000 --- a/src/core/ExamStateProvider.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import React, { useMemo } from 'react'; -import { withExamStore } from '../hocs'; -import * as dispatchActions from '../data/thunks'; -import ExamStateContext from '../context'; -import { IS_STARTED_STATUS } from '../constants'; - -/** - * Make exam state available as a context for all library components. - * @param children - sequence content - * @param state - exam state params and actions - * @returns {JSX.Element} - */ - -// eslint-disable-next-line react/prop-types -const StateProvider = ({ children, ...state }) => { - const contextValue = useMemo(() => ({ - ...state, - showTimer: !!(state.activeAttempt && IS_STARTED_STATUS(state.activeAttempt.attempt_status)), - }), [state]); - return ( - - {children} - - ); -}; - -const mapStateToProps = (state) => ({ ...state.specialExams }); - -const ExamStateProvider = withExamStore( - StateProvider, - mapStateToProps, - dispatchActions, -); - -export default ExamStateProvider; diff --git a/src/core/OuterExamTimer.jsx b/src/core/OuterExamTimer.jsx index fe70e7d6..2ae0f571 100644 --- a/src/core/OuterExamTimer.jsx +++ b/src/core/OuterExamTimer.jsx @@ -2,16 +2,15 @@ import React, { useEffect, useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import { AppContext } from '@edx/frontend-platform/react'; -import ExamStateContext from '../context'; -import { getLatestAttemptData } from '../data'; import { ExamTimerBlock } from '../timer'; import ExamAPIError from '../exam/ExamAPIError'; -import ExamStateProvider from './ExamStateProvider'; +import { getLatestAttemptData } from '../data'; +import { IS_STARTED_STATUS } from '../constants'; const ExamTimer = ({ courseId }) => { - const examState = useContext(ExamStateContext); + const { activeAttempt } = useSelector(state => state.specialExams); const { authenticatedUser } = useContext(AppContext); - const { showTimer } = examState; + const showTimer = !!(activeAttempt && IS_STARTED_STATUS(activeAttempt.attempt_status)); const { apiErrorMsg } = useSelector(state => state.specialExams); @@ -48,9 +47,7 @@ ExamTimer.propTypes = { * will be shown. */ const OuterExamTimer = ({ courseId }) => ( - - - + ); OuterExamTimer.propTypes = { diff --git a/src/core/OuterExamTimer.test.jsx b/src/core/OuterExamTimer.test.jsx index 056bfca6..7f96aaa6 100644 --- a/src/core/OuterExamTimer.test.jsx +++ b/src/core/OuterExamTimer.test.jsx @@ -2,12 +2,11 @@ import '@testing-library/jest-dom'; import { Factory } from 'rosie'; import React from 'react'; import OuterExamTimer from './OuterExamTimer'; -import { store, getLatestAttemptData } from '../data'; -import { render } from '../setupTest'; +import { getLatestAttemptData } from '../data'; +import { initializeTestStore, render } from '../setupTest'; import { ExamStatus } from '../constants'; jest.mock('../data', () => ({ - store: {}, getLatestAttemptData: jest.fn(), Emitter: { on: () => jest.fn(), @@ -17,12 +16,16 @@ jest.mock('../data', () => ({ }, })); getLatestAttemptData.mockReturnValue(jest.fn()); -store.subscribe = jest.fn(); -store.dispatch = jest.fn(); describe('OuterExamTimer', () => { const courseId = 'course-v1:test+test+test'; + let store; + + beforeEach(async () => { + store = await initializeTestStore(); + }); + it('is successfully rendered and shows timer if there is an exam in progress', () => { const attempt = Factory.build('attempt', { attempt_status: ExamStatus.STARTED, diff --git a/src/core/SequenceExamWrapper.jsx b/src/core/SequenceExamWrapper.jsx index dea56e2b..4480ac7f 100644 --- a/src/core/SequenceExamWrapper.jsx +++ b/src/core/SequenceExamWrapper.jsx @@ -1,6 +1,5 @@ import React from 'react'; import ExamWrapper from '../exam/ExamWrapper'; -import ExamStateProvider from './ExamStateProvider'; /** * SequenceExamWrapper is the component responsible for handling special exams. @@ -14,9 +13,7 @@ import ExamStateProvider from './ExamStateProvider'; * */ const SequenceExamWrapper = (props) => ( - - - + ); export default SequenceExamWrapper; diff --git a/src/data/index.js b/src/data/index.js index 701c493b..e0ced278 100644 --- a/src/data/index.js +++ b/src/data/index.js @@ -16,11 +16,11 @@ export { resetExam, getAllowProctoringOptOut, examRequiresAccessToken, + checkExamEntry, } from './thunks'; export { expireExamAttempt, } from './slice'; -export { default as store } from './store'; export { default as Emitter } from './emitter'; diff --git a/src/data/store.js b/src/data/store.js deleted file mode 100644 index 9fdef030..00000000 --- a/src/data/store.js +++ /dev/null @@ -1,8 +0,0 @@ -import { configureStore } from '@reduxjs/toolkit'; -import examReducer from './slice'; - -export default configureStore({ - reducer: { - specialExams: examReducer, - }, -}); diff --git a/src/exam/Exam.jsx b/src/exam/Exam.jsx index 7c19b766..306b306e 100644 --- a/src/exam/Exam.jsx +++ b/src/exam/Exam.jsx @@ -1,15 +1,15 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -import React, { useContext, useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n'; import { Alert, Spinner } from '@edx/paragon'; import { Info } from '@edx/paragon/icons'; import { ExamTimerBlock } from '../timer'; import Instructions from '../instructions'; -import ExamStateContext from '../context'; import ExamAPIError from './ExamAPIError'; -import { ExamStatus, ExamType } from '../constants'; +import { ExamStatus, ExamType, IS_STARTED_STATUS } from '../constants'; import messages from './messages'; +import { getProctoringSettings } from '../data'; /** * Exam component is intended to render exam instructions before and after exam. @@ -23,10 +23,12 @@ import messages from './messages'; const Exam = ({ isGated, isTimeLimited, originalUserIsStaff, canAccessProctoredExams, children, intl, }) => { - const state = useContext(ExamStateContext); const { - isLoading, showTimer, exam, apiErrorMsg, getProctoringSettings, - } = state; + isLoading, activeAttempt, exam, apiErrorMsg, + } = useSelector(state => state.specialExams); + const dispatch = useDispatch(); + + const showTimer = !!(activeAttempt && IS_STARTED_STATUS(activeAttempt.attempt_status)); const { attempt, @@ -59,7 +61,7 @@ const Exam = ({ if (proctoredExamTypes.includes(examType)) { // only fetch proctoring settings for a proctored exam if (examId) { - getProctoringSettings(); + dispatch(getProctoringSettings()); } // Only exclude Timed Exam when restricting access to exams @@ -68,7 +70,8 @@ const Exam = ({ // this makes sure useEffect gets called only one time after the exam has been fetched // we can't leave this empty since initially exam is just an empty object, so // API calls above would not get triggered - }, [examId]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [examId, dispatch]); if (isLoading) { return ( diff --git a/src/exam/ExamAPIError.jsx b/src/exam/ExamAPIError.jsx index a6b0e271..157f7e10 100644 --- a/src/exam/ExamAPIError.jsx +++ b/src/exam/ExamAPIError.jsx @@ -1,15 +1,14 @@ -import React, { useContext } from 'react'; +import React from 'react'; +import { useSelector } from 'react-redux'; import { getConfig } from '@edx/frontend-platform'; import { Alert, Hyperlink, Icon } from '@edx/paragon'; import { Info } from '@edx/paragon/icons'; import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n'; -import ExamStateContext from '../context'; import messages from './messages'; const ExamAPIError = ({ intl }) => { - const state = useContext(ExamStateContext); const { SITE_NAME, SUPPORT_URL } = getConfig(); - const { apiErrorMsg } = state; + const { apiErrorMsg } = useSelector(state => state.specialExams); const shouldShowApiErrorMsg = !!apiErrorMsg && !apiErrorMsg.includes('<'); return ( diff --git a/src/exam/ExamAPIError.test.jsx b/src/exam/ExamAPIError.test.jsx index edb16d1d..10c23f2b 100644 --- a/src/exam/ExamAPIError.test.jsx +++ b/src/exam/ExamAPIError.test.jsx @@ -1,9 +1,7 @@ import '@testing-library/jest-dom'; import React from 'react'; import { getConfig } from '@edx/frontend-platform'; -import { store } from '../data'; -import { render } from '../setupTest'; -import ExamStateProvider from '../core/ExamStateProvider'; +import { initializeTestStore, render } from '../setupTest'; import ExamAPIError from './ExamAPIError'; const originalConfig = jest.requireActual('@edx/frontend-platform').getConfig(); @@ -13,22 +11,20 @@ jest.mock('@edx/frontend-platform', () => ({ })); getConfig.mockImplementation(() => originalConfig); -jest.mock('../data', () => ({ - store: {}, -})); -store.subscribe = jest.fn(); -store.dispatch = jest.fn(); - describe('ExamAPIError', () => { const defaultMessage = 'A system error has occurred with your exam.'; + let store; + + beforeEach(async () => { + store = await initializeTestStore(); + }); + it('renders with the default information', () => { store.getState = () => ({ specialExams: {} }); const tree = render( - - - , + , { store }, ); @@ -45,9 +41,7 @@ describe('ExamAPIError', () => { store.getState = () => ({ specialExams: {} }); const { getByTestId } = render( - - - , + , { store }, ); @@ -62,9 +56,7 @@ describe('ExamAPIError', () => { }); const { queryByTestId } = render( - - - , + , { store }, ); @@ -77,9 +69,7 @@ describe('ExamAPIError', () => { }); const { queryByTestId } = render( - - - , + , { store }, ); @@ -92,9 +82,7 @@ describe('ExamAPIError', () => { }); const { queryByTestId } = render( - - - , + , { store }, ); diff --git a/src/exam/ExamWrapper.jsx b/src/exam/ExamWrapper.jsx index 68b7eee8..8b5ccde6 100644 --- a/src/exam/ExamWrapper.jsx +++ b/src/exam/ExamWrapper.jsx @@ -1,14 +1,18 @@ +import { useDispatch, useSelector } from 'react-redux'; import React, { useContext, useEffect } from 'react'; import { AppContext } from '@edx/frontend-platform/react'; import PropTypes from 'prop-types'; import Exam from './Exam'; -import ExamStateContext from '../context'; +import { + getExamAttemptsData, + getAllowProctoringOptOut, + checkExamEntry, +} from '../data'; /** * Exam wrapper is responsible for triggering initial exam data fetching and rendering Exam. */ const ExamWrapper = ({ children, ...props }) => { - const state = useContext(ExamStateContext); const { authenticatedUser } = useContext(AppContext); const { sequence, @@ -17,9 +21,13 @@ const ExamWrapper = ({ children, ...props }) => { originalUserIsStaff, canAccessProctoredExams, } = props; - const { getExamAttemptsData, getAllowProctoringOptOut, checkExamEntry } = state; + + const { isLoading } = useSelector(state => state.specialExams); + + const dispatch = useDispatch(); + const loadInitialData = async () => { - await getExamAttemptsData(courseId, sequence.id); + await dispatch(getExamAttemptsData(courseId, sequence.id)); await getAllowProctoringOptOut(sequence.allowProctoringOptOut); await checkExamEntry(); }; @@ -28,7 +36,7 @@ const ExamWrapper = ({ children, ...props }) => { useEffect(() => { // fetch exam data on exam sequences or if no exam data has been fetched yet - if (sequence.isTimeLimited || state.isLoading) { + if (sequence.isTimeLimited || isLoading) { loadInitialData(); } // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/src/exam/ExamWrapper.test.jsx b/src/exam/ExamWrapper.test.jsx index 04e43ab1..6f529bf4 100644 --- a/src/exam/ExamWrapper.test.jsx +++ b/src/exam/ExamWrapper.test.jsx @@ -2,10 +2,9 @@ import '@testing-library/jest-dom'; import { Factory } from 'rosie'; import React from 'react'; import SequenceExamWrapper from './ExamWrapper'; -import { store, startTimedExam } from '../data'; +import { startTimedExam } from '../data'; import { getExamAttemptsData } from '../data/thunks'; -import { render, waitFor } from '../setupTest'; -import ExamStateProvider from '../core/ExamStateProvider'; +import { render, waitFor, initializeTestStore } from '../setupTest'; import { ExamStatus, ExamType } from '../constants'; jest.mock('../data', () => ({ @@ -26,8 +25,6 @@ jest.mock('../data/thunks', () => { getExamAttemptsData.mockReturnValue(jest.fn()); startTimedExam.mockReturnValue(jest.fn()); -store.subscribe = jest.fn(); -store.dispatch = jest.fn(); describe('SequenceExamWrapper', () => { const sequence = { @@ -35,10 +32,11 @@ describe('SequenceExamWrapper', () => { isTimeLimited: true, }; const courseId = 'course-v1:test+test+test'; + let store; - beforeEach(() => { + beforeEach(async () => { jest.clearAllMocks(); - store.getState = () => ({ + store = await initializeTestStore({ specialExams: Factory.build('specialExams'), isLoading: false, }); @@ -46,11 +44,9 @@ describe('SequenceExamWrapper', () => { it('is successfully rendered and shows instructions if the user is not staff', () => { const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('exam-instructions-title')).toHaveTextContent('Subsection is a Timed Exam (30 minutes)'); @@ -66,11 +62,9 @@ describe('SequenceExamWrapper', () => { }), }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('proctored-exam-instructions-title')).toHaveTextContent('This exam is proctored'); @@ -83,11 +77,9 @@ describe('SequenceExamWrapper', () => { }), }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('spinner')).toBeInTheDocument(); @@ -101,11 +93,9 @@ describe('SequenceExamWrapper', () => { }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('exam-instructions-title')).toHaveTextContent('Subsection is a Timed Exam (30 minutes)'); @@ -120,11 +110,9 @@ describe('SequenceExamWrapper', () => { }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('exam-instructions-title')).not.toBeInTheDocument(); @@ -133,11 +121,9 @@ describe('SequenceExamWrapper', () => { it('does not fetch exam data if already loaded and the sequence is not an exam', async () => { render( - - -
children
-
-
, + +
children
+
, { store }, ); // assert the exam data is not fetched @@ -153,11 +139,9 @@ describe('SequenceExamWrapper', () => { }); render( - - -
children
-
-
, + +
children
+
, { store }, ); await waitFor(() => expect(getExamAttemptsData).toHaveBeenCalled()); @@ -165,11 +149,9 @@ describe('SequenceExamWrapper', () => { it('does not take any actions if sequence item is not exam', () => { const { getByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(getByTestId('sequence-content')).toHaveTextContent('children'); @@ -180,11 +162,9 @@ describe('SequenceExamWrapper', () => { authenticatedUser: null, }; const { getByTestId } = render( - - -
children
-
-
, + +
children
+
, { store, appContext }, ); expect(getByTestId('sequence-content')).toHaveTextContent('children'); @@ -199,11 +179,9 @@ describe('SequenceExamWrapper', () => { }), }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('sequence-content')).toHaveTextContent('children'); @@ -220,11 +198,9 @@ describe('SequenceExamWrapper', () => { }), }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('sequence-content')).toHaveTextContent('children'); @@ -243,11 +219,9 @@ describe('SequenceExamWrapper', () => { }), }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('sequence-content')).toHaveTextContent('children'); @@ -267,11 +241,9 @@ describe('SequenceExamWrapper', () => { }), }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('sequence-content')).toHaveTextContent('children'); @@ -292,11 +264,9 @@ describe('SequenceExamWrapper', () => { }), }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('sequence-content')).toHaveTextContent('children'); @@ -305,11 +275,9 @@ describe('SequenceExamWrapper', () => { it('does not display masquerade alert if sequence is not time gated', () => { const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('sequence-content')).toHaveTextContent('children'); @@ -328,15 +296,13 @@ describe('SequenceExamWrapper', () => { }), }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('no-access')).toHaveTextContent('You do not have access to proctored exams with your current enrollment.'); @@ -355,15 +321,13 @@ describe('SequenceExamWrapper', () => { }), }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('no-access')).toBeNull(); @@ -382,15 +346,13 @@ describe('SequenceExamWrapper', () => { }), }); const { queryByTestId } = render( - - -
children
-
-
, + +
children
+
, { store }, ); expect(queryByTestId('no-access')).toBeNull(); diff --git a/src/hocs.jsx b/src/hocs.jsx deleted file mode 100644 index 049ec614..00000000 --- a/src/hocs.jsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import { getDisplayName } from './helpers'; -import { store as examStore } from './data'; - -// eslint-disable-next-line import/prefer-default-export -export const withExamStore = (WrappedComponent, mapStateToProps = null, dispatchActions = null) => { - const ConnectedComp = connect(mapStateToProps, dispatchActions)(WrappedComponent); - const retValue = (props) => ; - retValue.displayName = `WithExamStore(${getDisplayName(WrappedComponent)})`; - return retValue; -}; diff --git a/src/index.jsx b/src/index.jsx index 84ae8cf9..e6aa4d3f 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -6,4 +6,3 @@ export { isExam, fetchExamAccess, } from './api'; -export { store } from './data'; diff --git a/src/instructions/Instructions.test.jsx b/src/instructions/Instructions.test.jsx index af9a5200..eda3eb2a 100644 --- a/src/instructions/Instructions.test.jsx +++ b/src/instructions/Instructions.test.jsx @@ -4,20 +4,19 @@ import React from 'react'; import { fireEvent, waitFor } from '@testing-library/dom'; import Instructions from './index'; import { - store, continueExam, getExamAttemptsData, startProctoredExam, startTimedExam, submitExam, + continueExam, getExamAttemptsData, startProctoredExam, startTimedExam, submitExam, } from '../data'; import { pollExamAttempt, softwareDownloadAttempt } from '../data/api'; import Emitter from '../data/emitter'; import { TIMER_REACHED_NULL } from '../timer/events'; import { - render, screen, act, initializeMockApp, + render, screen, act, initializeMockApp, initializeTestStore, } from '../setupTest'; import { ExamStatus, ExamType, INCOMPLETE_STATUSES, } from '../constants'; jest.mock('../data', () => ({ - store: {}, continueExam: jest.fn(), getExamAttemptsData: jest.fn(), getExamReviewPolicy: jest.fn(), @@ -35,12 +34,15 @@ getExamAttemptsData.mockReturnValue(jest.fn()); startProctoredExam.mockReturnValue(jest.fn()); startTimedExam.mockReturnValue(jest.fn()); pollExamAttempt.mockReturnValue(Promise.resolve({})); -store.subscribe = jest.fn(); -store.dispatch = jest.fn(); describe('SequenceExamWrapper', () => { - beforeEach(() => { + let store; + + beforeEach(async () => { initializeMockApp(); + store = await initializeTestStore(); + store.subscribe = jest.fn(); + store.dispatch = jest.fn(); }); it('Start exam instructions can be successfully rendered', () => { diff --git a/src/instructions/proctored_exam/ProctoredExamInstructions.test.jsx b/src/instructions/proctored_exam/ProctoredExamInstructions.test.jsx index df3d1023..0473b4d4 100644 --- a/src/instructions/proctored_exam/ProctoredExamInstructions.test.jsx +++ b/src/instructions/proctored_exam/ProctoredExamInstructions.test.jsx @@ -3,8 +3,13 @@ import { Factory } from 'rosie'; import React from 'react'; import { fireEvent, waitFor } from '@testing-library/dom'; import Instructions from '../index'; -import { store, getExamAttemptsData, submitExam } from '../../data'; -import { initializeMockApp, render, screen } from '../../setupTest'; +import { getExamAttemptsData, submitExam } from '../../data'; +import { + initializeMockApp, + initializeTestStore, + render, + screen, +} from '../../setupTest'; import { ExamType, ExamStatus, @@ -12,7 +17,6 @@ import { } from '../../constants'; jest.mock('../../data', () => ({ - store: {}, getExamAttemptsData: jest.fn(), getExamReviewPolicy: jest.fn(), submitExam: jest.fn(), @@ -20,13 +24,16 @@ jest.mock('../../data', () => ({ submitExam.mockReturnValue(jest.fn()); getExamAttemptsData.mockReturnValue(jest.fn()); -store.subscribe = jest.fn(); -store.dispatch = jest.fn(); describe('SequenceExamWrapper', () => { - beforeEach(() => { + let store; + + beforeEach(async () => { initializeMockApp(); jest.clearAllMocks(); + store = await initializeTestStore(); + store.subscribe = jest.fn(); + store.dispatch = jest.fn(); }); it('Start exam instructions can be successfully rendered', () => { diff --git a/src/timer/CountDownTimer.test.jsx b/src/timer/CountDownTimer.test.jsx index dc050bf2..160774f4 100644 --- a/src/timer/CountDownTimer.test.jsx +++ b/src/timer/CountDownTimer.test.jsx @@ -5,11 +5,6 @@ import { render, screen, initializeTestStore, fireEvent, } from '../setupTest'; import { stopExam, submitExam } from '../data'; -import specialExams from '../data/store'; - -jest.mock('../data/store', () => ({ - specialExams: {}, -})); // We do a partial mock to avoid mocking out other exported values (e.g. the store and the Emitter). jest.mock('../data', () => { @@ -50,7 +45,6 @@ describe('ExamTimerBlock', () => { }, }; store = await initializeTestStore(preloadedState); - specialExams.getState = store.getState; attempt = store.getState().specialExams.activeAttempt; }); @@ -113,7 +107,6 @@ describe('ExamTimerBlock', () => { }, }; const testStore = await initializeTestStore(preloadedState); - specialExams.getState = store.testStore; attempt = testStore.getState().specialExams.activeAttempt; render( , @@ -176,7 +169,6 @@ describe('ExamTimerBlock', () => { }, }; const testStore = await initializeTestStore(preloadedState); - specialExams.getState = store.testStore; attempt = testStore.getState().specialExams.activeAttempt; render( @@ -219,7 +211,6 @@ describe('ExamTimerBlock', () => { }, }; let testStore = await initializeTestStore(preloadedState); - specialExams.getState = store.testStore; attempt = testStore.getState().specialExams.activeAttempt; const { rerender } = render( , @@ -231,7 +222,6 @@ describe('ExamTimerBlock', () => { time_remaining_seconds: 20, }; testStore = await initializeTestStore(preloadedState); - specialExams.getState = store.testStore; const updatedAttempt = testStore.getState().specialExams.activeAttempt; expect(updatedAttempt.time_remaining_seconds).toBe(20); @@ -279,7 +269,6 @@ describe('ExamTimerBlock', () => { // Store it in the state const testStore = await initializeTestStore(preloadedState); - specialExams.getState = store.testStore; attempt = testStore.getState().specialExams.activeAttempt; // render an exam timer block with that data