refactor: mocks cleanup and intl refactor (#508)

This commit is contained in:
Diana Villalvazo
2025-09-08 12:57:00 -06:00
committed by GitHub
parent 40d7167744
commit 4a221c9caa
57 changed files with 213 additions and 362 deletions

54
package-lock.json generated
View File

@@ -14,7 +14,6 @@
"@edx/frontend-component-header": "^6.4.0",
"@edx/frontend-platform": "^8.3.7",
"@edx/openedx-atlas": "^0.6.0",
"@edx/react-unit-test-utils": "^4.0.0",
"@edx/reactifex": "^2.1.1",
"@fortawesome/fontawesome-svg-core": "^1.2.25",
"@fortawesome/free-brands-svg-icons": "^5.11.2",
@@ -67,6 +66,7 @@
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.2.tgz",
"integrity": "sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==",
"dev": true,
"license": "MIT"
},
"node_modules/@ampproject/remapping": {
@@ -2256,6 +2256,7 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@edx/browserslist-config/-/browserslist-config-1.5.0.tgz",
"integrity": "sha512-d2ggwi5j4DOBJOwhWZxBWQSDR0DhT4ke/1PbzRauICdFkuOyax+PsFjK8GUh443K2OaQpy9PGfiCzZ1Yg37AUA==",
"dev": true,
"license": "AGPL-3.0"
},
"node_modules/@edx/eslint-config": {
@@ -2515,30 +2516,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==",
"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/reactifex": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@edx/reactifex/-/reactifex-2.2.0.tgz",
@@ -5576,7 +5553,9 @@
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
"integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
@@ -5595,6 +5574,7 @@
"version": "6.6.4",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.4.tgz",
"integrity": "sha512-xDXgLjVunjHqczScfkCJ9iyjdNOVHvvCdqHSSxwM9L0l/wHkTRum67SDc020uAlCoqktJplgO2AAQeLP1wgqDQ==",
"dev": true,
"dependencies": {
"@adobe/css-tools": "^4.4.0",
"aria-query": "^5.0.0",
@@ -5614,12 +5594,14 @@
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
"integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
"dev": true,
"license": "MIT"
},
"node_modules/@testing-library/react": {
"version": "16.3.0",
"resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.0.tgz",
"integrity": "sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==",
"dev": true,
"dependencies": {
"@babel/runtime": "^7.12.5"
},
@@ -5714,7 +5696,9 @@
"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"
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/@types/babel__core": {
"version": "7.20.5",
@@ -9238,6 +9222,7 @@
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
"integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
"dev": true,
"license": "MIT"
},
"node_modules/cssesc": {
@@ -9841,7 +9826,9 @@
"version": "0.5.16",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
"license": "MIT"
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/dom-converter": {
"version": "0.2.0",
@@ -13165,6 +13152,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -15603,7 +15591,9 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"lz-string": "bin/bin.js"
}
@@ -15834,6 +15824,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -17768,7 +17759,9 @@
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0",
@@ -17782,7 +17775,9 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
},
@@ -18705,6 +18700,7 @@
"version": "16.15.0",
"resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz",
"integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==",
"dev": true,
"license": "MIT",
"dependencies": {
"object-assign": "^4.1.1",
@@ -18762,6 +18758,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.3.1.tgz",
"integrity": "sha512-KkAgygexHUkQqtvvx/otwxtuFu5cVjfzTCtjXLH9boS19/Nbtg84zS7wIQn39G8IlrhThBpQsMKkq5ZHZIYFXA==",
"dev": true,
"license": "MIT",
"dependencies": {
"react-is": "^18.3.1",
@@ -18776,6 +18773,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
"dev": true,
"license": "MIT"
},
"node_modules/react-transition-group": {
@@ -18876,6 +18874,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
"integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
"dev": true,
"license": "MIT",
"dependencies": {
"indent-string": "^4.0.0",
@@ -20502,6 +20501,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"min-indent": "^1.0.0"

View File

@@ -34,7 +34,6 @@
"@edx/frontend-component-header": "^6.4.0",
"@edx/frontend-platform": "^8.3.7",
"@edx/openedx-atlas": "^0.6.0",
"@edx/react-unit-test-utils": "^4.0.0",
"@edx/reactifex": "^2.1.1",
"@fortawesome/fontawesome-svg-core": "^1.2.25",
"@fortawesome/free-brands-svg-icons": "^5.11.2",

View File

@@ -1,11 +1,10 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import selectors from 'data/selectors';
import { BulkManagementAlerts, mapStateToProps } from './BulkManagementAlerts';
import { renderWithIntl, screen } from '../../testUtilsExtra';
jest.unmock('@openedx/paragon');
jest.mock('data/selectors', () => ({
__esModule: true,
default: {
@@ -22,16 +21,16 @@ describe('BulkManagementAlerts', () => {
describe('component', () => {
describe('states of the warnings', () => {
test('no alert shown', () => {
const el = render(<BulkManagementAlerts bulkImportError="" uploadSuccess={false} />);
expect(el.container.querySelectorAll('.alert').length).toEqual(0);
renderWithIntl(<BulkManagementAlerts bulkImportError="" uploadSuccess={false} />);
expect(document.querySelectorAll('.alert').length).toEqual(0);
});
test('Just success alert shown', () => {
const el = render(<BulkManagementAlerts bulkImportError="" uploadSuccess />);
expect(el.container.querySelectorAll('.alert-success').length).toEqual(1);
renderWithIntl(<BulkManagementAlerts bulkImportError="" uploadSuccess />);
expect(document.querySelectorAll('.alert-success').length).toEqual(1);
});
test('Just error alert shown', () => {
const el = render(<BulkManagementAlerts bulkImportError={errorMessage} uploadSuccess={false} />);
expect(el.container.querySelectorAll('.alert-danger').length).toEqual(1);
renderWithIntl(<BulkManagementAlerts bulkImportError={errorMessage} uploadSuccess={false} />);
expect(document.querySelectorAll('.alert-danger').length).toEqual(1);
expect(screen.getByText(errorMessage)).toBeInTheDocument();
});
});

View File

@@ -8,12 +8,10 @@ import { bulkManagementColumns } from 'data/constants/app';
import { HistoryTable, mapHistoryRows, mapStateToProps } from './HistoryTable';
import ResultsSummary from './ResultsSummary';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
initializeMocks();
jest.mock('@openedx/paragon', () => ({
...jest.requireActual('@openedx/paragon'),
DataTable: jest.fn(() => <div data-testid="data-table">DataTable</div>),
}));
jest.mock('./ResultsSummary', () => jest.fn(() => <div data-testid="results-summary">ResultsSummary</div>));

View File

@@ -1,10 +1,9 @@
import React from 'react';
import lms from 'data/services/lms';
import { render, screen } from '@testing-library/react';
import { renderWithIntl, screen } from '../../testUtilsExtra';
import ResultsSummary from './ResultsSummary';
jest.unmock('@openedx/paragon');
jest.mock('data/services/lms', () => ({
urls: {
bulkGradesUrlByRow: jest.fn((rowId) => (`www.edx.org/${rowId}`)),
@@ -16,10 +15,9 @@ describe('ResultsSummary component', () => {
rowId: 42,
text: 'texty',
};
let el;
let link;
beforeEach(() => {
el = render(<ResultsSummary {...props} />);
renderWithIntl(<ResultsSummary {...props} />);
link = screen.getByRole('link', { name: props.text });
});
test('Hyperlink has target="_blank" and rel="noopener noreferrer"', () => {
@@ -31,7 +29,7 @@ describe('ResultsSummary component', () => {
});
test('displays Download Icon and text', () => {
expect(link).toHaveTextContent(props.text);
const span = el.container.querySelector('span[aria-hidden="true"]');
expect(span).toBeInTheDocument();
const icon = screen.getByRole('img', { hidden: true });
expect(icon).toBeInTheDocument();
});
});

View File

@@ -3,10 +3,6 @@ import { render, initializeMocks, screen } from 'testUtilsExtra';
import { BulkManagementHistoryView } from '.';
import messages from './messages';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('./BulkManagementAlerts', () => jest.fn(() => <div>BulkManagementAlerts</div>));
jest.mock('./HistoryTable', () => jest.fn(() => <div>HistoryTable</div>));

View File

@@ -1,23 +1,35 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { getConfig } from '@edx/frontend-platform';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { render, screen } from '@testing-library/react';
import Header from '.';
jest.unmock('@openedx/paragon');
jest.mock('@edx/frontend-platform', () => ({
...jest.requireActual('@edx/frontend-platform'),
getConfig: jest.fn(),
}));
describe('Header', () => {
beforeEach(() => {
jest.clearAllMocks();
});
test('has edx link with logo url', () => {
const url = 'www.ourLogo.url';
const baseUrl = 'www.lms.url';
getConfig.mockReturnValue({ LOGO_URL: url, LMS_BASE_URL: baseUrl });
render(<Header />);
expect(screen.getByRole('link')).toHaveAttribute('href', `${baseUrl}/dashboard`);
expect(screen.getByAltText('edX logo')).toHaveAttribute('src', url);
render(
<IntlProvider messages={{}} locale="en">
<Header />
</IntlProvider>,
);
const link = screen.getByRole('link');
const logo = screen.getByAltText('edX logo');
expect(link).toHaveAttribute('href', `${baseUrl}/dashboard`);
expect(logo).toHaveAttribute('src', url);
});
});

View File

@@ -4,9 +4,6 @@ import { render, screen, initializeMocks } from 'testUtilsExtra';
import useAssignmentFilterData from './hooks';
import AssignmentFilter from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('./hooks', () => ({ __esModule: true, default: jest.fn() }));
const handleChange = jest.fn();

View File

@@ -1,15 +1,12 @@
/* eslint-disable import/no-extraneous-dependencies */
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 useAssignmentGradeFilterData from './hooks';
import AssignmentFilter from '.';
import { renderWithIntl } from '../../../testUtilsExtra';
jest.mock('./hooks', () => ({ __esModule: true, default: jest.fn() }));
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
const hookData = {
handleSubmit: jest.fn(),
@@ -26,7 +23,7 @@ const updateQueryParams = jest.fn();
describe('AssignmentFilter component', () => {
describe('behavior', () => {
it('initializes hooks', () => {
render(<IntlProvider locale="en" messages={{}}><AssignmentFilter updateQueryParams={updateQueryParams} /></IntlProvider>);
renderWithIntl(<AssignmentFilter updateQueryParams={updateQueryParams} />);
expect(useAssignmentGradeFilterData).toHaveBeenCalledWith({ updateQueryParams });
});
});
@@ -34,7 +31,7 @@ describe('AssignmentFilter component', () => {
describe('with selected assignment', () => {
beforeEach(() => {
jest.clearAllMocks();
render(<IntlProvider locale="en" messages={{}}><AssignmentFilter updateQueryParams={updateQueryParams} /></IntlProvider>);
renderWithIntl(<AssignmentFilter updateQueryParams={updateQueryParams} />);
});
it('renders a PercentGroup for both Max and Min filters', async () => {
const user = userEvent.setup();
@@ -64,7 +61,7 @@ describe('AssignmentFilter component', () => {
...hookData,
selectedAssignment: null,
});
render(<IntlProvider locale="en" messages={{}}><AssignmentFilter updateQueryParams={updateQueryParams} /></IntlProvider>);
renderWithIntl(<AssignmentFilter updateQueryParams={updateQueryParams} />);
});
it('disables controls', () => {
const minGrade = screen.getByRole('spinbutton', { name: /Min Grade/ });

View File

@@ -1,13 +1,9 @@
import React from 'react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { render, screen } from '@testing-library/react';
import { screen } from '@testing-library/react';
import useAssignmentFilterTypeData from './hooks';
import AssignmentFilterType from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
import { renderWithIntl } from '../../../testUtilsExtra';
jest.mock('./hooks', () => ({ __esModule: true, default: jest.fn() }));
@@ -25,7 +21,7 @@ const updateQueryParams = jest.fn();
describe('AssignmentFilterType component', () => {
beforeAll(() => {
render(<IntlProvider locale="en"><AssignmentFilterType updateQueryParams={updateQueryParams} /></IntlProvider>);
renderWithIntl(<AssignmentFilterType updateQueryParams={updateQueryParams} />);
});
describe('render', () => {
test('filter options', () => {

View File

@@ -1,13 +1,9 @@
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 useCourseGradeFilterData from './hooks';
import CourseFilter from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
import { renderWithIntl } from '../../../testUtilsExtra';
jest.mock('./hooks', () => ({ __esModule: true, default: jest.fn() }));
@@ -38,7 +34,7 @@ describe('CourseFilter component', () => {
});
describe('with selected assignment', () => {
beforeEach(() => {
render(<IntlProvider locale="en"><CourseFilter updateQueryParams={updateQueryParams} /></IntlProvider>);
renderWithIntl(<CourseFilter updateQueryParams={updateQueryParams} />);
});
it('renders a PercentGroup for both Max and Min filters', () => {
@@ -55,7 +51,7 @@ describe('CourseFilter component', () => {
beforeEach(() => {
jest.clearAllMocks();
useCourseGradeFilterData.mockReturnValueOnce({ ...hookData, isDisabled: true });
render(<IntlProvider locale="en"><CourseFilter updateQueryParams={updateQueryParams} /></IntlProvider>);
renderWithIntl(<CourseFilter updateQueryParams={updateQueryParams} />);
});
it('disables submit', () => {
expect(screen.getByRole('button', { name: 'Apply' })).toBeDisabled();

View File

@@ -2,10 +2,6 @@ import { render, screen, initializeMocks } from 'testUtilsExtra';
import PercentGroup from './PercentGroup';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
describe('PercentGroup', () => {
let props = {
id: 'group id',

View File

@@ -3,10 +3,6 @@ import { render, screen } from '@testing-library/react';
import SelectGroup from './SelectGroup';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
describe('SelectGroup', () => {
let props = {
id: 'group id',

View File

@@ -5,9 +5,6 @@ import SelectGroup from '../SelectGroup';
import { StudentGroupsFilter } from './index';
import useStudentGroupsFilterData from './hooks';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('../SelectGroup', () => jest.fn(() => <div data-testid="select-group">SelectGroup</div>));
jest.mock('./hooks', () => jest.fn());

View File

@@ -3,10 +3,6 @@ import { render, screen, initializeMocks } from 'testUtilsExtra';
import GradebookFilters from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
const updateQueryParams = jest.fn();
initializeMocks();

View File

@@ -8,9 +8,6 @@ import { GradebookHeader } from './index';
import useGradebookHeaderData from './hooks';
import messages from './messages';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('data/services/lms/urls', () => ({
instructorDashboardUrl: jest.fn(),
}));

View File

@@ -8,9 +8,6 @@ import { BulkManagementControls } from './index';
import useBulkManagementControlsData from './hooks';
import messages from './messages';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('components/NetworkButton', () => jest.fn(() => <div data-testid="network-button">NetworkButton</div>));
jest.mock('../ImportGradesButton', () => jest.fn(() => (
<div data-testid="import-grades-button">ImportGradesButton</div>

View File

@@ -3,10 +3,6 @@ import { render, screen, initializeMocks } from 'testUtilsExtra';
import HistoryHeader from './HistoryHeader';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
initializeMocks();
describe('HistoryHeader', () => {

View File

@@ -4,10 +4,6 @@ import { selectors } from 'data/redux/hooks';
import { render, screen, initializeMocks } from 'testUtilsExtra';
import ModalHeaders from './ModalHeaders';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('data/redux/hooks', () => ({
selectors: {
app: { useModalData: jest.fn() },

View File

@@ -4,10 +4,6 @@ import { render, screen } from '@testing-library/react';
import useAdjustedGradeInputData from './hooks';
import AdjustedGradeInput from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('./hooks', () => jest.fn());
const hookProps = {

View File

@@ -16,6 +16,12 @@ jest.mock('data/redux/hooks', () => ({
},
}));
jest.mock('react', () => ({
...jest.requireActual('react'),
useRef: jest.fn((val) => ({ current: val, useRef: true })),
useEffect: jest.fn((cb, prereqs) => ({ useEffect: { cb, prereqs } })),
}));
const modalData = { reasonForChange: 'test-reason-for-change' };
const setModalState = jest.fn();
selectors.app.useModalData.mockReturnValue(modalData);
@@ -25,6 +31,7 @@ const ref = { current: { focus: jest.fn() }, useRef: true };
React.useRef.mockReturnValue(ref);
let out;
describe('useReasonInputData hook', () => {
beforeEach(() => {
jest.clearAllMocks();

View File

@@ -5,9 +5,6 @@ import ReasonInput from '.';
jest.mock('./hooks', () => jest.fn());
jest.unmock('@openedx/paragon');
jest.unmock('react');
const hookProps = {
ref: jest.fn().mockName('hook.ref'),
onChange: jest.fn().mockName('hook.onChange'),

View File

@@ -4,8 +4,6 @@ import { render } from '@testing-library/react';
import useReasonInputData from './hooks';
import ReasonInput, { controlTestId } from '.';
jest.unmock('react');
jest.unmock('@openedx/paragon');
jest.mock('./hooks', () => ({ __esModule: true, default: jest.fn() }));
const focus = jest.fn();

View File

@@ -1,5 +1,4 @@
import { useIntl } from '@edx/frontend-platform/i18n';
import { formatMessage } from 'testUtils';
import { gradeOverrideHistoryColumns as columns } from 'data/constants/app';
import { selectors } from 'data/redux/hooks';
@@ -16,6 +15,18 @@ jest.mock('data/redux/hooks', () => ({
},
}));
jest.mock('react', () => ({
...jest.requireActual('react'),
useContext: jest.fn(context => context),
}));
jest.mock('@edx/frontend-platform/i18n', () => ({
...jest.requireActual('@edx/frontend-platform/i18n'),
useIntl: jest.fn(() => ({
formatMessage: (message) => message.defaultMessage,
})),
}));
selectors.grades.useHasOverrideErrors.mockReturnValue(false);
const gradeOverrides = ['some', 'override', 'data'];
const gradeData = { gradeOverrideHistoryResults: gradeOverrides };
@@ -44,22 +55,22 @@ describe('useOverrideTableData', () => {
describe('columns', () => {
test('date column', () => {
const { Header, accessor } = out.columns[0];
expect(Header).toEqual(formatMessage(messages.dateHeader));
expect(Header).toEqual(messages.dateHeader.defaultMessage);
expect(accessor).toEqual(columns.date);
});
test('grader column', () => {
const { Header, accessor } = out.columns[1];
expect(Header).toEqual(formatMessage(messages.graderHeader));
expect(Header).toEqual(messages.graderHeader.defaultMessage);
expect(accessor).toEqual(columns.grader);
});
test('reason column', () => {
const { Header, accessor } = out.columns[2];
expect(Header).toEqual(formatMessage(messages.reasonHeader));
expect(Header).toEqual(messages.reasonHeader.defaultMessage);
expect(accessor).toEqual(columns.reason);
});
test('adjustedGrade column', () => {
const { Header, accessor } = out.columns[3];
expect(Header).toEqual(formatMessage(messages.adjustedGradeHeader));
expect(Header).toEqual(messages.adjustedGradeHeader.defaultMessage);
expect(accessor).toEqual(columns.adjustedGrade);
});
});

View File

@@ -1,13 +1,9 @@
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 useOverrideTableData from './hooks';
import OverrideTable from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
import { renderWithIntl } from '../../../../testUtilsExtra';
jest.mock('utils', () => ({
...jest.requireActual('utils'),
@@ -41,19 +37,19 @@ describe('OverrideTable component', () => {
describe('hooks', () => {
it('initializes hook data', () => {
useOverrideTableData.mockReturnValue(hookProps);
render(<IntlProvider locale="en"><OverrideTable /></IntlProvider>);
renderWithIntl(<OverrideTable />);
expect(useOverrideTableData).toHaveBeenCalled();
});
});
describe('behavior', () => {
it('null render if hide', () => {
useOverrideTableData.mockReturnValue({ ...hookProps, hide: true });
render(<IntlProvider locale="en"><OverrideTable /></IntlProvider>);
renderWithIntl(<OverrideTable />);
expect(screen.queryByRole('table')).toBeNull();
});
it('renders table with correct data', () => {
useOverrideTableData.mockReturnValue(hookProps);
render(<IntlProvider locale="en"><OverrideTable /></IntlProvider>);
renderWithIntl(<OverrideTable />);
const table = screen.getByRole('table');
expect(table).toBeInTheDocument();
expect(screen.getByText(hookProps.columns[0].Header)).toBeInTheDocument();

View File

@@ -1,19 +1,15 @@
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 useEditModalData from './hooks';
import EditModal from '.';
import messages from './messages';
import { renderWithIntl } from '../../../testUtilsExtra';
jest.mock('./hooks', () => jest.fn());
jest.mock('./ModalHeaders', () => jest.fn(() => <div>ModalHeaders</div>));
jest.mock('./OverrideTable', () => jest.fn(() => <div>OverrideTable</div>));
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
const hookProps = {
onClose: jest.fn().mockName('hooks.onClose'),
error: 'test-error',
@@ -28,7 +24,7 @@ describe('EditModal component', () => {
describe('behavior', () => {
it('initializes component hooks', () => {
useEditModalData.mockReturnValue(hookProps);
render(<IntlProvider locale="en"><EditModal /></IntlProvider>);
renderWithIntl(<EditModal />);
expect(useEditModalData).toHaveBeenCalled();
});
});
@@ -80,7 +76,7 @@ describe('EditModal component', () => {
describe('without error', () => {
beforeEach(() => {
useEditModalData.mockReturnValueOnce({ ...hookProps, error: undefined });
render(<IntlProvider locale="en"><EditModal /></IntlProvider>);
renderWithIntl(<EditModal />);
});
testModal();
testBody();
@@ -93,7 +89,7 @@ describe('EditModal component', () => {
describe('with error', () => {
beforeEach(() => {
useEditModalData.mockReturnValue(hookProps);
render(<IntlProvider locale="en"><EditModal /></IntlProvider>);
renderWithIntl(<EditModal />);
});
testModal();
testBody();

View File

@@ -1,15 +1,12 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { useIntl } from '@edx/frontend-platform/i18n';
import { screen } from '@testing-library/react';
import { formatMessage } from 'testUtils';
import { selectors } from 'data/redux/hooks';
import userEvent from '@testing-library/user-event';
import FilterBadge from './FilterBadge';
import { renderWithIntl } from '../../../testUtilsExtra';
jest.mock('@openedx/paragon', () => ({
Button: () => 'Button',
}));
jest.mock('data/redux/hooks', () => ({
selectors: {
root: {
@@ -18,14 +15,12 @@ jest.mock('data/redux/hooks', () => ({
},
}));
jest.unmock('@openedx/paragon');
jest.unmock('react');
const handleClose = jest.fn();
const filterName = 'test-filter-name';
const hookProps = {
displayName: {
id: 'test.id',
defaultMessage: 'a common name',
},
isDefault: false,
@@ -38,10 +33,7 @@ selectors.root.useFilterBadgeConfig.mockReturnValue(hookProps);
describe('FilterBadge', () => {
describe('hooks', () => {
beforeEach(() => {
render(<FilterBadge {...{ handleClose, filterName }} />);
});
it('initializes intl hook', () => {
expect(useIntl).toHaveBeenCalled();
renderWithIntl(<FilterBadge {...{ handleClose, filterName }} />);
});
it('initializes redux hooks', () => {
expect(selectors.root.useFilterBadgeConfig).toHaveBeenCalledWith(filterName);
@@ -53,7 +45,7 @@ describe('FilterBadge', () => {
...hookProps,
isDefault: true,
});
render(<FilterBadge {...{ handleClose, filterName }} />);
renderWithIntl(<FilterBadge {...{ handleClose, filterName }} />);
expect(screen.queryByText(hookProps.displayName)).toBeNull();
});
describe('hide Value', () => {
@@ -62,7 +54,7 @@ describe('FilterBadge', () => {
...hookProps,
hideValue: true,
});
render(<FilterBadge {...{ handleClose, filterName }} />);
renderWithIntl(<FilterBadge {...{ handleClose, filterName }} />);
const user = userEvent.setup();
expect(screen.getByTestId('display-name')).toHaveTextContent(formatMessage(hookProps.displayName));
expect(screen.queryByTestId('filter-value')).toHaveTextContent('');
@@ -77,7 +69,7 @@ describe('FilterBadge', () => {
...hookProps,
hideValue: false,
});
render(<FilterBadge {...{ handleClose, filterName }} />);
renderWithIntl(<FilterBadge {...{ handleClose, filterName }} />);
const user = userEvent.setup();
expect(screen.getByTestId('display-name')).toHaveTextContent(formatMessage(hookProps.displayName));
expect(screen.getByTestId('filter-value')).toHaveTextContent(`: ${hookProps.value}`);

View File

@@ -6,9 +6,6 @@ import userEvent from '@testing-library/user-event';
import FilterBadges from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
const order = ['filter1', 'filter2', 'filter3'];
jest.mock('data/constants/filters', () => ({
...jest.requireActual('data/constants/filters'),

View File

@@ -1,11 +1,11 @@
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 { formatMessage } from 'testUtils';
import { thunkActions } from 'data/redux/hooks';
import FilterMenuToggle from '.';
import messages from './messages';
import { renderWithIntl } from '../../../testUtilsExtra';
jest.mock('data/redux/hooks', () => ({
thunkActions: {
@@ -17,17 +17,13 @@ jest.mock('data/redux/hooks', () => ({
},
}));
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
const toggleFilterMenu = jest.fn().mockName('hooks.toggleFilterMenu');
thunkActions.app.filterMenu.useToggleMenu.mockReturnValue(toggleFilterMenu);
describe('FilterMenuToggle component', () => {
beforeEach(() => {
jest.clearAllMocks();
render(<IntlProvider locale="en"><FilterMenuToggle /></IntlProvider>);
renderWithIntl(<FilterMenuToggle />);
});
describe('behavior', () => {
it('initializes redux hooks', () => {

View File

@@ -1,14 +1,9 @@
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/hooks';
import FilteredUsersLabel from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
import { renderWithIntl } from '../../../testUtilsExtra';
jest.mock('data/redux/hooks', () => ({
selectors: {
@@ -30,7 +25,7 @@ describe('FilteredUsersLabel component', () => {
});
describe('behavior', () => {
it('initializes redux hooks', () => {
render(<IntlProvider locale="en"><FilteredUsersLabel /></IntlProvider>);
renderWithIntl(<FilteredUsersLabel />);
expect(selectors.grades.useUserCounts).toHaveBeenCalled();
});
});
@@ -40,11 +35,11 @@ describe('FilteredUsersLabel component', () => {
...userCounts,
totalUsersCount: 0,
});
const { container } = render(<IntlProvider locale="en"><FilteredUsersLabel /></IntlProvider>);
const { container } = renderWithIntl(<FilteredUsersLabel />);
expect(container.firstChild).toBeNull();
});
it('renders users count correctly', () => {
render(<IntlProvider locale="en"><FilteredUsersLabel /></IntlProvider>);
renderWithIntl(<FilteredUsersLabel />);
expect(screen.getByText((text) => text.includes(userCounts.filteredUsersCount))).toBeInTheDocument();
expect(screen.getByText((text) => text.includes(userCounts.totalUsersCount))).toBeInTheDocument();
});

View File

@@ -26,10 +26,6 @@ jest.mock('data/redux/transforms', () => ({
},
}));
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
const props = {
subsection: {
attempted: false,

View File

@@ -1,7 +1,8 @@
import { render, screen } from '@testing-library/react';
import { getLocale, IntlProvider } from '@edx/frontend-platform/i18n';
import { screen } from '@testing-library/react';
import { getLocale } from '@edx/frontend-platform/i18n';
import LabelReplacements from './LabelReplacements';
import messages from './messages';
import { renderWithIntl } from '../../../testUtilsExtra';
const {
TotalGradeLabelReplacement,
@@ -9,10 +10,6 @@ const {
MastersOnlyLabelReplacement,
} = LabelReplacements;
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('@edx/frontend-platform/i18n', () => ({
...jest.requireActual('@edx/frontend-platform/i18n'),
getLocale: jest.fn(),
@@ -22,7 +19,7 @@ jest.mock('@edx/frontend-platform/i18n', () => ({
describe('LabelReplacements', () => {
describe('TotalGradeLabelReplacement', () => {
getLocale.mockImplementation(() => 'en');
render(<IntlProvider locale="en"><TotalGradeLabelReplacement /></IntlProvider>);
renderWithIntl(<TotalGradeLabelReplacement />);
it('displays overlay tooltip', () => {
const tooltip = screen.getByText(messages.totalGradePercentage.defaultMessage);
expect(tooltip).toBeInTheDocument();
@@ -30,7 +27,7 @@ describe('LabelReplacements', () => {
});
describe('UsernameLabelReplacement', () => {
it('renders correctly', () => {
render(<IntlProvider locale="en"><UsernameLabelReplacement /></IntlProvider>);
renderWithIntl(<UsernameLabelReplacement />);
expect(screen.getByText(messages.usernameHeading.defaultMessage)).toBeInTheDocument();
});
});
@@ -41,7 +38,7 @@ describe('LabelReplacements', () => {
defaultMessage: 'defaultMessAge',
description: 'desCripTion',
};
render(<IntlProvider locale="en"><MastersOnlyLabelReplacement {...message} /></IntlProvider>);
renderWithIntl(<MastersOnlyLabelReplacement {...message} />);
expect(screen.getByText(message.defaultMessage)).toBeInTheDocument();
});
});

View File

@@ -5,10 +5,6 @@ import { initializeMocks, render } from '../../../testUtilsExtra';
import * as hooks from './hooks';
import messages from './messages';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
let mockUseAllGrades;
let mockUseGetHeadings;

View File

@@ -1,15 +1,11 @@
import { render, screen } from '@testing-library/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { screen } from '@testing-library/react';
import useGradebookTableData from './hooks';
import GradebookTable from '.';
import { renderWithIntl } from '../../../testUtilsExtra';
jest.mock('./hooks', () => jest.fn());
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
const hookProps = {
columns: [{ Header: 'Username', accessor: 'username' }, { Header: 'Email', accessor: 'email' }, { Header: 'Total Grade', accessor: 'totalGrade' }],
data: [{ username: 'instructor', email: 'instructor@example.com', totalGrade: '100' }, { username: 'student', email: 'student@example.com', totalGrade: '90' }],
@@ -21,7 +17,7 @@ const hookProps = {
describe('GradebookTable', () => {
it('renders Datatable correctly', () => {
useGradebookTableData.mockReturnValue(hookProps);
render(<IntlProvider locale="en"><GradebookTable /></IntlProvider>);
renderWithIntl(<GradebookTable />);
expect(useGradebookTableData).toHaveBeenCalled();
const headers = screen.getAllByRole('columnheader');
expect(headers).toHaveLength(3);
@@ -40,7 +36,7 @@ describe('GradebookTable', () => {
data: [],
grades: [],
});
render(<IntlProvider locale="en"><GradebookTable /></IntlProvider>);
renderWithIntl(<GradebookTable />);
expect(screen.getByText(hookProps.emptyContent)).toBeInTheDocument();
});
});

View File

@@ -12,6 +12,11 @@ jest.mock('data/redux/hooks', () => ({
},
}));
jest.mock('react', () => ({
...jest.requireActual('react'),
useRef: jest.fn((val) => ({ current: val, useRef: true })),
}));
let out;
let submitThen;

View File

@@ -6,10 +6,6 @@ import {
import ImportGradesButton from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
initializeMocks();
describe('ImportGradesButton component', () => {

View File

@@ -1,11 +1,8 @@
import React from 'react';
import { render } from '@testing-library/react';
import useImportGradesButtonData from './hooks';
import ImportGradesButton from '.';
import { renderWithIntl, screen } from '../../../testUtilsExtra';
jest.unmock('react');
jest.unmock('@openedx/paragon');
jest.mock('components/NetworkButton', () => 'network-button');
jest.mock('./hooks', () => ({ __esModule: true, default: jest.fn() }));
@@ -17,11 +14,10 @@ const props = {
};
useImportGradesButtonData.mockReturnValue(props);
let el;
describe('ImportGradesButton ref test', () => {
it('loads ref from hook', () => {
el = render(<ImportGradesButton />);
const input = el.getByTestId('file-control');
renderWithIntl(<ImportGradesButton />);
const input = screen.getByTestId('file-control');
expect(input).toEqual(props.fileInputRef.current);
});
});

View File

@@ -19,6 +19,18 @@ jest.mock('data/redux/hooks', () => ({
},
}));
jest.mock('react', () => ({
...jest.requireActual('react'),
useContext: jest.fn(context => context),
}));
jest.mock('@edx/frontend-platform/i18n', () => ({
...jest.requireActual('@edx/frontend-platform/i18n'),
useIntl: jest.fn(() => ({
formatMessage: (message) => message.defaultMessage,
})),
}));
const setView = jest.fn().mockName('hooks.setView');
const setShowToast = jest.fn().mockName('hooks.setShowImportSuccessToast');
actions.app.useSetView.mockReturnValue(setView);

View File

@@ -5,10 +5,6 @@ import { render, initializeMocks, screen } from 'testUtilsExtra';
import ImportSuccessToast from '.';
import useImportSuccessToastData from './hooks';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('data/redux/hooks', () => ({
actions: {
app: {

View File

@@ -4,10 +4,6 @@ import { render, screen, initializeMocks } from 'testUtilsExtra';
import InterventionsReport from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('components/NetworkButton', () => 'NetworkButton');
jest.mock('./hooks', () => jest.fn());

View File

@@ -15,6 +15,18 @@ jest.mock('data/redux/hooks', () => ({
},
}));
jest.mock('react', () => ({
...jest.requireActual('react'),
useContext: jest.fn(context => context),
}));
jest.mock('@edx/frontend-platform/i18n', () => ({
...jest.requireActual('@edx/frontend-platform/i18n'),
useIntl: jest.fn(() => ({
formatMessage: (message) => message.defaultMessage,
})),
}));
const gradeData = { nextPage: 'test-next-page', prevPage: 'test-prev-page' };
selectors.grades.useGradeData.mockReturnValue(gradeData);

View File

@@ -5,9 +5,6 @@ import { initializeMocks, render, screen } from 'testUtilsExtra';
import usePageButtonsData from './hooks';
import PageButtons from '.';
jest.unmock('@openedx/paragon');
jest.unmock('@edx/frontend-platform/i18n');
jest.unmock('react');
jest.mock('./hooks', () => jest.fn());
const hookProps = {

View File

@@ -5,10 +5,6 @@ import userEvent from '@testing-library/user-event';
import { ScoreViewInput } from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('data/redux/hooks', () => ({
actions: {
grades: {

View File

@@ -18,6 +18,18 @@ jest.mock('data/redux/hooks', () => ({
},
}));
jest.mock('react', () => ({
...jest.requireActual('react'),
useContext: jest.fn(context => context),
}));
jest.mock('@edx/frontend-platform/i18n', () => ({
...jest.requireActual('@edx/frontend-platform/i18n'),
useIntl: jest.fn(() => ({
formatMessage: (message) => message.defaultMessage,
})),
}));
const searchValue = 'test-search-value';
selectors.app.useSearchValue.mockReturnValue(searchValue);
const setSearchValue = jest.fn();

View File

@@ -4,9 +4,6 @@ import { initializeMocks, render, screen } from 'testUtilsExtra';
import useSearchControlsData from './hooks';
import SearchControls from '.';
jest.unmock('@openedx/paragon');
jest.unmock('@edx/frontend-platform/i18n');
jest.unmock('react');
jest.mock('./hooks', () => jest.fn());
const hookProps = {

View File

@@ -4,9 +4,6 @@ import { render } from '@testing-library/react';
import { selectors } from 'data/redux/hooks';
import SpinnerIcon from './SpinnerIcon';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('data/redux/hooks', () => ({
selectors: {
root: { useShouldShowSpinner: jest.fn() },

View File

@@ -1,6 +1,5 @@
import { useIntl } from '@edx/frontend-platform/i18n';
import { formatMessage } from 'testUtils';
import { actions, selectors } from 'data/redux/hooks';
import useStatusAlertsData from './hooks';
@@ -16,6 +15,18 @@ jest.mock('data/redux/hooks', () => ({
},
}));
jest.mock('react', () => ({
...jest.requireActual('react'),
useContext: jest.fn(context => context),
}));
jest.mock('@edx/frontend-platform/i18n', () => ({
...jest.requireActual('@edx/frontend-platform/i18n'),
useIntl: jest.fn(() => ({
formatMessage: (message) => message.defaultMessage,
})),
}));
const validity = {
isMinValid: true,
isMaxValid: true,
@@ -49,7 +60,7 @@ describe('useStatusAlertsData', () => {
expect(out.successBanner.show).toEqual(showSuccess);
});
test('message', () => {
expect(out.successBanner.text).toEqual(formatMessage(messages.editSuccessAlert));
expect(out.successBanner.text).toEqual(messages.editSuccessAlert.defaultMessage);
});
});
describe('gradeFilter', () => {
@@ -70,7 +81,7 @@ describe('useStatusAlertsData', () => {
expect(out.gradeFilter.show).toEqual(true);
});
test('filter message', () => {
expect(out.gradeFilter.text).toEqual(formatMessage(messages.minGradeInvalid));
expect(out.gradeFilter.text).toEqual(messages.minGradeInvalid.defaultMessage);
});
});
describe('max filter is invalid', () => {
@@ -85,7 +96,7 @@ describe('useStatusAlertsData', () => {
expect(out.gradeFilter.show).toEqual(true);
});
test('filter message', () => {
expect(out.gradeFilter.text).toEqual(formatMessage(messages.maxGradeInvalid));
expect(out.gradeFilter.text).toEqual(messages.maxGradeInvalid.defaultMessage);
});
});
describe('both filters are invalid', () => {
@@ -101,7 +112,7 @@ describe('useStatusAlertsData', () => {
});
test('filter message', () => {
expect(out.gradeFilter.text).toEqual(
`${formatMessage(messages.minGradeInvalid)}${formatMessage(messages.maxGradeInvalid)}`,
`${messages.minGradeInvalid.defaultMessage}${messages.maxGradeInvalid.defaultMessage}`,
);
});
});

View File

@@ -5,7 +5,6 @@ import useStatusAlertsData from './hooks';
import StatusAlerts from '.';
jest.mock('./hooks', () => jest.fn());
jest.unmock('@openedx/paragon');
const hookProps = {
successBanner: {

View File

@@ -1,6 +1,5 @@
import { useIntl } from '@edx/frontend-platform/i18n';
import { formatMessage } from 'testUtils';
import { actions, thunkActions } from 'data/redux/hooks';
import useGradesViewData from './hooks';
@@ -15,6 +14,18 @@ jest.mock('data/redux/hooks', () => ({
},
}));
jest.mock('react', () => ({
...jest.requireActual('react'),
useContext: jest.fn(context => context),
}));
jest.mock('@edx/frontend-platform/i18n', () => ({
...jest.requireActual('@edx/frontend-platform/i18n'),
useIntl: jest.fn(() => ({
formatMessage: (message) => message.defaultMessage,
})),
}));
const fetchGrades = jest.fn();
thunkActions.grades.useFetchGrades.mockReturnValue(fetchGrades);
const resetFilters = jest.fn();
@@ -39,11 +50,11 @@ describe('useGradesViewData', () => {
});
describe('output', () => {
test('stepHeadings', () => {
expect(out.stepHeadings.filter).toEqual(formatMessage(messages.filterStepHeading));
expect(out.stepHeadings.gradebook).toEqual(formatMessage(messages.gradebookStepHeading));
expect(out.stepHeadings.filter).toEqual(messages.filterStepHeading.defaultMessage);
expect(out.stepHeadings.gradebook).toEqual(messages.gradebookStepHeading.defaultMessage);
});
test('mastersHint', () => {
expect(out.mastersHint).toEqual(formatMessage(messages.mastersHint));
expect(out.mastersHint).toEqual(messages.mastersHint.defaultMessage);
});
describe('handleFilterBadgeClose', () => {
it('resets filters locally and in query params, and fetches grades', () => {

View File

@@ -6,9 +6,6 @@ import { render, initializeMocks } from 'testUtilsExtra';
import useGradesViewData from './hooks';
import GradesView from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('./hooks', () => jest.fn());
const hookProps = {

View File

@@ -6,10 +6,6 @@ import userEvent from '@testing-library/user-event';
import { NetworkButton, mapStateToProps, buttonStates } from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('data/selectors', () => ({
root: {
shouldShowSpinner: jest.fn(),

View File

@@ -4,10 +4,6 @@ import { render, screen, initializeMocks } from 'testUtilsExtra';
import { WithSidebar, mapStateToProps, mapDispatchToProps } from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('data/selectors', () => ({
app: {
filterMenu: {

View File

@@ -4,10 +4,6 @@ import { render, screen, initializeMocks } from 'testUtilsExtra';
import { GradebookPage, mapStateToProps, mapDispatchToProps } from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock(
'components/WithSidebar',
// eslint-disable-next-line react/prop-types

View File

@@ -8,6 +8,11 @@ import { formatDateForDisplay } from '../actions/utils';
import * as selectors from './grades';
import exportedSelectors from './grades';
jest.mock('@edx/frontend-platform/i18n', () => ({
...jest.requireActual('@edx/frontend-platform/i18n'),
getLocale: jest.fn(),
}));
const { minGrade, maxGrade } = selectors;
const genericResultsRows = [

View File

@@ -4,10 +4,6 @@ import { initializeMocks, render, waitFor } from 'testUtilsExtra';
import Head from './Head';
jest.unmock('@openedx/paragon');
jest.unmock('@edx/frontend-platform/i18n');
jest.unmock('react');
describe('Head', () => {
it('should match render title tag and favicon with the site configuration values', async () => {
initializeMocks();

View File

@@ -17,102 +17,3 @@ process.env.LOGOUT_URL = `${mockConfigs.LMS_BASE_URL}/logout`;
process.env.REFRESH_ACCESS_TOKEN_ENDPOINT = `${mockConfigs.LMS_BASE_URL}/refresh_access_token`;
process.env.ACCESS_TOKEN_COOKIE_NAME = 'edx';
process.env.CSRF_TOKEN_API_PATH = 'TOKEN_PATH';
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: jest.fn(() => ({
formatMessage,
formatDate,
})),
IntlProvider: () => 'IntlProvider',
defineMessages: m => m,
FormattedMessage: () => 'FormattedMessage',
getLocale: jest.fn(),
};
});
jest.mock('@edx/frontend-component-header', () => ({
messages: ['some', 'messages'],
}));
jest.mock('@edx/frontend-component-footer', () => ({
messages: ['some', 'messages'],
}));
jest.mock('@openedx/paragon/icons', () => ({
FilterAlt: 'FilterAlt',
Close: 'Close',
}));
jest.mock('@openedx/paragon', () => jest.requireActual('testUtils').mockNestedComponents({
Alert: 'Alert',
ActionRow: 'ActionRow',
Badge: 'Badge',
Button: 'Button',
Collapsible: {
Advanced: 'Collapsible.Advanced',
Body: 'Collapsible.Body',
Trigger: 'Collapsible.Trigger',
Visible: 'Collapsible.Visible',
},
DataTable: {
EmptyTable: 'DataTable.EmptyTable',
Table: 'DataTable.Table',
TableControlBar: 'DataTable.TableControlBar',
TableController: 'DataTable.TableController',
TableFooter: 'DataTable.TableFooter',
},
Form: {
Checkbox: 'Form.Checkbox',
CheckboxSet: 'Form.CheckboxSet',
Control: {
Feedback: 'Form.Control.Feedback',
},
Group: 'Form.Group',
Label: 'Form.Label',
Radio: 'Form.Radio',
RadioSet: 'Form.RadioSet',
Switch: 'Form.Switch',
},
FormControl: 'FormControl',
FormGroup: 'FormGroup',
FormLabel: 'FormLabel',
Hyperlink: 'Hyperlink',
Icon: 'Icon',
IconButton: 'IconButton',
Input: 'Input',
ModalDialog: {
Body: 'ModalDialog.Body',
CloseButton: 'ModalDialog.CloseButton',
Header: 'ModalDialog.Header',
Hero: 'ModalDialog.Hero',
Footer: 'ModalDialog.Footer',
},
OverlayTrigger: 'OverlayTrigger',
Row: 'Row',
SearchField: 'SearchField',
Spinner: 'Spinner',
StatefulButton: 'StatefulButton',
Toast: 'Toast',
useCheckboxSetValues: () => jest.fn().mockImplementation((values) => ([values, {
add: jest.fn().mockName('useCheckboxSetValues.add'),
remove: jest.fn().mockName('useCheckboxSetValues.remove'),
}])),
}));
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 } })),
useMemo: jest.fn((cb, prereqs) => cb(prereqs)),
useContext: jest.fn(context => context),
}));

View File

@@ -143,3 +143,9 @@ export * from '@testing-library/react';
export {
customRender as render,
};
export const renderWithIntl = (component) => render(
<IntlProvider locale="en" messages={{}}>
{component}
</IntlProvider>,
);