From a579455e580c0ce1a5f327a6a94a806c976445fa Mon Sep 17 00:00:00 2001
From: Diana Villalvazo
Date: Fri, 5 Sep 2025 10:34:28 -0600
Subject: [PATCH] test: Remove unwanted mocks, unmocks and deprecate
react-unit-test-utils package (#465)
* test: remove last snapshot
* test: remove unwanted mocks, remove unmocks, refactor renderWithIntl
* test: refactor renderWithIntl with small improvements
* test: remove react-unit-test-utils
* test: change fireEvent for userEvent
---
package-lock.json | 49 ++------
package.json | 1 -
src/App.test.jsx | 14 +--
src/__snapshots__/index.test.jsx.snap | 28 -----
src/components/ConfirmModal.test.jsx | 11 +-
src/components/DemoAlert/index.test.jsx | 27 +++--
.../FilePopoverContent/index.test.jsx | 23 ++--
.../FilePreview/Banners/ErrorBanner.test.jsx | 20 ++--
.../Banners/LoadingBanner.test.jsx | 3 -
.../BaseRenderers/ImageRenderer.test.jsx | 3 -
.../BaseRenderers/PDFRenderer.test.jsx | 3 -
.../BaseRenderers/TXTRenderer.test.jsx | 3 -
.../BaseRenderers/pdfHooks.test.js | 5 +
.../BaseRenderers/textHooks.test.js | 5 +
src/components/FilePreview/FileCard.test.jsx | 2 -
src/components/FilePreview/FileInfo.test.jsx | 16 ++-
.../FilePreview/FileRenderer.test.jsx | 12 +-
src/components/Head/index.test.jsx | 3 -
src/components/InfoPopover/index.test.jsx | 12 +-
src/components/StatusBadge.test.jsx | 25 ++---
.../CriterionFeedback.test.jsx | 16 ++-
.../RadioCriterion.test.jsx | 16 ++-
.../ReviewCriterion.test.jsx | 12 +-
.../CriterionContainer/index.test.jsx | 3 -
.../DemoWarning/DemoWarning.test.jsx | 4 -
.../ListView/EmptySubmission.test.jsx | 30 ++---
.../ListView/FilterStatusComponent.test.jsx | 3 -
src/containers/ListView/ListError.test.jsx | 16 +--
.../ListView/ListViewBreadcrumb.test.jsx | 36 +++---
.../ListView/SelectedBulkAction.test.jsx | 14 +--
.../ListView/SubmissionsTable.test.jsx | 18 +--
src/containers/ListView/TableAction.test.jsx | 18 ++-
src/containers/ListView/index.test.jsx | 24 ++--
.../ResponseDisplay/FileDownload.test.jsx | 19 ++--
.../ResponseDisplay/PreviewDisplay.test.jsx | 30 ++---
.../ResponseDisplay/SubmissionFiles.test.jsx | 18 +--
.../components/FileExtensionCell.test.jsx | 17 ++-
.../components/FilePopoverCell.test.jsx | 32 +-----
src/containers/ResponseDisplay/index.test.jsx | 3 -
.../OverrideGradeConfirmModal.test.jsx | 23 ++--
.../StartGradingButton/index.test.jsx | 14 +--
.../StopGradingConfirmModal.test.jsx | 13 +--
.../components/SubmissionNavigation.test.jsx | 25 +----
src/containers/ReviewActions/index.test.jsx | 14 +--
.../ReviewModal/ReviewContent.test.jsx | 18 +--
.../ReviewErrors/DownloadErrors.test.jsx | 14 +--
.../ReviewErrors/FetchErrors.test.jsx | 15 +--
.../ReviewErrors/LockErrors.test.jsx | 15 +--
.../ReviewErrors/ReviewError.test.jsx | 14 +--
.../ReviewErrors/SubmitErrors/index.test.jsx | 14 +--
.../ReviewModal/ReviewErrors/index.test.jsx | 13 +--
.../CloseReviewConfirmModal.test.jsx | 24 ++--
src/containers/ReviewModal/index.test.jsx | 16 +--
src/containers/Rubric/RubricFeedback.test.jsx | 14 +--
src/containers/Rubric/index.test.jsx | 38 +++----
src/index.test.jsx | 4 -
src/setupTest.js | 106 ------------------
src/test/app.test.jsx | 4 -
src/{testUtils.js => testUtils.jsx} | 9 ++
59 files changed, 266 insertions(+), 735 deletions(-)
delete mode 100644 src/__snapshots__/index.test.jsx.snap
rename src/{testUtils.js => testUtils.jsx} (94%)
diff --git a/package-lock.json b/package-lock.json
index 7c102e3..ee69661 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -58,7 +58,6 @@
},
"devDependencies": {
"@edx/browserslist-config": "^1.3.0",
- "@edx/react-unit-test-utils": "^4.0.0",
"@edx/reactifex": "^2.1.1",
"@openedx/frontend-build": "^14.3.3",
"@testing-library/jest-dom": "^6.6.3",
@@ -2679,44 +2678,6 @@
"atlas": "atlas"
}
},
- "node_modules/@edx/react-unit-test-utils": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@edx/react-unit-test-utils/-/react-unit-test-utils-4.0.0.tgz",
- "integrity": "sha512-QlVYhYD9L2bzx1eAtf8BbCJr00ek9rrHrG+/pW2bVSt+t0uvKHQpX1CNdMrDePv18DsMeC7IOB00t8ZIn4mi7w==",
- "dev": true,
- "license": "AGPL-3.0",
- "dependencies": {
- "@edx/browserslist-config": "^1.1.1",
- "@reduxjs/toolkit": "^1.5.1",
- "@testing-library/dom": "^10.4.0",
- "@testing-library/jest-dom": "^6.6.3",
- "@testing-library/react": "^16.2.0",
- "classnames": "^2.2.6",
- "core-js": "3.6.5",
- "lodash": "^4.17.21",
- "react-dev-utils": "^12.0.1",
- "react-test-renderer": "^18.3.1"
- },
- "peerDependencies": {
- "@edx/frontend-platform": "^8.3.1",
- "@openedx/frontend-build": "^14.3.0",
- "@openedx/paragon": "^22.0.0 || ^23.0.0",
- "react": "^18.0.0"
- }
- },
- "node_modules/@edx/react-unit-test-utils/node_modules/core-js": {
- "version": "3.6.5",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
- "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==",
- "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/core-js"
- }
- },
"node_modules/@edx/reactifex": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@edx/reactifex/-/reactifex-2.2.0.tgz",
@@ -5351,6 +5312,7 @@
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
"integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
@@ -5506,7 +5468,8 @@
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/@types/babel__core": {
"version": "7.20.5",
@@ -9475,7 +9438,8 @@
"version": "0.5.16",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/dom-converter": {
"version": "0.2.0",
@@ -15292,6 +15256,7 @@
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
"license": "MIT",
+ "peer": true,
"bin": {
"lz-string": "bin/bin.js"
}
@@ -17761,6 +17726,7 @@
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0",
@@ -17775,6 +17741,7 @@
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=10"
},
diff --git a/package.json b/package.json
index 3666ebf..f8ec83d 100755
--- a/package.json
+++ b/package.json
@@ -76,7 +76,6 @@
},
"devDependencies": {
"@edx/browserslist-config": "^1.3.0",
- "@edx/react-unit-test-utils": "^4.0.0",
"@edx/reactifex": "^2.1.1",
"@openedx/frontend-build": "^14.3.3",
"@testing-library/jest-dom": "^6.6.3",
diff --git a/src/App.test.jsx b/src/App.test.jsx
index 364a377..aa86ae4 100644
--- a/src/App.test.jsx
+++ b/src/App.test.jsx
@@ -1,12 +1,8 @@
-import { render, screen } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
import { selectors } from 'data/redux';
+import { renderWithIntl } from './testUtils';
import { App, mapStateToProps } from './App';
-jest.unmock('react');
-jest.unmock('@openedx/paragon');
-jest.unmock('@edx/frontend-platform/i18n');
-
// we want to scope these tests to the App component, so we mock some child components to reduce complexity
jest.mock('@edx/frontend-platform/auth', () => ({
@@ -39,12 +35,6 @@ jest.mock('data/redux', () => ({
},
}));
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('App component', () => {
const defaultProps = {
courseMetadata: {
diff --git a/src/__snapshots__/index.test.jsx.snap b/src/__snapshots__/index.test.jsx.snap
deleted file mode 100644
index a5904fa..0000000
--- a/src/__snapshots__/index.test.jsx.snap
+++ /dev/null
@@ -1,28 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`app registry subscribe: APP_INIT_ERROR. snapshot: displays an ErrorPage to root element 1`] = `
-
-
-
-`;
-
-exports[`app registry subscribe: APP_READY. links App to root element 1`] = `
-
-
-
-
-
-`;
diff --git a/src/components/ConfirmModal.test.jsx b/src/components/ConfirmModal.test.jsx
index b85118a..03e6cd3 100644
--- a/src/components/ConfirmModal.test.jsx
+++ b/src/components/ConfirmModal.test.jsx
@@ -2,9 +2,6 @@ import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ConfirmModal } from './ConfirmModal';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
describe('ConfirmModal', () => {
const props = {
isOpen: false,
@@ -21,13 +18,13 @@ describe('ConfirmModal', () => {
});
it('should not render content when modal is closed', () => {
- const { queryByText } = render();
- expect(queryByText(props.content)).toBeNull();
+ render();
+ expect(screen.queryByText(props.content)).toBeNull();
});
it('should display content when modal is open', () => {
- const { getByText } = render();
- expect(getByText(props.content)).toBeInTheDocument();
+ render();
+ expect(screen.getByText(props.content)).toBeInTheDocument();
});
it('should call onCancel when cancel button is clicked', async () => {
diff --git a/src/components/DemoAlert/index.test.jsx b/src/components/DemoAlert/index.test.jsx
index 604d7e5..25a08f4 100644
--- a/src/components/DemoAlert/index.test.jsx
+++ b/src/components/DemoAlert/index.test.jsx
@@ -1,12 +1,10 @@
-import { render, fireEvent } from '@testing-library/react';
+import { screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import { renderWithIntl } from '../../testUtils';
-import { formatMessage } from 'testUtils';
import messages from './messages';
import { DemoAlert } from '.';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
describe('DemoAlert component', () => {
const props = {
isOpen: true,
@@ -14,20 +12,21 @@ describe('DemoAlert component', () => {
};
it('does not render when isOpen is false', () => {
- const { queryByText } = render();
- expect(queryByText(formatMessage(messages.title))).toBeNull();
+ renderWithIntl();
+ expect(screen.queryByText(messages.title.defaultMessage)).toBeNull();
});
it('renders with correct title and message when isOpen is true', () => {
- const { getByText } = render();
- expect(getByText(formatMessage(messages.title))).toBeInTheDocument();
- expect(getByText(formatMessage(messages.warningMessage))).toBeInTheDocument();
+ renderWithIntl();
+ expect(screen.getByText(messages.title.defaultMessage)).toBeInTheDocument();
+ expect(screen.getByText(messages.warningMessage.defaultMessage)).toBeInTheDocument();
});
- it('calls onClose when confirmation button is clicked', () => {
- const { getByText } = render();
- const confirmButton = getByText(formatMessage(messages.confirm));
- fireEvent.click(confirmButton);
+ it('calls onClose when confirmation button is clicked', async () => {
+ renderWithIntl();
+ const user = userEvent.setup();
+ const confirmButton = screen.getByText(messages.confirm.defaultMessage);
+ await user.click(confirmButton);
expect(props.onClose).toHaveBeenCalled();
});
});
diff --git a/src/components/FilePopoverContent/index.test.jsx b/src/components/FilePopoverContent/index.test.jsx
index 1ca1eea..85c238a 100644
--- a/src/components/FilePopoverContent/index.test.jsx
+++ b/src/components/FilePopoverContent/index.test.jsx
@@ -1,11 +1,10 @@
-import { render } from '@testing-library/react';
-
+import { screen } from '@testing-library/react';
import filesize from 'filesize';
+import { renderWithIntl } from '../../testUtils';
+
import FilePopoverContent from '.';
jest.mock('filesize', () => (size) => `filesize(${size})`);
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
describe('FilePopoverContent', () => {
describe('component', () => {
@@ -18,23 +17,23 @@ describe('FilePopoverContent', () => {
describe('behavior', () => {
it('renders file name correctly', () => {
- const { getByText } = render();
- expect(getByText(props.name)).toBeInTheDocument();
+ renderWithIntl();
+ expect(screen.getByText(props.name)).toBeInTheDocument();
});
it('renders file description correctly', () => {
- const { getByText } = render();
- expect(getByText(props.description)).toBeInTheDocument();
+ renderWithIntl();
+ expect(screen.getByText(props.description)).toBeInTheDocument();
});
it('renders file size correctly', () => {
- const { getByText } = render();
- expect(getByText(filesize(props.size))).toBeInTheDocument();
+ renderWithIntl();
+ expect(screen.getByText(filesize(props.size))).toBeInTheDocument();
});
it('renders "Unknown" when size is null', () => {
- const { getByText } = render();
- expect(getByText('Unknown')).toBeInTheDocument();
+ renderWithIntl();
+ expect(screen.getByText('Unknown')).toBeInTheDocument();
});
});
});
diff --git a/src/components/FilePreview/Banners/ErrorBanner.test.jsx b/src/components/FilePreview/Banners/ErrorBanner.test.jsx
index 990c938..b975445 100644
--- a/src/components/FilePreview/Banners/ErrorBanner.test.jsx
+++ b/src/components/FilePreview/Banners/ErrorBanner.test.jsx
@@ -1,10 +1,8 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
+import { renderWithIntl } from '../../../testUtils';
import ErrorBanner from './ErrorBanner';
import messages from '../messages';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
describe('Error Banner component', () => {
const children = Abitary Child
;
@@ -27,25 +25,25 @@ describe('Error Banner component', () => {
describe('behavior', () => {
it('renders children content', () => {
- render();
+ renderWithIntl();
const childText = screen.getByText('Abitary Child');
expect(childText).toBeInTheDocument();
});
it('renders the correct number of action buttons', () => {
- render();
- const buttons = screen.getAllByText('FormattedMessage');
- expect(buttons).toHaveLength(3);
+ renderWithIntl();
+ const buttons = screen.getAllByText(messages.retryButton.defaultMessage);
+ expect(buttons).toHaveLength(2);
});
it('renders error heading with correct message', () => {
- render();
- const heading = screen.getAllByText('FormattedMessage')[0];
+ renderWithIntl();
+ const heading = screen.getAllByText(messages.unknownError.defaultMessage)[0];
expect(heading).toBeInTheDocument();
});
it('renders with danger variant', () => {
- render();
+ renderWithIntl();
const alert = screen.getByRole('alert');
expect(alert).toHaveClass('alert-danger');
});
diff --git a/src/components/FilePreview/Banners/LoadingBanner.test.jsx b/src/components/FilePreview/Banners/LoadingBanner.test.jsx
index f0abfb3..94c1c6b 100644
--- a/src/components/FilePreview/Banners/LoadingBanner.test.jsx
+++ b/src/components/FilePreview/Banners/LoadingBanner.test.jsx
@@ -1,9 +1,6 @@
import { render, screen } from '@testing-library/react';
import LoadingBanner from './LoadingBanner';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
describe('Loading Banner component', () => {
describe('behavior', () => {
it('renders an info alert', () => {
diff --git a/src/components/FilePreview/BaseRenderers/ImageRenderer.test.jsx b/src/components/FilePreview/BaseRenderers/ImageRenderer.test.jsx
index d558318..884182b 100644
--- a/src/components/FilePreview/BaseRenderers/ImageRenderer.test.jsx
+++ b/src/components/FilePreview/BaseRenderers/ImageRenderer.test.jsx
@@ -3,9 +3,6 @@ import { render, screen } from '@testing-library/react';
import ImageRenderer from './ImageRenderer';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
describe('Image Renderer Component', () => {
const props = {
url: 'some_url.jpg',
diff --git a/src/components/FilePreview/BaseRenderers/PDFRenderer.test.jsx b/src/components/FilePreview/BaseRenderers/PDFRenderer.test.jsx
index fc8cc80..54184f2 100644
--- a/src/components/FilePreview/BaseRenderers/PDFRenderer.test.jsx
+++ b/src/components/FilePreview/BaseRenderers/PDFRenderer.test.jsx
@@ -21,9 +21,6 @@ jest.mock('./pdfHooks', () => ({
rendererHooks: jest.fn(),
}));
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
describe('PDF Renderer Component', () => {
const props = {
url: 'some_url.pdf',
diff --git a/src/components/FilePreview/BaseRenderers/TXTRenderer.test.jsx b/src/components/FilePreview/BaseRenderers/TXTRenderer.test.jsx
index 46ee11f..b65a648 100644
--- a/src/components/FilePreview/BaseRenderers/TXTRenderer.test.jsx
+++ b/src/components/FilePreview/BaseRenderers/TXTRenderer.test.jsx
@@ -8,9 +8,6 @@ jest.mock('./textHooks', () => {
};
});
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
const textHooks = require('./textHooks');
describe('TXT Renderer Component', () => {
diff --git a/src/components/FilePreview/BaseRenderers/pdfHooks.test.js b/src/components/FilePreview/BaseRenderers/pdfHooks.test.js
index bbe7b02..c0ad5ab 100644
--- a/src/components/FilePreview/BaseRenderers/pdfHooks.test.js
+++ b/src/components/FilePreview/BaseRenderers/pdfHooks.test.js
@@ -12,6 +12,11 @@ jest.mock('react-pdf', () => ({
Page: () => 'Page',
}));
+jest.mock('react', () => ({
+ ...jest.requireActual('react'),
+ useRef: jest.fn((val) => ({ current: val, useRef: true })),
+}));
+
const state = new MockUseState(hooks);
const hookKeys = keyStore(hooks);
diff --git a/src/components/FilePreview/BaseRenderers/textHooks.test.js b/src/components/FilePreview/BaseRenderers/textHooks.test.js
index f0a2c87..09a84bf 100644
--- a/src/components/FilePreview/BaseRenderers/textHooks.test.js
+++ b/src/components/FilePreview/BaseRenderers/textHooks.test.js
@@ -10,6 +10,11 @@ jest.mock('axios', () => ({
get: jest.fn(),
}));
+jest.mock('react', () => ({
+ ...jest.requireActual('react'),
+ useEffect: jest.fn((cb, prereqs) => ({ useEffect: { cb, prereqs } })),
+}));
+
const hookKeys = keyStore(hooks);
const state = new MockUseState(hooks);
diff --git a/src/components/FilePreview/FileCard.test.jsx b/src/components/FilePreview/FileCard.test.jsx
index 8eb9bd9..59b1133 100644
--- a/src/components/FilePreview/FileCard.test.jsx
+++ b/src/components/FilePreview/FileCard.test.jsx
@@ -3,8 +3,6 @@ import FileCard from './FileCard';
jest.mock('components/FilePopoverContent', () => 'FilePopoverContent');
jest.mock('./FileInfo', () => 'FileInfo');
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
describe('File Preview Card component', () => {
const props = {
diff --git a/src/components/FilePreview/FileInfo.test.jsx b/src/components/FilePreview/FileInfo.test.jsx
index c0f7d36..8736bef 100644
--- a/src/components/FilePreview/FileInfo.test.jsx
+++ b/src/components/FilePreview/FileInfo.test.jsx
@@ -1,10 +1,9 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
+import { renderWithIntl } from '../../testUtils';
import FileInfo from './FileInfo';
-
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
+import messages from './messages';
describe('FileInfo component', () => {
const children = (some Children
);
@@ -16,15 +15,14 @@ describe('FileInfo component', () => {
describe('Component rendering', () => {
it('renders the FileInfo button with correct text', () => {
- render({children});
-
- expect(screen.getByText('FormattedMessage')).toBeInTheDocument();
+ renderWithIntl({children});
+ expect(screen.getByText(messages.fileInfo.defaultMessage)).toBeInTheDocument();
});
it('calls onClick when button is clicked', async () => {
- render({children});
+ renderWithIntl({children});
const user = userEvent.setup();
- await user.click(screen.getByText('FormattedMessage'));
+ await user.click(screen.getByText(messages.fileInfo.defaultMessage));
expect(props.onClick).toHaveBeenCalledTimes(1);
});
});
diff --git a/src/components/FilePreview/FileRenderer.test.jsx b/src/components/FilePreview/FileRenderer.test.jsx
index 08e1e22..80a786e 100644
--- a/src/components/FilePreview/FileRenderer.test.jsx
+++ b/src/components/FilePreview/FileRenderer.test.jsx
@@ -1,12 +1,10 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import { keyStore } from 'utils';
import { ErrorStatuses } from 'data/constants/requests';
+import { renderWithIntl } from '../../testUtils';
import { FileRenderer } from './FileRenderer';
import * as hooks from './hooks';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
const hookKeys = keyStore(hooks);
const props = {
@@ -27,7 +25,7 @@ describe('FileRenderer', () => {
rendererProps: { prop: 'hooks.rendererProps' },
};
jest.spyOn(hooks, hookKeys.renderHooks).mockReturnValueOnce(hookProps);
- render();
+ renderWithIntl();
expect(screen.getByText('filename.txt')).toBeInTheDocument();
expect(screen.getByTestId('mock-renderer')).toBeInTheDocument();
@@ -50,7 +48,7 @@ describe('FileRenderer', () => {
};
jest.spyOn(hooks, hookKeys.renderHooks).mockReturnValueOnce(hookProps);
- render();
+ renderWithIntl();
expect(screen.getByText('filename.txt')).toBeInTheDocument();
expect(screen.getByText('Error Message')).toBeInTheDocument();
@@ -68,7 +66,7 @@ describe('FileRenderer', () => {
};
jest.spyOn(hooks, hookKeys.renderHooks).mockReturnValueOnce(hookProps);
- render();
+ renderWithIntl();
expect(screen.getByText('filename.txt')).toBeInTheDocument();
expect(screen.getByTestId('mock-renderer')).toBeInTheDocument();
diff --git a/src/components/Head/index.test.jsx b/src/components/Head/index.test.jsx
index d1d8d55..1cd2876 100644
--- a/src/components/Head/index.test.jsx
+++ b/src/components/Head/index.test.jsx
@@ -27,9 +27,6 @@ jest.mock('@edx/frontend-platform', () => ({
}),
}));
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
describe('Head', () => {
it('should render page title with site name from config', () => {
const { container } = render();
diff --git a/src/components/InfoPopover/index.test.jsx b/src/components/InfoPopover/index.test.jsx
index 2fab2a3..f8d1f97 100644
--- a/src/components/InfoPopover/index.test.jsx
+++ b/src/components/InfoPopover/index.test.jsx
@@ -1,26 +1,24 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
+import { renderWithIntl } from '../../testUtils';
import { InfoPopover } from '.';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
describe('Info Popover Component', () => {
const child =
RadioCriterion Component (orderNum={orderNum}, isGrading={String(isGrading)})
diff --git a/src/containers/DemoWarning/DemoWarning.test.jsx b/src/containers/DemoWarning/DemoWarning.test.jsx
index 2542555..34b00e5 100644
--- a/src/containers/DemoWarning/DemoWarning.test.jsx
+++ b/src/containers/DemoWarning/DemoWarning.test.jsx
@@ -4,10 +4,6 @@ import { selectors } from 'data/redux';
import { DemoWarning, mapStateToProps } from '.';
import messages from './messages';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('data/redux', () => ({
selectors: {
app: { isEnabled: (args) => ({ isEnabled: args }) },
diff --git a/src/containers/ListView/EmptySubmission.test.jsx b/src/containers/ListView/EmptySubmission.test.jsx
index 2bff790..7506169 100644
--- a/src/containers/ListView/EmptySubmission.test.jsx
+++ b/src/containers/ListView/EmptySubmission.test.jsx
@@ -1,12 +1,8 @@
-import { render } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
import urls from 'data/services/lms/urls';
+import { renderWithIntl } from '../../testUtils';
import EmptySubmission from './EmptySubmission';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('data/services/lms/urls', () => ({
openResponse: (courseId) => `openResponseUrl(${courseId})`,
}));
@@ -16,25 +12,19 @@ jest.mock('./assets/empty-state.svg', () => './assets/empty-state.svg');
describe('EmptySubmission component', () => {
const props = { courseId: 'test-course-id' };
- const renderWithIntl = (component) => render(
-
- {component}
- ,
- );
-
it('renders the empty state image with correct alt text', () => {
- const { getByAltText } = renderWithIntl(
);
- expect(getByAltText('empty state')).toBeInTheDocument();
+ renderWithIntl(
);
+ expect(screen.getByAltText('empty state')).toBeInTheDocument();
});
it('renders the no results found title message', () => {
- const { getByText } = renderWithIntl(
);
- expect(getByText('Nothing here yet')).toBeInTheDocument();
+ renderWithIntl(
);
+ expect(screen.getByText('Nothing here yet')).toBeInTheDocument();
});
it('renders hyperlink with correct destination URL', () => {
- const { container } = renderWithIntl(
);
- const hyperlink = container.querySelector('a');
+ renderWithIntl(
);
+ const hyperlink = screen.getByRole('link');
expect(hyperlink).toHaveAttribute(
'href',
urls.openResponse(props.courseId),
@@ -42,7 +32,7 @@ describe('EmptySubmission component', () => {
});
it('renders the back to responses button', () => {
- const { getByText } = renderWithIntl(
);
- expect(getByText('Back to all open responses')).toBeInTheDocument();
+ renderWithIntl(
);
+ expect(screen.getByText('Back to all open responses')).toBeInTheDocument();
});
});
diff --git a/src/containers/ListView/FilterStatusComponent.test.jsx b/src/containers/ListView/FilterStatusComponent.test.jsx
index aae61ef..daca105 100644
--- a/src/containers/ListView/FilterStatusComponent.test.jsx
+++ b/src/containers/ListView/FilterStatusComponent.test.jsx
@@ -5,9 +5,6 @@ import { DataTableContext } from '@openedx/paragon';
import * as module from './FilterStatusComponent';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
const fieldIds = ['field-id-0', 'field-id-1', 'field-id-2', 'field-id-3'];
const filterOrder = [1, 0, 3, 2];
const filters = filterOrder.map((v) => ({ id: fieldIds[v] }));
diff --git a/src/containers/ListView/ListError.test.jsx b/src/containers/ListView/ListError.test.jsx
index 55dc574..2f2039e 100644
--- a/src/containers/ListView/ListError.test.jsx
+++ b/src/containers/ListView/ListError.test.jsx
@@ -1,14 +1,10 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
import { selectors, thunkActions } from 'data/redux';
+import { renderWithIntl } from '../../testUtils';
import { ListError, mapDispatchToProps, mapStateToProps } from './ListError';
import messages from './messages';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('data/redux', () => ({
selectors: {
app: {
@@ -38,28 +34,28 @@ describe('ListError component', () => {
describe('behavior', () => {
it('renders error alert with proper styling', () => {
- render(
);
+ renderWithIntl(
);
const alert = screen.getByRole('alert');
expect(alert).toBeInTheDocument();
expect(alert).toHaveClass('alert-danger');
});
it('displays error heading and message', () => {
- render(
);
+ renderWithIntl(
);
const heading = screen.getByRole('alert').querySelector('.alert-heading');
expect(heading).toBeInTheDocument();
expect(heading).toHaveTextContent(messages.loadErrorHeading.defaultMessage);
});
it('displays try again button', () => {
- render(
);
+ renderWithIntl(
);
const button = screen.getByRole('button');
expect(button).toBeInTheDocument();
expect(button).toHaveClass('btn-primary');
});
it('calls initializeApp when try again button is clicked', async () => {
- render(
);
+ renderWithIntl(
);
const user = userEvent.setup();
const button = screen.getByRole('button');
await user.click(button);
diff --git a/src/containers/ListView/ListViewBreadcrumb.test.jsx b/src/containers/ListView/ListViewBreadcrumb.test.jsx
index bb6c496..0b37432 100644
--- a/src/containers/ListView/ListViewBreadcrumb.test.jsx
+++ b/src/containers/ListView/ListViewBreadcrumb.test.jsx
@@ -1,15 +1,11 @@
-import { render } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
import { selectors } from 'data/redux';
+import { renderWithIntl } from '../../testUtils';
import {
ListViewBreadcrumb,
mapStateToProps,
} from './ListViewBreadcrumb';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('data/redux', () => ({
selectors: {
app: {
@@ -36,41 +32,37 @@ describe('ListViewBreadcrumb component', () => {
oraName: 'fake-ora-name',
};
- const renderWithIntl = (component) => render(
-
- {component}
- ,
- );
-
beforeEach(() => {
jest.clearAllMocks();
});
describe('behavior', () => {
it('renders back to responses link with correct destination', () => {
- const { container } = renderWithIntl(
);
- const backLink = container.querySelector('a[href*="openResponseUrl"]');
+ renderWithIntl(
);
+ const backLink = screen.getAllByRole('link').find(
+ link => link.getAttribute('href') === `openResponseUrl(${props.courseId})`,
+ );
expect(backLink).toBeInTheDocument();
- expect(backLink).toHaveAttribute('href', `openResponseUrl(${props.courseId})`);
});
it('displays ORA name in heading', () => {
- const { getByText } = renderWithIntl(
);
- const heading = getByText(props.oraName);
+ renderWithIntl(
);
+ const heading = screen.getByText(props.oraName);
expect(heading).toBeInTheDocument();
expect(heading).toHaveClass('h3');
});
it('renders ORA link with correct destination', () => {
- const { container } = renderWithIntl(
);
- const oraLink = container.querySelector('a[href*="oraUrl"]');
+ renderWithIntl(
);
+ const oraLink = screen.getAllByRole('link').find(
+ link => link.getAttribute('href') === `oraUrl(${props.courseId}, test-location-id)`,
+ );
expect(oraLink).toBeInTheDocument();
- expect(oraLink).toHaveAttribute('href', `oraUrl(${props.courseId}, test-location-id)`);
});
it('displays back to responses text', () => {
- const { getByText } = renderWithIntl(
);
- expect(getByText('Back to all open responses')).toBeInTheDocument();
+ renderWithIntl(
);
+ expect(screen.getByText('Back to all open responses')).toBeInTheDocument();
});
});
diff --git a/src/containers/ListView/SelectedBulkAction.test.jsx b/src/containers/ListView/SelectedBulkAction.test.jsx
index 7e50d6d..4b62c49 100644
--- a/src/containers/ListView/SelectedBulkAction.test.jsx
+++ b/src/containers/ListView/SelectedBulkAction.test.jsx
@@ -1,11 +1,7 @@
-import { render, screen } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
+import { renderWithIntl } from '../../testUtils';
import { SelectedBulkAction } from './SelectedBulkAction';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
describe('SelectedBulkAction component', () => {
const props = {
selectedFlatRows: [{ id: 1 }, { id: 2 }],
@@ -17,21 +13,21 @@ describe('SelectedBulkAction component', () => {
});
it('renders button with correct text and selected count', () => {
- render(
);
+ renderWithIntl(
);
const button = screen.getByRole('button');
expect(button).toBeInTheDocument();
expect(button).toHaveTextContent(`View selected responses (${props.selectedFlatRows.length})`);
});
it('applies correct CSS class to button', () => {
- render(
);
+ renderWithIntl(
);
const button = screen.getByRole('button');
expect(button).toHaveClass('view-selected-responses-btn');
expect(button).toHaveClass('btn-primary');
});
it('calls handleClick with selectedFlatRows on render', () => {
- render(
);
+ renderWithIntl(
);
expect(props.handleClick).toHaveBeenCalledWith(props.selectedFlatRows);
});
});
diff --git a/src/containers/ListView/SubmissionsTable.test.jsx b/src/containers/ListView/SubmissionsTable.test.jsx
index 7a3c6f6..45da23d 100644
--- a/src/containers/ListView/SubmissionsTable.test.jsx
+++ b/src/containers/ListView/SubmissionsTable.test.jsx
@@ -1,17 +1,13 @@
-import { render, screen } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
import { selectors, thunkActions } from 'data/redux';
import { gradingStatuses as statuses } from 'data/services/lms/constants';
+import { renderWithIntl } from '../../testUtils';
import {
SubmissionsTable,
mapStateToProps,
mapDispatchToProps,
} from './SubmissionsTable';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('data/redux', () => ({
selectors: {
app: {
@@ -91,20 +87,14 @@ describe('SubmissionsTable component', () => {
loadSelectionForReview: jest.fn(),
};
- const renderWithIntl = (component) => render(
-
- {component}
- ,
- );
-
beforeEach(() => {
jest.clearAllMocks();
});
describe('behavior', () => {
it('renders DataTable component', () => {
- const { container } = renderWithIntl(
);
- const submissionsTable = container.querySelector('.submissions-table');
+ renderWithIntl(
);
+ const submissionsTable = screen.getByRole('table');
expect(submissionsTable).toBeInTheDocument();
});
diff --git a/src/containers/ListView/TableAction.test.jsx b/src/containers/ListView/TableAction.test.jsx
index e7e9d1c..9ef94d3 100644
--- a/src/containers/ListView/TableAction.test.jsx
+++ b/src/containers/ListView/TableAction.test.jsx
@@ -1,12 +1,8 @@
-import { render, screen } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
+import { renderWithIntl } from '../../testUtils';
import { TableAction } from './TableAction';
import messages from './messages';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
describe('TableAction component', () => {
const props = {
tableInstance: { rows: [{ id: 1 }, { id: 2 }] },
@@ -18,21 +14,21 @@ describe('TableAction component', () => {
});
it('renders button with correct text', () => {
- render(
);
+ renderWithIntl(
);
const button = screen.getByRole('button');
expect(button).toBeInTheDocument();
expect(button).toHaveTextContent(messages.viewAllResponses.defaultMessage);
});
it('applies correct CSS class to button', () => {
- render(
);
+ renderWithIntl(
);
const button = screen.getByRole('button');
expect(button).toHaveClass('view-all-responses-btn');
expect(button).toHaveClass('btn-primary');
});
it('enables button when rows are present', () => {
- render(
);
+ renderWithIntl(
);
const button = screen.getByRole('button');
expect(button).not.toBeDisabled();
});
@@ -42,13 +38,13 @@ describe('TableAction component', () => {
tableInstance: { rows: [] },
handleClick: jest.fn(() => () => {}),
};
- render(
);
+ renderWithIntl(
);
const button = screen.getByRole('button');
expect(button).toBeDisabled();
});
it('calls handleClick with table rows on render', () => {
- render(
);
+ renderWithIntl(
);
expect(props.handleClick).toHaveBeenCalledWith(props.tableInstance.rows);
});
});
diff --git a/src/containers/ListView/index.test.jsx b/src/containers/ListView/index.test.jsx
index c8bc5ac..be7fad2 100644
--- a/src/containers/ListView/index.test.jsx
+++ b/src/containers/ListView/index.test.jsx
@@ -1,18 +1,14 @@
import React from 'react';
-import { render, screen } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
import { selectors, thunkActions } from 'data/redux';
import { RequestKeys } from 'data/constants/requests';
import { formatMessage } from 'testUtils';
+import { renderWithIntl } from '../../testUtils';
import { ListView, mapStateToProps, mapDispatchToProps } from '.';
import messages from './messages';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('containers/ReviewModal', () => {
const ReviewModal = () =>
ReviewModal
;
return ReviewModal;
@@ -108,7 +104,7 @@ describe('ListView component', () => {
});
it('displays loading spinner and message when not loaded and no error', () => {
- render(
);
+ renderWithIntl(
);
// Check for loading message
expect(screen.getByText(messages.loadingResponses.defaultMessage)).toBeInTheDocument();
@@ -119,7 +115,7 @@ describe('ListView component', () => {
});
it('displays ListViewBreadcrumb and SubmissionsTable when loaded with data', () => {
- render(
);
+ renderWithIntl(
);
expect(
screen.getByText('Back to all open responses'),
@@ -129,7 +125,7 @@ describe('ListView component', () => {
});
it('displays EmptySubmission component when loaded but has no submission data', () => {
- render(
);
+ renderWithIntl(
);
expect(
screen.getByRole('heading', { name: 'Nothing here yet' }),
@@ -146,7 +142,7 @@ describe('ListView component', () => {
});
it('displays ListError component when there is an error', () => {
- render(
);
+ renderWithIntl(
);
expect(
screen.getByRole('button', { name: 'Reload submissions' }),
@@ -155,18 +151,18 @@ describe('ListView component', () => {
});
it('always displays ReviewModal component regardless of state', () => {
- const { rerender } = render(
);
+ const { rerender } = renderWithIntl(
);
expect(screen.getByText('ReviewModal')).toBeInTheDocument();
- rerender(
);
+ rerender(
);
expect(screen.getByText('ReviewModal')).toBeInTheDocument();
- rerender(
);
+ rerender(
);
expect(screen.getByText('ReviewModal')).toBeInTheDocument();
});
it('calls initializeApp on component mount', () => {
- render(
);
+ renderWithIntl(
);
expect(props.initializeApp).toHaveBeenCalledTimes(1);
});
});
diff --git a/src/containers/ResponseDisplay/FileDownload.test.jsx b/src/containers/ResponseDisplay/FileDownload.test.jsx
index 5fd0965..7eccd63 100644
--- a/src/containers/ResponseDisplay/FileDownload.test.jsx
+++ b/src/containers/ResponseDisplay/FileDownload.test.jsx
@@ -1,6 +1,5 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
import { RequestKeys, RequestStates } from 'data/constants/requests';
import { selectors, thunkActions } from 'data/redux';
import {
@@ -10,10 +9,7 @@ import {
statusMapping,
} from './FileDownload';
import messages from './messages';
-
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
+import { renderWithIntl } from '../../testUtils';
jest.mock('data/redux', () => ({
selectors: {
@@ -36,7 +32,7 @@ describe('FileDownload', () => {
describe('behavior', () => {
it('renders StatefulButton with default state when inactive', () => {
- render(
);
+ renderWithIntl(
);
const button = screen.getByRole('button');
expect(button).toBeInTheDocument();
expect(button).toHaveTextContent(messages.downloadFiles.defaultMessage);
@@ -44,9 +40,8 @@ describe('FileDownload', () => {
it('renders with pending state when download is pending', () => {
const props = { ...defaultProps, requestStatus: { status: RequestStates.pending } };
- render(
);
+ renderWithIntl(
);
const button = screen.getByRole('button');
- screen.debug();
expect(button).toHaveClass('pgn__stateful-btn-state-pending');
expect(button).toHaveAttribute('aria-disabled', 'true');
expect(button).toHaveTextContent(messages.downloading.defaultMessage);
@@ -54,14 +49,14 @@ describe('FileDownload', () => {
it('renders with completed state when download is completed', () => {
const props = { ...defaultProps, requestStatus: { status: RequestStates.completed } };
- render(
);
+ renderWithIntl(
);
const button = screen.getByRole('button');
expect(button).toHaveClass('pgn__stateful-btn-state-completed');
});
it('renders with failed state when download fails', () => {
const props = { ...defaultProps, requestStatus: { status: RequestStates.failed } };
- render(
);
+ renderWithIntl(
);
const button = screen.getByRole('button');
expect(button).toBeInTheDocument();
expect(button).toHaveClass('pgn__stateful-btn-state-failed');
@@ -69,7 +64,7 @@ describe('FileDownload', () => {
});
it('calls downloadFiles when button is clicked', async () => {
- render(
);
+ renderWithIntl(
);
const user = userEvent.setup();
const button = screen.getByRole('button');
await user.click(button);
diff --git a/src/containers/ResponseDisplay/PreviewDisplay.test.jsx b/src/containers/ResponseDisplay/PreviewDisplay.test.jsx
index ca0da40..f60c05c 100644
--- a/src/containers/ResponseDisplay/PreviewDisplay.test.jsx
+++ b/src/containers/ResponseDisplay/PreviewDisplay.test.jsx
@@ -1,12 +1,8 @@
-import { render } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
import { FileTypes } from 'data/constants/files';
+import { renderWithIntl } from '../../testUtils';
import { PreviewDisplay } from './PreviewDisplay';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
describe('PreviewDisplay', () => {
const supportedTypes = Object.values(FileTypes);
const props = {
@@ -24,32 +20,26 @@ describe('PreviewDisplay', () => {
],
};
- const renderWithIntl = (component) => render(
-
- {component}
- ,
- );
-
beforeEach(() => {
jest.clearAllMocks();
});
it('renders preview display container', () => {
- const { container } = renderWithIntl(
);
- const previewDisplay = container.querySelector('.preview-display');
+ renderWithIntl(
);
+ const previewDisplay = screen.getByRole('button', { name: 'fake_file_0.pdf' });
expect(previewDisplay).toBeInTheDocument();
});
it('renders empty container when no files provided', () => {
- const { container } = renderWithIntl(
);
- const previewDisplay = container.querySelector('.preview-display');
+ renderWithIntl(
);
+ const previewDisplay = document.querySelector('.preview-display');
expect(previewDisplay).toBeInTheDocument();
expect(previewDisplay.children.length).toBe(0);
});
it('only renders supported file types', () => {
- const { container } = renderWithIntl(
);
- const previewDisplay = container.querySelector('.preview-display');
+ renderWithIntl(
);
+ const previewDisplay = document.querySelector('.preview-display');
expect(previewDisplay.children.length).toBe(supportedTypes.length);
});
@@ -59,8 +49,8 @@ describe('PreviewDisplay', () => {
description: 'unsupported file',
downloadUrl: '/unsupported.xyz',
};
- const { container } = renderWithIntl(
);
- const previewDisplay = container.querySelector('.preview-display');
+ renderWithIntl(
);
+ const previewDisplay = document.querySelector('.preview-display');
expect(previewDisplay.children.length).toBe(0);
});
});
diff --git a/src/containers/ResponseDisplay/SubmissionFiles.test.jsx b/src/containers/ResponseDisplay/SubmissionFiles.test.jsx
index 999f121..5af854a 100644
--- a/src/containers/ResponseDisplay/SubmissionFiles.test.jsx
+++ b/src/containers/ResponseDisplay/SubmissionFiles.test.jsx
@@ -1,12 +1,8 @@
-import { render, screen } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
import { downloadAllLimit, downloadSingleLimit } from 'data/constants/files';
+import { renderWithIntl } from '../../testUtils';
import { SubmissionFiles } from './SubmissionFiles';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('./components/FileNameCell', () => jest.fn(({ value }) =>
Name: {value}
));
jest.mock('./components/FileExtensionCell', () => jest.fn(({ value }) =>
Extension: {value}
));
jest.mock('./components/FilePopoverCell', () => jest.fn(() =>
Popover
));
@@ -30,12 +26,6 @@ describe('SubmissionFiles', () => {
],
};
- const renderWithIntl = (component) => render(
-
- {component}
- ,
- );
-
beforeEach(() => {
jest.clearAllMocks();
});
@@ -88,8 +78,8 @@ describe('SubmissionFiles', () => {
});
it('displays title only when no files are provided', () => {
- const { container } = renderWithIntl(
);
- const title = container.querySelector('.submission-files-title h3');
+ renderWithIntl(
);
+ const title = screen.getByRole('heading', { level: 3 });
expect(title).toBeInTheDocument();
expect(title).toHaveTextContent('Submission Files (0)');
expect(screen.queryByTestId('file-download')).not.toBeInTheDocument();
diff --git a/src/containers/ResponseDisplay/components/FileExtensionCell.test.jsx b/src/containers/ResponseDisplay/components/FileExtensionCell.test.jsx
index 57f64d2..3cccd54 100644
--- a/src/containers/ResponseDisplay/components/FileExtensionCell.test.jsx
+++ b/src/containers/ResponseDisplay/components/FileExtensionCell.test.jsx
@@ -1,9 +1,6 @@
-import { render } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
import FileExtensionCell from './FileExtensionCell';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
describe('FileExtensionCell', () => {
const props = {
value: 'file_name.with_extension.pdf',
@@ -14,8 +11,8 @@ describe('FileExtensionCell', () => {
});
it('renders file extension in uppercase', () => {
- const { getByText } = render(
);
- expect(getByText('PDF')).toBeInTheDocument();
+ render(
);
+ expect(screen.getByText('PDF')).toBeInTheDocument();
});
it('applies correct CSS class', () => {
@@ -25,13 +22,13 @@ describe('FileExtensionCell', () => {
});
it('extracts extension from file with multiple dots', () => {
- const { getByText } = render(
);
- expect(getByText('DOCX')).toBeInTheDocument();
+ render(
);
+ expect(screen.getByText('DOCX')).toBeInTheDocument();
});
it('handles file without extension', () => {
- const { getByText } = render(
);
- expect(getByText('FILENAME')).toBeInTheDocument();
+ render(
);
+ expect(screen.getByText('FILENAME')).toBeInTheDocument();
});
it('handles empty file extension', () => {
diff --git a/src/containers/ResponseDisplay/components/FilePopoverCell.test.jsx b/src/containers/ResponseDisplay/components/FilePopoverCell.test.jsx
index 5c8f2a4..b0f9b58 100644
--- a/src/containers/ResponseDisplay/components/FilePopoverCell.test.jsx
+++ b/src/containers/ResponseDisplay/components/FilePopoverCell.test.jsx
@@ -1,18 +1,8 @@
-import { render } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
+import { renderWithIntl } from '../../../testUtils';
import FilePopoverCell from './FilePopoverCell';
-const mockMessages = {
- en: {},
-};
-
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('FilePopoverCell', () => {
const props = {
row: {
@@ -25,20 +15,10 @@ describe('FilePopoverCell', () => {
},
};
- it('renders the component without errors', () => {
- const { container } = renderWithIntl(
);
- expect(container.firstChild).toBeInTheDocument();
- });
-
- it('renders the info icon button', () => {
- const { getByTestId } = renderWithIntl(
);
- expect(getByTestId('esg-help-icon')).toBeInTheDocument();
- });
-
- it('info button has correct alt text', () => {
- const { getByTestId } = renderWithIntl(
);
- const button = getByTestId('esg-help-icon');
- expect(button).toHaveAttribute('alt', 'Display more info');
+ it('renders info button has correct alt text', () => {
+ renderWithIntl(
);
+ const button = screen.getByRole('button', { name: /display more info/i });
+ expect(button).toBeInTheDocument();
});
it('handles empty row.original object', () => {
diff --git a/src/containers/ResponseDisplay/index.test.jsx b/src/containers/ResponseDisplay/index.test.jsx
index be56044..8925400 100644
--- a/src/containers/ResponseDisplay/index.test.jsx
+++ b/src/containers/ResponseDisplay/index.test.jsx
@@ -3,9 +3,6 @@ import { fileUploadResponseOptions } from 'data/services/lms/constants';
import { selectors } from 'data/redux';
import { ResponseDisplay, mapStateToProps } from '.';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
jest.mock('data/redux', () => ({
selectors: {
grading: {
diff --git a/src/containers/ReviewActions/components/OverrideGradeConfirmModal.test.jsx b/src/containers/ReviewActions/components/OverrideGradeConfirmModal.test.jsx
index 6bc037a..a297c58 100644
--- a/src/containers/ReviewActions/components/OverrideGradeConfirmModal.test.jsx
+++ b/src/containers/ReviewActions/components/OverrideGradeConfirmModal.test.jsx
@@ -1,17 +1,8 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { renderWithIntl } from '../../../testUtils';
import OverrideGradeConfirmModal from './OverrideGradeConfirmModal';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('OverrideGradeConfirmModal', () => {
const props = {
isOpen: false,
@@ -24,14 +15,14 @@ describe('OverrideGradeConfirmModal', () => {
});
it('should not render content when modal is closed', () => {
- const { queryByText } = renderWithIntl(
);
- expect(queryByText('This cannot be undone')).toBeNull();
+ renderWithIntl(
);
+ expect(screen.queryByText('This cannot be undone')).toBeNull();
});
it('should display content when modal is open', () => {
- const { getByText } = renderWithIntl(
);
- expect(getByText('Are you sure you want to override this grade?')).toBeInTheDocument();
- expect(getByText(/This cannot be undone.*The learner may have already received their grade/)).toBeInTheDocument();
+ renderWithIntl(
);
+ expect(screen.getByText('Are you sure you want to override this grade?')).toBeInTheDocument();
+ expect(screen.getByText(/This cannot be undone.*The learner may have already received their grade/)).toBeInTheDocument();
});
it('should call onCancel when cancel button is clicked', async () => {
diff --git a/src/containers/ReviewActions/components/StartGradingButton/index.test.jsx b/src/containers/ReviewActions/components/StartGradingButton/index.test.jsx
index 2c806e6..b369e19 100644
--- a/src/containers/ReviewActions/components/StartGradingButton/index.test.jsx
+++ b/src/containers/ReviewActions/components/StartGradingButton/index.test.jsx
@@ -1,14 +1,10 @@
-import { render, screen } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
import { useDispatch } from 'react-redux';
+import { renderWithIntl } from '../../../../testUtils';
import * as hooks from './hooks';
import { StartGradingButton } from '.';
import messages from '../messages';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('react-redux', () => ({
useDispatch: jest.fn(),
}));
@@ -20,12 +16,6 @@ jest.mock('./hooks', () => ({
describe('StartGradingButton', () => {
const mockDispatch = jest.fn();
- const renderWithIntl = (component) => render(
-
- {component}
- ,
- );
-
beforeEach(() => {
jest.clearAllMocks();
useDispatch.mockReturnValue(mockDispatch);
diff --git a/src/containers/ReviewActions/components/StopGradingConfirmModal.test.jsx b/src/containers/ReviewActions/components/StopGradingConfirmModal.test.jsx
index 433bd9b..e5083ee 100644
--- a/src/containers/ReviewActions/components/StopGradingConfirmModal.test.jsx
+++ b/src/containers/ReviewActions/components/StopGradingConfirmModal.test.jsx
@@ -1,17 +1,8 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { renderWithIntl } from '../../../testUtils';
import StopGradingConfirmModal from './StopGradingConfirmModal';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('StopGradingConfirmModal', () => {
const props = {
isOpen: false,
diff --git a/src/containers/ReviewActions/components/SubmissionNavigation.test.jsx b/src/containers/ReviewActions/components/SubmissionNavigation.test.jsx
index f590597..a055a21 100644
--- a/src/containers/ReviewActions/components/SubmissionNavigation.test.jsx
+++ b/src/containers/ReviewActions/components/SubmissionNavigation.test.jsx
@@ -1,30 +1,15 @@
import React from 'react';
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
import { thunkActions } from 'data/redux';
+import { renderWithIntl } from '../../../testUtils';
import {
SubmissionNavigation,
mapDispatchToProps,
} from './SubmissionNavigation';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-
-const mockMessages = {
- 'ora-grading.ReviewActions.loadPrevious': 'Load previous submission',
- 'ora-grading.ReviewActions.loadNext': 'Load next submission',
- 'ora-grading.ReviewActions.navigationLabel': '{current} of {total}',
-};
-
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('SubmissionNavigation component', () => {
describe('component', () => {
const defaultProps = {
@@ -44,7 +29,7 @@ describe('SubmissionNavigation component', () => {
it('renders navigation with current position and total submissions', () => {
renderWithIntl(
);
- expect(screen.getByText('FormattedMessage')).toBeInTheDocument();
+ expect(screen.getByText(`${defaultProps.activeIndex + 1} of ${defaultProps.selectionLength}`)).toBeInTheDocument();
});
it('disables previous button when no previous submission exists', () => {
@@ -90,10 +75,10 @@ describe('SubmissionNavigation component', () => {
});
it('shows correct position when at first submission', () => {
- render(
+ renderWithIntl(
,
);
- expect(screen.getByText('FormattedMessage')).toBeInTheDocument();
+ expect(screen.getByText(`${1} of ${defaultProps.selectionLength}`)).toBeInTheDocument();
});
});
diff --git a/src/containers/ReviewActions/index.test.jsx b/src/containers/ReviewActions/index.test.jsx
index a33cc38..051b618 100644
--- a/src/containers/ReviewActions/index.test.jsx
+++ b/src/containers/ReviewActions/index.test.jsx
@@ -1,14 +1,10 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
import { actions, selectors } from 'data/redux';
import { RequestKeys } from 'data/constants/requests';
+import { renderWithIntl } from '../../testUtils';
import { ReviewActions, mapStateToProps, mapDispatchToProps } from '.';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('data/redux', () => ({
actions: {
app: {
@@ -65,12 +61,6 @@ jest.mock('./components/SubmissionNavigation', () => {
});
describe('ReviewActions component', () => {
- const renderWithIntl = (component) => render(
-
- {component}
- ,
- );
-
describe('component', () => {
const props = {
gradingStatus: 'ungraded',
diff --git a/src/containers/ReviewModal/ReviewContent.test.jsx b/src/containers/ReviewModal/ReviewContent.test.jsx
index 5edda55..a5c0ea7 100644
--- a/src/containers/ReviewModal/ReviewContent.test.jsx
+++ b/src/containers/ReviewModal/ReviewContent.test.jsx
@@ -1,13 +1,9 @@
-import { render, screen } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
+import { renderWithIntl } from '../../testUtils';
import {
ReviewContent,
} from './ReviewContent';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
// Since we are only testing the ReviewContent component,
// we can mock the child components to avoid unnecessary complexity on mocking the redux store.
jest.mock('containers/ReviewModal/ReviewErrors/FetchErrors', () => {
@@ -50,12 +46,6 @@ jest.mock('data/redux', () => ({
}));
describe('ReviewContent component', () => {
- const renderWithIntl = (component) => render(
-
- {component}
- ,
- );
-
beforeEach(() => {
jest.clearAllMocks();
});
@@ -80,10 +70,10 @@ describe('ReviewContent component', () => {
});
it('renders with rubric when showRubric is true and loaded', () => {
- const { container, getByText } = renderWithIntl(
);
+ const { container } = renderWithIntl(
);
expect(container.querySelector('.content-block')).toBeInTheDocument();
expect(container.querySelector('.flex-nowrap')).toBeInTheDocument();
- expect(getByText('Rubric')).toBeInTheDocument();
+ expect(screen.getByText('Rubric')).toBeInTheDocument();
});
});
});
diff --git a/src/containers/ReviewModal/ReviewErrors/DownloadErrors.test.jsx b/src/containers/ReviewModal/ReviewErrors/DownloadErrors.test.jsx
index e5d7260..093e8a9 100644
--- a/src/containers/ReviewModal/ReviewErrors/DownloadErrors.test.jsx
+++ b/src/containers/ReviewModal/ReviewErrors/DownloadErrors.test.jsx
@@ -1,14 +1,10 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
import { selectors, actions, thunkActions } from 'data/redux';
import { RequestKeys } from 'data/constants/requests';
+import { renderWithIntl } from '../../../testUtils';
import { DownloadErrors, mapStateToProps, mapDispatchToProps } from './DownloadErrors';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('data/redux', () => ({
selectors: {
requests: {
@@ -24,12 +20,6 @@ jest.mock('data/redux', () => ({
},
}));
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('DownloadErrors component', () => {
const defaultProps = {
isFailed: false,
diff --git a/src/containers/ReviewModal/ReviewErrors/FetchErrors.test.jsx b/src/containers/ReviewModal/ReviewErrors/FetchErrors.test.jsx
index 39d0aad..0fcebf5 100644
--- a/src/containers/ReviewModal/ReviewErrors/FetchErrors.test.jsx
+++ b/src/containers/ReviewModal/ReviewErrors/FetchErrors.test.jsx
@@ -1,20 +1,15 @@
import React from 'react';
-import { render, screen } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
import { selectors, thunkActions } from 'data/redux';
import { RequestKeys } from 'data/constants/requests';
-
+import { renderWithIntl } from '../../../testUtils';
import {
FetchErrors,
mapStateToProps,
mapDispatchToProps,
} from './FetchErrors';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('data/redux', () => ({
selectors: {
requests: {
@@ -30,12 +25,6 @@ jest.mock('data/redux', () => ({
const requestKey = RequestKeys.fetchSubmission;
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('FetchErrors component', () => {
const props = {
isFailed: false,
diff --git a/src/containers/ReviewModal/ReviewErrors/LockErrors.test.jsx b/src/containers/ReviewModal/ReviewErrors/LockErrors.test.jsx
index d5f82b8..7ce085f 100644
--- a/src/containers/ReviewModal/ReviewErrors/LockErrors.test.jsx
+++ b/src/containers/ReviewModal/ReviewErrors/LockErrors.test.jsx
@@ -1,20 +1,15 @@
import React from 'react';
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import '@testing-library/jest-dom';
-
-import { IntlProvider } from '@edx/frontend-platform/i18n';
import { selectors } from 'data/redux';
import { ErrorStatuses, RequestKeys } from 'data/constants/requests';
+import { renderWithIntl } from '../../../testUtils';
import {
LockErrors,
mapStateToProps,
} from './LockErrors';
-jest.unmock('react');
-jest.unmock('@openedx/paragon');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('data/redux', () => ({
selectors: {
requests: {
@@ -24,12 +19,6 @@ jest.mock('data/redux', () => ({
},
}));
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('LockErrors component', () => {
describe('when not failed', () => {
it('renders nothing when isFailed is false', () => {
diff --git a/src/containers/ReviewModal/ReviewErrors/ReviewError.test.jsx b/src/containers/ReviewModal/ReviewErrors/ReviewError.test.jsx
index 6a315ed..44d33dc 100644
--- a/src/containers/ReviewModal/ReviewErrors/ReviewError.test.jsx
+++ b/src/containers/ReviewModal/ReviewErrors/ReviewError.test.jsx
@@ -1,18 +1,8 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { renderWithIntl } from '../../../testUtils';
import ReviewError from './ReviewError';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('ReviewError component', () => {
const messages = {
heading: {
diff --git a/src/containers/ReviewModal/ReviewErrors/SubmitErrors/index.test.jsx b/src/containers/ReviewModal/ReviewErrors/SubmitErrors/index.test.jsx
index dc212d4..0eee1a5 100644
--- a/src/containers/ReviewModal/ReviewErrors/SubmitErrors/index.test.jsx
+++ b/src/containers/ReviewModal/ReviewErrors/SubmitErrors/index.test.jsx
@@ -1,14 +1,10 @@
import React from 'react';
-import { render, screen } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
+import { renderWithIntl } from '../../../../testUtils';
import * as hooks from './hooks';
import { SubmitErrors } from '.';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('react-redux', () => ({
useDispatch: jest.fn(() => jest.fn()),
}));
@@ -17,12 +13,6 @@ jest.mock('./hooks', () => ({
rendererHooks: jest.fn(() => ({ show: false })),
}));
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('SubmitErrors component', () => {
beforeEach(() => {
jest.clearAllMocks();
diff --git a/src/containers/ReviewModal/ReviewErrors/index.test.jsx b/src/containers/ReviewModal/ReviewErrors/index.test.jsx
index 2964280..6609b68 100644
--- a/src/containers/ReviewModal/ReviewErrors/index.test.jsx
+++ b/src/containers/ReviewModal/ReviewErrors/index.test.jsx
@@ -1,11 +1,6 @@
-import { render } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { renderWithIntl } from '../../../testUtils';
import { ReviewErrors } from '.';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('react-redux', () => ({
useDispatch: jest.fn(() => jest.fn()),
useSelector: jest.fn((selector) => selector({
@@ -63,12 +58,6 @@ jest.mock('data/redux', () => ({
},
}));
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('ReviewErrors component', () => {
it('renders without errors', () => {
const { container } = renderWithIntl(
);
diff --git a/src/containers/ReviewModal/components/CloseReviewConfirmModal.test.jsx b/src/containers/ReviewModal/components/CloseReviewConfirmModal.test.jsx
index 2667060..fc9dcc2 100644
--- a/src/containers/ReviewModal/components/CloseReviewConfirmModal.test.jsx
+++ b/src/containers/ReviewModal/components/CloseReviewConfirmModal.test.jsx
@@ -1,18 +1,8 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { renderWithIntl } from '../../../testUtils';
import CloseReviewConfirmModal from './CloseReviewConfirmModal';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('CloseReviewConfirmModal', () => {
const props = {
isOpen: false,
@@ -25,14 +15,14 @@ describe('CloseReviewConfirmModal', () => {
});
it('should not render content when modal is closed', () => {
- const { queryByText } = renderWithIntl(
);
- expect(queryByText('This cannot be undone')).toBeNull();
+ renderWithIntl(
);
+ expect(screen.queryByText('This cannot be undone')).toBeNull();
});
it('should display content when modal is open', () => {
- const { getByText } = renderWithIntl(
);
- expect(getByText('Are you sure you want to close this modal?')).toBeInTheDocument();
- expect(getByText(/This cannot be undone.*This will discard unsaved work/)).toBeInTheDocument();
+ renderWithIntl(
);
+ expect(screen.getByText('Are you sure you want to close this modal?')).toBeInTheDocument();
+ expect(screen.getByText(/This cannot be undone.*This will discard unsaved work/)).toBeInTheDocument();
});
it('should call onCancel when cancel button is clicked', async () => {
diff --git a/src/containers/ReviewModal/index.test.jsx b/src/containers/ReviewModal/index.test.jsx
index e3f73b7..a141ecd 100644
--- a/src/containers/ReviewModal/index.test.jsx
+++ b/src/containers/ReviewModal/index.test.jsx
@@ -1,14 +1,10 @@
import { useDispatch } from 'react-redux';
-import { render, screen } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
import * as hooks from './hooks';
import { ReviewModal } from '.';
import messages from './messages';
-
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
+import { renderWithIntl } from '../../testUtils';
jest.mock('react-redux', () => ({
useDispatch: jest.fn(),
@@ -59,7 +55,7 @@ describe('ReviewModal', () => {
},
});
- render(
);
+ renderWithIntl(
);
expect(hooks.rendererHooks).toHaveBeenCalledWith({
dispatch: mockDispatch,
@@ -80,7 +76,7 @@ describe('ReviewModal', () => {
},
});
- render(
);
+ renderWithIntl(
);
expect(useDispatch).toHaveBeenCalled();
});
@@ -97,7 +93,7 @@ describe('ReviewModal', () => {
},
});
- render(
);
+ renderWithIntl(
);
const reviewActions = screen.getByText('ReviewActions');
expect(reviewActions).toBeInTheDocument();
@@ -124,7 +120,7 @@ describe('ReviewModal', () => {
},
});
- render(
);
+ renderWithIntl(
);
const loadingMessage = screen.getByText(messages.loadingResponse.defaultMessage);
expect(loadingMessage).toBeInTheDocument();
});
diff --git a/src/containers/Rubric/RubricFeedback.test.jsx b/src/containers/Rubric/RubricFeedback.test.jsx
index 038e377..8d2e327 100644
--- a/src/containers/Rubric/RubricFeedback.test.jsx
+++ b/src/containers/Rubric/RubricFeedback.test.jsx
@@ -1,14 +1,10 @@
-import { render, screen } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
import { actions, selectors } from 'data/redux';
import { feedbackRequirement, gradeStatuses } from 'data/services/lms/constants';
+import { renderWithIntl } from '../../testUtils';
import { RubricFeedback, mapDispatchToProps, mapStateToProps } from './RubricFeedback';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('data/redux', () => ({
actions: {
grading: { setRubricFeedback: jest.fn() },
@@ -32,12 +28,6 @@ jest.mock('data/redux', () => ({
},
}));
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('Rubric Feedback component', () => {
const defaultProps = {
config: 'config string',
diff --git a/src/containers/Rubric/index.test.jsx b/src/containers/Rubric/index.test.jsx
index 6a4598a..c9ace28 100644
--- a/src/containers/Rubric/index.test.jsx
+++ b/src/containers/Rubric/index.test.jsx
@@ -1,12 +1,8 @@
-import { render } from '@testing-library/react';
-import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { screen } from '@testing-library/react';
+import { renderWithIntl } from '../../testUtils';
import { Rubric } from '.';
import * as hooks from './hooks';
-jest.unmock('@openedx/paragon');
-jest.unmock('react');
-jest.unmock('@edx/frontend-platform/i18n');
-
jest.mock('react-redux', () => ({
useDispatch: jest.fn(() => jest.fn()),
connect: jest.fn((mapStateToProps, mapDispatchToProps) => (Component) => {
@@ -93,12 +89,6 @@ jest.mock('./hooks', () => ({
ButtonStates: jest.requireActual('./hooks').ButtonStates,
}));
-const renderWithIntl = (component) => render(
-
- {component}
- ,
-);
-
describe('Rubric Container', () => {
const hookProps = {
criteria: [
@@ -115,20 +105,20 @@ describe('Rubric Container', () => {
hooks.rendererHooks.mockReturnValue(hookProps);
});
- it('renders rubric with footer when showFooter is true', () => {
+ it('renders rubric with submit button in footer when showFooter is true', () => {
hooks.rendererHooks.mockReturnValueOnce({ ...hookProps, showFooter: true });
- const { container } = renderWithIntl(
);
- const rubricCard = container.querySelector('.grading-rubric-card');
- const footer = container.querySelector('.grading-rubric-footer');
- expect(rubricCard).toBeInTheDocument();
- expect(footer).toBeInTheDocument();
+ renderWithIntl(
);
+ const rubricCardTitle = screen.getByRole('heading', { name: /rubric/i });
+ const submitButton = screen.queryByRole('button', { name: /submit grade/i });
+ expect(rubricCardTitle).toBeInTheDocument();
+ expect(submitButton).toBeInTheDocument();
});
- it('renders rubric without footer when showFooter is false', () => {
- const { container } = renderWithIntl(
);
- const rubricCard = container.querySelector('.grading-rubric-card');
- const footer = container.querySelector('.grading-rubric-footer');
- expect(rubricCard).toBeInTheDocument();
- expect(footer).not.toBeInTheDocument();
+ it('renders rubric without submit button on footer when showFooter is false', () => {
+ renderWithIntl(
);
+ const rubricCardTitle = screen.getByRole('heading', { name: /rubric/i });
+ const submitButton = screen.queryByRole('button', { name: /submit grade/i });
+ expect(rubricCardTitle).toBeInTheDocument();
+ expect(submitButton).not.toBeInTheDocument();
});
});
diff --git a/src/index.test.jsx b/src/index.test.jsx
index 9436eee..c85df13 100644
--- a/src/index.test.jsx
+++ b/src/index.test.jsx
@@ -65,16 +65,12 @@ describe('app registry', () => {
const callArgs = subscribe.mock.calls[0];
expect(callArgs[0]).toEqual(APP_READY);
callArgs[1]();
- const [rendered] = mockRender.mock.calls[0];
- expect(rendered).toMatchSnapshot();
});
test('subscribe: APP_INIT_ERROR. snapshot: displays an ErrorPage to root element', () => {
const callArgs = subscribe.mock.calls[1];
expect(callArgs[0]).toEqual(APP_INIT_ERROR);
const error = { message: 'test-error-message' };
callArgs[1](error);
- const [rendered] = mockRender.mock.calls[0];
- expect(rendered).toMatchSnapshot();
});
test('initialize is called with footerMessages and requireAuthenticatedUser', () => {
expect(initialize).toHaveBeenCalledTimes(1);
diff --git a/src/setupTest.js b/src/setupTest.js
index 47cdbc1..e2c8fcd 100755
--- a/src/setupTest.js
+++ b/src/setupTest.js
@@ -1,111 +1,5 @@
/* eslint-disable import/no-extraneous-dependencies */
import '@testing-library/jest-dom';
-// breaking change here: https://github.com/testing-library/jest-dom/releases/tag/v6.0.0
-
-jest.mock('react', () => ({
- ...jest.requireActual('react'),
- useRef: jest.fn((val) => ({ current: val, useRef: true })),
- useCallback: jest.fn((cb, prereqs) => ({ useCallback: { cb, prereqs } })),
- useEffect: jest.fn((cb, prereqs) => ({ useEffect: { cb, prereqs } })),
- useContext: jest.fn(context => context),
-}));
-
-jest.mock('@edx/frontend-platform/i18n', () => {
- const i18n = jest.requireActual('@edx/frontend-platform/i18n');
- const PropTypes = jest.requireActual('prop-types');
- const { formatMessage } = jest.requireActual('./testUtils');
- const formatDate = jest.fn(date => new Date(date).toLocaleDateString()).mockName('useIntl.formatDate');
- return {
- ...i18n,
- intlShape: PropTypes.shape({
- formatMessage: PropTypes.func,
- }),
- useIntl: () => ({
- formatMessage,
- formatDate,
- }),
- defineMessages: m => m,
- FormattedMessage: () => 'FormattedMessage',
- };
-});
-
-jest.mock('@openedx/paragon', () => jest.requireActual('testUtils').mockNestedComponents({
- Alert: {
- Heading: 'Alert.Heading',
- },
- AlertModal: 'AlertModal',
- ActionRow: 'ActionRow',
- Badge: 'Badge',
- Button: 'Button',
- Card: {
- Body: 'Card.Body',
- Section: 'Card.Section',
- Footer: 'Card.Footer',
- },
- Col: 'Col',
- Collapsible: {
- Advanced: 'Collapsible.Advanced',
- Body: 'Collapsible.Body',
- Trigger: 'Collapsible.Trigger',
- Visible: 'Collapsible.Visible',
- },
- Container: 'Container',
- DataTable: {
- EmptyTable: 'DataTable.EmptyTable',
- Table: 'DataTable.Table',
- TableControlBar: 'DataTable.TableControlBar',
- TableController: 'DataTable.TableController',
- TableFooter: 'DataTable.TableFooter',
- },
- Dropdown: {
- Item: 'Dropdown.Item',
- Menu: 'Dropdown.Menu',
- Toggle: 'Dropdown.Toggle',
- },
- Form: {
- Control: {
- Feedback: 'Form.Control.Feedback',
- },
- Group: 'Form.Group',
- Label: 'Form.Label',
- Radio: 'Form.Radio',
- RadioSet: 'Form.RadioSet',
- },
- FormControlFeedback: 'FormControlFeedback',
- FullscreenModal: 'FullscreenModal',
- Hyperlink: 'Hyperlink',
- Icon: 'Icon',
- IconButton: 'IconButton',
- MultiSelectDropdownFilter: 'MultiSelectDropdownFilter',
- OverlayTrigger: 'OverlayTrigger',
- PageBanner: 'PageBanner',
- Popover: {
- Content: 'Popover.Content',
- },
- Row: 'Row',
- StatefulButton: 'StatefulButton',
- TextFilter: 'TextFilter',
- Spinner: 'Spinner',
-}));
-
-jest.mock('@fortawesome/react-fontawesome', () => ({
- FontAwesomeIcon: 'FontAwesomeIcon',
-}));
-jest.mock('@fortawesome/free-solid-svg-icons', () => ({
- faUserCircle: jest.fn().mockName('fa-user-circle-icon'),
-}));
-
-jest.mock('@openedx/paragon/icons', () => ({
- ArrowBack: jest.fn().mockName('icons.ArrowBack'),
- ArrowDropDown: jest.fn().mockName('icons.ArrowDropDown'),
- ArrowDropUp: jest.fn().mockName('icons.ArrowDropUp'),
- Cancel: jest.fn().mockName('icons.Cancel'),
- ChevronLeft: jest.fn().mockName('icons.ChevronLeft'),
- ChevronRight: jest.fn().mockName('icons.ChevronRight'),
- Highlight: jest.fn().mockName('icons.Highlight'),
- InfoOutline: jest.fn().mockName('icons.InfoOutline'),
- Launch: jest.fn().mockName('icons.Launch'),
-}));
jest.mock('data/constants/app', () => ({
locationId: () => 'fake-location-id',
diff --git a/src/test/app.test.jsx b/src/test/app.test.jsx
index 5f7d250..d009301 100644
--- a/src/test/app.test.jsx
+++ b/src/test/app.test.jsx
@@ -27,10 +27,6 @@ import App from 'App';
import Inspector from './inspector';
import appMessages from './messages';
-jest.unmock('@openedx/paragon');
-jest.unmock('@openedx/paragon/icons');
-jest.unmock('@edx/frontend-platform/i18n');
-jest.unmock('react');
jest.unmock('react-redux');
jest.unmock('hooks');
diff --git a/src/testUtils.js b/src/testUtils.jsx
similarity index 94%
rename from src/testUtils.js
rename to src/testUtils.jsx
index baf986a..c9d5bb2 100644
--- a/src/testUtils.js
+++ b/src/testUtils.jsx
@@ -1,4 +1,7 @@
import react from 'react';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { render } from '@testing-library/react';
+import { IntlProvider } from '@edx/frontend-platform/i18n';
import { StrictDict } from 'utils';
@@ -185,3 +188,9 @@ export class MockUseState {
});
}
}
+
+export const renderWithIntl = (component) => render(
+
+ {component}
+ ,
+);