Skip to content

Commit 5bef624

Browse files
refactor: Replace injectIntl with the useIntl() hook (#798)
* refactor: Replace of injectIntl with useIntl * test: improve coverage
1 parent 28b1b19 commit 5bef624

File tree

6 files changed

+110
-33
lines changed

6 files changed

+110
-33
lines changed

src/components/FilterBar.jsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useMemo, useState } from 'react';
1+
import { useCallback, useMemo, useState } from 'react';
22
import PropTypes from 'prop-types';
33

44
import {
@@ -8,7 +8,7 @@ import { Tune } from '@openedx/paragon/icons';
88
import { capitalize, toString } from 'lodash';
99
import { useSelector } from 'react-redux';
1010

11-
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
11+
import { useIntl } from '@edx/frontend-platform/i18n';
1212

1313
import {
1414
PostsStatusFilter, RequestStatus,
@@ -19,12 +19,12 @@ import messages from '../discussions/posts/post-filter-bar/messages';
1919
import { ActionItem } from '../discussions/posts/post-filter-bar/PostFilterBar';
2020

2121
const FilterBar = ({
22-
intl,
2322
filters,
2423
selectedFilters,
2524
onFilterChange,
2625
showCohortsFilter,
2726
}) => {
27+
const intl = useIntl();
2828
const [isOpen, setOpen] = useState(false);
2929
const cohorts = useSelector(selectCourseCohorts);
3030
const { status } = useSelector(state => state.cohorts);
@@ -192,7 +192,6 @@ const FilterBar = ({
192192
};
193193

194194
FilterBar.propTypes = {
195-
intl: intlShape.isRequired,
196195
filters: PropTypes.arrayOf(PropTypes.shape({
197196
name: PropTypes.string,
198197
filters: PropTypes.arrayOf(PropTypes.string),
@@ -211,4 +210,4 @@ FilterBar.defaultProps = {
211210
showCohortsFilter: false,
212211
};
213212

214-
export default injectIntl(FilterBar);
213+
export default FilterBar;

src/components/Head/Head.jsx

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
import React from 'react';
2-
31
import { Helmet } from 'react-helmet';
42

53
import { getConfig } from '@edx/frontend-platform';
6-
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
4+
import { useIntl } from '@edx/frontend-platform/i18n';
75

86
import messages from './messages';
97

10-
const Head = ({ intl }) => (
11-
<Helmet>
12-
<title>
13-
{intl.formatMessage(messages['discussions.page.title'], { siteName: getConfig().SITE_NAME })}
14-
</title>
15-
<link rel="shortcut icon" href={getConfig().FAVICON_URL} type="image/x-icon" />
16-
</Helmet>
17-
);
8+
const Head = () => {
9+
const intl = useIntl();
1810

19-
Head.propTypes = {
20-
intl: intlShape.isRequired,
11+
return (
12+
<Helmet>
13+
<title>
14+
{intl.formatMessage(messages['discussions.page.title'], { siteName: getConfig().SITE_NAME })}
15+
</title>
16+
<link rel="shortcut icon" href={getConfig().FAVICON_URL} type="image/x-icon" />
17+
</Helmet>
18+
);
2119
};
2220

23-
export default injectIntl(Head);
21+
export default Head;

src/discussions/common/ActionsDropdown.test.jsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,25 @@ describe('ActionsDropdown', () => {
242242
await waitFor(() => expect(screen.queryByText('Copy link')).not.toBeInTheDocument());
243243
});
244244

245+
it('should close the dropdown when pressing escape', async () => {
246+
const discussionObject = buildTestContent({ editable_fields: ['copy_link'] }).discussion;
247+
await mockThreadAndComment(discussionObject);
248+
renderComponent({ ...camelCaseObject(discussionObject) });
249+
250+
const openButton = await findOpenActionsDropdownButton();
251+
await act(async () => {
252+
fireEvent.click(openButton);
253+
});
254+
255+
await waitFor(() => expect(screen.getByRole('button', { name: 'Copy link' })).toBeInTheDocument());
256+
257+
await act(async () => {
258+
fireEvent.keyDown(document.body, { key: 'Escape', code: 'Escape' });
259+
});
260+
261+
await waitFor(() => expect(screen.queryByRole('button', { name: 'Copy link' })).toBeNull());
262+
});
263+
245264
describe.each(canPerformActionTestData)('Actions', ({
246265
testFor, action, label, ...commentOrPost
247266
}) => {

src/discussions/in-context-topics/components/BackButton.jsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
import React from 'react';
21
import PropTypes from 'prop-types';
32

43
import { Icon, IconButton, Spinner } from '@openedx/paragon';
54
import { ArrowBack } from '@openedx/paragon/icons';
65
import { useNavigate } from 'react-router-dom';
76

8-
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
7+
import { useIntl } from '@edx/frontend-platform/i18n';
98

109
import messages from '../messages';
1110

1211
const BackButton = ({
13-
intl, path, title, loading,
12+
path,
13+
title,
14+
loading,
1415
}) => {
16+
const intl = useIntl();
1517
const navigate = useNavigate();
1618

1719
return (
@@ -35,7 +37,6 @@ const BackButton = ({
3537
};
3638

3739
BackButton.propTypes = {
38-
intl: intlShape.isRequired,
3940
path: PropTypes.shape({}).isRequired,
4041
title: PropTypes.string.isRequired,
4142
loading: PropTypes.bool,
@@ -45,4 +46,4 @@ BackButton.defaultProps = {
4546
loading: false,
4647
};
4748

48-
export default injectIntl(BackButton);
49+
export default BackButton;
Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import React from 'react';
2-
31
import { SearchField } from '@openedx/paragon';
42
import { useDispatch } from 'react-redux';
53

6-
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
4+
import { useIntl } from '@edx/frontend-platform/i18n';
75

86
import { setFilter } from '../data';
97
import messages from '../messages';
108

11-
const TopicSearchResultBar = ({ intl }) => {
9+
const TopicSearchResultBar = () => {
10+
const intl = useIntl();
1211
const dispatch = useDispatch();
1312

1413
return (
@@ -23,8 +22,4 @@ const TopicSearchResultBar = ({ intl }) => {
2322
);
2423
};
2524

26-
TopicSearchResultBar.propTypes = {
27-
intl: intlShape.isRequired,
28-
};
29-
30-
export default injectIntl(TopicSearchResultBar);
25+
export default TopicSearchResultBar;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { fireEvent, render } from '@testing-library/react';
2+
import { useDispatch } from 'react-redux';
3+
4+
import { IntlProvider } from '@edx/frontend-platform/i18n';
5+
6+
import { setFilter } from '../data';
7+
import messages from '../messages';
8+
import TopicSearchResultBar from './TopicSearchResultBar';
9+
10+
jest.mock('react-redux', () => ({
11+
useDispatch: jest.fn(),
12+
}));
13+
14+
jest.mock('../data', () => ({
15+
setFilter: jest.fn(),
16+
}));
17+
18+
describe('TopicSearchResultBar', () => {
19+
const dispatch = jest.fn();
20+
21+
beforeEach(() => {
22+
useDispatch.mockReturnValue(dispatch);
23+
setFilter.mockReturnValue({ type: 'SET_FILTER' });
24+
});
25+
26+
afterEach(() => {
27+
jest.clearAllMocks();
28+
});
29+
30+
it('should render search field', () => {
31+
const { getByPlaceholderText } = render(
32+
<IntlProvider locale="en">
33+
<TopicSearchResultBar />
34+
</IntlProvider>,
35+
);
36+
expect(getByPlaceholderText(messages.searchTopics.defaultMessage)).toBeInTheDocument();
37+
});
38+
39+
it('should dispatch setFilter on submit', () => {
40+
const { getByPlaceholderText } = render(
41+
<IntlProvider locale="en">
42+
<TopicSearchResultBar />
43+
</IntlProvider>,
44+
);
45+
const searchField = getByPlaceholderText(messages.searchTopics.defaultMessage);
46+
fireEvent.change(searchField, { target: { value: 'test query' } });
47+
fireEvent.submit(searchField);
48+
49+
expect(setFilter).toHaveBeenCalledWith('test query');
50+
expect(dispatch).toHaveBeenCalled();
51+
});
52+
53+
it('should dispatch setFilter on change', () => {
54+
const { getByPlaceholderText } = render(
55+
<IntlProvider locale="en">
56+
<TopicSearchResultBar />
57+
</IntlProvider>,
58+
);
59+
const searchField = getByPlaceholderText(messages.searchTopics.defaultMessage);
60+
fireEvent.change(searchField, { target: { value: 'test' } });
61+
62+
expect(setFilter).toHaveBeenCalledWith('test');
63+
expect(dispatch).toHaveBeenCalled();
64+
});
65+
});

0 commit comments

Comments
 (0)