Skip to content

Commit 6ae8180

Browse files
test: Deprecate react-unit-test-utils 8/15 (#664)
1 parent ab0f139 commit 6ae8180

File tree

10 files changed

+178
-643
lines changed

10 files changed

+178
-643
lines changed

src/containers/CoursesPanel/__snapshots__/index.test.jsx.snap

Lines changed: 0 additions & 55 deletions
This file was deleted.
Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,93 @@
1-
import { shallow } from '@edx/react-unit-test-utils';
2-
1+
import { render, screen } from '@testing-library/react';
2+
import { IntlProvider } from '@edx/frontend-platform/i18n';
3+
import { FilterKeys } from 'data/constants/app';
34
import { reduxHooks } from 'hooks';
5+
6+
import messagesNoCourses from 'containers/CoursesPanel/NoCoursesView/messages';
47
import { useCourseListData } from './hooks';
58
import CoursesPanel from '.';
9+
import messages from './messages';
10+
11+
const courseSearchUrl = '/course-search-url';
612

713
jest.mock('hooks', () => ({
8-
reduxHooks: { useHasCourses: jest.fn() },
14+
reduxHooks: {
15+
useHasCourses: jest.fn(),
16+
usePlatformSettingsData: jest.fn(() => ({
17+
courseSearchUrl,
18+
})),
19+
},
920
}));
1021

1122
jest.mock('./hooks', () => ({
1223
useCourseListData: jest.fn(),
1324
}));
1425

15-
jest.mock('containers/CourseCard', () => 'CourseCard');
26+
jest.mock('containers/CourseCard', () => jest.fn(() => <div>CourseCard</div>));
1627
jest.mock('containers/CourseFilterControls', () => ({
17-
ActiveCourseFilters: 'ActiveCourseFilters',
18-
CourseFilterControls: 'CourseFilterControls',
28+
ActiveCourseFilters: jest.fn(() => <div>ActiveCourseFilters</div>),
29+
CourseFilterControls: jest.fn(() => <div>CourseFilterControls</div>),
1930
}));
31+
2032
jest.mock('@openedx/frontend-plugin-framework', () => ({
2133
PluginSlot: 'PluginSlot',
2234
}));
23-
jest.mock('./CourseList', () => 'CourseList');
35+
36+
jest.unmock('@edx/frontend-platform/i18n');
37+
jest.unmock('@openedx/paragon');
38+
jest.unmock('react');
39+
40+
const filters = Object.values(FilterKeys);
2441

2542
reduxHooks.useHasCourses.mockReturnValue(true);
2643

2744
describe('CoursesPanel', () => {
2845
const defaultCourseListData = {
29-
filterOptions: {},
46+
filterOptions: { filters, handleRemoveFilter: jest.fn() },
3047
numPages: 1,
3148
setPageNumber: jest.fn().mockName('setPageNumber'),
3249
showFilters: false,
3350
visibleList: [],
3451
};
3552

3653
const createWrapper = (courseListData) => {
37-
useCourseListData.mockReturnValueOnce({
54+
useCourseListData.mockReturnValue({
3855
...defaultCourseListData,
3956
...courseListData,
4057
});
41-
return shallow(<CoursesPanel />);
58+
return render(<IntlProvider locale="en"><CoursesPanel /></IntlProvider>);
4259
};
4360

4461
describe('no courses', () => {
45-
test('snapshot', () => {
62+
it('should render no courses view slot', () => {
4663
reduxHooks.useHasCourses.mockReturnValue(false);
47-
const wrapper = createWrapper();
48-
expect(wrapper.snapshot).toMatchSnapshot();
64+
createWrapper();
65+
const imgNoCourses = screen.getByRole('img', { name: messagesNoCourses.bannerAlt.defaultMessage });
66+
expect(imgNoCourses).toBeInTheDocument();
67+
const courseCard = screen.queryByText('CourseCard');
68+
expect(courseCard).toBeNull();
4969
});
5070
});
5171
describe('with courses', () => {
52-
test('snapshot', () => {
72+
it('should render courselist', () => {
73+
const visibleList = [{ cardId: 'foo' }, { cardId: 'bar' }, { cardId: 'baz' }];
74+
reduxHooks.useHasCourses.mockReturnValue(true);
75+
createWrapper({ visibleList });
76+
const courseCards = screen.getAllByText('CourseCard');
77+
expect(courseCards.length).toEqual(visibleList.length);
78+
});
79+
it('displays course filter controls', () => {
80+
reduxHooks.useHasCourses.mockReturnValue(true);
81+
createWrapper();
82+
expect(screen.getByText('CourseFilterControls')).toBeInTheDocument();
83+
});
84+
85+
it('displays course list slot when courses exist', () => {
5386
reduxHooks.useHasCourses.mockReturnValue(true);
54-
const wrapper = createWrapper();
55-
expect(wrapper.snapshot).toMatchSnapshot();
87+
const visibleList = [{ cardId: 'foo' }, { cardId: 'bar' }, { cardId: 'baz' }];
88+
createWrapper({ visibleList });
89+
const heading = screen.getByText(messages.myCourses.defaultMessage);
90+
expect(heading).toBeInTheDocument();
5691
});
5792
});
5893
});
Lines changed: 44 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,71 @@
1-
import React from 'react';
2-
import { shallow } from '@edx/react-unit-test-utils';
3-
import { Col, Row } from '@openedx/paragon';
1+
import { render, screen } from '@testing-library/react';
2+
import { IntlProvider } from '@edx/frontend-platform/i18n';
43

54
import hooks from './hooks';
6-
import DashboardLayout, { columnConfig } from './DashboardLayout';
5+
import DashboardLayout from './DashboardLayout';
76

87
jest.mock('./hooks', () => ({
98
useDashboardLayoutData: jest.fn(),
109
}));
1110

11+
jest.mock('@openedx/frontend-plugin-framework', () => ({
12+
PluginSlot: 'PluginSlot',
13+
}));
14+
15+
jest.unmock('@edx/frontend-platform/i18n');
16+
jest.unmock('@openedx/paragon');
17+
jest.unmock('react');
18+
1219
const hookProps = {
1320
isCollapsed: true,
1421
sidebarShowing: false,
1522
setSidebarShowing: jest.fn().mockName('hooks.setSidebarShowing'),
1623
};
1724
hooks.useDashboardLayoutData.mockReturnValue(hookProps);
1825

19-
const children = 'test-children';
26+
const children = <div>test children</div>;
2027

21-
let el;
2228
describe('DashboardLayout', () => {
2329
beforeEach(() => {
2430
jest.clearAllMocks();
25-
el = shallow(<DashboardLayout>{children}</DashboardLayout>);
31+
render(<IntlProvider locale="en"><DashboardLayout>{children}</DashboardLayout></IntlProvider>);
2632
});
2733

2834
const testColumns = () => {
29-
it('loads courseList and sidebar column layout', () => {
30-
const columns = el.instance.findByType(Row)[0].findByType(Col);
31-
Object.keys(columnConfig.sidebar).forEach(size => {
32-
expect(columns[1].props[size]).toEqual(columnConfig.sidebar[size]);
33-
});
35+
it('loads courseList and sidebar column layout with corresponding children', () => {
36+
const courseChildren = screen.getByText('test children');
37+
const courseListCol = courseChildren.parentElement;
38+
const sidebarCol = courseListCol.nextSibling;
39+
expect(courseListCol).toHaveClass('course-list-column');
40+
expect(sidebarCol).toHaveClass('sidebar-column');
3441
});
3542
it('displays children in first column', () => {
36-
const columns = el.instance.findByType(Row)[0].findByType(Col);
37-
expect(columns[0].children).not.toHaveLength(0);
43+
const courseChildren = screen.getByText('test children');
44+
const courseListCol = courseChildren.parentElement;
45+
expect(courseChildren).toBeInTheDocument();
46+
expect(courseListCol).toHaveClass('course-list-column');
3847
});
3948
it('displays WidgetSidebarSlot in second column', () => {
40-
const columns = el.instance.findByType(Row)[0].findByType(Col);
41-
expect(columns[1].findByType('WidgetSidebarSlot')).toHaveLength(1);
49+
const courseListCol = screen.getByText('test children').parentElement;
50+
const sidebarCol = courseListCol.nextSibling;
51+
expect(sidebarCol).toHaveClass('sidebar-column');
52+
expect(sidebarCol.children[0]).toHaveAttribute('id', 'org.openedx.frontend.learner_dashboard.widget_sidebar.v1');
4253
});
4354
};
44-
const testSidebarLayout = () => {
55+
const testSidebarLayout = ({ isCollapsed }) => {
4556
it('displays withSidebar width for course list column', () => {
46-
const columns = el.instance.findByType(Row)[0].findByType(Col);
47-
Object.keys(columnConfig.courseList.withSidebar).forEach(size => {
48-
expect(columns[0].props[size]).toEqual(columnConfig.courseList.withSidebar[size]);
49-
});
57+
const courseListCol = screen.getByText('test children').parentElement;
58+
expect(courseListCol).toHaveClass('col-xl-8');
59+
const sidebarCol = courseListCol.nextSibling;
60+
expect(sidebarCol).toHaveClass('sidebar-column', !isCollapsed && 'not-collapsed');
5061
});
5162
};
52-
const testNoSidebarLayout = () => {
63+
const testNoSidebarLayout = ({ isCollapsed }) => {
5364
it('displays noSidebar width for course list column', () => {
54-
const columns = el.instance.findByType(Row)[0].findByType(Col);
55-
Object.keys(columnConfig.courseList.noSidebar).forEach(size => {
56-
expect(columns[0].props[size]).toEqual(columnConfig.courseList.noSidebar[size]);
57-
});
58-
});
59-
};
60-
const testSnapshot = () => {
61-
test('snapshot', () => {
62-
expect(el.snapshot).toMatchSnapshot();
65+
const courseListCol = screen.getByText('test children').parentElement;
66+
expect(courseListCol).toHaveClass('col-xl-12');
67+
const sidebarCol = courseListCol.nextSibling;
68+
expect(sidebarCol).toHaveClass('sidebar-column', !isCollapsed && 'not-collapsed');
6369
});
6470
};
6571
describe('collapsed', () => {
@@ -68,27 +74,18 @@ describe('DashboardLayout', () => {
6874
hooks.useDashboardLayoutData.mockReturnValueOnce({ ...hookProps, sidebarShowing: true });
6975
});
7076
testColumns();
71-
testSnapshot();
72-
testSidebarLayout();
77+
testSidebarLayout({ isCollapsed: true });
7378
});
7479
describe('sidebar not showing', () => {
80+
beforeEach(() => {
81+
hooks.useDashboardLayoutData.mockReturnValueOnce({ ...hookProps });
82+
});
7583
testColumns();
76-
testSnapshot();
77-
testNoSidebarLayout();
78-
});
79-
it('does not show spacer component above widget sidebar', () => {
80-
const columns = el.instance.findByType(Col);
81-
expect(columns[1].findByType('h2').length).toEqual(0);
84+
testNoSidebarLayout({ isCollapsed: true });
8285
});
8386
});
8487

8588
describe('not collapsed', () => {
86-
const testWidgetSpacing = () => {
87-
it('shows not-collapsed class on widget sidebar', () => {
88-
const columns = el.instance.findByType(Col);
89-
expect(columns[1].props.className).toContain('not-collapsed');
90-
});
91-
};
9289
describe('sidebar showing', () => {
9390
beforeEach(() => {
9491
hooks.useDashboardLayoutData.mockReturnValueOnce({
@@ -98,18 +95,14 @@ describe('DashboardLayout', () => {
9895
});
9996
});
10097
testColumns();
101-
testSnapshot();
102-
testSidebarLayout();
103-
testWidgetSpacing();
98+
testSidebarLayout({ isCollapsed: false });
10499
});
105100
describe('sidebar not showing', () => {
106101
beforeEach(() => {
107102
hooks.useDashboardLayoutData.mockReturnValueOnce({ ...hookProps, isCollapsed: false });
108103
});
109104
testColumns();
110-
testSnapshot();
111-
testNoSidebarLayout();
112-
testWidgetSpacing();
105+
testNoSidebarLayout({ isCollapsed: false });
113106
});
114107
});
115108
});
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { shallow } from '@edx/react-unit-test-utils';
2-
import { Spinner } from '@openedx/paragon';
1+
import { render, screen } from '@testing-library/react';
32

43
import hooks from './hooks';
54
import LoadingView from './LoadingView';
@@ -8,16 +7,16 @@ jest.mock('./hooks', () => ({
87
useDashboardMessages: jest.fn(),
98
}));
109

10+
jest.unmock('@edx/frontend-platform/i18n');
11+
jest.unmock('@openedx/paragon');
12+
jest.unmock('react');
13+
1114
const spinnerScreenReaderText = 'test-sr-text';
1215
describe('LoadingView', () => {
13-
beforeEach(() => {
14-
hooks.useDashboardMessages.mockReturnValueOnce({ spinnerScreenReaderText });
15-
});
16-
test('snapshot', () => {
17-
expect(shallow(<LoadingView />).snapshot).toMatchSnapshot();
18-
});
1916
it('renders spinner component with associated screen reader text', () => {
20-
const wrapper = shallow(<LoadingView />);
21-
expect(wrapper.instance.findByType(Spinner)[0].props.screenReaderText).toEqual(spinnerScreenReaderText);
17+
hooks.useDashboardMessages.mockReturnValueOnce({ spinnerScreenReaderText });
18+
render(<LoadingView />);
19+
const loader = screen.getByRole('status');
20+
expect(loader.children[0].innerHTML).toBe(spinnerScreenReaderText);
2221
});
2322
});

0 commit comments

Comments
 (0)