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:
Bilal Qamar
2023-10-11 11:08:26 +05:00
committed by GitHub
parent 3fe35344f0
commit 97d0a1ce61
6 changed files with 3406 additions and 4402 deletions

7601
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -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"
}
}

View File

@@ -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();
});

View File

@@ -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();
}
});
});
});

View File

@@ -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';

View File

@@ -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();
});
});
});
});