Skip to content

Commit a920f66

Browse files
chore(tests): migrate test cases from Enzyme to React Testing Library
1 parent 4e29750 commit a920f66

File tree

82 files changed

+9544
-7937
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+9544
-7937
lines changed

jest.config.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
const { createConfig } = require('@openedx/frontend-build');
2-
2+
const { TestEnvironment } = require('jest-environment-jsdom');
33
module.exports = createConfig('jest', {
44
setupFiles: ['<rootDir>/src/setupTest.js'],
5+
testEnvironment: 'jsdom',
6+
7+
8+
9+
setupFilesAfterEnv: ['@testing-library/jest-dom'],
10+
11+
12+
513
collectCoverage: true,
614
collectCoverageFrom: ['src/**/*.{js,jsx}'],
715
coveragePathIgnorePatterns: [

package-lock.json

Lines changed: 5927 additions & 4912 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"lint:fix": "fedx-scripts eslint --fix --ext .js --ext .jsx .",
1717
"start": "fedx-scripts webpack-dev-server --progress",
1818
"debug-test": "node --inspect-brk node_modules/.bin/jest --coverage --runInBand",
19-
"test": "TZ=UTC fedx-scripts jest --coverage --maxWorkers=2",
19+
"test": "fedx-scripts jest --coverage --maxWorkers=2",
2020
"test:watch": "npm run test -- --watch",
2121
"snapshot": "fedx-scripts jest --updateSnapshot"
2222
},
@@ -31,15 +31,15 @@
3131
},
3232
"dependencies": {
3333
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
34-
"@edx/frontend-enterprise-utils": "9.1.0",
35-
"@edx/frontend-platform": "^8.3.2",
34+
"@edx/frontend-enterprise-utils": "^10.0.0",
35+
"@edx/frontend-platform": "^8.5.0",
3636
"@edx/openedx-atlas": "^0.6.0",
3737
"@fortawesome/fontawesome-svg-core": "1.2.32",
3838
"@fortawesome/free-brands-svg-icons": "5.15.1",
3939
"@fortawesome/free-regular-svg-icons": "5.15.1",
4040
"@fortawesome/free-solid-svg-icons": "5.15.1",
4141
"@fortawesome/react-fontawesome": "^0.1.14",
42-
"@openedx/paragon": "^23.4.2",
42+
"@openedx/paragon": "^22.17.0",
4343
"axios": "^1.7.7",
4444
"babel-polyfill": "6.26.0",
4545
"classnames": "2.2.6",
@@ -48,36 +48,34 @@
4848
"lodash.snakecase": "4.1.1",
4949
"moment": "2.29.4",
5050
"prop-types": "15.7.2",
51-
"react": "17.0.2",
52-
"react-dom": "17.0.2",
53-
"react-helmet": "^6.1.0",
54-
"react-redux": "^7.2.9",
51+
"react": "18.3.1",
52+
"react-dom": "18.3.1",
53+
"react-helmet-async": "^2.0.4",
54+
"react-redux": "^8.1.3",
5555
"react-responsive": "^8.2.0",
5656
"react-router": "6.15.0",
5757
"react-router-dom": "6.15.0",
5858
"react-table": "^7.6.3",
5959
"react-transition-group": "4.4.1",
60-
"redux": "4.0.5",
60+
"redux": "^4.2.1",
6161
"use-context-selector": "1.4.1",
6262
"uuid": "9.0.0"
6363
},
6464
"devDependencies": {
6565
"@edx/browserslist-config": "^1.1.0",
6666
"@edx/reactifex": "^1.0.3",
67-
"@openedx/frontend-build": "^14.3.3",
68-
"@testing-library/dom": "^9.3.4",
69-
"@testing-library/jest-dom": "^5.17.0",
70-
"@testing-library/react": "12.1.4",
71-
"@testing-library/react-hooks": "^8.0.1",
67+
"@emotion/jest": "^11.13.0",
68+
"@openedx/frontend-build": "^14.6.0",
69+
"@testing-library/jest-dom": "^6.6.4",
70+
"@testing-library/react": "^14.3.1",
7271
"@testing-library/user-event": "^14.5.2",
7372
"@types/react-table": "^7.7.2",
74-
"@wojtekmaj/enzyme-adapter-react-17": "^0.8.0",
7573
"axios-mock-adapter": "^1.19.0",
76-
"enzyme": "3.11.0",
7774
"glob": "7.1.6",
7875
"jest": "^29.7.0",
76+
"jest-emotion": "^11.0.0",
7977
"jest-environment-jsdom": "^29.7.0",
80-
"react-test-renderer": "^17.0.2",
78+
"react-test-renderer": "^18.3.1",
8179
"reactifex": "1.1.1"
8280
}
8381
}

