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.
This commit is contained in:
@@ -14,6 +14,15 @@ module.exports = createConfig(
|
||||
'no-restricted-exports': 'off',
|
||||
// There is no reason to disallow this syntax anymore; we don't use regenerator-runtime in new browsers
|
||||
'no-restricted-syntax': 'off',
|
||||
'no-restricted-imports': ['error', {
|
||||
patterns: [
|
||||
{
|
||||
group: ['@edx/frontend-platform/i18n'],
|
||||
importNames: ['injectIntl'],
|
||||
message: "Use 'useIntl' hook instead of injectIntl.",
|
||||
},
|
||||
],
|
||||
}],
|
||||
},
|
||||
settings: {
|
||||
// Import URLs should be resolved using aliases
|
||||
|
||||
4
.github/pull_request_template.md
vendored
4
.github/pull_request_template.md
vendored
@@ -30,9 +30,9 @@ We're trying to move away from some deprecated patterns in this codebase. Please
|
||||
check if your PR meets these recommendations before asking for a review:
|
||||
|
||||
- [ ] Any _new_ files are using TypeScript (`.ts`, `.tsx`).
|
||||
- [ ] Deprecated `propTypes`, `defaultProps`, and `injectIntl` patterns are not used in any new or modified code.
|
||||
- [ ] Avoid `propTypes` and `defaultProps` in any new or modified code.
|
||||
- [ ] Tests should use the helpers in `src/testUtils.tsx` (specifically `initializeMocks`)
|
||||
- [ ] Do not add new fields to the Redux state/store. Use React Context to share state among multiple components.
|
||||
- [ ] Use React Query to load data from REST APIs. See any `apiHooks.ts` in this repo for examples.
|
||||
- [ ] All new i18n messages in `messages.ts` files have a `description` for translators to use.
|
||||
- [ ] Imports avoid using `../`. To import from parent folders, use `@src`, e.g. `import { initializeMocks } from '@src/testUtils';` instead of `from '../../../../testUtils'`
|
||||
- [ ] Avoid using `../` in import paths. To import from parent folders, use `@src`, e.g. `import { initializeMocks } from '@src/testUtils';` instead of `from '../../../../testUtils'`
|
||||
|
||||
@@ -6,7 +6,7 @@ import MockAdapter from 'axios-mock-adapter';
|
||||
|
||||
import { initializeMockApp, mergeConfig } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { AppProvider } from '@edx/frontend-platform/react';
|
||||
|
||||
import StudioApiService from 'CourseAuthoring/data/services/StudioApiService';
|
||||
@@ -20,7 +20,6 @@ const defaultProps = {
|
||||
courseId,
|
||||
onClose: () => {},
|
||||
};
|
||||
const IntlProctoredExamSettings = injectIntl(ProctoredExamSettings);
|
||||
let store;
|
||||
|
||||
const intlWrapper = children => (
|
||||
@@ -102,7 +101,7 @@ describe('ProctoredExamSettings', () => {
|
||||
|
||||
describe('Field dependencies', () => {
|
||||
beforeEach(async () => {
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
});
|
||||
|
||||
it('Updates Zendesk ticket field if proctortrack is provider', async () => {
|
||||
@@ -152,7 +151,7 @@ describe('ProctoredExamSettings', () => {
|
||||
course_start_date: '2070-01-01T00:00:00Z',
|
||||
});
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
await waitFor(() => {
|
||||
screen.getByText('Proctored exams');
|
||||
});
|
||||
@@ -225,7 +224,7 @@ describe('ProctoredExamSettings', () => {
|
||||
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
|
||||
).reply(200, {});
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
});
|
||||
|
||||
proctoringProvidersRequiringEscalationEmail.forEach(provider => {
|
||||
@@ -409,7 +408,7 @@ describe('ProctoredExamSettings', () => {
|
||||
const isAdmin = false;
|
||||
setupApp(isAdmin);
|
||||
mockCourseData(mockGetPastCourseData);
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const providerOption = screen.getByTestId('proctortrack');
|
||||
expect(providerOption.hasAttribute('disabled')).toEqual(true);
|
||||
});
|
||||
@@ -418,7 +417,7 @@ describe('ProctoredExamSettings', () => {
|
||||
const isAdmin = false;
|
||||
setupApp(isAdmin);
|
||||
mockCourseData(mockGetFutureCourseData);
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const providerOption = screen.getByTestId('proctortrack');
|
||||
expect(providerOption.hasAttribute('disabled')).toEqual(false);
|
||||
});
|
||||
@@ -428,7 +427,7 @@ describe('ProctoredExamSettings', () => {
|
||||
const org = 'test-org';
|
||||
setupApp(isAdmin, org);
|
||||
mockCourseData(mockGetFutureCourseData);
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const providerOption = screen.getByTestId('proctortrack');
|
||||
expect(providerOption.hasAttribute('disabled')).toEqual(false);
|
||||
});
|
||||
@@ -437,7 +436,7 @@ describe('ProctoredExamSettings', () => {
|
||||
const isAdmin = true;
|
||||
setupApp(isAdmin);
|
||||
mockCourseData(mockGetPastCourseData);
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const providerOption = screen.getByTestId('proctortrack');
|
||||
expect(providerOption.hasAttribute('disabled')).toEqual(false);
|
||||
});
|
||||
@@ -446,7 +445,7 @@ describe('ProctoredExamSettings', () => {
|
||||
const isAdmin = true;
|
||||
setupApp(isAdmin);
|
||||
mockCourseData(mockGetFutureCourseData);
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const providerOption = screen.getByTestId('proctortrack');
|
||||
expect(providerOption.hasAttribute('disabled')).toEqual(false);
|
||||
});
|
||||
@@ -457,7 +456,7 @@ describe('ProctoredExamSettings', () => {
|
||||
available_proctoring_providers: ['lti_external', 'proctortrack', 'mockproc'],
|
||||
};
|
||||
mockCourseData(courseData);
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
await waitFor(() => {
|
||||
screen.getByDisplayValue('mockproc');
|
||||
});
|
||||
@@ -470,7 +469,7 @@ describe('ProctoredExamSettings', () => {
|
||||
available_proctoring_providers: ['lti_external', 'proctortrack', 'mockproc'],
|
||||
};
|
||||
mockCourseData(courseData);
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
await waitFor(() => {
|
||||
screen.getByDisplayValue('mockproc');
|
||||
});
|
||||
@@ -483,7 +482,7 @@ describe('ProctoredExamSettings', () => {
|
||||
const isAdmin = true;
|
||||
setupApp(isAdmin);
|
||||
mockCourseData(mockGetFutureCourseData);
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
await waitFor(() => {
|
||||
screen.getByDisplayValue('mockproc');
|
||||
});
|
||||
@@ -497,7 +496,7 @@ describe('ProctoredExamSettings', () => {
|
||||
EXAMS_BASE_URL: null,
|
||||
}, 'CourseAuthoringConfig');
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
await waitFor(() => {
|
||||
screen.getByDisplayValue('mockproc');
|
||||
});
|
||||
@@ -516,7 +515,7 @@ describe('ProctoredExamSettings', () => {
|
||||
).reply(200, {
|
||||
provider: 'test_lti',
|
||||
});
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
await waitFor(() => {
|
||||
screen.getByText('Proctoring provider');
|
||||
});
|
||||
@@ -529,14 +528,14 @@ describe('ProctoredExamSettings', () => {
|
||||
describe('Toggles field visibility based on user permissions', () => {
|
||||
it('Hides opting out and zendesk tickets for non edX staff', async () => {
|
||||
setupApp(false);
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
expect(screen.queryByTestId('allowOptingOutYes')).toBeNull();
|
||||
expect(screen.queryByTestId('createZendeskTicketsYes')).toBeNull();
|
||||
});
|
||||
|
||||
it('Shows opting out and zendesk tickets for edX staff', async () => {
|
||||
setupApp(true);
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
expect(screen.queryByTestId('allowOptingOutYes')).not.toBeNull();
|
||||
expect(screen.queryByTestId('createZendeskTicketsYes')).not.toBeNull();
|
||||
});
|
||||
@@ -544,7 +543,7 @@ describe('ProctoredExamSettings', () => {
|
||||
|
||||
describe('Connection states', () => {
|
||||
it('Shows the spinner before the connection is complete', async () => {
|
||||
render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />));
|
||||
render(intlWrapper(<ProctoredExamSettings {...defaultProps} />));
|
||||
const spinner = await screen.findByRole('status');
|
||||
expect(spinner.textContent).toEqual('Loading...');
|
||||
});
|
||||
@@ -554,7 +553,7 @@ describe('ProctoredExamSettings', () => {
|
||||
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
|
||||
).reply(500);
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const connectionError = screen.getByTestId('connectionErrorAlert');
|
||||
expect(connectionError.textContent).toEqual(
|
||||
expect.stringContaining('We encountered a technical error when loading this page.'),
|
||||
@@ -566,7 +565,7 @@ describe('ProctoredExamSettings', () => {
|
||||
`${ExamsApiService.getExamsBaseUrl()}/api/v1/providers`,
|
||||
).reply(500);
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const connectionError = screen.getByTestId('connectionErrorAlert');
|
||||
expect(connectionError.textContent).toEqual(
|
||||
expect.stringContaining('We encountered a technical error when loading this page.'),
|
||||
@@ -578,7 +577,7 @@ describe('ProctoredExamSettings', () => {
|
||||
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
|
||||
).reply(403);
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const permissionError = screen.getByTestId('permissionDeniedAlert');
|
||||
expect(permissionError.textContent).toEqual(
|
||||
expect.stringContaining('You are not authorized to view this page'),
|
||||
@@ -597,7 +596,7 @@ describe('ProctoredExamSettings', () => {
|
||||
});
|
||||
|
||||
it('Disable button while submitting', async () => {
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
let submitButton = screen.getByTestId('submissionButton');
|
||||
expect(screen.queryByTestId('saveInProgress')).toBeFalsy();
|
||||
fireEvent.click(submitButton);
|
||||
@@ -607,7 +606,7 @@ describe('ProctoredExamSettings', () => {
|
||||
});
|
||||
|
||||
it('Makes API call successfully with proctoring_escalation_email if proctortrack', async () => {
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
// Make a change to the provider to proctortrack and set the email
|
||||
const selectElement = screen.getByDisplayValue('mockproc');
|
||||
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });
|
||||
@@ -638,7 +637,7 @@ describe('ProctoredExamSettings', () => {
|
||||
});
|
||||
|
||||
it('Makes API call successfully without proctoring_escalation_email if not proctortrack', async () => {
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
|
||||
// make sure we have not selected proctortrack as the proctoring provider
|
||||
expect(screen.getByDisplayValue('mockproc')).toBeDefined();
|
||||
@@ -665,7 +664,7 @@ describe('ProctoredExamSettings', () => {
|
||||
});
|
||||
|
||||
it('Successfully updates exam configuration and studio provider is set to "lti_external" for lti providers', async () => {
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
// Make a change to the provider to test_lti and set the email
|
||||
const selectElement = screen.getByDisplayValue('mockproc');
|
||||
fireEvent.change(selectElement, { target: { value: 'test_lti' } });
|
||||
@@ -706,7 +705,7 @@ describe('ProctoredExamSettings', () => {
|
||||
});
|
||||
|
||||
it('Sets exam service provider to null if a non-lti provider is selected', async () => {
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
fireEvent.click(submitButton);
|
||||
// update exam service config
|
||||
@@ -750,7 +749,7 @@ describe('ProctoredExamSettings', () => {
|
||||
course_start_date: '2070-01-01T00:00:00Z',
|
||||
});
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
fireEvent.click(submitButton);
|
||||
// does not update exam service config
|
||||
@@ -780,7 +779,7 @@ describe('ProctoredExamSettings', () => {
|
||||
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
|
||||
).reply(500);
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
fireEvent.click(submitButton);
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
@@ -798,7 +797,7 @@ describe('ProctoredExamSettings', () => {
|
||||
`${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`,
|
||||
).reply(500, 'error');
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
fireEvent.click(submitButton);
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
@@ -816,7 +815,7 @@ describe('ProctoredExamSettings', () => {
|
||||
`${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`,
|
||||
).reply(403, 'error');
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
fireEvent.click(submitButton);
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
@@ -835,7 +834,7 @@ describe('ProctoredExamSettings', () => {
|
||||
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
|
||||
).reply(500);
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
fireEvent.click(submitButton);
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
@@ -868,7 +867,7 @@ describe('ProctoredExamSettings', () => {
|
||||
const isAdmin = false;
|
||||
setupApp(isAdmin);
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
await act(async () => render(intlWrapper(<ProctoredExamSettings {...defaultProps} />)));
|
||||
// Make a change to the proctoring provider
|
||||
const selectElement = screen.getByDisplayValue('mockproc');
|
||||
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { injectIntl, FormattedMessage, FormattedNumber } from '@edx/frontend-platform/i18n';
|
||||
import { FormattedMessage, FormattedNumber } from '@edx/frontend-platform/i18n';
|
||||
import { Icon } from '@openedx/paragon';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ModeComment } from '@openedx/paragon/icons';
|
||||
@@ -127,4 +127,4 @@ ChecklistItemComment.propTypes = {
|
||||
]).isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(ChecklistItemComment);
|
||||
export default ChecklistItemComment;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* istanbul ignore file */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* eslint-disable import/extensions */
|
||||
@@ -13,7 +14,7 @@ import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { Spinner } from '@openedx/paragon';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import EditorContainer from '../EditorContainer';
|
||||
// This 'module' self-import hack enables mocking during tests.
|
||||
@@ -30,7 +31,7 @@ export const hooks = {
|
||||
}),
|
||||
};
|
||||
|
||||
export const thumbEditor = ({
|
||||
export const ThumbEditor = ({
|
||||
onClose,
|
||||
// redux
|
||||
blockValue,
|
||||
@@ -38,10 +39,11 @@ export const thumbEditor = ({
|
||||
blockFailed,
|
||||
blockFinished,
|
||||
initializeEditor,
|
||||
// eslint-disable-next-line react/prop-types
|
||||
exampleValue,
|
||||
// inject
|
||||
intl,
|
||||
}) => (
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
return (
|
||||
<EditorContainer
|
||||
getContent={module.hooks.getContent}
|
||||
onClose={onClose}
|
||||
@@ -71,11 +73,12 @@ export const thumbEditor = ({
|
||||
</div>
|
||||
</EditorContainer>
|
||||
);
|
||||
thumbEditor.defaultProps = {
|
||||
};
|
||||
ThumbEditor.defaultProps = {
|
||||
blockValue: null,
|
||||
lmsEndpointUrl: null,
|
||||
};
|
||||
thumbEditor.propTypes = {
|
||||
ThumbEditor.propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
// redux
|
||||
blockValue: PropTypes.shape({
|
||||
@@ -85,8 +88,6 @@ thumbEditor.propTypes = {
|
||||
blockFailed: PropTypes.bool.isRequired,
|
||||
blockFinished: PropTypes.bool.isRequired,
|
||||
initializeEditor: PropTypes.func.isRequired,
|
||||
// inject
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
export const mapStateToProps = (state) => ({
|
||||
@@ -103,4 +104,4 @@ export const mapDispatchToProps = {
|
||||
// TODO fill with dispatches here if needed
|
||||
};
|
||||
|
||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(thumbEditor));
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ThumbEditor);
|
||||
|
||||
@@ -13,7 +13,7 @@ import HintsCard from './settingsComponents/HintsCard';
|
||||
import ResetCard from './settingsComponents/ResetCard';
|
||||
import TimerCard from './settingsComponents/TimerCard';
|
||||
import TypeCard from './settingsComponents/TypeCard';
|
||||
import ToleranceCard from './settingsComponents/Tolerance';
|
||||
import { ToleranceCard } from './settingsComponents/Tolerance';
|
||||
import GroupFeedbackCard from './settingsComponents/GroupFeedback/index';
|
||||
import SwitchEditorCard from './settingsComponents/SwitchEditorCard';
|
||||
import messages from './messages';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { injectIntl, FormattedMessage, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { Alert, Form } from '@openedx/paragon';
|
||||
import PropTypes from 'prop-types';
|
||||
import SettingsOption from '../../SettingsOption';
|
||||
@@ -46,14 +46,13 @@ export const getSummary = ({ tolerance, intl }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const ToleranceCard = ({
|
||||
export const ToleranceCard = ({
|
||||
tolerance,
|
||||
answers,
|
||||
updateSettings,
|
||||
correctAnswerCount,
|
||||
// inject
|
||||
intl,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const isAnswerRange = isAnswerRangeSet({ answers });
|
||||
const hasMultipleCorrectAnswers = correctAnswerCount > 1;
|
||||
let summary = getSummary({ tolerance, intl });
|
||||
@@ -141,8 +140,4 @@ ToleranceCard.propTypes = {
|
||||
unselectedFeedback: PropTypes.string,
|
||||
})).isRequired,
|
||||
updateSettings: PropTypes.func.isRequired,
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
export const ToleranceCardInternal = ToleranceCard; // For testing only
|
||||
export default injectIntl(ToleranceCard);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
import React from 'react';
|
||||
import messages from './messages';
|
||||
import { ToleranceTypes } from './constants';
|
||||
import { ToleranceCardInternal as ToleranceCard } from './index';
|
||||
import { ToleranceCard } from './index';
|
||||
import { formatMessage } from '../../../../../../../testUtils';
|
||||
|
||||
jest.mock('@edx/frontend-platform/i18n', () => ({
|
||||
@@ -13,6 +13,9 @@ jest.mock('@edx/frontend-platform/i18n', () => ({
|
||||
FormattedMessage: jest.fn(({ defaultMessage }) => (
|
||||
<div>{ defaultMessage }</div>
|
||||
)),
|
||||
useIntl: () => ({
|
||||
formatMessage: (message) => message.defaultMessage,
|
||||
}),
|
||||
}));
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
|
||||
@@ -3,8 +3,7 @@ import { connect, useDispatch } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
FormattedMessage,
|
||||
injectIntl,
|
||||
intlShape,
|
||||
useIntl,
|
||||
} from '@edx/frontend-platform/i18n';
|
||||
import {
|
||||
Image,
|
||||
@@ -32,14 +31,13 @@ import { ErrorContext } from '../../../../hooks';
|
||||
* Collapsible Form widget controlling video thumbnail
|
||||
*/
|
||||
const ThumbnailWidget = ({
|
||||
// injected
|
||||
intl,
|
||||
// redux
|
||||
isLibrary,
|
||||
allowThumbnailUpload,
|
||||
thumbnail,
|
||||
videoId,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
const [error] = React.useContext(ErrorContext).thumbnail;
|
||||
const imgRef = React.useRef();
|
||||
@@ -126,8 +124,6 @@ const ThumbnailWidget = ({
|
||||
};
|
||||
|
||||
ThumbnailWidget.propTypes = {
|
||||
// injected
|
||||
intl: intlShape.isRequired,
|
||||
// redux
|
||||
isLibrary: PropTypes.bool.isRequired,
|
||||
allowThumbnailUpload: PropTypes.bool.isRequired,
|
||||
@@ -144,4 +140,4 @@ export const mapStateToProps = (state) => ({
|
||||
export const mapDispatchToProps = {};
|
||||
|
||||
export const ThumbnailWidgetInternal = ThumbnailWidget; // For testing only
|
||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ThumbnailWidget));
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ThumbnailWidget);
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect, useDispatch } from 'react-redux';
|
||||
|
||||
import { FormattedMessage, injectIntl } from '@edx/frontend-platform/i18n';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
import { Dropdown, Icon, IconButton } from '@openedx/paragon';
|
||||
import { MoreHoriz } from '@openedx/paragon/icons';
|
||||
|
||||
@@ -90,4 +90,4 @@ export const mapDispatchToProps = {
|
||||
};
|
||||
|
||||
export const TranscriptActionMenuInternal = TranscriptActionMenu; // For testing only
|
||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(TranscriptActionMenu));
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(TranscriptActionMenu);
|
||||
|
||||
@@ -15,13 +15,9 @@ import 'jest-canvas-mock';
|
||||
|
||||
jest.mock('@edx/frontend-platform/i18n', () => {
|
||||
const i18n = jest.requireActual('@edx/frontend-platform/i18n');
|
||||
const PropTypes = jest.requireActual('prop-types');
|
||||
return {
|
||||
...i18n,
|
||||
useIntl: () => ({ formatMessage: mockFormatMessage }),
|
||||
intlShape: PropTypes.shape({
|
||||
formatMessage: PropTypes.func,
|
||||
}),
|
||||
defineMessages: m => m,
|
||||
getLocale: () => 'getLocale',
|
||||
FormattedDate: () => 'FormattedDate',
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
useToggle,
|
||||
} from '@openedx/paragon';
|
||||
import { DeleteOutline } from '@openedx/paragon/icons';
|
||||
import { injectIntl, FormattedMessage, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { isEmpty } from 'lodash';
|
||||
import LanguageSelect from './LanguageSelect';
|
||||
import TranscriptMenu from './TranscriptMenu';
|
||||
@@ -20,9 +20,8 @@ const Transcript = ({
|
||||
transcript,
|
||||
previousSelection,
|
||||
handleTranscript,
|
||||
// injected
|
||||
intl,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const [isConfirmationOpen, openConfirmation, closeConfirmation] = useToggle();
|
||||
const [newLanguage, setNewLanguage] = useState(transcript);
|
||||
const language = transcript;
|
||||
@@ -122,8 +121,6 @@ Transcript.propTypes = {
|
||||
transcript: PropTypes.string.isRequired,
|
||||
previousSelection: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
handleTranscript: PropTypes.func.isRequired,
|
||||
// injected
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(Transcript);
|
||||
export default Transcript;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { injectIntl, FormattedMessage, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
|
||||
import {
|
||||
Form,
|
||||
Icon,
|
||||
@@ -18,9 +18,8 @@ const ThreePlayMediaForm = ({
|
||||
data,
|
||||
setData,
|
||||
transcriptionPlan,
|
||||
// injected
|
||||
intl,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
if (hasTranscriptCredentials) {
|
||||
const selectedLanguages = data.preferredLanguages ? data.preferredLanguages : [];
|
||||
const turnaroundOptions = transcriptionPlan.turnaround;
|
||||
@@ -133,8 +132,6 @@ ThreePlayMediaForm.propTypes = {
|
||||
translations: PropTypes.shape({}),
|
||||
languages: PropTypes.shape({}),
|
||||
}).isRequired,
|
||||
// injected
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(ThreePlayMediaForm);
|
||||
export default ThreePlayMediaForm;
|
||||
|
||||
6
src/frontend-platform.d.ts
vendored
6
src/frontend-platform.d.ts
vendored
@@ -3,12 +3,6 @@
|
||||
// (whichever comes first).
|
||||
|
||||
declare module '@edx/frontend-platform/i18n' {
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import { injectIntl as _injectIntl } from 'react-intl';
|
||||
/** @deprecated Use useIntl() hook instead. */
|
||||
export const injectIntl: typeof _injectIntl;
|
||||
/** @deprecated Use useIntl() hook instead. */
|
||||
export const intlShape: any;
|
||||
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
export {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { initializeMockApp } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { AppProvider } from '@edx/frontend-platform/react';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import {
|
||||
@@ -25,7 +25,7 @@ const RootWrapper = () => (
|
||||
<AppProvider store={store}>
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<GradingSettings intl={injectIntl} courseId={courseId} />
|
||||
<GradingSettings courseId={courseId} />
|
||||
</QueryClientProvider>
|
||||
</IntlProvider>
|
||||
</AppProvider>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { initializeMockApp } from '@edx/frontend-platform';
|
||||
import { render, waitFor, fireEvent } from '@testing-library/react';
|
||||
|
||||
@@ -19,7 +19,6 @@ const sortedGrades = [
|
||||
const RootWrapper = () => (
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
<GradingScale
|
||||
intl={injectIntl}
|
||||
gradeCutoffs={gradeCutoffs}
|
||||
gradeLetters={gradeLetters}
|
||||
sortedGrades={sortedGrades}
|
||||
@@ -103,7 +102,6 @@ describe('<GradingScale />', () => {
|
||||
const { getAllByTestId } = render(
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
<GradingScale
|
||||
intl={injectIntl}
|
||||
gradeCutoffs={shortGradeCutoffs}
|
||||
gradeLetters={['A']}
|
||||
sortedGrades={shortSortedGrades}
|
||||
@@ -128,7 +126,6 @@ describe('<GradingScale />', () => {
|
||||
const { getAllByTestId } = render(
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
<GradingScale
|
||||
intl={injectIntl}
|
||||
gradeCutoffs={gradeCutoffs}
|
||||
gradeLetters={gradeLetters}
|
||||
sortedGrades={sortedGrades}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { injectIntl } from '@edx/frontend-platform/i18n';
|
||||
import {
|
||||
initializeMocks, render, screen,
|
||||
} from '../../testUtils';
|
||||
@@ -11,7 +10,7 @@ describe('<GradingSidebar />', () => {
|
||||
});
|
||||
|
||||
it('renders sidebar text content correctly', async () => {
|
||||
render(<GradingSidebar intl={injectIntl} courseId="123" />);
|
||||
render(<GradingSidebar courseId="123" />);
|
||||
expect(await screen.findByText(messages.gradingSidebarTitle.defaultMessage)).toBeInTheDocument();
|
||||
expect(screen.getByText(messages.gradingSidebarAbout1.defaultMessage)).toBeInTheDocument();
|
||||
expect(screen.getByText(messages.gradingSidebarAbout2.defaultMessage)).toBeInTheDocument();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { initializeMockApp } from '@edx/frontend-platform';
|
||||
import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { AppProvider } from '@edx/frontend-platform/react';
|
||||
import { fireEvent, render, waitFor } from '@testing-library/react';
|
||||
|
||||
@@ -14,7 +14,7 @@ const courseId = '123';
|
||||
const RootWrapper = () => (
|
||||
<AppProvider store={store}>
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
<FileSection intl={injectIntl} courseId={courseId} />
|
||||
<FileSection courseId={courseId} />
|
||||
</IntlProvider>
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user