Skip to content

Commit 42a2118

Browse files
test: Deprecate react-unit-test-utils 1/15 (#640)
1 parent c4205e9 commit 42a2118

File tree

11 files changed

+123
-222
lines changed

11 files changed

+123
-222
lines changed

package-lock.json

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

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
"@openedx/frontend-build": "^14.3.3",
7474
"@testing-library/jest-dom": "^6.6.3",
7575
"@testing-library/react": "^16.2.0",
76+
"@testing-library/user-event": "^14.6.1",
7677
"copy-webpack-plugin": "^12.0.0",
7778
"identity-obj-proxy": "^3.0.0",
7879
"jest": "^29.7.0",

src/components/Banner.test.jsx

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
1-
import { shallow } from '@edx/react-unit-test-utils';
1+
import { render, screen } from '@testing-library/react';
2+
import Banner from './Banner';
23

3-
import { Alert } from '@openedx/paragon';
4+
jest.unmock('@openedx/paragon');
5+
jest.unmock('react');
46

5-
import Banner from './Banner';
7+
describe('Banner component', () => {
8+
it('renders children content', () => {
9+
render(<Banner>Test content</Banner>);
10+
expect(screen.getByText('Test content')).toBeInTheDocument();
11+
});
612

7-
describe('Banner', () => {
8-
const props = {
9-
children: 'Hello, world!',
10-
};
11-
describe('snapshot', () => {
12-
test('renders default banner', () => {
13-
const wrapper = shallow(<Banner {...props} />);
14-
expect(wrapper.snapshot).toMatchSnapshot();
15-
});
16-
test('renders with variants', () => {
17-
const wrapper = shallow(<Banner {...props} variant="success" />);
18-
expect(wrapper.snapshot).toMatchSnapshot();
13+
it('uses default props correctly', () => {
14+
render(<Banner>Test content</Banner>);
15+
const banner = screen.getByRole('alert');
16+
expect(banner).toHaveClass('mb-0');
17+
});
18+
19+
it('accepts custom variant prop', () => {
20+
render(<Banner variant="success">Test content</Banner>);
21+
const banner = screen.getByRole('alert');
22+
expect(banner).toHaveClass('alert-success');
23+
});
1924

20-
expect(wrapper.instance.findByType(Alert)[0].props.variant).toEqual('success');
21-
});
22-
test('renders with custom class', () => {
23-
const wrapper = shallow(<Banner {...props} className="custom-class" />);
24-
expect(wrapper.snapshot).toMatchSnapshot();
25-
});
25+
it('accepts custom className prop', () => {
26+
render(<Banner className="custom-class">Test content</Banner>);
27+
const banner = screen.getByRole('alert');
28+
expect(banner).toHaveClass('custom-class');
2629
});
2730
});
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
import React from 'react';
2-
import { shallow } from '@edx/react-unit-test-utils';
1+
import { render, screen } from '@testing-library/react';
32

43
import useNoticesWrapperData from './hooks';
54
import NoticesWrapper from '.';
65

76
jest.mock('./hooks', () => jest.fn());
87

98
const hookProps = { isRedirected: false };
10-
useNoticesWrapperData.mockReturnValue(hookProps);
119

12-
let el;
1310
const children = [<b key={1}>some</b>, <i key={2}>children</i>];
1411
describe('NoticesWrapper component', () => {
12+
beforeEach(() => {
13+
useNoticesWrapperData.mockClear();
14+
});
1515
describe('behavior', () => {
1616
it('initializes hooks', () => {
17-
el = shallow(<NoticesWrapper>{children}</NoticesWrapper>);
17+
useNoticesWrapperData.mockReturnValue(hookProps);
18+
render(<NoticesWrapper>{children}</NoticesWrapper>);
1819
expect(useNoticesWrapperData).toHaveBeenCalledWith();
1920
});
2021
});
2122
describe('output', () => {
2223
it('does not show children if redirected', () => {
2324
useNoticesWrapperData.mockReturnValueOnce({ isRedirected: true });
24-
el = shallow(<NoticesWrapper>{children}</NoticesWrapper>);
25-
expect(el.instance.children.length).toEqual(0);
25+
render(<NoticesWrapper>{children}</NoticesWrapper>);
26+
expect(screen.queryByText('some')).not.toBeInTheDocument();
27+
expect(screen.queryByText('children')).not.toBeInTheDocument();
2628
});
2729
it('shows children if not redirected', () => {
28-
el = shallow(<NoticesWrapper>{children}</NoticesWrapper>);
29-
expect(el.instance.children.length).toEqual(2);
30-
expect(el.instance.children[0].type).toEqual(shallow(children[0]).type);
31-
expect(el.instance.props).toEqual(shallow(children[0]).props);
32-
expect(el.instance.children[1].type).toEqual(shallow(children[1]).type);
33-
expect(el.instance.props).toEqual(shallow(children[1]).props);
30+
useNoticesWrapperData.mockReturnValue(hookProps);
31+
render(<NoticesWrapper>{children}</NoticesWrapper>);
32+
expect(screen.getByText('some')).toBeInTheDocument();
33+
expect(screen.getByText('children')).toBeInTheDocument();
3434
});
3535
});
3636
});

src/components/__snapshots__/Banner.test.jsx.snap

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/containers/CourseCard/components/CourseCardActions/ActionButton/__snapshots__/index.test.jsx.snap

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
1-
import { shallow } from '@edx/react-unit-test-utils';
2-
1+
import { render, screen } from '@testing-library/react';
32
import ActionButton from '.';
43

54
import useIsCollapsed from './hooks';
65

76
jest.mock('./hooks', () => jest.fn());
87

8+
jest.unmock('@openedx/paragon');
9+
910
describe('ActionButton', () => {
1011
const props = {
11-
arbitary: 'props',
12+
className: 'custom-class',
13+
children: 'Test',
1214
};
13-
describe('snapshot', () => {
14-
test('is collapsed', () => {
15-
useIsCollapsed.mockReturnValueOnce(true);
16-
const wrapper = shallow(<ActionButton {...props} />);
17-
expect(wrapper.snapshot).toMatchSnapshot();
18-
});
19-
test('is not collapsed', () => {
20-
useIsCollapsed.mockReturnValueOnce(false);
21-
const wrapper = shallow(<ActionButton {...props} />);
22-
expect(wrapper.snapshot).toMatchSnapshot();
23-
});
15+
16+
it('is collapsed', async () => {
17+
useIsCollapsed.mockReturnValue(true);
18+
render(<ActionButton {...props} />);
19+
const button = screen.getByRole('button', { name: 'Test' });
20+
expect(button).toHaveClass('btn-sm', 'custom-class');
21+
});
22+
23+
it('is not collapsed', () => {
24+
useIsCollapsed.mockReturnValue(false);
25+
render(<ActionButton {...props} />);
26+
const button = screen.getByRole('button', { name: 'Test' });
27+
expect(button).toBeInTheDocument();
28+
expect(button).not.toHaveClass('size', 'sm');
2429
});
2530
});

src/containers/CourseCard/components/CourseCardActions/BeginCourseButton.test.jsx

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import { shallow } from '@edx/react-unit-test-utils';
2-
1+
import { render, screen } from '@testing-library/react';
2+
import userEvent from '@testing-library/user-event';
33
import { reduxHooks } from 'hooks';
44
import track from 'tracking';
55
import useActionDisabledState from '../hooks';
66
import BeginCourseButton from './BeginCourseButton';
77

8+
jest.unmock('@openedx/paragon');
9+
810
jest.mock('tracking', () => ({
911
course: {
1012
enterCourseClicked: jest.fn().mockName('segment.enterCourseClicked'),
@@ -18,10 +20,11 @@ jest.mock('hooks', () => ({
1820
useTrackCourseEvent: jest.fn(),
1921
},
2022
}));
23+
2124
jest.mock('../hooks', () => jest.fn(() => ({ disableBeginCourse: false })));
22-
jest.mock('./ActionButton', () => 'ActionButton');
2325

24-
let wrapper;
26+
jest.mock('./ActionButton/hooks', () => jest.fn(() => false));
27+
2528
const homeUrl = 'home-url';
2629
reduxHooks.useCardCourseRunData.mockReturnValue({ homeUrl });
2730
const execEdPath = (cardId) => `exec-ed-tracking-path=${cardId}`;
@@ -37,49 +40,47 @@ describe('BeginCourseButton', () => {
3740
beforeEach(() => {
3841
jest.clearAllMocks();
3942
});
40-
describe('behavior', () => {
43+
describe('initiliaze hooks', () => {
4144
it('initializes course run data with cardId', () => {
42-
wrapper = shallow(<BeginCourseButton {...props} />);
45+
render(<BeginCourseButton {...props} />);
4346
expect(reduxHooks.useCardCourseRunData).toHaveBeenCalledWith(props.cardId);
4447
});
4548
it('loads exec education path param', () => {
46-
wrapper = shallow(<BeginCourseButton {...props} />);
49+
render(<BeginCourseButton {...props} />);
4750
expect(reduxHooks.useCardExecEdTrackingParam).toHaveBeenCalledWith(props.cardId);
4851
});
4952
it('loads disabled states for begin action from action hooks', () => {
50-
wrapper = shallow(<BeginCourseButton {...props} />);
53+
render(<BeginCourseButton {...props} />);
5154
expect(useActionDisabledState).toHaveBeenCalledWith(props.cardId);
5255
});
5356
});
54-
describe('snapshot', () => {
57+
describe('behavior', () => {
5558
describe('disabled', () => {
56-
beforeEach(() => {
57-
useActionDisabledState.mockReturnValueOnce({ disableBeginCourse: true });
58-
wrapper = shallow(<BeginCourseButton {...props} />);
59-
});
60-
test('snapshot', () => {
61-
expect(wrapper.snapshot).toMatchSnapshot();
62-
});
6359
it('should be disabled', () => {
64-
expect(wrapper.instance.props.disabled).toEqual(true);
60+
useActionDisabledState.mockReturnValueOnce({ disableBeginCourse: true });
61+
render(<BeginCourseButton {...props} />);
62+
const button = screen.getByRole('button', { name: 'Begin Course' });
63+
expect(button).toHaveClass('disabled');
64+
expect(button).toHaveAttribute('aria-disabled', 'true');
6565
});
6666
});
6767
describe('enabled', () => {
68-
beforeEach(() => {
69-
wrapper = shallow(<BeginCourseButton {...props} />);
70-
});
71-
test('snapshot', () => {
72-
expect(wrapper.snapshot).toMatchSnapshot();
73-
});
7468
it('should be enabled', () => {
75-
expect(wrapper.instance.props.disabled).toEqual(false);
69+
render(<BeginCourseButton {...props} />);
70+
const button = screen.getByRole('button', { name: 'Begin Course' });
71+
expect(button).not.toHaveClass('disabled');
72+
expect(button).not.toHaveAttribute('aria-disabled', 'true');
7673
});
77-
it('should track enter course clicked event on click, with exec ed param', () => {
78-
expect(wrapper.instance.props.onClick).toEqual(reduxHooks.useTrackCourseEvent(
74+
it('should track enter course clicked event on click, with exec ed param', async () => {
75+
render(<BeginCourseButton {...props} />);
76+
const user = userEvent.setup();
77+
const button = screen.getByRole('button', { name: 'Begin Course' });
78+
user.click(button);
79+
expect(reduxHooks.useTrackCourseEvent).toHaveBeenCalledWith(
7980
track.course.enterCourseClicked,
8081
props.cardId,
8182
homeUrl + execEdPath(props.cardId),
82-
));
83+
);
8384
});
8485
});
8586
});

0 commit comments

Comments
 (0)