src/Configuration/Customers/data/hooks/tests/useCustomerUsersTableData.test.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { renderHook } from '@testing-library/react-hooks';
2-
import { waitFor } from '@testing-library/react';
1+
import { renderHook, waitFor } from '@testing-library/react';
32

43
import LmsApiService from '../../../../../data/services/EnterpriseApiService';
54
import useCustomerUsersTableData from '../useCustomerUsersTableData';
@@ -14,9 +13,12 @@ describe('useCustomerUsersTableData', () => {
1413
};
1514
const { result } = renderHook(() => useCustomerUsersTableData(args));
1615
const { enterpriseUsersTableData } = result.current;
17-
expect(enterpriseUsersTableData).toEqual({ itemCount: 0, pageCount: 0, results: [] });
16+
expect(enterpriseUsersTableData).toEqual({
17+
itemCount: 0,
18+
pageCount: 0,
19+
results: [],
20+
});
1821

19-
// shouldn't fetch because its only 2 characters
2022
const searchArgs1 = {
2123
filters: [{ id: 'details', value: 'vi' }],
2224
sortBy: [{}],
Lines changed: 93 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
/* eslint-disable react/prop-types */
1+
import PropTypes from 'prop-types';
22
import { renderWithRouter } from '@edx/frontend-enterprise-utils';
3-
import {
4-
fireEvent, screen, waitFor, act,
5-
} from '@testing-library/react';
3+
import { fireEvent, screen, waitFor } from '@testing-library/react';
64
import ProvisioningFormCustomCatalogDropdown from '../ProvisioningFormCustomCatalogDropdown';
75
import { initialStateValue, ProvisioningContext } from '../../../../testData/Provisioning';
86
import PROVISIONING_PAGE_TEXT from '../../../data/constants';
@@ -22,126 +20,167 @@ jest.mock('../../../../../data/services/EnterpriseApiService', () => ({
2220
fetchEnterpriseCustomerCatalogs: jest.fn(() => Promise.resolve(mockData)),
2321
}));
2422

25-
// Patch frontend-platform to serve a custom version of PREDEFINED_CATALOG_QUERIES.
2623
jest.mock('@edx/frontend-platform', () => ({
2724
...jest.requireActual('@edx/frontend-platform'),
2825
getConfig: jest.fn(() => ({
2926
PREDEFINED_CATALOG_QUERIES: MOCK_PREDEFINED_CATALOG_QUERIES,
3027
})),
3128
}));
3229

33-
const ProvisioningFormCustomCatalogDropdownWrapper = ({
34-
value = {
30+
const ProvisioningFormCustomCatalogDropdownWrapper = ({ value }) => (
31+
<ProvisioningContext value={value}>
32+
<ProvisioningFormCustomCatalogDropdown />
33+
</ProvisioningContext>
34+
);
35+
36+
ProvisioningFormCustomCatalogDropdownWrapper.propTypes = {
37+
value: PropTypes.shape({
38+
existingEnterpriseCatalogs: PropTypes.shape({
39+
data: PropTypes.arrayOf(
40+
PropTypes.shape({
41+
title: PropTypes.string,
42+
enterpriseCatalogQuery: PropTypes.string,
43+
uuid: PropTypes.string,
44+
}),
45+
),
46+
isLoading: PropTypes.bool,
47+
}),
48+
isEditMode: PropTypes.bool,
49+
formData: PropTypes.shape({
50+
policies: PropTypes.arrayOf(
51+
PropTypes.shape({
52+
oldCustomCatalog: PropTypes.bool,
53+
oldCatalogTitle: PropTypes.string,
54+
customCatalog: PropTypes.bool,
55+
catalogTitle: PropTypes.string,
56+
catalogUuid: PropTypes.string,
57+
}),
58+
),
59+
}),
60+
}),
61+
};
62+
63+
ProvisioningFormCustomCatalogDropdownWrapper.defaultProps = {
64+
value: {
3565
...initialStateValue,
3666
existingEnterpriseCatalogs: {
3767
data: sampleCatalogs,
3868
isLoading: false,
3969
},
4070
},
41-
}) => (
42-
<ProvisioningContext value={value}>
43-
<ProvisioningFormCustomCatalogDropdown />
44-
</ProvisioningContext>
45-
);
71+
};
4672

4773
describe('ProvisioningFormCustomCatalogDropdown', () => {
4874
beforeEach(() => {
4975
jest.clearAllMocks();
5076
});
51-
it('renders the custom catalog dropdown', () => {
52-
renderWithRouter(
53-
<ProvisioningFormCustomCatalogDropdownWrapper />,
54-
);
5577

78+
it('renders the custom catalog dropdown', () => {
79+
renderWithRouter(<ProvisioningFormCustomCatalogDropdownWrapper />);
5680
expect(screen.getByText(CUSTOM_CATALOG.OPTIONS.enterpriseCatalog.title)).toBeTruthy();
5781
expect(screen.getByText(CUSTOM_CATALOG.OPTIONS.enterpriseCatalog.subtitle)).toBeTruthy();
5882
});
83+
5984
it('renders the custom catalog dropdown options', () => {
60-
renderWithRouter(
61-
<ProvisioningFormCustomCatalogDropdownWrapper />,
62-
);
85+
renderWithRouter(<ProvisioningFormCustomCatalogDropdownWrapper />);
6386

6487
const autoSuggestInput = screen.getByTestId('custom-catalog-dropdown-autosuggest');
6588
const autoSuggestButton = screen.getAllByRole('button')[0];
66-
// open dropdown
6789
fireEvent.click(autoSuggestButton);
68-
// Check values are populating
90+
6991
const { queryIdToQueryType } = getPredefinedCatalogQueryMappings();
7092
sampleCatalogs.forEach(({ title, enterpriseCatalogQuery }) => {
7193
if (!(enterpriseCatalogQuery in queryIdToQueryType)) {
7294
expect(screen.getByText(title, { exact: false })).toBeTruthy();
7395
}
7496
});
97+
7598
const autoSuggestDropdownButtons = screen.getAllByRole('button');
7699
const filteredDropdowns = autoSuggestDropdownButtons.filter((element) => element.textContent.includes('73cb6181'));
77-
// close dropdown
100+
78101
fireEvent.click(autoSuggestButton);
79102

80103
for (let i = 0; i < filteredDropdowns.length; i++) {
81104
fireEvent.click(autoSuggestButton);
82105
fireEvent.click(filteredDropdowns[i]);
83-
waitFor(() => expect(autoSuggestInput.getAttribute('value')).toContain(filteredDropdowns[i].textContent));
106+
waitFor(() => {
107+
expect(autoSuggestInput).toHaveValue(expect.stringContaining(filteredDropdowns[i].textContent));
108+
});
84109
}
85110
});
111+
86112
it('renders correct dropdown when catalogs list is still loading', () => {
87113
LmsApiService.fetchEnterpriseCustomerCatalogs.mockResolvedValueOnce({ data: { results: [] } });
88-
renderWithRouter(
89-
<ProvisioningFormCustomCatalogDropdownWrapper
90-
value={initialStateValue}
91-
/>,
92-
);
93-
114+
renderWithRouter(<ProvisioningFormCustomCatalogDropdownWrapper value={initialStateValue} />);
94115
const autoSuggestButton = screen.getAllByRole('button')[0];
95116
fireEvent.click(autoSuggestButton);
96117
expect(screen.getByText('Loading...')).toBeTruthy();
97118
});
119+
98120
it('renders correct dropdown when the selected customer has no custom catalogs', () => {
99121
LmsApiService.fetchEnterpriseCustomerCatalogs.mockResolvedValueOnce({ data: { results: [] } });
100122
renderWithRouter(
101123
<ProvisioningFormCustomCatalogDropdownWrapper
102124
value={{
103125
...initialStateValue,
104126
existingEnterpriseCatalogs: {
105-
data: [], // This customer has no custom/unique/curated catalogs!
127+
data: [],
106128
isLoading: false,
107129
},
108130
}}
109131
/>,
110132
);
111-
112133
const autoSuggestButton = screen.getAllByRole('button')[0];
113134
fireEvent.click(autoSuggestButton);
114135
expect(screen.getByText('No catalogs found for customer.')).toBeTruthy();
115136
});
137+
116138
it('renders default catalog query title when isEditMode is true', async () => {
117-
LmsApiService.fetchEnterpriseCustomerCatalogs.mockResolvedValue({ data: { results: sampleCatalogs } });
139+
const customSampleCatalogs = [
140+
...sampleCatalogs,
141+
{
142+
title: 'Snoopy gang',
143+
enterpriseCatalogQuery: 'custom-query',
144+
uuid: '4ev3r',
145+
},
146+
];
147+
148+
LmsApiService.fetchEnterpriseCustomerCatalogs.mockResolvedValue({
149+
data: { results: customSampleCatalogs },
150+
});
151+
118152
renderWithRouter(
119153
<ProvisioningFormCustomCatalogDropdownWrapper
120154
value={{
121155
...initialStateValue,
122156
isEditMode: true,
123157
existingEnterpriseCatalogs: {
124-
data: sampleCatalogs,
158+
data: customSampleCatalogs,
125159
isLoading: false,
126160
},
127161
formData: {
128-
policies: [{
129-
oldCustomCatalog: true,
130-
oldCatalogTitle: 'Snoopy gang',
131-
customCatalog: true,
132-
catalogTitle: 'Snoopy gang',
133-
catalogUuid: '4ev3r',
134-
}],
162+
policies: [
163+
{
164+
oldCustomCatalog: true,
165+
oldCatalogTitle: 'Snoopy gang',
166+
customCatalog: true,
167+
catalogTitle: 'Snoopy gang',
168+
catalogUuid: '4ev3r',
169+
},
170+
],
135171
},
136172
}}
137173
/>,
138174
);
139-
act(async () => {
140-
expect(await screen.findByRole('list', {
141-
name: 'Enterprise Catalog',
142-
}).value).toBe('Snoopy gang --- 4ev3r');
143-
});
175+
176+
const input = await screen.findByTestId('custom-catalog-dropdown-autosuggest');
177+
const toggleButton = screen.getAllByRole('button')[0];
178+
fireEvent.click(toggleButton);
179+
const option = await screen.findByText(/Snoopy gang --- 4ev3r/i);
180+
fireEvent.click(option);
181+
expect(input).toHaveValue('Snoopy gang --- 4ev3r');
144182
});
183+
145184
it('renders empty string title when isEditMode is false', async () => {
146185
renderWithRouter(
147186
<ProvisioningFormCustomCatalogDropdownWrapper
@@ -153,19 +192,18 @@ describe('ProvisioningFormCustomCatalogDropdown', () => {
153192
isLoading: false,
154193
},
155194
formData: {
156-
policies: [{
157-
customCatalog: true,
158-
catalogTitle: 'Snoopy gang',
159-
catalogUuid: '4ev3r',
160-
}],
195+
policies: [
196+
{
197+
customCatalog: true,
198+
catalogTitle: 'Snoopy gang',
199+
catalogUuid: '4ev3r',
200+
},
201+
],
161202
},
162203
}}
163204
/>,
164205
);
165-
act(async () => {
166-
expect(await screen.findByRole('list', {
167-
name: 'Enterprise Catalog',
168-
}).value).toBe('');
169-
});
206+
const input = await screen.findByTestId('custom-catalog-dropdown-autosuggest');
207+
expect(input).toHaveValue('');
170208
});
171209
});

0 commit comments

Comments
 (0)