Skip to content

Commit 36c9eba

Browse files
refactor: remove remaining injectIntl(), ban it using eslint (#2585)
This finished the removal of `injectIntl` from this codebase, and configures a new eslint rule to ban it completely.
1 parent 2dc087f commit 36c9eba

File tree

18 files changed

+109
-126
lines changed

18 files changed

+109
-126
lines changed

.eslintrc.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ module.exports = createConfig(
1414
'no-restricted-exports': 'off',
1515
// There is no reason to disallow this syntax anymore; we don't use regenerator-runtime in new browsers
1616
'no-restricted-syntax': 'off',
17+
'no-restricted-imports': ['error', {
18+
patterns: [
19+
{
20+
group: ['@edx/frontend-platform/i18n'],
21+
importNames: ['injectIntl'],
22+
message: "Use 'useIntl' hook instead of injectIntl.",
23+
},
24+
],
25+
}],
1726
},
1827
settings: {
1928
// Import URLs should be resolved using aliases

.github/pull_request_template.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ We're trying to move away from some deprecated patterns in this codebase. Please
3030
check if your PR meets these recommendations before asking for a review:
3131

3232
- [ ] Any _new_ files are using TypeScript (`.ts`, `.tsx`).
33-
- [ ] Deprecated `propTypes`, `defaultProps`, and `injectIntl` patterns are not used in any new or modified code.
33+
- [ ] Avoid `propTypes` and `defaultProps` in any new or modified code.
3434
- [ ] Tests should use the helpers in `src/testUtils.tsx` (specifically `initializeMocks`)
3535
- [ ] Do not add new fields to the Redux state/store. Use React Context to share state among multiple components.
3636
- [ ] Use React Query to load data from REST APIs. See any `apiHooks.ts` in this repo for examples.
3737
- [ ] All new i18n messages in `messages.ts` files have a `description` for translators to use.
38-
- [ ] Imports avoid using `../`. To import from parent folders, use `@src`, e.g. `import { initializeMocks } from '@src/testUtils';` instead of `from '../../../../testUtils'`
38+
- [ ] Avoid using `../` in import paths. To import from parent folders, use `@src`, e.g. `import { initializeMocks } from '@src/testUtils';` instead of `from '../../../../testUtils'`

plugins/course-apps/proctoring/Settings.test.jsx

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import MockAdapter from 'axios-mock-adapter';
66

77
import { initializeMockApp, mergeConfig } from '@edx/frontend-platform';
88
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
9-
import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
9+
import { IntlProvider } from '@edx/frontend-platform/i18n';
1010
import { AppProvider } from '@edx/frontend-platform/react';
1111

1212
import StudioApiService from 'CourseAuthoring/data/services/StudioApiService';
@@ -20,7 +20,6 @@ const defaultProps = {
2020
courseId,
2121
onClose: () => {},
2222
};
23-
const IntlProctoredExamSettings = injectIntl(ProctoredExamSettings);
2423
let store;
2524

2625
const intlWrapper = children => (
@@ -102,7 +101,7 @@ describe('ProctoredExamSettings', () => {
102101

103102
describe('Field dependencies', () => {
104103
beforeEach(async () => {
105-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
104+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
106105
});
107106

108107
it('Updates Zendesk ticket field if proctortrack is provider', async () => {
@@ -152,7 +151,7 @@ describe('ProctoredExamSettings', () => {
152151
course_start_date: '2070-01-01T00:00:00Z',
153152
});
154153

155-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
154+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
156155
await waitFor(() => {
157156
screen.getByText('Proctored exams');
158157
});
@@ -225,7 +224,7 @@ describe('ProctoredExamSettings', () => {
225224
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
226225
).reply(200, {});
227226

228-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
227+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
229228
});
230229

231230
proctoringProvidersRequiringEscalationEmail.forEach(provider => {
@@ -409,7 +408,7 @@ describe('ProctoredExamSettings', () => {
409408
const isAdmin = false;
410409
setupApp(isAdmin);
411410
mockCourseData(mockGetPastCourseData);
412-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
411+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
413412
const providerOption = screen.getByTestId('proctortrack');
414413
expect(providerOption.hasAttribute('disabled')).toEqual(true);
415414
});
@@ -418,7 +417,7 @@ describe('ProctoredExamSettings', () => {
418417
const isAdmin = false;
419418
setupApp(isAdmin);
420419
mockCourseData(mockGetFutureCourseData);
421-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
420+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
422421
const providerOption = screen.getByTestId('proctortrack');
423422
expect(providerOption.hasAttribute('disabled')).toEqual(false);
424423
});
@@ -428,7 +427,7 @@ describe('ProctoredExamSettings', () => {
428427
const org = 'test-org';
429428
setupApp(isAdmin, org);
430429
mockCourseData(mockGetFutureCourseData);
431-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
430+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
432431
const providerOption = screen.getByTestId('proctortrack');
433432
expect(providerOption.hasAttribute('disabled')).toEqual(false);
434433
});
@@ -437,7 +436,7 @@ describe('ProctoredExamSettings', () => {
437436
const isAdmin = true;
438437
setupApp(isAdmin);
439438
mockCourseData(mockGetPastCourseData);
440-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
439+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
441440
const providerOption = screen.getByTestId('proctortrack');
442441
expect(providerOption.hasAttribute('disabled')).toEqual(false);
443442
});
@@ -446,7 +445,7 @@ describe('ProctoredExamSettings', () => {
446445
const isAdmin = true;
447446
setupApp(isAdmin);
448447
mockCourseData(mockGetFutureCourseData);
449-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
448+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
450449
const providerOption = screen.getByTestId('proctortrack');
451450
expect(providerOption.hasAttribute('disabled')).toEqual(false);
452451
});
@@ -457,7 +456,7 @@ describe('ProctoredExamSettings', () => {
457456
available_proctoring_providers: ['lti_external', 'proctortrack', 'mockproc'],
458457
};
459458
mockCourseData(courseData);
460-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
459+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
461460
await waitFor(() => {
462461
screen.getByDisplayValue('mockproc');
463462
});
@@ -470,7 +469,7 @@ describe('ProctoredExamSettings', () => {
470469
available_proctoring_providers: ['lti_external', 'proctortrack', 'mockproc'],
471470
};
472471
mockCourseData(courseData);
473-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
472+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
474473
await waitFor(() => {
475474
screen.getByDisplayValue('mockproc');
476475
});
@@ -483,7 +482,7 @@ describe('ProctoredExamSettings', () => {
483482
const isAdmin = true;
484483
setupApp(isAdmin);
485484
mockCourseData(mockGetFutureCourseData);
486-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
485+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
487486
await waitFor(() => {
488487
screen.getByDisplayValue('mockproc');
489488
});
@@ -497,7 +496,7 @@ describe('ProctoredExamSettings', () => {
497496
EXAMS_BASE_URL: null,
498497
}, 'CourseAuthoringConfig');
499498

500-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
499+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
501500
await waitFor(() => {
502501
screen.getByDisplayValue('mockproc');
503502
});
@@ -516,7 +515,7 @@ describe('ProctoredExamSettings', () => {
516515
).reply(200, {
517516
provider: 'test_lti',
518517
});
519-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
518+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
520519
await waitFor(() => {
521520
screen.getByText('Proctoring provider');
522521
});
@@ -529,22 +528,22 @@ describe('ProctoredExamSettings', () => {
529528
describe('Toggles field visibility based on user permissions', () => {
530529
it('Hides opting out and zendesk tickets for non edX staff', async () => {
531530
setupApp(false);
532-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
531+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
533532
expect(screen.queryByTestId('allowOptingOutYes')).toBeNull();
534533
expect(screen.queryByTestId('createZendeskTicketsYes')).toBeNull();
535534
});
536535

537536
it('Shows opting out and zendesk tickets for edX staff', async () => {
538537
setupApp(true);
539-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
538+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
540539
expect(screen.queryByTestId('allowOptingOutYes')).not.toBeNull();
541540
expect(screen.queryByTestId('createZendeskTicketsYes')).not.toBeNull();
542541
});
543542
});
544543

545544
describe('Connection states', () => {
546545
it('Shows the spinner before the connection is complete', async () => {
547-
render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />));
546+
render(intlWrapper(<ProctoredExamSettings {...defaultProps} />));
548547
const spinner = await screen.findByRole('status');
549548
expect(spinner.textContent).toEqual('Loading...');
550549
});
@@ -554,7 +553,7 @@ describe('ProctoredExamSettings', () => {
554553
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
555554
).reply(500);
556555

557-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
556+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
558557
const connectionError = screen.getByTestId('connectionErrorAlert');
559558
expect(connectionError.textContent).toEqual(
560559
expect.stringContaining('We encountered a technical error when loading this page.'),
@@ -566,7 +565,7 @@ describe('ProctoredExamSettings', () => {
566565
`${ExamsApiService.getExamsBaseUrl()}/api/v1/providers`,
567566
).reply(500);
568567

569-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
568+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
570569
const connectionError = screen.getByTestId('connectionErrorAlert');
571570
expect(connectionError.textContent).toEqual(
572571
expect.stringContaining('We encountered a technical error when loading this page.'),
@@ -578,7 +577,7 @@ describe('ProctoredExamSettings', () => {
578577
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
579578
).reply(403);
580579

581-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
580+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
582581
const permissionError = screen.getByTestId('permissionDeniedAlert');
583582
expect(permissionError.textContent).toEqual(
584583
expect.stringContaining('You are not authorized to view this page'),
@@ -597,7 +596,7 @@ describe('ProctoredExamSettings', () => {
597596
});
598597

599598
it('Disable button while submitting', async () => {
600-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
599+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
601600
let submitButton = screen.getByTestId('submissionButton');
602601
expect(screen.queryByTestId('saveInProgress')).toBeFalsy();
603602
fireEvent.click(submitButton);
@@ -607,7 +606,7 @@ describe('ProctoredExamSettings', () => {
607606
});
608607

609608
it('Makes API call successfully with proctoring_escalation_email if proctortrack', async () => {
610-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
609+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
611610
// Make a change to the provider to proctortrack and set the email
612611
const selectElement = screen.getByDisplayValue('mockproc');
613612
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });
@@ -638,7 +637,7 @@ describe('ProctoredExamSettings', () => {
638637
});
639638

640639
it('Makes API call successfully without proctoring_escalation_email if not proctortrack', async () => {
641-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
640+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
642641

643642
// make sure we have not selected proctortrack as the proctoring provider
644643
expect(screen.getByDisplayValue('mockproc')).toBeDefined();
@@ -665,7 +664,7 @@ describe('ProctoredExamSettings', () => {
665664
});
666665

667666
it('Successfully updates exam configuration and studio provider is set to "lti_external" for lti providers', async () => {
668-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
667+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
669668
// Make a change to the provider to test_lti and set the email
670669
const selectElement = screen.getByDisplayValue('mockproc');
671670
fireEvent.change(selectElement, { target: { value: 'test_lti' } });
@@ -706,7 +705,7 @@ describe('ProctoredExamSettings', () => {
706705
});
707706

708707
it('Sets exam service provider to null if a non-lti provider is selected', async () => {
709-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
708+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
710709
const submitButton = screen.getByTestId('submissionButton');
711710
fireEvent.click(submitButton);
712711
// update exam service config
@@ -750,7 +749,7 @@ describe('ProctoredExamSettings', () => {
750749
course_start_date: '2070-01-01T00:00:00Z',
751750
});
752751

753-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
752+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
754753
const submitButton = screen.getByTestId('submissionButton');
755754
fireEvent.click(submitButton);
756755
// does not update exam service config
@@ -780,7 +779,7 @@ describe('ProctoredExamSettings', () => {
780779
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
781780
).reply(500);
782781

783-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
782+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
784783
const submitButton = screen.getByTestId('submissionButton');
785784
fireEvent.click(submitButton);
786785
expect(axiosMock.history.post.length).toBe(1);
@@ -798,7 +797,7 @@ describe('ProctoredExamSettings', () => {
798797
`${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`,
799798
).reply(500, 'error');
800799

801-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
800+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
802801
const submitButton = screen.getByTestId('submissionButton');
803802
fireEvent.click(submitButton);
804803
expect(axiosMock.history.post.length).toBe(1);
@@ -816,7 +815,7 @@ describe('ProctoredExamSettings', () => {
816815
`${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`,
817816
).reply(403, 'error');
818817

819-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
818+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
820819
const submitButton = screen.getByTestId('submissionButton');
821820
fireEvent.click(submitButton);
822821
expect(axiosMock.history.post.length).toBe(1);
@@ -835,7 +834,7 @@ describe('ProctoredExamSettings', () => {
835834
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
836835
).reply(500);
837836

838-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
837+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
839838
const submitButton = screen.getByTestId('submissionButton');
840839
fireEvent.click(submitButton);
841840
expect(axiosMock.history.post.length).toBe(1);
@@ -868,7 +867,7 @@ describe('ProctoredExamSettings', () => {
868867
const isAdmin = false;
869868
setupApp(isAdmin);
870869

871-
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
870+
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
872871
// Make a change to the proctoring provider
873872
const selectElement = screen.getByDisplayValue('mockproc');
874873
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });

src/course-checklist/ChecklistSection/ChecklistItemComment.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import PropTypes from 'prop-types';
2-
import { injectIntl, FormattedMessage, FormattedNumber } from '@edx/frontend-platform/i18n';
2+
import { FormattedMessage, FormattedNumber } from '@edx/frontend-platform/i18n';
33
import { Icon } from '@openedx/paragon';
44
import { Link } from 'react-router-dom';
55
import { ModeComment } from '@openedx/paragon/icons';
@@ -127,4 +127,4 @@ ChecklistItemComment.propTypes = {
127127
]).isRequired,
128128
};
129129

130-
export default injectIntl(ChecklistItemComment);
130+
export default ChecklistItemComment;

0 commit comments

Comments
 (0)