mirror of https://github.com/vector-im/riot-web
apply minor changes from review
parent
0b1e7adf91
commit
f4b403d236
|
@ -6,19 +6,11 @@ Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useCallback, useRef, useState } from "react";
|
import React, { useCallback, useRef, useState } from "react";
|
||||||
import {
|
import { EventType, KnownMembership, MatrixEvent, Room, RoomStateEvent, RoomMember } from "matrix-js-sdk/src/matrix";
|
||||||
CryptoEvent,
|
import { CryptoApi, CryptoEvent, UserVerificationStatus } from "matrix-js-sdk/src/crypto-api";
|
||||||
EventType,
|
|
||||||
KnownMembership,
|
|
||||||
MatrixEvent,
|
|
||||||
Room,
|
|
||||||
RoomStateEvent,
|
|
||||||
RoomMember,
|
|
||||||
} from "matrix-js-sdk/src/matrix";
|
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { Button, Separator } from "@vector-im/compound-web";
|
import { Button, Separator } from "@vector-im/compound-web";
|
||||||
|
|
||||||
import type { CryptoApi, UserVerificationStatus } from "matrix-js-sdk/src/crypto-api";
|
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
import MemberAvatar from "../avatars/MemberAvatar";
|
import MemberAvatar from "../avatars/MemberAvatar";
|
||||||
import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
|
import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
|
||||||
|
|
|
@ -8,7 +8,6 @@ Please see LICENSE files in the repository root for full details.
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { sleep } from "matrix-js-sdk/src/utils";
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
import {
|
import {
|
||||||
CryptoEvent,
|
|
||||||
EventType,
|
EventType,
|
||||||
MatrixClient,
|
MatrixClient,
|
||||||
MatrixEvent,
|
MatrixEvent,
|
||||||
|
@ -17,8 +16,9 @@ import {
|
||||||
RoomStateEvent,
|
RoomStateEvent,
|
||||||
RoomMember,
|
RoomMember,
|
||||||
} from "matrix-js-sdk/src/matrix";
|
} from "matrix-js-sdk/src/matrix";
|
||||||
import { UserVerificationStatus } from "matrix-js-sdk/src/crypto-api";
|
import { CryptoEvent, UserVerificationStatus } from "matrix-js-sdk/src/crypto-api";
|
||||||
import { act, fireEvent, render, screen, waitFor } from "jest-matrix-react";
|
import { act, render, screen, waitFor } from "jest-matrix-react";
|
||||||
|
import userEvent from "@testing-library/user-event";
|
||||||
|
|
||||||
import { stubClient } from "../../../../test-utils";
|
import { stubClient } from "../../../../test-utils";
|
||||||
import { UserIdentityWarning } from "../../../../../src/components/views/rooms/UserIdentityWarning";
|
import { UserIdentityWarning } from "../../../../../src/components/views/rooms/UserIdentityWarning";
|
||||||
|
@ -52,7 +52,11 @@ function dummyRoomState(): RoomState {
|
||||||
return new RoomState(ROOM_ID);
|
return new RoomState(ROOM_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the warning element, given the warning text (excluding the "Learn more" link).
|
/**
|
||||||
|
* Get the warning element, given the warning text (excluding the "Learn more"
|
||||||
|
* link). This is needed because the warning text contains a `<b>` tag, so the
|
||||||
|
* normal `getByText` doesn't work.
|
||||||
|
*/
|
||||||
function getWarningByText(text: string): Element {
|
function getWarningByText(text: string): Element {
|
||||||
return screen.getByText((content?: string, element?: Element | null): boolean => {
|
return screen.getByText((content?: string, element?: Element | null): boolean => {
|
||||||
return (
|
return (
|
||||||
|
@ -63,6 +67,12 @@ function getWarningByText(text: string): Element {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderComponent(client: MatrixClient, room: Room) {
|
||||||
|
return render(<UserIdentityWarning room={room} key={ROOM_ID} />, {
|
||||||
|
wrapper: ({ ...rest }) => <MatrixClientContext.Provider value={client} {...rest} />,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
describe("UserIdentityWarning", () => {
|
describe("UserIdentityWarning", () => {
|
||||||
let client: MatrixClient;
|
let client: MatrixClient;
|
||||||
let room: Room;
|
let room: Room;
|
||||||
|
@ -80,24 +90,22 @@ describe("UserIdentityWarning", () => {
|
||||||
// member whose identity needs accepting, we should display a warning. When
|
// member whose identity needs accepting, we should display a warning. When
|
||||||
// the "OK" button gets pressed, it should call `pinCurrentUserIdentity`.
|
// the "OK" button gets pressed, it should call `pinCurrentUserIdentity`.
|
||||||
it("displays a warning when a user's identity needs approval", async () => {
|
it("displays a warning when a user's identity needs approval", async () => {
|
||||||
room.getEncryptionTargetMembers = jest.fn(async () => {
|
jest.spyOn(room, "getEncryptionTargetMembers").mockResolvedValue([
|
||||||
return [mockRoomMember("@alice:example.org", "Alice")];
|
mockRoomMember("@alice:example.org", "Alice"),
|
||||||
});
|
]);
|
||||||
const crypto = client.getCrypto()!;
|
const crypto = client.getCrypto()!;
|
||||||
crypto["getUserVerificationStatus"] = jest.fn(async () => {
|
jest.spyOn(crypto, "getUserVerificationStatus").mockResolvedValue(
|
||||||
return Promise.resolve(new UserVerificationStatus(false, false, false, true));
|
new UserVerificationStatus(false, false, false, true),
|
||||||
});
|
);
|
||||||
crypto.pinCurrentUserIdentity = jest.fn();
|
crypto.pinCurrentUserIdentity = jest.fn();
|
||||||
const { container } = render(<UserIdentityWarning room={room} key={ROOM_ID} />, {
|
renderComponent(client, room);
|
||||||
wrapper: ({ ...rest }) => <MatrixClientContext.Provider value={client} {...rest} />,
|
|
||||||
});
|
|
||||||
|
|
||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
expect(
|
expect(
|
||||||
getWarningByText("Alice's (@alice:example.org) identity appears to have changed."),
|
getWarningByText("Alice's (@alice:example.org) identity appears to have changed."),
|
||||||
).toBeInTheDocument(),
|
).toBeInTheDocument(),
|
||||||
);
|
);
|
||||||
fireEvent.click(container.querySelector("[role=button]")!);
|
await userEvent.click(screen.getByRole("button")!);
|
||||||
await waitFor(() => expect(crypto.pinCurrentUserIdentity).toHaveBeenCalledWith("@alice:example.org"));
|
await waitFor(() => expect(crypto.pinCurrentUserIdentity).toHaveBeenCalledWith("@alice:example.org"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -105,19 +113,17 @@ describe("UserIdentityWarning", () => {
|
||||||
// enabled, then we should display a warning if there are any users whose
|
// enabled, then we should display a warning if there are any users whose
|
||||||
// identity need accepting.
|
// identity need accepting.
|
||||||
it("displays pending warnings when encryption is enabled", async () => {
|
it("displays pending warnings when encryption is enabled", async () => {
|
||||||
room.getEncryptionTargetMembers = jest.fn(async () => {
|
jest.spyOn(room, "getEncryptionTargetMembers").mockResolvedValue([
|
||||||
return [mockRoomMember("@alice:example.org", "Alice")];
|
mockRoomMember("@alice:example.org", "Alice"),
|
||||||
});
|
]);
|
||||||
// Start the room off unencrypted. We shouldn't display anything.
|
// Start the room off unencrypted. We shouldn't display anything.
|
||||||
room.hasEncryptionStateEvent = jest.fn(() => false);
|
jest.spyOn(room, "hasEncryptionStateEvent").mockReturnValue(false);
|
||||||
const crypto = client.getCrypto()!;
|
const crypto = client.getCrypto()!;
|
||||||
crypto["getUserVerificationStatus"] = jest.fn(async () => {
|
jest.spyOn(crypto, "getUserVerificationStatus").mockResolvedValue(
|
||||||
return Promise.resolve(new UserVerificationStatus(false, false, false, true));
|
new UserVerificationStatus(false, false, false, true),
|
||||||
});
|
);
|
||||||
|
|
||||||
render(<UserIdentityWarning room={room} key={ROOM_ID} />, {
|
renderComponent(client, room);
|
||||||
wrapper: ({ ...rest }) => <MatrixClientContext.Provider value={client} {...rest} />,
|
|
||||||
});
|
|
||||||
await sleep(10); // give it some time to finish initialising
|
await sleep(10); // give it some time to finish initialising
|
||||||
expect(() => getWarningByText("Alice's (@alice:example.org) identity appears to have changed.")).toThrow();
|
expect(() => getWarningByText("Alice's (@alice:example.org) identity appears to have changed.")).toThrow();
|
||||||
|
|
||||||
|
@ -148,17 +154,15 @@ describe("UserIdentityWarning", () => {
|
||||||
// When a user's identity needs approval, or has been approved, the display
|
// When a user's identity needs approval, or has been approved, the display
|
||||||
// should update appropriately.
|
// should update appropriately.
|
||||||
it("updates the display when identity changes", async () => {
|
it("updates the display when identity changes", async () => {
|
||||||
room.getEncryptionTargetMembers = jest.fn(async () => {
|
jest.spyOn(room, "getEncryptionTargetMembers").mockResolvedValue([
|
||||||
return [mockRoomMember("@alice:example.org", "Alice")];
|
mockRoomMember("@alice:example.org", "Alice"),
|
||||||
});
|
]);
|
||||||
room.getMember = jest.fn(() => mockRoomMember("@alice:example.org", "Alice"));
|
jest.spyOn(room, "getMember").mockReturnValue(mockRoomMember("@alice:example.org", "Alice"));
|
||||||
const crypto = client.getCrypto()!;
|
const crypto = client.getCrypto()!;
|
||||||
crypto["getUserVerificationStatus"] = jest.fn(async () => {
|
jest.spyOn(crypto, "getUserVerificationStatus").mockResolvedValue(
|
||||||
return Promise.resolve(new UserVerificationStatus(false, false, false, false));
|
new UserVerificationStatus(false, false, false, false),
|
||||||
});
|
);
|
||||||
render(<UserIdentityWarning room={room} key={ROOM_ID} />, {
|
renderComponent(client, room);
|
||||||
wrapper: ({ ...rest }) => <MatrixClientContext.Provider value={client} {...rest} />,
|
|
||||||
});
|
|
||||||
await sleep(10); // give it some time to finish initialising
|
await sleep(10); // give it some time to finish initialising
|
||||||
expect(() => getWarningByText("Alice's (@alice:example.org) identity appears to have changed.")).toThrow();
|
expect(() => getWarningByText("Alice's (@alice:example.org) identity appears to have changed.")).toThrow();
|
||||||
|
|
||||||
|
@ -194,17 +198,13 @@ describe("UserIdentityWarning", () => {
|
||||||
// joins/leaves, we should update the warning appropriately.
|
// joins/leaves, we should update the warning appropriately.
|
||||||
it("updates the display when a member joins/leaves", async () => {
|
it("updates the display when a member joins/leaves", async () => {
|
||||||
// Nobody in the room yet
|
// Nobody in the room yet
|
||||||
room.getEncryptionTargetMembers = jest.fn(async () => {
|
jest.spyOn(room, "getEncryptionTargetMembers").mockResolvedValue([]);
|
||||||
return [];
|
jest.spyOn(room, "getMember").mockReturnValue(mockRoomMember("@alice:example.org", "Alice"));
|
||||||
});
|
|
||||||
room.getMember = jest.fn(() => mockRoomMember("@alice:example.org", "Alice"));
|
|
||||||
const crypto = client.getCrypto()!;
|
const crypto = client.getCrypto()!;
|
||||||
crypto["getUserVerificationStatus"] = jest.fn(async () => {
|
jest.spyOn(crypto, "getUserVerificationStatus").mockResolvedValue(
|
||||||
return Promise.resolve(new UserVerificationStatus(false, false, false, true));
|
new UserVerificationStatus(false, false, false, true),
|
||||||
});
|
);
|
||||||
render(<UserIdentityWarning room={room} key={ROOM_ID} />, {
|
renderComponent(client, room);
|
||||||
wrapper: ({ ...rest }) => <MatrixClientContext.Provider value={client} {...rest} />,
|
|
||||||
});
|
|
||||||
await sleep(10); // give it some time to finish initialising
|
await sleep(10); // give it some time to finish initialising
|
||||||
|
|
||||||
// Alice joins. Her identity needs approval, so we should show a warning.
|
// Alice joins. Her identity needs approval, so we should show a warning.
|
||||||
|
@ -253,20 +253,19 @@ describe("UserIdentityWarning", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// When we have multiple users whose identity needs approval, one user's
|
// When we have multiple users whose identity needs approval, one user's
|
||||||
// identity no longer reeds approval (e.g. their identity was approved),
|
// identity no longer needs approval (e.g. their identity was approved),
|
||||||
// then we show the next one.
|
// then we show the next one.
|
||||||
it("displays the next user when the current user's identity is approved", async () => {
|
it("displays the next user when the current user's identity is approved", async () => {
|
||||||
room.getEncryptionTargetMembers = jest.fn(async () => {
|
jest.spyOn(room, "getEncryptionTargetMembers").mockResolvedValue([
|
||||||
return [mockRoomMember("@alice:example.org", "Alice"), mockRoomMember("@bob:example.org")];
|
mockRoomMember("@alice:example.org", "Alice"),
|
||||||
});
|
mockRoomMember("@bob:example.org"),
|
||||||
|
]);
|
||||||
const crypto = client.getCrypto()!;
|
const crypto = client.getCrypto()!;
|
||||||
crypto["getUserVerificationStatus"] = jest.fn(async () => {
|
jest.spyOn(crypto, "getUserVerificationStatus").mockResolvedValue(
|
||||||
return Promise.resolve(new UserVerificationStatus(false, false, false, true));
|
new UserVerificationStatus(false, false, false, true),
|
||||||
});
|
);
|
||||||
|
|
||||||
render(<UserIdentityWarning room={room} key={ROOM_ID} />, {
|
renderComponent(client, room);
|
||||||
wrapper: ({ ...rest }) => <MatrixClientContext.Provider value={client} {...rest} />,
|
|
||||||
});
|
|
||||||
// We should warn about Alice's identity first.
|
// We should warn about Alice's identity first.
|
||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
expect(
|
expect(
|
||||||
|
@ -295,22 +294,22 @@ describe("UserIdentityWarning", () => {
|
||||||
// First case: check that if the update says that the user identity
|
// First case: check that if the update says that the user identity
|
||||||
// needs approval, but the fetch says it doesn't, we show the warning.
|
// needs approval, but the fetch says it doesn't, we show the warning.
|
||||||
it("update says identity needs approval", async () => {
|
it("update says identity needs approval", async () => {
|
||||||
room.getEncryptionTargetMembers = jest.fn(async () => {
|
jest.spyOn(room, "getEncryptionTargetMembers").mockResolvedValue([
|
||||||
return [mockRoomMember("@alice:example.org", "Alice")];
|
mockRoomMember("@alice:example.org", "Alice"),
|
||||||
});
|
]);
|
||||||
room.getMember = jest.fn(() => mockRoomMember("@alice:example.org", "Alice"));
|
jest.spyOn(room, "getMember").mockReturnValue(mockRoomMember("@alice:example.org", "Alice"));
|
||||||
const crypto = client.getCrypto()!;
|
const crypto = client.getCrypto()!;
|
||||||
crypto["getUserVerificationStatus"] = jest.fn(async () => {
|
jest.spyOn(crypto, "getUserVerificationStatus").mockImplementation(async () => {
|
||||||
client.emit(
|
act(() => {
|
||||||
CryptoEvent.UserTrustStatusChanged,
|
client.emit(
|
||||||
"@alice:example.org",
|
CryptoEvent.UserTrustStatusChanged,
|
||||||
new UserVerificationStatus(false, false, false, true),
|
"@alice:example.org",
|
||||||
);
|
new UserVerificationStatus(false, false, false, true),
|
||||||
|
);
|
||||||
|
});
|
||||||
return Promise.resolve(new UserVerificationStatus(false, false, false, false));
|
return Promise.resolve(new UserVerificationStatus(false, false, false, false));
|
||||||
});
|
});
|
||||||
render(<UserIdentityWarning room={room} key={ROOM_ID} />, {
|
renderComponent(client, room);
|
||||||
wrapper: ({ ...rest }) => <MatrixClientContext.Provider value={client} {...rest} />,
|
|
||||||
});
|
|
||||||
await sleep(10); // give it some time to finish initialising
|
await sleep(10); // give it some time to finish initialising
|
||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
expect(
|
expect(
|
||||||
|
@ -323,22 +322,22 @@ describe("UserIdentityWarning", () => {
|
||||||
// doesn't needs approval, but the fetch says it does, we don't show the
|
// doesn't needs approval, but the fetch says it does, we don't show the
|
||||||
// warning.
|
// warning.
|
||||||
it("update says identity doesn't need approval", async () => {
|
it("update says identity doesn't need approval", async () => {
|
||||||
room.getEncryptionTargetMembers = jest.fn(async () => {
|
jest.spyOn(room, "getEncryptionTargetMembers").mockResolvedValue([
|
||||||
return [mockRoomMember("@alice:example.org", "Alice")];
|
mockRoomMember("@alice:example.org", "Alice"),
|
||||||
});
|
]);
|
||||||
room.getMember = jest.fn(() => mockRoomMember("@alice:example.org", "Alice"));
|
jest.spyOn(room, "getMember").mockReturnValue(mockRoomMember("@alice:example.org", "Alice"));
|
||||||
const crypto = client.getCrypto()!;
|
const crypto = client.getCrypto()!;
|
||||||
crypto["getUserVerificationStatus"] = jest.fn(async () => {
|
jest.spyOn(crypto, "getUserVerificationStatus").mockImplementation(async () => {
|
||||||
client.emit(
|
act(() => {
|
||||||
CryptoEvent.UserTrustStatusChanged,
|
client.emit(
|
||||||
"@alice:example.org",
|
CryptoEvent.UserTrustStatusChanged,
|
||||||
new UserVerificationStatus(false, false, false, false),
|
"@alice:example.org",
|
||||||
);
|
new UserVerificationStatus(false, false, false, false),
|
||||||
|
);
|
||||||
|
});
|
||||||
return Promise.resolve(new UserVerificationStatus(false, false, false, true));
|
return Promise.resolve(new UserVerificationStatus(false, false, false, true));
|
||||||
});
|
});
|
||||||
render(<UserIdentityWarning room={room} key={ROOM_ID} />, {
|
renderComponent(client, room);
|
||||||
wrapper: ({ ...rest }) => <MatrixClientContext.Provider value={client} {...rest} />,
|
|
||||||
});
|
|
||||||
await sleep(10); // give it some time to finish initialising
|
await sleep(10); // give it some time to finish initialising
|
||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
expect(() =>
|
expect(() =>
|
||||||
|
|
Loading…
Reference in New Issue