Remove all usages of UNSAFE_* React methods (#9583)
This commit is contained in:
parent
38dbe8ed33
commit
590b845f3f
33 changed files with 585 additions and 413 deletions
102
test/components/structures/auth/ForgotPassword-test.tsx
Normal file
102
test/components/structures/auth/ForgotPassword-test.tsx
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { fireEvent, render, screen, waitFor, waitForElementToBeRemoved } from "@testing-library/react";
|
||||
import { createClient, MatrixClient } from 'matrix-js-sdk/src/matrix';
|
||||
import { mocked } from 'jest-mock';
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
|
||||
import SdkConfig, { DEFAULTS } from '../../../../src/SdkConfig';
|
||||
import { mkServerConfig, mockPlatformPeg, unmockPlatformPeg } from "../../../test-utils";
|
||||
import ForgotPassword from "../../../../src/components/structures/auth/ForgotPassword";
|
||||
import PasswordReset from "../../../../src/PasswordReset";
|
||||
|
||||
jest.mock('matrix-js-sdk/src/matrix');
|
||||
jest.mock("../../../../src/PasswordReset", () => (jest.fn().mockReturnValue({
|
||||
resetPassword: jest.fn().mockReturnValue(new Promise(() => {})),
|
||||
})));
|
||||
jest.useFakeTimers();
|
||||
|
||||
describe('<ForgotPassword/>', () => {
|
||||
const mockClient = mocked({
|
||||
doesServerSupportLogoutDevices: jest.fn().mockResolvedValue(true),
|
||||
} as unknown as MatrixClient);
|
||||
|
||||
beforeEach(function() {
|
||||
SdkConfig.put({
|
||||
...DEFAULTS,
|
||||
disable_custom_urls: true,
|
||||
});
|
||||
mocked(createClient).mockImplementation(opts => {
|
||||
mockClient.idBaseUrl = opts.idBaseUrl;
|
||||
mockClient.baseUrl = opts.baseUrl;
|
||||
return mockClient;
|
||||
});
|
||||
fetchMock.get("https://matrix.org/_matrix/client/versions", {
|
||||
unstable_features: {},
|
||||
versions: [],
|
||||
});
|
||||
mockPlatformPeg({
|
||||
startSingleSignOn: jest.fn(),
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
fetchMock.restore();
|
||||
SdkConfig.unset(); // we touch the config, so clean up
|
||||
unmockPlatformPeg();
|
||||
});
|
||||
|
||||
const defaultProps = {
|
||||
defaultDeviceDisplayName: 'test-device-display-name',
|
||||
onServerConfigChange: jest.fn(),
|
||||
onLoginClick: jest.fn(),
|
||||
onComplete: jest.fn(),
|
||||
};
|
||||
|
||||
function getRawComponent(hsUrl = "https://matrix.org", isUrl = "https://vector.im") {
|
||||
return <ForgotPassword
|
||||
{...defaultProps}
|
||||
serverConfig={mkServerConfig(hsUrl, isUrl)}
|
||||
/>;
|
||||
}
|
||||
|
||||
it("should handle serverConfig updates correctly", async () => {
|
||||
const { container, rerender } = render(getRawComponent());
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
|
||||
fetchMock.get("https://server2/_matrix/client/versions", {
|
||||
unstable_features: {},
|
||||
versions: [],
|
||||
});
|
||||
fetchMock.get("https://vector.im/_matrix/identity/api/v1", {});
|
||||
rerender(getRawComponent("https://server2"));
|
||||
|
||||
const email = "email@addy.com";
|
||||
const pass = "thisIsAT0tallySecurePassword";
|
||||
|
||||
fireEvent.change(container.querySelector('[label=Email]'), { target: { value: email } });
|
||||
fireEvent.change(container.querySelector('[label="New Password"]'), { target: { value: pass } });
|
||||
fireEvent.change(container.querySelector('[label=Confirm]'), { target: { value: pass } });
|
||||
fireEvent.change(container.querySelector('[type=checkbox]')); // this allows us to bypass the modal
|
||||
fireEvent.submit(container.querySelector("form"));
|
||||
|
||||
await waitFor(() => {
|
||||
return expect(PasswordReset).toHaveBeenCalledWith("https://server2", expect.anything());
|
||||
}, { timeout: 5000 });
|
||||
});
|
||||
});
|
|
@ -14,25 +14,24 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ReactTestUtils from 'react-dom/test-utils';
|
||||
import { mocked } from 'jest-mock';
|
||||
import React from 'react';
|
||||
import { fireEvent, render, screen, waitForElementToBeRemoved } from "@testing-library/react";
|
||||
import { mocked, MockedObject } from 'jest-mock';
|
||||
import { createClient, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
|
||||
import SdkConfig from '../../../../src/SdkConfig';
|
||||
import { mkServerConfig } from "../../../test-utils";
|
||||
import { mkServerConfig, mockPlatformPeg, unmockPlatformPeg } from "../../../test-utils";
|
||||
import Login from "../../../../src/components/structures/auth/Login";
|
||||
import PasswordLogin from "../../../../src/components/views/auth/PasswordLogin";
|
||||
import BasePlatform from "../../../../src/BasePlatform";
|
||||
|
||||
jest.mock("matrix-js-sdk/src/matrix");
|
||||
|
||||
const flushPromises = async () => await new Promise(process.nextTick);
|
||||
|
||||
jest.useRealTimers();
|
||||
|
||||
describe('Login', function() {
|
||||
let parentDiv;
|
||||
let platform: MockedObject<BasePlatform>;
|
||||
|
||||
const mockClient = mocked({
|
||||
login: jest.fn().mockResolvedValue({}),
|
||||
loginFlows: jest.fn(),
|
||||
|
@ -45,25 +44,37 @@ describe('Login', function() {
|
|||
});
|
||||
mockClient.login.mockClear().mockResolvedValue({});
|
||||
mockClient.loginFlows.mockClear().mockResolvedValue({ flows: [{ type: "m.login.password" }] });
|
||||
mocked(createClient).mockReturnValue(mockClient);
|
||||
|
||||
parentDiv = document.createElement('div');
|
||||
document.body.appendChild(parentDiv);
|
||||
mocked(createClient).mockImplementation(opts => {
|
||||
mockClient.idBaseUrl = opts.idBaseUrl;
|
||||
mockClient.baseUrl = opts.baseUrl;
|
||||
return mockClient;
|
||||
});
|
||||
fetchMock.get("https://matrix.org/_matrix/client/versions", {
|
||||
unstable_features: {},
|
||||
versions: [],
|
||||
});
|
||||
platform = mockPlatformPeg({
|
||||
startSingleSignOn: jest.fn(),
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
ReactDOM.unmountComponentAtNode(parentDiv);
|
||||
parentDiv.remove();
|
||||
fetchMock.restore();
|
||||
SdkConfig.unset(); // we touch the config, so clean up
|
||||
unmockPlatformPeg();
|
||||
});
|
||||
|
||||
function render() {
|
||||
return ReactDOM.render(<Login
|
||||
serverConfig={mkServerConfig("https://matrix.org", "https://vector.im")}
|
||||
function getRawComponent(hsUrl = "https://matrix.org", isUrl = "https://vector.im") {
|
||||
return <Login
|
||||
serverConfig={mkServerConfig(hsUrl, isUrl)}
|
||||
onLoggedIn={() => { }}
|
||||
onRegisterClick={() => { }}
|
||||
onServerConfigChange={() => { }}
|
||||
/>, parentDiv) as unknown as Component<any, any, any>;
|
||||
/>;
|
||||
}
|
||||
|
||||
function getComponent(hsUrl?: string, isUrl?: string) {
|
||||
return render(getRawComponent(hsUrl, isUrl));
|
||||
}
|
||||
|
||||
it('should show form with change server link', async () => {
|
||||
|
@ -71,54 +82,41 @@ describe('Login', function() {
|
|||
brand: "test-brand",
|
||||
disable_custom_urls: false,
|
||||
});
|
||||
const root = render();
|
||||
const { container } = getComponent();
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
|
||||
await flushPromises();
|
||||
expect(container.querySelector("form")).toBeTruthy();
|
||||
|
||||
const form = ReactTestUtils.findRenderedComponentWithType(
|
||||
root,
|
||||
PasswordLogin,
|
||||
);
|
||||
expect(form).toBeTruthy();
|
||||
|
||||
const changeServerLink = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_ServerPicker_change');
|
||||
expect(changeServerLink).toBeTruthy();
|
||||
expect(container.querySelector(".mx_ServerPicker_change")).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show form without change server link when custom URLs disabled', async () => {
|
||||
const root = render();
|
||||
await flushPromises();
|
||||
const { container } = getComponent();
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
|
||||
const form = ReactTestUtils.findRenderedComponentWithType(
|
||||
root,
|
||||
PasswordLogin,
|
||||
);
|
||||
expect(form).toBeTruthy();
|
||||
|
||||
const changeServerLinks = ReactTestUtils.scryRenderedDOMComponentsWithClass(root, 'mx_ServerPicker_change');
|
||||
expect(changeServerLinks).toHaveLength(0);
|
||||
expect(container.querySelector("form")).toBeTruthy();
|
||||
expect(container.querySelectorAll(".mx_ServerPicker_change")).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("should show SSO button if that flow is available", async () => {
|
||||
mockClient.loginFlows.mockResolvedValue({ flows: [{ type: "m.login.sso" }] });
|
||||
|
||||
const root = render();
|
||||
await flushPromises();
|
||||
const { container } = getComponent();
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
|
||||
const ssoButton = ReactTestUtils.findRenderedDOMComponentWithClass(root, "mx_SSOButton");
|
||||
const ssoButton = container.querySelector(".mx_SSOButton");
|
||||
expect(ssoButton).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should show both SSO button and username+password if both are available", async () => {
|
||||
mockClient.loginFlows.mockResolvedValue({ flows: [{ type: "m.login.password" }, { type: "m.login.sso" }] });
|
||||
|
||||
const root = render();
|
||||
await flushPromises();
|
||||
const { container } = getComponent();
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
|
||||
const form = ReactTestUtils.findRenderedComponentWithType(root, PasswordLogin);
|
||||
expect(form).toBeTruthy();
|
||||
expect(container.querySelector("form")).toBeTruthy();
|
||||
|
||||
const ssoButton = ReactTestUtils.findRenderedDOMComponentWithClass(root, "mx_SSOButton");
|
||||
const ssoButton = container.querySelector(".mx_SSOButton");
|
||||
expect(ssoButton).toBeTruthy();
|
||||
});
|
||||
|
||||
|
@ -139,11 +137,10 @@ describe('Login', function() {
|
|||
}],
|
||||
});
|
||||
|
||||
const root = render();
|
||||
const { container } = getComponent();
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
|
||||
await flushPromises();
|
||||
|
||||
const ssoButtons = ReactTestUtils.scryRenderedDOMComponentsWithClass(root, "mx_SSOButton");
|
||||
const ssoButtons = container.querySelectorAll(".mx_SSOButton");
|
||||
expect(ssoButtons.length).toBe(3);
|
||||
});
|
||||
|
||||
|
@ -154,11 +151,33 @@ describe('Login', function() {
|
|||
}],
|
||||
});
|
||||
|
||||
const root = render();
|
||||
const { container } = getComponent();
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
|
||||
await flushPromises();
|
||||
|
||||
const ssoButtons = ReactTestUtils.scryRenderedDOMComponentsWithClass(root, "mx_SSOButton");
|
||||
const ssoButtons = container.querySelectorAll(".mx_SSOButton");
|
||||
expect(ssoButtons.length).toBe(1);
|
||||
});
|
||||
|
||||
it("should handle serverConfig updates correctly", async () => {
|
||||
mockClient.loginFlows.mockResolvedValue({
|
||||
flows: [{
|
||||
"type": "m.login.sso",
|
||||
}],
|
||||
});
|
||||
|
||||
const { container, rerender } = render(getRawComponent());
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
|
||||
fireEvent.click(container.querySelector(".mx_SSOButton"));
|
||||
expect(platform.startSingleSignOn.mock.calls[0][0].baseUrl).toBe("https://matrix.org");
|
||||
|
||||
fetchMock.get("https://server2/_matrix/client/versions", {
|
||||
unstable_features: {},
|
||||
versions: [],
|
||||
});
|
||||
rerender(getRawComponent("https://server2"));
|
||||
|
||||
fireEvent.click(container.querySelector(".mx_SSOButton"));
|
||||
expect(platform.startSingleSignOn.mock.calls[1][0].baseUrl).toBe("https://server2");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,93 +16,115 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ReactTestUtils from 'react-dom/test-utils';
|
||||
import { createClient } from 'matrix-js-sdk/src/matrix';
|
||||
import { fireEvent, render, screen, waitForElementToBeRemoved } from "@testing-library/react";
|
||||
import { createClient, MatrixClient } from 'matrix-js-sdk/src/matrix';
|
||||
import { MatrixError } from 'matrix-js-sdk/src/http-api/errors';
|
||||
import { mocked } from 'jest-mock';
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
|
||||
import SdkConfig, { DEFAULTS } from '../../../../src/SdkConfig';
|
||||
import { createTestClient, mkServerConfig } from "../../../test-utils";
|
||||
import { mkServerConfig, mockPlatformPeg, unmockPlatformPeg } from "../../../test-utils";
|
||||
import Registration from "../../../../src/components/structures/auth/Registration";
|
||||
import RegistrationForm from "../../../../src/components/views/auth/RegistrationForm";
|
||||
|
||||
jest.mock('matrix-js-sdk/src/matrix');
|
||||
jest.useFakeTimers();
|
||||
|
||||
describe('Registration', function() {
|
||||
let parentDiv;
|
||||
const registerRequest = jest.fn();
|
||||
const mockClient = mocked({
|
||||
registerRequest,
|
||||
loginFlows: jest.fn(),
|
||||
} as unknown as MatrixClient);
|
||||
|
||||
beforeEach(function() {
|
||||
SdkConfig.put({
|
||||
...DEFAULTS,
|
||||
disable_custom_urls: true,
|
||||
});
|
||||
parentDiv = document.createElement('div');
|
||||
document.body.appendChild(parentDiv);
|
||||
mocked(createClient).mockImplementation(() => createTestClient());
|
||||
mockClient.registerRequest.mockRejectedValueOnce(new MatrixError({
|
||||
flows: [{ stages: [] }],
|
||||
}, 401));
|
||||
mockClient.loginFlows.mockClear().mockResolvedValue({ flows: [{ type: "m.login.password" }] });
|
||||
mocked(createClient).mockImplementation(opts => {
|
||||
mockClient.idBaseUrl = opts.idBaseUrl;
|
||||
mockClient.baseUrl = opts.baseUrl;
|
||||
return mockClient;
|
||||
});
|
||||
fetchMock.get("https://matrix.org/_matrix/client/versions", {
|
||||
unstable_features: {},
|
||||
versions: [],
|
||||
});
|
||||
mockPlatformPeg({
|
||||
startSingleSignOn: jest.fn(),
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
ReactDOM.unmountComponentAtNode(parentDiv);
|
||||
parentDiv.remove();
|
||||
fetchMock.restore();
|
||||
SdkConfig.unset(); // we touch the config, so clean up
|
||||
unmockPlatformPeg();
|
||||
});
|
||||
|
||||
const defaultProps = {
|
||||
defaultDeviceDisplayName: 'test-device-display-name',
|
||||
serverConfig: mkServerConfig("https://matrix.org", "https://vector.im"),
|
||||
makeRegistrationUrl: jest.fn(),
|
||||
onLoggedIn: jest.fn(),
|
||||
onLoginClick: jest.fn(),
|
||||
onServerConfigChange: jest.fn(),
|
||||
};
|
||||
function render() {
|
||||
return ReactDOM.render<typeof Registration>(<Registration
|
||||
|
||||
function getRawComponent(hsUrl = "https://matrix.org", isUrl = "https://vector.im") {
|
||||
return <Registration
|
||||
{...defaultProps}
|
||||
/>, parentDiv) as React.Component<typeof Registration>;
|
||||
serverConfig={mkServerConfig(hsUrl, isUrl)}
|
||||
/>;
|
||||
}
|
||||
|
||||
function getComponent(hsUrl?: string, isUrl?: string) {
|
||||
return render(getRawComponent(hsUrl, isUrl));
|
||||
}
|
||||
|
||||
it('should show server picker', async function() {
|
||||
const root = render();
|
||||
const selector = ReactTestUtils.findRenderedDOMComponentWithClass(root, "mx_ServerPicker");
|
||||
expect(selector).toBeTruthy();
|
||||
const { container } = getComponent();
|
||||
expect(container.querySelector(".mx_ServerPicker")).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show form when custom URLs disabled', async function() {
|
||||
const root = render();
|
||||
|
||||
// Set non-empty flows & matrixClient to get past the loading spinner
|
||||
root.setState({
|
||||
flows: [{
|
||||
stages: [],
|
||||
}],
|
||||
matrixClient: {},
|
||||
busy: false,
|
||||
});
|
||||
|
||||
const form = ReactTestUtils.findRenderedComponentWithType(
|
||||
root,
|
||||
RegistrationForm,
|
||||
);
|
||||
expect(form).toBeTruthy();
|
||||
const { container } = getComponent();
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
expect(container.querySelector("form")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should show SSO options if those are available", async () => {
|
||||
const root = render();
|
||||
mockClient.loginFlows.mockClear().mockResolvedValue({ flows: [{ type: "m.login.sso" }] });
|
||||
const { container } = getComponent();
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
|
||||
// Set non-empty flows & matrixClient to get past the loading spinner
|
||||
root.setState({
|
||||
flows: [{
|
||||
stages: [],
|
||||
}],
|
||||
ssoFlow: {
|
||||
type: "m.login.sso",
|
||||
},
|
||||
matrixClient: {},
|
||||
busy: false,
|
||||
});
|
||||
|
||||
const ssoButton = ReactTestUtils.findRenderedDOMComponentWithClass(root, "mx_SSOButton");
|
||||
const ssoButton = container.querySelector(".mx_SSOButton");
|
||||
expect(ssoButton).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should handle serverConfig updates correctly", async () => {
|
||||
mockClient.loginFlows.mockResolvedValue({
|
||||
flows: [{
|
||||
"type": "m.login.sso",
|
||||
}],
|
||||
});
|
||||
|
||||
const { container, rerender } = render(getRawComponent());
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
|
||||
fireEvent.click(container.querySelector(".mx_SSOButton"));
|
||||
expect(registerRequest.mock.instances[0].baseUrl).toBe("https://matrix.org");
|
||||
|
||||
fetchMock.get("https://server2/_matrix/client/versions", {
|
||||
unstable_features: {},
|
||||
versions: [],
|
||||
});
|
||||
rerender(getRawComponent("https://server2"));
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading..."));
|
||||
|
||||
fireEvent.click(container.querySelector(".mx_SSOButton"));
|
||||
expect(registerRequest.mock.instances[1].baseUrl).toBe("https://server2");
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue