Refactor MKeyVerificationRequest to shared view MVVM (#33461)

* Refactor key verification request to shared view

* Fix prettier

* add tests to pass coverage
This commit is contained in:
Zack
2026-05-11 13:36:07 +02:00
committed by GitHub
parent 7af8beea40
commit c62acc6634
16 changed files with 699 additions and 206 deletions
@@ -6,8 +6,10 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import React from "react";
import { render, screen } from "jest-matrix-react";
import { mocked } from "jest-mock";
import { EventType, type MatrixClient, MatrixEvent, MsgType, Room } from "matrix-js-sdk/src/matrix";
import { EventType, type MatrixClient, MatrixEvent, MsgType, Room, type RoomMember } from "matrix-js-sdk/src/matrix";
import {
JSONEventFactory,
@@ -20,9 +22,25 @@ import SettingsStore from "../../../src/settings/SettingsStore";
import { createTestClient, mkEvent } from "../../test-utils";
import { TimelineRenderingType } from "../../../src/contexts/RoomContext";
import { ModuleApi } from "../../../src/modules/Api";
import MatrixClientContext from "../../../src/contexts/MatrixClientContext";
const roomId = "!room:example.com";
function makeVerificationRequestEvent({ sender, to }: { sender: string; to: string }): MatrixEvent {
return mkEvent({
event: true,
type: EventType.RoomMessage,
user: sender,
room: roomId,
content: {
msgtype: MsgType.KeyVerificationRequest,
from_device: "DEVICE",
methods: ["m.sas.v1"],
to,
},
});
}
describe("pickFactory", () => {
let client: MatrixClient;
let room: Room;
@@ -206,14 +224,30 @@ describe("pickFactory", () => {
it("should return a MessageEventFactory for a UTD event", () => {
expect(pickFactory(utdEvent, client, false)).toBe(MessageEventFactory);
});
it("should not render key verification requests which do not involve the current user", () => {
const event = makeVerificationRequestEvent({
sender: "@alice:example.com",
to: "@bob:example.com",
});
expect(pickFactory(event, client, false)).toBeUndefined();
});
});
});
describe("renderTile", () => {
let client: MatrixClient;
let originalRenderMessage: typeof ModuleApi.instance.customComponents.renderMessage;
beforeEach(() => {
client = createTestClient();
originalRenderMessage = ModuleApi.instance.customComponents.renderMessage;
});
afterEach(() => {
ModuleApi.instance.customComponents.renderMessage = originalRenderMessage;
jest.restoreAllMocks();
});
it("rendering a tile defers to the module API", () => {
@@ -258,4 +292,75 @@ describe("renderTile", () => {
mxEvent: messageEvent,
});
});
it("renders an incoming key verification request with the wrapped shared-components view", () => {
const sender = "@alice:example.com";
const room = new Room(roomId, client, client.getSafeUserId());
jest.spyOn(room, "getMember").mockImplementation((userId: string) => {
if (userId === sender) return { name: "Alice" } as RoomMember;
return null;
});
mocked(client.getRoom).mockReturnValue(room);
const verificationRequestEvent = makeVerificationRequestEvent({
sender,
to: client.getUserId()!,
});
const tile = renderTile(
TimelineRenderingType.Room,
{ mxEvent: verificationRequestEvent, showHiddenEvents: false },
client,
);
if (!tile) throw new Error("Expected a key verification request tile");
render(React.createElement(MatrixClientContext.Provider, { value: client }, tile));
expect(screen.getByText("Alice wants to verify")).toBeInTheDocument();
expect(screen.getByText("Alice (@alice:example.com)")).toBeInTheDocument();
});
it("renders an outgoing key verification request with the wrapped shared-components view", () => {
const recipient = "@alice:example.com";
const room = new Room(roomId, client, client.getSafeUserId());
jest.spyOn(room, "getMember").mockImplementation((userId: string) => {
if (userId === recipient) return { name: "Alice" } as RoomMember;
return null;
});
mocked(client.getRoom).mockReturnValue(room);
const verificationRequestEvent = makeVerificationRequestEvent({
sender: client.getUserId()!,
to: recipient,
});
const tile = renderTile(
TimelineRenderingType.Room,
{ mxEvent: verificationRequestEvent, showHiddenEvents: false },
client,
);
if (!tile) throw new Error("Expected a key verification request tile");
render(React.createElement(MatrixClientContext.Provider, { value: client }, tile));
expect(screen.getByText("You sent a verification request")).toBeInTheDocument();
expect(screen.getByText("Alice (@alice:example.com)")).toBeInTheDocument();
});
it("throws when a key verification request tile is rendered without a client context", () => {
jest.spyOn(console, "error").mockImplementation(() => {});
const verificationRequestEvent = makeVerificationRequestEvent({
sender: client.getUserId()!,
to: "@alice:example.com",
});
const tile = renderTile(
TimelineRenderingType.Room,
{ mxEvent: verificationRequestEvent, showHiddenEvents: false },
client,
);
if (!tile) throw new Error("Expected a key verification request tile");
expect(() => render(tile)).toThrow("Attempting to render verification request without a client context!");
});
});