feat: update react & react-dom to v17 (#514)
* feat: update react & react-dom to v17 * refactor: updated package-lock * refactor: updated failing tests * refactor: updated FilesAndUploads test to resolve delay issue * refactor: updated DiscussionSettings tests * refactor: downgraded frontend-lib-content-components * refactor: resolved lint issue * refactor: bumped frontend-lib-content-components version * refactor: updated CollapsibleStateWithAction test suit * refactor: update FilesAndUploads test
This commit is contained in:
7601
package-lock.json
generated
7601
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
26
package.json
26
package.json
@@ -38,14 +38,14 @@
|
||||
"@edx/frontend-component-footer": "^12.3.0",
|
||||
"@edx/frontend-component-header": "^4.7.0",
|
||||
"@edx/frontend-enterprise-hotjar": "^1.2.1",
|
||||
"@edx/frontend-lib-content-components": "^1.174.0",
|
||||
"@edx/frontend-platform": "4.2.0",
|
||||
"@edx/frontend-lib-content-components": "1.174.0",
|
||||
"@edx/frontend-platform": "4.6.3",
|
||||
"@edx/paragon": "^20.45.4",
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.28",
|
||||
"@fortawesome/free-brands-svg-icons": "5.11.2",
|
||||
"@fortawesome/free-regular-svg-icons": "5.11.2",
|
||||
"@fortawesome/free-solid-svg-icons": "5.11.2",
|
||||
"@fortawesome/react-fontawesome": "0.1.9",
|
||||
"@fortawesome/react-fontawesome": "0.2.0",
|
||||
"@reduxjs/toolkit": "1.5.0",
|
||||
"classnames": "2.2.6",
|
||||
"core-js": "3.8.1",
|
||||
@@ -56,12 +56,12 @@
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.2",
|
||||
"prop-types": "15.7.2",
|
||||
"react": "16.14.0",
|
||||
"react": "17.0.2",
|
||||
"react-datepicker": "^4.13.0",
|
||||
"react-dom": "16.14.0",
|
||||
"react-dom": "17.0.2",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-redux": "7.1.3",
|
||||
"react-responsive": "8.1.0",
|
||||
"react-redux": "7.2.9",
|
||||
"react-responsive": "9.0.2",
|
||||
"react-router": "5.2.0",
|
||||
"react-router-dom": "5.2.0",
|
||||
"react-textarea-autosize": "^8.4.1",
|
||||
@@ -74,19 +74,19 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@edx/browserslist-config": "1.0.0",
|
||||
"@edx/frontend-build": "12.8.6",
|
||||
"@edx/frontend-build": "12.9.4",
|
||||
"@edx/reactifex": "^1.0.3",
|
||||
"@edx/stylelint-config-edx": "^2.3.0",
|
||||
"@testing-library/jest-dom": "5.16.4",
|
||||
"@testing-library/react": "12.1.1",
|
||||
"@testing-library/react": "12.1.5",
|
||||
"@testing-library/user-event": "^13.2.1",
|
||||
"axios-mock-adapter": "1.20.0",
|
||||
"enzyme": "3.11.0",
|
||||
"enzyme-adapter-react-16": "1.15.6",
|
||||
"@wojtekmaj/enzyme-adapter-react-17": "0.8.0",
|
||||
"enzyme-to-json": "^3.6.2",
|
||||
"glob": "7.1.6",
|
||||
"husky": "3.1.0",
|
||||
"react-test-renderer": "16.9.0",
|
||||
"glob": "7.2.0",
|
||||
"husky": "7.0.4",
|
||||
"react-test-renderer": "17.0.2",
|
||||
"reactifex": "1.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,18 +223,27 @@ describe('FilesAndUploads', () => {
|
||||
expect(deleteButton).not.toHaveClass('disabled');
|
||||
|
||||
axiosMock.onDelete(`${getAssetsUrl(courseId)}mOckID1`).reply(204);
|
||||
await waitFor(() => {
|
||||
fireEvent.click(deleteButton);
|
||||
expect(screen.getByText(messages.deleteConfirmationTitle.defaultMessage)).toBeVisible();
|
||||
|
||||
fireEvent.click(screen.getByText(messages.deleteFileButtonLabel.defaultMessage));
|
||||
expect(screen.queryByText(messages.deleteConfirmationTitle.defaultMessage)).toBeNull();
|
||||
|
||||
executeThunk(deleteAssetFile(courseId, 'mOckID1', 5), store.dispatch);
|
||||
fireEvent.click(deleteButton);
|
||||
expect(screen.getByText(messages.deleteConfirmationTitle.defaultMessage)).toBeVisible();
|
||||
await act(async () => {
|
||||
userEvent.click(deleteButton);
|
||||
});
|
||||
|
||||
// Wait for the delete confirmation button to appear
|
||||
const confirmDeleteButton = await screen.findByRole('button', {
|
||||
name: messages.deleteFileButtonLabel.defaultMessage,
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
userEvent.click(confirmDeleteButton);
|
||||
});
|
||||
|
||||
expect(screen.queryByText(messages.deleteConfirmationTitle.defaultMessage)).toBeNull();
|
||||
|
||||
// Check if the asset is deleted in the store and UI
|
||||
const deleteStatus = store.getState().assets.deletingStatus;
|
||||
expect(deleteStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
|
||||
expect(screen.queryByTestId('grid-card-mOckID1')).toBeNull();
|
||||
});
|
||||
|
||||
|
||||
@@ -196,18 +196,20 @@ describe('DiscussionsSettings', () => {
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
|
||||
userEvent.click(queryByLabelText(container, 'Select Piazza'));
|
||||
act(async () => {
|
||||
userEvent.click(queryByLabelText(container, 'Select Piazza'));
|
||||
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Next' }));
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Next' }));
|
||||
|
||||
userEvent.click(await findByRole(container, 'button', { name: 'Save' }));
|
||||
userEvent.click(await findByRole(container, 'button', { name: 'Save' }));
|
||||
|
||||
// This is an important line that ensures the Close button has been removed, which implies that
|
||||
// the full screen modal has been closed following our click of Apply. Once this has happened,
|
||||
// then it's safe to proceed with our expectations.
|
||||
await waitForElementToBeRemoved(queryByRole(container, 'button', { name: 'Close' }));
|
||||
// This is an important line that ensures the Close button has been removed, which implies that
|
||||
// the full screen modal has been closed following our click of Apply. Once this has happened,
|
||||
// then it's safe to proceed with our expectations.
|
||||
await waitFor(() => expect(screen.queryByRole(container, 'button', { name: 'Close' })).toBeNull());
|
||||
|
||||
await waitFor(() => expect(window.location.pathname).toEqual(`/course/${courseId}/pages-and-resources`));
|
||||
await waitFor(() => expect(window.location.pathname).toEqual(`/course/${courseId}/pages-and-resources`));
|
||||
});
|
||||
});
|
||||
|
||||
test('requires confirmation if changing provider', async () => {
|
||||
@@ -219,16 +221,18 @@ describe('DiscussionsSettings', () => {
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
|
||||
userEvent.click(getByRole(container, 'checkbox', { name: 'Select Discourse' }));
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Next' }));
|
||||
act(async () => {
|
||||
userEvent.click(getByRole(container, 'checkbox', { name: 'Select Discourse' }));
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Next' }));
|
||||
|
||||
await findByRole(container, 'button', { name: 'Save' });
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Key' }), 'key');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Secret' }), 'secret');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Launch URL' }), 'http://example.test');
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
await findByRole(container, 'button', { name: 'Save' });
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Key' }), 'key');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Secret' }), 'secret');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Launch URL' }), 'http://example.test');
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
|
||||
await waitFor(() => expect(getByRole(container, 'dialog', { name: 'OK' })).toBeInTheDocument());
|
||||
await waitFor(() => expect(queryByRole(container, 'dialog', { name: 'OK' })).toBeInTheDocument());
|
||||
});
|
||||
});
|
||||
|
||||
test('can cancel confirmation', async () => {
|
||||
@@ -245,19 +249,23 @@ describe('DiscussionsSettings', () => {
|
||||
userEvent.click(discourseBox);
|
||||
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Next' }));
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
expect(getByRole(container, 'heading', { name: 'Discourse' })).toBeInTheDocument();
|
||||
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Key' }), 'a');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Secret' }), 'secret');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Launch URL' }), 'http://example.test');
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
await waitFor(() => expect(screen.queryByRole('status')).toBeNull());
|
||||
|
||||
await waitFor(() => expect(getByRole(container, 'dialog', { name: 'OK' })).toBeInTheDocument());
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Cancel' }));
|
||||
act(async () => {
|
||||
expect(await findByRole(container, 'heading', { name: 'Discourse' })).toBeInTheDocument();
|
||||
|
||||
expect(queryByRole(container, 'dialog', { name: 'Confirm' })).not.toBeInTheDocument();
|
||||
expect(queryByRole(container, 'dialog', { name: 'Configure discussion' }));
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Key' }), 'a');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Secret' }), 'secret');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Launch URL' }), 'http://example.test');
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
|
||||
waitFor(() => expect(getByRole(container, 'dialog', { name: 'OK' })).toBeInTheDocument());
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Cancel' }));
|
||||
|
||||
expect(queryByRole(container, 'dialog', { name: 'Confirm' })).not.toBeInTheDocument();
|
||||
expect(queryByRole(container, 'dialog', { name: 'Configure discussion' }));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -312,17 +320,16 @@ describe('DiscussionsSettings', () => {
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
|
||||
// Apply causes an async action to take place
|
||||
act(() => {
|
||||
act(async () => {
|
||||
userEvent.click(queryByText(container, appMessages.saveButton.defaultMessage));
|
||||
await waitFor(() => expect(axiosMock.history.post.length).toBe(1));
|
||||
|
||||
expect(queryByTestId(container, 'appConfigForm')).toBeInTheDocument();
|
||||
const alert = await findByRole(container, 'alert');
|
||||
expect(alert).toBeInTheDocument();
|
||||
expect(alert.textContent).toEqual(expect.stringContaining('We encountered a technical error when applying changes.'));
|
||||
expect(alert.innerHTML).toEqual(expect.stringContaining(getConfig().SUPPORT_URL));
|
||||
});
|
||||
|
||||
await waitFor(() => expect(axiosMock.history.post.length).toBe(1));
|
||||
|
||||
expect(queryByTestId(container, 'appConfigForm')).toBeInTheDocument();
|
||||
const alert = await findByRole(container, 'alert');
|
||||
expect(alert).toBeInTheDocument();
|
||||
expect(alert.textContent).toEqual(expect.stringContaining('We encountered a technical error when applying changes.'));
|
||||
expect(alert.innerHTML).toEqual(expect.stringContaining(getConfig().SUPPORT_URL));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -364,19 +371,21 @@ describe('DiscussionsSettings', () => {
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
act(async () => {
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
|
||||
await waitFor(() => expect(axiosMock.history.post.length).toBe(1));
|
||||
await waitFor(() => expect(axiosMock.history.post.length).toBe(1));
|
||||
|
||||
expect(queryByTestId(container, 'appList')).not.toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'appConfigForm')).not.toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'appList')).not.toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'appConfigForm')).not.toBeInTheDocument();
|
||||
|
||||
// We don't technically leave the route in this case, though the modal is hidden.
|
||||
expect(window.location.pathname).toEqual(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
|
||||
// We don't technically leave the route in this case, though the modal is hidden.
|
||||
expect(window.location.pathname).toEqual(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
|
||||
|
||||
const alert = await findByRole(container, 'alert');
|
||||
expect(alert).toBeInTheDocument();
|
||||
expect(alert.textContent).toEqual(expect.stringContaining('You are not authorized to view this page.'));
|
||||
const alert = await findByRole(container, 'alert');
|
||||
expect(alert).toBeInTheDocument();
|
||||
expect(alert.textContent).toEqual(expect.stringContaining('You are not authorized to view this page.'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -421,19 +430,21 @@ describe.each([
|
||||
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
|
||||
userEvent.click(queryByLabelText(container, 'Select Piazza'));
|
||||
userEvent.click(queryByText(container, messages.nextButton.defaultMessage));
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
act(async () => {
|
||||
userEvent.click(await screen.findByLabelText('Select Piazza'));
|
||||
userEvent.click(queryByText(container, messages.nextButton.defaultMessage));
|
||||
waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
|
||||
if (showLTIConfig) {
|
||||
expect(queryByText(container, ltiMessages.formInstructions.defaultMessage)).toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'ltiConfigFields')).toBeInTheDocument();
|
||||
} else {
|
||||
expect(queryByText(container, ltiMessages.formInstructions.defaultMessage)).not.toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'ltiConfigFields')).not.toBeInTheDocument();
|
||||
}
|
||||
if (showLTIConfig) {
|
||||
expect(queryByText(container, ltiMessages.formInstructions.defaultMessage)).toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'ltiConfigFields')).toBeInTheDocument();
|
||||
} else {
|
||||
expect(queryByText(container, ltiMessages.formInstructions.defaultMessage)).not.toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'ltiConfigFields')).not.toBeInTheDocument();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -477,15 +488,18 @@ describe.each([
|
||||
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
|
||||
userEvent.click(queryByLabelText(container, 'Select Piazza'));
|
||||
userEvent.click(queryByText(container, messages.nextButton.defaultMessage));
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
if (enablePIISharing) {
|
||||
expect(queryByTestId(container, 'piiSharingFields')).toBeInTheDocument();
|
||||
} else {
|
||||
expect(queryByTestId(container, 'piiSharingFields')).not.toBeInTheDocument();
|
||||
}
|
||||
act(async () => {
|
||||
userEvent.click(await screen.findByLabelText('Select Piazza'));
|
||||
userEvent.click(await screen.findByText(messages.nextButton.defaultMessage));
|
||||
|
||||
waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
if (enablePIISharing) {
|
||||
expect(queryByTestId(container, 'piiSharingFields')).toBeInTheDocument();
|
||||
} else {
|
||||
expect(queryByTestId(container, 'piiSharingFields')).not.toBeInTheDocument();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ import '@testing-library/jest-dom/extend-expect';
|
||||
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import Enzyme from 'enzyme';
|
||||
import Adapter from 'enzyme-adapter-react-16';
|
||||
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
|
||||
import 'babel-polyfill';
|
||||
|
||||
import { mergeConfig } from '@edx/frontend-platform';
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { render, fireEvent, waitFor } from '@testing-library/react';
|
||||
import {
|
||||
render, fireEvent, waitFor, act,
|
||||
} from '@testing-library/react';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { initializeMockApp } from '@edx/frontend-platform';
|
||||
import { AppProvider } from '@edx/frontend-platform/react';
|
||||
@@ -89,9 +91,11 @@ describe('<CollapsibleStateWithAction />', async () => {
|
||||
const container = getByText(messages.deniedCollapsibleTitle.defaultMessage);
|
||||
|
||||
fireEvent.click(container);
|
||||
waitFor(() => {
|
||||
expect(getByText(messages.deniedCollapsibleState.defaultMessage)).toBeInTheDocument();
|
||||
expect(getByText(messages.deniedCollapsibleActionTitle.defaultMessage)).toBeInTheDocument();
|
||||
act(async () => {
|
||||
await waitFor(() => {
|
||||
expect(getByText(messages.deniedCollapsibleState.defaultMessage)).toBeInTheDocument();
|
||||
expect(getByText(messages.deniedCollapsibleActionTitle.defaultMessage)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user