diff --git a/jest.config.js b/jest.config.js
index 23aa0724..0b5f7dd3 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -12,6 +12,8 @@ const config = createConfig('jest', {
'src/hooks/testHooks', // don't check coverage for jest mocking tools
// 'src/data/services/lms/fakeData', // don't check coverage for mock data
'src/test', // don't check coverage for test integration test utils
+ 'messages.js', // don't check coverage for i18n messages
+ 'src/data/services/lms/fakeData', // don't check coverage for fake data
],
testTimeout: 120000,
});
diff --git a/src/components/ActionButton.test.jsx b/src/components/ActionButton.test.jsx
new file mode 100644
index 00000000..3af2dfd8
--- /dev/null
+++ b/src/components/ActionButton.test.jsx
@@ -0,0 +1,28 @@
+import { shallow } from '@edx/react-unit-test-utils';
+
+import ActionButton from './ActionButton';
+
+describe('
+ Criterion Description +
++ Selected Option + : + 5 + + Points +
++ Comment Body +
++ Criterion Description +
++ Selected Option + : + 5 + + Points +
++ Selected Option + : + 5 + + Points +
++ Comment Body +
++ Criterion Description +
++ Comment Body +
++ + 1 + : +
++ + 2 + : +
++ content ++`; diff --git a/src/components/FilePreview/components/FileRenderer/BaseRenderers/pdfHooks.test.js b/src/components/FilePreview/components/FileRenderer/BaseRenderers/pdfHooks.test.js new file mode 100644 index 00000000..4d6e9c11 --- /dev/null +++ b/src/components/FilePreview/components/FileRenderer/BaseRenderers/pdfHooks.test.js @@ -0,0 +1,92 @@ +import React from 'react'; +import { mockUseKeyedState } from '@edx/react-unit-test-utils'; +import { when } from 'jest-when'; + +import { + usePDFRendererData, safeSetPageNumber, stateKeys, initialState, +} from './pdfHooks'; + +const state = mockUseKeyedState(stateKeys); + +describe('PDF Renderer hooks', () => { + describe('safeSetPageNumber', () => { + it('returns value handler that sets page number if valid', () => { + const rawSetPageNumber = jest.fn(); + const numPages = 10; + const goToPage = safeSetPageNumber({ numPages, rawSetPageNumber }); + // should not call rawSetPageNumber when page number smaller than 1 or greater than numPages + goToPage(0); + expect(rawSetPageNumber).not.toHaveBeenCalled(); + goToPage(numPages + 1); + expect(rawSetPageNumber).not.toHaveBeenCalled(); + // should call rawSetPageNumber when page number is valid + goToPage(numPages); + expect(rawSetPageNumber).toHaveBeenCalledWith(numPages); + }); + }); + + describe('usePDFRendererData', () => { + const onSuccess = jest.fn(); + const onError = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + state.mock(); + }); + afterEach(() => { + state.resetVals(); + }); + + it('start with initial state', () => { + usePDFRendererData({}); + state.expectInitializedWith(stateKeys.pageNumber, initialState.pageNumber); + state.expectInitializedWith(stateKeys.numPages, initialState.numPages); + state.expectInitializedWith(stateKeys.relativeHeight, initialState.relativeHeight); + }); + + it('calls onSuccess and sets numPages based on args', () => { + const out = usePDFRendererData({ onSuccess }); + out.onDocumentLoadSuccess({ numPages: 5 }); + expect(onSuccess).toHaveBeenCalled(); + state.expectSetStateCalledWith(stateKeys.numPages, 5); + }); + + it('sets relative height based on page size', () => { + when(React.useRef) + .calledWith() + .mockReturnValueOnce({ + current: { getBoundingClientRect: () => ({ width: 20 }) }, + }); + const out = usePDFRendererData({}); + + const page = { view: [0, 0, 20, 30] }; + out.onLoadPageSuccess(page); + expect(state.setState.relativeHeight).toHaveBeenCalledWith(30); + }); + + it('calls onErro if error happened', () => { + const out = usePDFRendererData({ onError }); + out.onDocumentLoadError('notFound'); + expect(onError).toHaveBeenCalledWith('notFound'); + }); + + it('has good page logic', () => { + // start with 3 pages + // this seems to be the only way to mock initial value + initialState.pageNumber = 2; + initialState.numPages = 3; + const out = usePDFRendererData({ onSuccess }); + // go to next page + out.onNextPageButtonClick(); + state.expectSetStateCalledWith(stateKeys.pageNumber, 3); + + // go to prev page + out.onPrevPageButtonClick(); + state.expectSetStateCalledWith(stateKeys.pageNumber, 1); + + // reset initial state + initialState.pageNumber = 1; + initialState.numPages = 1; + }); + }); +}); diff --git a/src/components/FilePreview/components/FileRenderer/BaseRenderers/textHooks.test.js b/src/components/FilePreview/components/FileRenderer/BaseRenderers/textHooks.test.js new file mode 100644 index 00000000..1a5c6179 --- /dev/null +++ b/src/components/FilePreview/components/FileRenderer/BaseRenderers/textHooks.test.js @@ -0,0 +1,60 @@ +import React from 'react'; +import { mockUseKeyedState } from '@edx/react-unit-test-utils'; + +import axios from 'axios'; +import { useTextRendererData, fetchFile, stateKeys } from './textHooks'; + +jest.mock('axios'); + +const state = mockUseKeyedState(stateKeys); + +describe('textHooks', () => { + const url = 'http://example.com'; + const setContent = jest.fn(); + const onError = jest.fn(); + const onSuccess = jest.fn(); + + describe('fetchFile', () => { + it('should call onSuccess and setContent when the request is successful', async () => { + const response = { data: 'file content' }; + axios.get.mockResolvedValue(response); + await fetchFile({ setContent, url, onSuccess }); + expect(onSuccess).toHaveBeenCalled(); + expect(setContent).toHaveBeenCalledWith(response.data); + }); + + it('should call onError when the request fails', async () => { + const response = { response: { status: 404 } }; + axios.get.mockRejectedValue(response); + await fetchFile({ url, onError }); + expect(onError).toHaveBeenCalledWith(response.response.status); + }); + }); + + describe('useTextRendererData', () => { + beforeEach(() => { + jest.clearAllMocks(); + state.mock(); + }); + afterEach(() => { state.resetVals(); }); + + it('start with empty content', () => { + useTextRendererData({}); + state.expectInitializedWith(stateKeys.content, ''); + }); + + it('update content after useEffect get call', async () => { + axios.get.mockResolvedValue({ data: 'file content' }); + useTextRendererData({ url, onError, onSuccess }); + // wouldn't call before useEffect + expect(axios.get).not.toHaveBeenCalled(); + const [[cb]] = React.useEffect.mock.calls; + cb(); + // because fetchFile was written with async/await, we need to wait for the next tick + await new Promise(process.nextTick); + expect(axios.get).toHaveBeenCalled(); + expect(onSuccess).toHaveBeenCalled(); + state.expectSetStateCalledWith(stateKeys.content, 'file content'); + }); + }); +}); diff --git a/src/components/FilePreview/components/FileRenderer/FileCard/__snapshots__/index.test.jsx.snap b/src/components/FilePreview/components/FileRenderer/FileCard/__snapshots__/index.test.jsx.snap new file mode 100644 index 00000000..69b7500f --- /dev/null +++ b/src/components/FilePreview/components/FileRenderer/FileCard/__snapshots__/index.test.jsx.snap @@ -0,0 +1,28 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`
+ + Instructions + : + + arbitrarilyInstructionsMessage +
+{subLabel}
+{subLabel}
)}+ Past due! +
++ 1 / 2 +
+- {effectiveAssessmentType === 'peer' + {effectiveAssessmentType === stepNames.peer ? formatMessage(messages.peerAsFinalGradeInfo) : formatMessage(messages.finalGradeInfo, { step: effectiveAssessmentType })}
diff --git a/src/views/GradeView/FinalGrade.test.jsx b/src/views/GradeView/FinalGrade.test.jsx new file mode 100644 index 00000000..aac5526d --- /dev/null +++ b/src/views/GradeView/FinalGrade.test.jsx @@ -0,0 +1,59 @@ +import { shallow } from '@edx/react-unit-test-utils'; + +import { + useAssessmentData, + useStepInfo, +} from 'hooks/app'; +import { stepNames } from 'constants/index'; + +import FinalGrade from './FinalGrade'; + +jest.mock('hooks/app', () => ({ + useAssessmentData: jest.fn(), + useStepInfo: jest.fn(), +})); +jest.mock('components/InfoPopover', () => 'InfoPopover'); +jest.mock('components/Assessment/ReadonlyAssessment', () => 'ReadOnlyAssessment'); + +describe('
+ Your grade is based on your Peer assessment score for this problem. Other assessments don't count towards your final score.
+
+ Only the required number of peer grades will counted against your final grade. The others are shown, but are not included in your grade calculation
+
+ Your grade is based on your Self assessment score for this problem. Other assessments don't count towards your final score. +
++ Only the required number of peer grades will counted against your final grade. The others are shown, but are not included in your grade calculation +
++ Your grade is based on your self score for this problem. Other assessments don't count towards your final score. +
++ These grades are given to your response. However, these are not used to compute your final grade. +
+
+
+ test
+
+ start:
+
+
+
+ test
+
+ due:
+
+
+
+ Response
+
+ start:
+
+
+
+ Response
+
+ due:
+
+
+
+ Response
+
+ start:
+
+
+
+ Response
+
+ due:
+
+
{formatMessage(messages.criteriaNameLabel)}
{criterion.name}
diff --git a/src/views/XBlockStudioView/components/StudioViewRubric.test.jsx b/src/views/XBlockStudioView/components/StudioViewRubric.test.jsx
new file mode 100644
index 00000000..e816da96
--- /dev/null
+++ b/src/views/XBlockStudioView/components/StudioViewRubric.test.jsx
@@ -0,0 +1,68 @@
+import { shallow } from '@edx/react-unit-test-utils';
+
+import { useRubricConfig } from 'hooks/app';
+
+import StudioViewRubric from './StudioViewRubric';
+
+jest.mock('hooks/app', () => ({
+ useRubricConfig: jest.fn(),
+}));
+jest.mock('./XBlockStudioViewProvider', () => ({
+ useXBlockStudioViewContext: () => ({
+ rubricIsOpen: true,
+ toggleRubric: jest.fn().mockName('toggleRubric'),
+ }),
+}));
+
+describe('
+
+ File uploads:
+
+
+
+ File upload limit:
+
+
+ 10
+
+
+
+ Text response:
+
+
+
+ Response editor:
+
+
+ WYSIWYG editor
+
+
+
+ Allow LaTeX responses:
+
+
+ True
+
+
+
+ Top responses:
+
+
+ 10
+
+
+
+ Teams enabled:
+
+
+ True
+
+
+
+ Show rubric during response:
+
+
+ False
+
+
+
+ Text response:
+
+
+
+ Response editor:
+
+
+ Text editor
+
+
+
+ Allow LaTeX responses:
+
+
+ False
+
+
+
+ Teams enabled:
+
+
+ False
+
+
+
+ Show rubric during response:
+
+
+ False
+
+
+
{formatMessage(messages.topResponsesLabel)} {leaderboardConfig.numberOfEntries}
diff --git a/src/views/XBlockStudioView/components/StudioViewSettings/index.test.jsx b/src/views/XBlockStudioView/components/StudioViewSettings/index.test.jsx new file mode 100644 index 00000000..100c7d0e --- /dev/null +++ b/src/views/XBlockStudioView/components/StudioViewSettings/index.test.jsx @@ -0,0 +1,72 @@ +import { shallow } from '@edx/react-unit-test-utils'; + +import { useORAConfigData } from 'hooks/app'; + +import StudioViewSettings from './index'; + +jest.mock('hooks/app', () => ({ + useORAConfigData: jest.fn(), +})); +jest.mock('../XBlockStudioViewProvider', () => ({ + useXBlockStudioViewContext: () => ({ + settingIsOpen: true, + toggleStudioViewSetting: jest.fn().mockName('toggleStudioViewSetting'), + }), +})); +jest.mock('./RequiredConfig', () => 'RequiredConfig'); +jest.mock('./FileUploadConfig', () => 'FileUploadConfig'); + +describe('+ + Criteria name: + + criterion1 +
++ + Criteria description: + + description1 +
++ + Criteria options: + +
++ description1 +
++ description2 +
++ + Criteria name: + + criterion2 +
++ + Criteria description: + + description2 +
++ + Criteria options: + +
++ description2 +
++ + Step + + 1 + : + + + Self assessment + +
++ + Step + + 2 + : + + + Peer assessment + +
+