diff --git a/src/components/Assessment/__snapshots__/index.test.jsx.snap b/src/components/Assessment/__snapshots__/index.test.jsx.snap deleted file mode 100644 index 763d745d..00000000 --- a/src/components/Assessment/__snapshots__/index.test.jsx.snap +++ /dev/null @@ -1,11 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` renders nothing if not initialized 1`] = `null`; - -exports[` renders the EditableAssessment 1`] = ``; - -exports[` renders the ReadonlyAssessment 1`] = ` - -`; diff --git a/src/components/Assessment/index.test.jsx b/src/components/Assessment/index.test.jsx index f43855e2..2954343c 100644 --- a/src/components/Assessment/index.test.jsx +++ b/src/components/Assessment/index.test.jsx @@ -1,38 +1,55 @@ -import { shallow } from '@edx/react-unit-test-utils'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import Assessment from './index'; - import { useAssessmentData } from './useAssessmentData'; +jest.unmock('@openedx/paragon'); +jest.unmock('react'); +jest.unmock('@edx/frontend-platform/i18n'); + jest.mock('./useAssessmentData', () => ({ useAssessmentData: jest.fn(), })); -jest.mock('./EditableAssessment', () => 'EditableAssessment'); -jest.mock('./ReadonlyAssessment', () => 'ReadonlyAssessment'); +jest.mock('./EditableAssessment', () => () =>
Editable Assessment
); + +jest.mock('./ReadonlyAssessment', () => () =>
Readonly Assessment
); + +const renderWithIntl = (component) => render({component}); describe('', () => { - it('renders the ReadonlyAssessment', () => { - useAssessmentData.mockReturnValue({ initialized: true, hasSubmitted: true }); - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders the ReadonlyAssessment when assessment has been submitted', () => { + useAssessmentData.mockReturnValue({ + initialized: true, + hasSubmitted: true, + }); + renderWithIntl(); - expect(wrapper.instance.findByType('ReadonlyAssessment')).toHaveLength(1); - expect(wrapper.instance.findByType('EditableAssessment')).toHaveLength(0); + expect(screen.getByText('Readonly Assessment')).toBeInTheDocument(); + expect(screen.queryByText('Editable Assessment')).not.toBeInTheDocument(); }); - it('renders the EditableAssessment', () => { - useAssessmentData.mockReturnValue({ initialized: true, hasSubmitted: false }); - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); - expect(wrapper.instance.findByType('ReadonlyAssessment')).toHaveLength(0); - expect(wrapper.instance.findByType('EditableAssessment')).toHaveLength(1); + it('renders the EditableAssessment when assessment has not been submitted', () => { + useAssessmentData.mockReturnValue({ + initialized: true, + hasSubmitted: false, + }); + renderWithIntl(); + + expect(screen.getByText('Editable Assessment')).toBeInTheDocument(); + expect(screen.queryByText('Readonly Assessment')).not.toBeInTheDocument(); }); - it('renders nothing if not initialized', () => { + + it('renders nothing when assessment data is not initialized', () => { useAssessmentData.mockReturnValue({ initialized: false }); - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); + const { container } = renderWithIntl(); - expect(wrapper.isEmptyRender()).toBe(true); + expect(container).toBeEmptyDOMElement(); }); }); diff --git a/src/components/ProgressBar/__snapshots__/index.test.jsx.snap b/src/components/ProgressBar/__snapshots__/index.test.jsx.snap deleted file mode 100644 index 6da556ee..00000000 --- a/src/components/ProgressBar/__snapshots__/index.test.jsx.snap +++ /dev/null @@ -1,111 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` renders all steps 1`] = ` - - -
- - - Create response - (Step 1/5) - - -
-
- -
- - - - - -
-
-`; - -exports[` renders at least 2 steps: submission and done 1`] = ` - - -
- - - Create response - (Step 1/2) - - -
-
- -
- - -
-
-`; - -exports[` renders null when page data is not loaded 1`] = `null`; diff --git a/src/components/ProgressBar/hooks.test.js b/src/components/ProgressBar/hooks.test.js index d18e702b..5c8ea016 100644 --- a/src/components/ProgressBar/hooks.test.js +++ b/src/components/ProgressBar/hooks.test.js @@ -57,12 +57,17 @@ describe('useProgressStepData', () => { isXblockStep.mockReturnValueOnce(true); const result = useProgressStepData(props); result.onClick(); - expect(mockOpenModal).toHaveBeenCalledWith({ view: stepNames.self, title: stepNames.self }); + expect(mockOpenModal).toHaveBeenCalledWith({ + view: stepNames.self, + title: stepNames.self, + }); }); it('should have href when is not xblock', () => { const result = useProgressStepData(props); - expect(result.href).toBe(`/${stepRoutes[stepNames.self]}/courseId/xblockId`); + expect(result.href).toBe( + `/${stepRoutes[stepNames.self]}/courseId/xblockId`, + ); }); it('is complete when step state is done', () => { @@ -99,12 +104,12 @@ describe('useProgressStepData', () => { expect(result.isEnabled).toBe(false); }); - it('use effect grade from global state', () => { + it('uses effective grade from global state', () => { const result = useProgressStepData(props); expect(result.myGrade).toBe(8); }); - test('for peer step is not enabled when waiting for submissions', () => { + it('disables peer step when waiting for submissions', () => { useStepInfo.mockReturnValue({ peer: { numberOfReceivedAssessments: 0, @@ -115,7 +120,7 @@ describe('useProgressStepData', () => { expect(result.isEnabled).toBe(false); }); - test('for peer step is enabled iif peer is complete and no waiting for submission', () => { + it('enables peer step when peer is complete and not waiting for submissions', () => { useStepInfo.mockReturnValue({ peer: { numberOfReceivedAssessments: 1, diff --git a/src/components/ProgressBar/index.test.jsx b/src/components/ProgressBar/index.test.jsx index 92413303..298cf7d5 100644 --- a/src/components/ProgressBar/index.test.jsx +++ b/src/components/ProgressBar/index.test.jsx @@ -1,4 +1,6 @@ -import { shallow } from '@edx/react-unit-test-utils'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { useAssessmentStepOrder, @@ -12,6 +14,12 @@ import { isXblockStep } from 'utils'; import ProgressBar from './index'; +/* eslint-disable react/prop-types */ + +jest.unmock('@openedx/paragon'); +jest.unmock('react'); +jest.unmock('@edx/frontend-platform/i18n'); + jest.mock('hooks/app', () => ({ useAssessmentStepOrder: jest.fn(), useGlobalState: jest.fn(), @@ -24,7 +32,12 @@ jest.mock('hooks/routing', () => ({ jest.mock('utils', () => ({ isXblockStep: jest.fn(), })); -jest.mock('./ProgressStep', () => 'ProgressStep'); + +jest.mock('./ProgressStep', () => ({ step }) => ( +
Progress Step {step}
+)); + +const renderWithIntl = (component) => render({component}); describe('', () => { const props = { @@ -32,37 +45,41 @@ describe('', () => { }; beforeEach(() => { - useIsPageDataLoaded.mockReturnValue(true); + jest.clearAllMocks(); + }); + + it('renders null when page data is not loaded', () => { + useIsPageDataLoaded.mockReturnValue(false); useHasReceivedFinalGrade.mockReturnValue(false); useGlobalState.mockReturnValue({ activeStepName: stepNames.submission }); useAssessmentStepOrder.mockReturnValue([]); useViewStep.mockReturnValue(stepNames.submission); isXblockStep.mockReturnValue(false); - }); - it('renders null when page data is not loaded', () => { - useIsPageDataLoaded.mockReturnValueOnce(false); - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); - - expect(wrapper.isEmptyRender()).toBe(true); - }); - - it('renders at least 2 steps: submission and done', () => { - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); - expect(wrapper.instance.findByType('ProgressStep')).toHaveLength(2); + renderWithIntl(); + expect(screen.queryByRole('navigation')).not.toBeInTheDocument(); }); - it('renders all steps', () => { - isXblockStep.mockReturnValueOnce(true); - useAssessmentStepOrder.mockReturnValueOnce([ + it('renders all steps when xblock step with assessment order', () => { + useIsPageDataLoaded.mockReturnValue(true); + useHasReceivedFinalGrade.mockReturnValue(false); + useGlobalState.mockReturnValue({ activeStepName: stepNames.submission }); + useAssessmentStepOrder.mockReturnValue([ stepNames.studentTraining, stepNames.self, stepNames.peer, ]); - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); - expect(wrapper.instance.findByType('ProgressStep')).toHaveLength(5); + useViewStep.mockReturnValue(stepNames.submission); + isXblockStep.mockReturnValue(true); + + renderWithIntl(); + + expect(screen.getByText('Progress Step submission')).toBeInTheDocument(); + expect( + screen.getByText('Progress Step studentTraining'), + ).toBeInTheDocument(); + expect(screen.getByText('Progress Step self')).toBeInTheDocument(); + expect(screen.getByText('Progress Step peer')).toBeInTheDocument(); + expect(screen.getByText('Progress Step done')).toBeInTheDocument(); }); }); diff --git a/src/views/GradeView/Content.test.jsx b/src/views/GradeView/Content.test.jsx index c08924fc..dbab1bdb 100644 --- a/src/views/GradeView/Content.test.jsx +++ b/src/views/GradeView/Content.test.jsx @@ -1,36 +1,75 @@ -import { shallow } from '@edx/react-unit-test-utils'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { usePrompts, useResponseData, useEffectiveGradeStep } from 'hooks/app'; import { stepNames } from 'constants/index'; import Content from './Content'; +/* eslint-disable react/prop-types */ + +jest.unmock('@openedx/paragon'); +jest.unmock('react'); +jest.unmock('@edx/frontend-platform/i18n'); + jest.mock('hooks/app', () => ({ usePrompts: jest.fn(), useResponseData: jest.fn(), useEffectiveGradeStep: jest.fn(), })); -jest.mock('components/FileUpload', () => 'FileUpload'); -jest.mock('components/Prompt', () => 'Prompt'); -jest.mock('components/TextResponse', () => 'TextResponse'); + +jest.mock('components/FileUpload', () => () =>
File Upload
); + +jest.mock('components/Prompt', () => ({ prompt }) => ( +
Prompt: {prompt}
+)); + +jest.mock('components/TextResponse', () => ({ response }) => ( +
Text Response: {response}
+)); + +const renderWithIntl = (component) => render({component}); describe('', () => { - it('render without prompt and effectiveGradeStep is not peer', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders without prompts when effectiveGradeStep is not peer', () => { usePrompts.mockReturnValue([]); useResponseData.mockReturnValue({ textResponses: [], uploadedFiles: [] }); useEffectiveGradeStep.mockReturnValue(stepNames.self); - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); + + renderWithIntl(); + + expect(screen.queryByText(/^Prompt:/)).not.toBeInTheDocument(); + expect(screen.queryByText(/^Text Response:/)).not.toBeInTheDocument(); + expect(screen.getByText('File Upload')).toBeInTheDocument(); + expect(screen.queryByText(/peer/i)).not.toBeInTheDocument(); }); - it('render with prompt, textResponse and effectiveGradeStep is peer', () => { + it('renders prompts and responses when effectiveGradeStep is peer', () => { usePrompts.mockReturnValue(['prompt1', 'prompt2']); useResponseData.mockReturnValue({ textResponses: ['text response 1', 'text response 2'], uploadedFiles: ['upload'], }); useEffectiveGradeStep.mockReturnValue(stepNames.peer); - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); + + renderWithIntl(); + + expect(screen.getByText('Prompt: prompt1')).toBeInTheDocument(); + expect(screen.getByText('Prompt: prompt2')).toBeInTheDocument(); + + expect( + screen.getByText('Text Response: text response 1'), + ).toBeInTheDocument(); + expect( + screen.getByText('Text Response: text response 2'), + ).toBeInTheDocument(); + + expect(screen.getByText('File Upload')).toBeInTheDocument(); + expect(screen.getByText(/peer/i)).toBeInTheDocument(); }); }); diff --git a/src/views/GradeView/FinalGrade.test.jsx b/src/views/GradeView/FinalGrade.test.jsx index aac5526d..fd209bcd 100644 --- a/src/views/GradeView/FinalGrade.test.jsx +++ b/src/views/GradeView/FinalGrade.test.jsx @@ -1,45 +1,56 @@ -import { shallow } from '@edx/react-unit-test-utils'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; -import { - useAssessmentData, - useStepInfo, -} from 'hooks/app'; +import { useAssessmentData, useStepInfo } from 'hooks/app'; import { stepNames } from 'constants/index'; import FinalGrade from './FinalGrade'; +/* eslint-disable react/prop-types */ + +jest.unmock('@openedx/paragon'); +jest.unmock('react'); +jest.unmock('@edx/frontend-platform/i18n'); + jest.mock('hooks/app', () => ({ useAssessmentData: jest.fn(), useStepInfo: jest.fn(), })); -jest.mock('components/InfoPopover', () => 'InfoPopover'); -jest.mock('components/Assessment/ReadonlyAssessment', () => 'ReadOnlyAssessment'); + +jest.mock('components/Assessment/ReadonlyAssessment', () => ({ step }) => ( +
Readonly Assessment {step}
+)); + +const renderWithIntl = (component) => render({component}); describe('', () => { - const mockUseAssessmentData = { - effectiveAssessmentType: stepNames.self, - [stepNames.self]: { - stepScore: 1, - }, - [stepNames.peer]: { - stepScore: 2, - }, - }; - - it('self and peer grades', () => { - useAssessmentData.mockReturnValue(mockUseAssessmentData); + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders both self and peer assessments when both are available', () => { + useAssessmentData.mockReturnValue({ + effectiveAssessmentType: stepNames.self, + [stepNames.self]: { + stepScore: 1, + }, + [stepNames.peer]: { + stepScore: 2, + }, + }); useStepInfo.mockReturnValue({ [stepNames.self]: true, [stepNames.peer]: true, }); - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); + renderWithIntl(); - expect(wrapper.instance.findByType('ReadOnlyAssessment')).toHaveLength(2); + expect(screen.getByText('Readonly Assessment self')).toBeInTheDocument(); + expect(screen.getByText('Readonly Assessment peer')).toBeInTheDocument(); }); - it('peer only', () => { + it('renders only peer assessment when self is not available', () => { useAssessmentData.mockReturnValue({ effectiveAssessmentType: stepNames.peer, [stepNames.peer]: { @@ -51,9 +62,11 @@ describe('', () => { [stepNames.peer]: true, }); - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); + renderWithIntl(); - expect(wrapper.instance.findByType('ReadOnlyAssessment')).toHaveLength(1); + expect(screen.getByText('Readonly Assessment peer')).toBeInTheDocument(); + expect( + screen.queryByText('Readonly Assessment self'), + ).not.toBeInTheDocument(); }); }); diff --git a/src/views/GradeView/__snapshots__/Content.test.jsx.snap b/src/views/GradeView/__snapshots__/Content.test.jsx.snap deleted file mode 100644 index bc9a15de..00000000 --- a/src/views/GradeView/__snapshots__/Content.test.jsx.snap +++ /dev/null @@ -1,99 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` render with prompt, textResponse and effectiveGradeStep is peer 1`] = ` -
- - About your grade: - -

- 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 response -

- -
-
- -

- Your response -

- -
- -
-
-`; - -exports[` render without prompt and effectiveGradeStep is not peer 1`] = ` -
- - About your grade: - -

- Your grade is based on your Self assessment score for this problem. Other assessments don't count towards your final score. -

-
- -
-
-`; diff --git a/src/views/GradeView/__snapshots__/FinalGrade.test.jsx.snap b/src/views/GradeView/__snapshots__/FinalGrade.test.jsx.snap deleted file mode 100644 index c7017d75..00000000 --- a/src/views/GradeView/__snapshots__/FinalGrade.test.jsx.snap +++ /dev/null @@ -1,70 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` peer only 1`] = ` -
-

- Your final grade: {earned}/{possible} - -

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

-
-

-
- -
-
-
-`; - -exports[` self and peer grades 1`] = ` -
-

- Your final grade: {earned}/{possible} - -

- Your grade is based on your self score for this problem. Other assessments don't count towards your final score. -

-
-

-
- -
-
-

- Unweighted grades - -

- These grades are given to your response. However, these are not used to compute your final grade. -

-
-

- -
-`; diff --git a/src/views/SubmissionView/__snapshots__/index.test.jsx.snap b/src/views/SubmissionView/__snapshots__/index.test.jsx.snap deleted file mode 100644 index 494064e7..00000000 --- a/src/views/SubmissionView/__snapshots__/index.test.jsx.snap +++ /dev/null @@ -1,112 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` renders disable show rubric 1`] = ` -
-
- - -
-
-

- Your response -

-
- - - - -
- - -
-
-
-`; - -exports[` renders enable show rubric 1`] = ` -
-
- - -
-
-

- Your response -

-
- - - - -
- - - -
-
-
-`; diff --git a/src/views/SubmissionView/index.test.jsx b/src/views/SubmissionView/index.test.jsx index 427fcf18..17ff8a48 100644 --- a/src/views/SubmissionView/index.test.jsx +++ b/src/views/SubmissionView/index.test.jsx @@ -1,17 +1,34 @@ -import { shallow } from '@edx/react-unit-test-utils'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import useSubmissionViewData from './hooks'; - import SubmissionView from './index'; -jest.mock('components/Rubric', () => 'Rubric'); -jest.mock('components/ModalActions', () => 'ModalActions'); -jest.mock('components/FileUpload', () => 'FileUpload'); -jest.mock('components/Instructions', () => 'Instructions'); -jest.mock('components/StatusAlert', () => 'StatusAlert'); -jest.mock('./SubmissionPrompts', () => 'SubmissionPrompts'); +jest.unmock('@openedx/paragon'); +jest.unmock('react'); +jest.unmock('@edx/frontend-platform/i18n'); + +jest.mock('components/Rubric', () => () =>
Rubric
); +jest.mock('components/ModalActions', () => () => ( +
Modal Actions
+)); +jest.mock('components/FileUpload', () => () => ( +
File Upload
+)); +jest.mock('components/Instructions', () => () => ( +
Instructions
+)); +jest.mock('components/StatusAlert', () => () => ( +
Status Alert
+)); +jest.mock('./SubmissionPrompts', () => () => ( +
Submission Prompts
+)); jest.mock('./hooks', () => jest.fn()); +const renderWithIntl = (component) => render({component}); + describe('', () => { const mockUseSubmissionViewData = { actionOptions: { @@ -28,20 +45,29 @@ describe('', () => { onFileUploaded: jest.fn(), isReadOnly: false, }; - useSubmissionViewData.mockReturnValue(mockUseSubmissionViewData); - it('renders disable show rubric', () => { - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); + beforeEach(() => { + jest.clearAllMocks(); + useSubmissionViewData.mockReturnValue(mockUseSubmissionViewData); + }); + + it('does not render rubric when showRubric is false', () => { + renderWithIntl(); - expect(wrapper.instance.findByType('Rubric').length).toBe(0); + expect(screen.queryByText('Rubric')).not.toBeInTheDocument(); + expect(screen.getByText('Modal Actions')).toBeInTheDocument(); + expect(screen.getByText('Submission Prompts')).toBeInTheDocument(); }); - it('renders enable show rubric', () => { - mockUseSubmissionViewData.showRubric = true; - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); + it('renders rubric when showRubric is true', () => { + useSubmissionViewData.mockReturnValue({ + ...mockUseSubmissionViewData, + showRubric: true, + }); + renderWithIntl(); - expect(wrapper.instance.findByType('Rubric').length).toBe(1); + expect(screen.getByText('Rubric')).toBeInTheDocument(); + expect(screen.getByText('Modal Actions')).toBeInTheDocument(); + expect(screen.getByText('Submission Prompts')).toBeInTheDocument(); }); });