Prepare for repo merge
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
0f670b8dc0
commit
b084ff2313
807 changed files with 0 additions and 0 deletions
|
@ -1,535 +0,0 @@
|
|||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { render, screen, waitFor } from "jest-matrix-react";
|
||||
import { MatrixClient, ThreepidMedium } from "matrix-js-sdk/src/matrix";
|
||||
import React from "react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { mocked } from "jest-mock";
|
||||
|
||||
import { AddRemoveThreepids } from "../../../../src/components/views/settings/AddRemoveThreepids";
|
||||
import { clearAllModals, stubClient } from "../../../test-utils";
|
||||
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
||||
import Modal from "../../../../src/Modal";
|
||||
|
||||
const MOCK_IDENTITY_ACCESS_TOKEN = "mock_identity_access_token";
|
||||
const mockGetAccessToken = jest.fn().mockResolvedValue(MOCK_IDENTITY_ACCESS_TOKEN);
|
||||
jest.mock("../../../../src/IdentityAuthClient", () =>
|
||||
jest.fn().mockImplementation(() => ({
|
||||
getAccessToken: mockGetAccessToken,
|
||||
})),
|
||||
);
|
||||
|
||||
const EMAIL1 = {
|
||||
medium: ThreepidMedium.Email,
|
||||
address: "alice@nowhere.dummy",
|
||||
};
|
||||
|
||||
const PHONE1 = {
|
||||
medium: ThreepidMedium.Phone,
|
||||
address: "447700900000",
|
||||
};
|
||||
|
||||
const PHONE1_LOCALNUM = "07700900000";
|
||||
|
||||
describe("AddRemoveThreepids", () => {
|
||||
let client: MatrixClient;
|
||||
|
||||
beforeEach(() => {
|
||||
client = stubClient();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
clearAllModals();
|
||||
});
|
||||
|
||||
const clientProviderWrapper: React.FC = ({ children }) => (
|
||||
<MatrixClientContext.Provider value={client}>{children}</MatrixClientContext.Provider>
|
||||
);
|
||||
|
||||
it("should render a loader while loading", async () => {
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="hs"
|
||||
medium={ThreepidMedium.Email}
|
||||
threepids={[]}
|
||||
isLoading={true}
|
||||
onChange={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByLabelText("Loading…")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should render email addresses", async () => {
|
||||
const { container } = render(
|
||||
<AddRemoveThreepids
|
||||
mode="hs"
|
||||
medium={ThreepidMedium.Email}
|
||||
threepids={[EMAIL1]}
|
||||
isLoading={false}
|
||||
onChange={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should render phone numbers", async () => {
|
||||
const { container } = render(
|
||||
<AddRemoveThreepids
|
||||
mode="hs"
|
||||
medium={ThreepidMedium.Phone}
|
||||
threepids={[PHONE1]}
|
||||
isLoading={false}
|
||||
onChange={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should handle no email addresses", async () => {
|
||||
const { container } = render(
|
||||
<AddRemoveThreepids
|
||||
mode="hs"
|
||||
medium={ThreepidMedium.Email}
|
||||
threepids={[]}
|
||||
isLoading={false}
|
||||
onChange={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should add an email address", async () => {
|
||||
const onChangeFn = jest.fn();
|
||||
mocked(client.requestAdd3pidEmailToken).mockResolvedValue({ sid: "1" });
|
||||
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="hs"
|
||||
medium={ThreepidMedium.Email}
|
||||
threepids={[]}
|
||||
isLoading={false}
|
||||
onChange={onChangeFn}
|
||||
/>,
|
||||
{
|
||||
wrapper: clientProviderWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
const input = screen.getByRole("textbox", { name: "Email Address" });
|
||||
await userEvent.type(input, EMAIL1.address);
|
||||
const addButton = screen.getByRole("button", { name: "Add" });
|
||||
await userEvent.click(addButton);
|
||||
|
||||
expect(client.requestAdd3pidEmailToken).toHaveBeenCalledWith(EMAIL1.address, client.generateClientSecret(), 1);
|
||||
const continueButton = screen.getByRole("button", { name: "Continue" });
|
||||
|
||||
expect(continueButton).toBeEnabled();
|
||||
|
||||
await userEvent.click(continueButton);
|
||||
|
||||
expect(client.addThreePidOnly).toHaveBeenCalledWith({
|
||||
client_secret: client.generateClientSecret(),
|
||||
sid: "1",
|
||||
auth: undefined,
|
||||
});
|
||||
|
||||
expect(onChangeFn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should display an error if the link has not been clicked", async () => {
|
||||
const onChangeFn = jest.fn();
|
||||
const createDialogFn = jest.spyOn(Modal, "createDialog");
|
||||
mocked(client.requestAdd3pidEmailToken).mockResolvedValue({ sid: "1" });
|
||||
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="hs"
|
||||
medium={ThreepidMedium.Email}
|
||||
threepids={[]}
|
||||
isLoading={false}
|
||||
onChange={onChangeFn}
|
||||
/>,
|
||||
{
|
||||
wrapper: clientProviderWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
const input = screen.getByRole("textbox", { name: "Email Address" });
|
||||
await userEvent.type(input, EMAIL1.address);
|
||||
const addButton = screen.getByRole("button", { name: "Add" });
|
||||
await userEvent.click(addButton);
|
||||
|
||||
const continueButton = screen.getByRole("button", { name: "Continue" });
|
||||
|
||||
expect(continueButton).toBeEnabled();
|
||||
|
||||
mocked(client).addThreePidOnly.mockRejectedValueOnce(new Error("Unauthorized"));
|
||||
|
||||
await userEvent.click(continueButton);
|
||||
|
||||
expect(createDialogFn).toHaveBeenCalledWith(expect.anything(), {
|
||||
description: "Unauthorized",
|
||||
title: "Unable to verify email address.",
|
||||
});
|
||||
|
||||
expect(onChangeFn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should add a phone number", async () => {
|
||||
const onChangeFn = jest.fn();
|
||||
mocked(client.requestAdd3pidMsisdnToken).mockResolvedValue({
|
||||
sid: "1",
|
||||
msisdn: PHONE1.address,
|
||||
intl_fmt: "+" + PHONE1.address,
|
||||
success: true,
|
||||
submit_url: "https://example.dummy",
|
||||
});
|
||||
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="hs"
|
||||
medium={ThreepidMedium.Phone}
|
||||
threepids={[]}
|
||||
isLoading={false}
|
||||
onChange={onChangeFn}
|
||||
/>,
|
||||
{
|
||||
wrapper: clientProviderWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
const countryDropdown = screen.getByRole("button", { name: /Country Dropdown/ });
|
||||
await userEvent.click(countryDropdown);
|
||||
const gbOption = screen.getByRole("option", { name: "🇬🇧 United Kingdom (+44)" });
|
||||
await userEvent.click(gbOption);
|
||||
|
||||
const input = screen.getByRole("textbox", { name: "Phone Number" });
|
||||
await userEvent.type(input, PHONE1_LOCALNUM);
|
||||
|
||||
const addButton = screen.getByRole("button", { name: /Add/ });
|
||||
userEvent.click(addButton);
|
||||
|
||||
const continueButton = await screen.findByRole("button", { name: /Continue/ });
|
||||
|
||||
await expect(continueButton).toHaveAttribute("aria-disabled", "true");
|
||||
|
||||
await expect(
|
||||
await screen.findByText(
|
||||
`A text message has been sent to +${PHONE1.address}. Please enter the verification code it contains.`,
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
|
||||
expect(client.requestAdd3pidMsisdnToken).toHaveBeenCalledWith(
|
||||
"GB",
|
||||
PHONE1_LOCALNUM,
|
||||
client.generateClientSecret(),
|
||||
1,
|
||||
);
|
||||
|
||||
const verificationInput = screen.getByRole("textbox", { name: "Verification code" });
|
||||
await userEvent.type(verificationInput, "123456");
|
||||
|
||||
expect(continueButton).not.toHaveAttribute("aria-disabled", "true");
|
||||
userEvent.click(continueButton);
|
||||
|
||||
await waitFor(() => expect(continueButton).toHaveAttribute("aria-disabled", "true"));
|
||||
|
||||
expect(client.addThreePidOnly).toHaveBeenCalledWith({
|
||||
client_secret: client.generateClientSecret(),
|
||||
sid: "1",
|
||||
auth: undefined,
|
||||
});
|
||||
|
||||
expect(onChangeFn).toHaveBeenCalled();
|
||||
}, 10000);
|
||||
|
||||
it("should display an error if the code is incorrect", async () => {
|
||||
const onChangeFn = jest.fn();
|
||||
const createDialogFn = jest.spyOn(Modal, "createDialog");
|
||||
mocked(client.requestAdd3pidMsisdnToken).mockResolvedValue({
|
||||
sid: "1",
|
||||
msisdn: PHONE1.address,
|
||||
intl_fmt: "+" + PHONE1.address,
|
||||
success: true,
|
||||
submit_url: "https://example.dummy",
|
||||
});
|
||||
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="hs"
|
||||
medium={ThreepidMedium.Phone}
|
||||
threepids={[]}
|
||||
isLoading={false}
|
||||
onChange={onChangeFn}
|
||||
/>,
|
||||
{
|
||||
wrapper: clientProviderWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
const input = screen.getByRole("textbox", { name: "Phone Number" });
|
||||
await userEvent.type(input, PHONE1_LOCALNUM);
|
||||
|
||||
const countryDropdown = screen.getByRole("button", { name: /Country Dropdown/ });
|
||||
await userEvent.click(countryDropdown);
|
||||
const gbOption = screen.getByRole("option", { name: "🇬🇧 United Kingdom (+44)" });
|
||||
await userEvent.click(gbOption);
|
||||
|
||||
const addButton = screen.getByRole("button", { name: /Add/ });
|
||||
await userEvent.click(addButton);
|
||||
|
||||
mocked(client).addThreePidOnly.mockRejectedValueOnce(new Error("Unauthorized"));
|
||||
|
||||
const verificationInput = screen.getByRole("textbox", { name: "Verification code" });
|
||||
await userEvent.type(verificationInput, "123457");
|
||||
|
||||
const continueButton = screen.getByRole("button", { name: /Continue/ });
|
||||
await userEvent.click(continueButton);
|
||||
|
||||
expect(createDialogFn).toHaveBeenCalledWith(expect.anything(), {
|
||||
description: "Unauthorized",
|
||||
title: "Unable to verify phone number.",
|
||||
});
|
||||
|
||||
expect(onChangeFn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should remove an email address", async () => {
|
||||
const onChangeFn = jest.fn();
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="hs"
|
||||
medium={ThreepidMedium.Email}
|
||||
threepids={[EMAIL1]}
|
||||
isLoading={false}
|
||||
onChange={onChangeFn}
|
||||
/>,
|
||||
{
|
||||
wrapper: clientProviderWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
const removeButton = screen.getByRole("button", { name: /Remove/ });
|
||||
await userEvent.click(removeButton);
|
||||
|
||||
expect(screen.getByText(`Remove ${EMAIL1.address}?`)).toBeVisible();
|
||||
|
||||
const confirmRemoveButton = screen.getByRole("button", { name: /Remove/ });
|
||||
await userEvent.click(confirmRemoveButton);
|
||||
|
||||
expect(client.deleteThreePid).toHaveBeenCalledWith(ThreepidMedium.Email, EMAIL1.address);
|
||||
expect(onChangeFn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should return to default view if adding is cancelled", async () => {
|
||||
const onChangeFn = jest.fn();
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="hs"
|
||||
medium={ThreepidMedium.Email}
|
||||
threepids={[EMAIL1]}
|
||||
isLoading={false}
|
||||
onChange={onChangeFn}
|
||||
/>,
|
||||
{
|
||||
wrapper: clientProviderWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
const removeButton = screen.getByRole("button", { name: /Remove/ });
|
||||
await userEvent.click(removeButton);
|
||||
|
||||
expect(screen.getByText(`Remove ${EMAIL1.address}?`)).toBeVisible();
|
||||
|
||||
const confirmRemoveButton = screen.getByRole("button", { name: /Cancel/ });
|
||||
await userEvent.click(confirmRemoveButton);
|
||||
|
||||
expect(screen.queryByText(`Remove ${EMAIL1.address}?`)).not.toBeInTheDocument();
|
||||
|
||||
expect(client.deleteThreePid).not.toHaveBeenCalledWith(ThreepidMedium.Email, EMAIL1.address);
|
||||
expect(onChangeFn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should remove a phone number", async () => {
|
||||
const onChangeFn = jest.fn();
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="hs"
|
||||
medium={ThreepidMedium.Phone}
|
||||
threepids={[PHONE1]}
|
||||
isLoading={false}
|
||||
onChange={onChangeFn}
|
||||
/>,
|
||||
{
|
||||
wrapper: clientProviderWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
const removeButton = screen.getByRole("button", { name: /Remove/ });
|
||||
await userEvent.click(removeButton);
|
||||
|
||||
expect(screen.getByText(`Remove ${PHONE1.address}?`)).toBeVisible();
|
||||
|
||||
const confirmRemoveButton = screen.getByRole("button", { name: /Remove/ });
|
||||
await userEvent.click(confirmRemoveButton);
|
||||
|
||||
expect(client.deleteThreePid).toHaveBeenCalledWith(ThreepidMedium.Phone, PHONE1.address);
|
||||
expect(onChangeFn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should bind an email address", async () => {
|
||||
mocked(client).requestEmailToken.mockResolvedValue({ sid: "1" });
|
||||
|
||||
mocked(client).getIdentityServerUrl.mockReturnValue("https://the_best_id_server.dummy");
|
||||
|
||||
const onChangeFn = jest.fn();
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="is"
|
||||
medium={ThreepidMedium.Email}
|
||||
threepids={[Object.assign({}, EMAIL1, { bound: false })]}
|
||||
isLoading={false}
|
||||
onChange={onChangeFn}
|
||||
/>,
|
||||
{
|
||||
wrapper: clientProviderWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(screen.getByText(EMAIL1.address)).toBeVisible();
|
||||
const shareButton = screen.getByRole("button", { name: /Share/ });
|
||||
await userEvent.click(shareButton);
|
||||
|
||||
expect(screen.getByText("Verify the link in your inbox")).toBeVisible();
|
||||
|
||||
expect(client.requestEmailToken).toHaveBeenCalledWith(
|
||||
EMAIL1.address,
|
||||
client.generateClientSecret(),
|
||||
1,
|
||||
undefined,
|
||||
MOCK_IDENTITY_ACCESS_TOKEN,
|
||||
);
|
||||
|
||||
const completeButton = screen.getByRole("button", { name: /Complete/ });
|
||||
await userEvent.click(completeButton);
|
||||
|
||||
expect(client.bindThreePid).toHaveBeenCalledWith({
|
||||
sid: "1",
|
||||
client_secret: client.generateClientSecret(),
|
||||
id_server: "https://the_best_id_server.dummy",
|
||||
id_access_token: MOCK_IDENTITY_ACCESS_TOKEN,
|
||||
});
|
||||
|
||||
expect(onChangeFn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should bind a phone number", async () => {
|
||||
mocked(client).requestMsisdnToken.mockResolvedValue({
|
||||
success: true,
|
||||
sid: "1",
|
||||
msisdn: PHONE1.address,
|
||||
intl_fmt: "+" + PHONE1.address,
|
||||
});
|
||||
|
||||
mocked(client).getIdentityServerUrl.mockReturnValue("https://the_best_id_server.dummy");
|
||||
|
||||
const onChangeFn = jest.fn();
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="is"
|
||||
medium={ThreepidMedium.Phone}
|
||||
threepids={[Object.assign({}, PHONE1, { bound: false })]}
|
||||
isLoading={false}
|
||||
onChange={onChangeFn}
|
||||
/>,
|
||||
{
|
||||
wrapper: clientProviderWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(screen.getByText(PHONE1.address)).toBeVisible();
|
||||
const shareButton = screen.getByRole("button", { name: /Share/ });
|
||||
await userEvent.click(shareButton);
|
||||
|
||||
expect(screen.getByText("Please enter verification code sent via text.")).toBeVisible();
|
||||
|
||||
expect(client.requestMsisdnToken).toHaveBeenCalledWith(
|
||||
null,
|
||||
"+" + PHONE1.address,
|
||||
client.generateClientSecret(),
|
||||
1,
|
||||
undefined,
|
||||
MOCK_IDENTITY_ACCESS_TOKEN,
|
||||
);
|
||||
|
||||
const codeInput = screen.getByRole("textbox", { name: "Verification code" });
|
||||
await userEvent.type(codeInput, "123456");
|
||||
await userEvent.keyboard("{Enter}");
|
||||
|
||||
expect(client.bindThreePid).toHaveBeenCalledWith({
|
||||
sid: "1",
|
||||
client_secret: client.generateClientSecret(),
|
||||
id_server: "https://the_best_id_server.dummy",
|
||||
id_access_token: MOCK_IDENTITY_ACCESS_TOKEN,
|
||||
});
|
||||
|
||||
expect(onChangeFn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should revoke a bound email address", async () => {
|
||||
const onChangeFn = jest.fn();
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="is"
|
||||
medium={ThreepidMedium.Email}
|
||||
threepids={[Object.assign({}, EMAIL1, { bound: true })]}
|
||||
isLoading={false}
|
||||
onChange={onChangeFn}
|
||||
/>,
|
||||
{
|
||||
wrapper: clientProviderWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(screen.getByText(EMAIL1.address)).toBeVisible();
|
||||
const revokeButton = screen.getByRole("button", { name: /Revoke/ });
|
||||
await userEvent.click(revokeButton);
|
||||
|
||||
expect(client.unbindThreePid).toHaveBeenCalledWith(ThreepidMedium.Email, EMAIL1.address);
|
||||
expect(onChangeFn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should revoke a bound phone number", async () => {
|
||||
const onChangeFn = jest.fn();
|
||||
render(
|
||||
<AddRemoveThreepids
|
||||
mode="is"
|
||||
medium={ThreepidMedium.Phone}
|
||||
threepids={[Object.assign({}, PHONE1, { bound: true })]}
|
||||
isLoading={false}
|
||||
onChange={onChangeFn}
|
||||
/>,
|
||||
{
|
||||
wrapper: clientProviderWrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(screen.getByText(PHONE1.address)).toBeVisible();
|
||||
const revokeButton = screen.getByRole("button", { name: /Revoke/ });
|
||||
await userEvent.click(revokeButton);
|
||||
|
||||
expect(client.unbindThreePid).toHaveBeenCalledWith(ThreepidMedium.Phone, PHONE1.address);
|
||||
expect(onChangeFn).toHaveBeenCalled();
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue