Factor out `MessageEvent.from()` usage (#9882)

* Factor out `MessageEvent.from()` usage

The class/function is disappearing from the events-sdk, at least in this form.

* Manually create contents for events used by cypress

The utility function is out of range of the calling code at runtime, for some reason.

* Run prettier

* Maybe this will fix the build
pull/28217/head
Travis Ralston 2023-01-10 09:20:10 -07:00 committed by GitHub
parent 34f0229d75
commit c09ca7b4ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 127 additions and 61 deletions

View File

@ -16,15 +16,17 @@ limitations under the License.
/// <reference types="cypress" />
import { MessageEvent } from "matrix-events-sdk";
import type { MsgType } from "matrix-js-sdk/src/@types/event";
import type { ISendEventResponse } from "matrix-js-sdk/src/@types/requests";
import type { EventType } from "matrix-js-sdk/src/@types/event";
import { SynapseInstance } from "../../plugins/synapsedocker";
import Chainable = Cypress.Chainable;
const sendEvent = (roomId: string): Chainable<ISendEventResponse> => {
return cy.sendEvent(roomId, null, "m.room.message" as EventType, MessageEvent.from("Message").serialize().content);
return cy.sendEvent(roomId, null, "m.room.message" as EventType, {
msgtype: "m.text" as MsgType,
body: "Message",
});
};
describe("Editing", () => {

View File

@ -16,10 +16,8 @@ limitations under the License.
/// <reference types="cypress" />
import { MessageEvent } from "matrix-events-sdk";
import type { ISendEventResponse } from "matrix-js-sdk/src/@types/requests";
import type { EventType } from "matrix-js-sdk/src/@types/event";
import type { EventType, MsgType } from "matrix-js-sdk/src/@types/event";
import { SynapseInstance } from "../../plugins/synapsedocker";
import { SettingLevel } from "../../../src/settings/SettingLevel";
import { Layout } from "../../../src/settings/enums/Layout";
@ -55,12 +53,17 @@ const expectAvatar = (e: JQuery<HTMLElement>, avatarUrl: string): void => {
};
const sendEvent = (roomId: string, html = false): Chainable<ISendEventResponse> => {
return cy.sendEvent(
roomId,
null,
"m.room.message" as EventType,
MessageEvent.from("Message", html ? "<b>Message</b>" : undefined).serialize().content,
);
const content = {
msgtype: "m.text" as MsgType,
body: "Message",
format: undefined,
formatted_body: undefined,
};
if (html) {
content.format = "org.matrix.custom.html";
content.formatted_body = "<b>Message</b>";
}
return cy.sendEvent(roomId, null, "m.room.message" as EventType, content);
};
describe("Timeline", () => {
@ -314,12 +317,10 @@ describe("Timeline", () => {
},
}).as("preview_url");
cy.sendEvent(
roomId,
null,
"m.room.message" as EventType,
MessageEvent.from("https://call.element.io/").serialize().content,
);
cy.sendEvent(roomId, null, "m.room.message" as EventType, {
msgtype: "m.text" as MsgType,
body: "https://call.element.io/",
});
cy.visit("/#/room/" + roomId);
cy.get(".mx_LinkPreviewWidget").should("exist").should("contain.text", "Element Call");

View File

@ -17,7 +17,6 @@ limitations under the License.
import { render, RenderResult, waitFor, screen } from "@testing-library/react";
// eslint-disable-next-line deprecate/import
import { mount, ReactWrapper } from "enzyme";
import { MessageEvent } from "matrix-events-sdk";
import { ReceiptType } from "matrix-js-sdk/src/@types/read_receipts";
import {
EventTimelineSet,
@ -48,6 +47,7 @@ import SettingsStore from "../../../src/settings/SettingsStore";
import { isCallEvent } from "../../../src/components/structures/LegacyCallEventGrouper";
import { flushPromises, mkMembership, mkRoom, stubClient } from "../../test-utils";
import { mkThread } from "../../test-utils/threads";
import { createMessageEventContent } from "../../test-utils/events";
const newReceipt = (eventId: string, userId: string, readTs: number, fullyReadTs: number): MatrixEvent => {
const receiptContent = {
@ -89,8 +89,8 @@ const mockEvents = (room: Room, count = 2): MatrixEvent[] => {
room_id: room.roomId,
event_id: `${room.roomId}_event_${index}`,
type: EventType.RoomMessage,
user_id: "userId",
content: MessageEvent.from(`Event${index}`).serialize().content,
sender: "userId",
content: createMessageEventContent("`Event${index}`"),
}),
);
}
@ -125,13 +125,15 @@ describe("TimelinePanel", () => {
event_id: "ev0",
sender: "@u2:m.org",
origin_server_ts: 111,
...MessageEvent.from("hello 1").serialize(),
type: EventType.RoomMessage,
content: createMessageEventContent("hello 1"),
});
const ev1 = new MatrixEvent({
event_id: "ev1",
sender: "@u2:m.org",
origin_server_ts: 222,
...MessageEvent.from("hello 2").serialize(),
type: EventType.RoomMessage,
content: createMessageEventContent("hello 2"),
});
const roomId = "#room:example.com";
@ -385,24 +387,24 @@ describe("TimelinePanel", () => {
room_id: room.roomId,
event_id: "event_reply_1",
type: EventType.RoomMessage,
user_id: "userId",
content: MessageEvent.from(`ReplyEvent1`).serialize().content,
sender: "userId",
content: createMessageEventContent("ReplyEvent1"),
});
reply2 = new MatrixEvent({
room_id: room.roomId,
event_id: "event_reply_2",
type: EventType.RoomMessage,
user_id: "userId",
content: MessageEvent.from(`ReplyEvent2`).serialize().content,
sender: "userId",
content: createMessageEventContent("ReplyEvent2"),
});
root = new MatrixEvent({
room_id: room.roomId,
event_id: "event_root_1",
type: EventType.RoomMessage,
user_id: "userId",
content: MessageEvent.from(`RootEvent`).serialize().content,
sender: "userId",
content: createMessageEventContent("RootEvent"),
});
const eventMap: { [key: string]: MatrixEvent } = {

View File

@ -26,7 +26,7 @@ import {
getBeaconInfoIdentifier,
EventType,
} from "matrix-js-sdk/src/matrix";
import { ExtensibleEvent, MessageEvent, M_POLL_KIND_DISCLOSED, PollStartEvent } from "matrix-events-sdk";
import { M_POLL_KIND_DISCLOSED, PollStartEvent } from "matrix-events-sdk";
import { FeatureSupport, Thread } from "matrix-js-sdk/src/models/thread";
import { mocked } from "jest-mock";
import { act } from "@testing-library/react";
@ -44,6 +44,7 @@ import { ReadPinsEventId } from "../../../../src/components/views/right_panel/ty
import { Action } from "../../../../src/dispatcher/actions";
import { mkVoiceBroadcastInfoStateEvent } from "../../../voice-broadcast/utils/test-utils";
import { VoiceBroadcastInfoState } from "../../../../src/voice-broadcast";
import { createMessageEventContent } from "../../../test-utils/events";
jest.mock("../../../../src/utils/strings", () => ({
copyPlaintext: jest.fn(),
@ -64,7 +65,7 @@ describe("MessageContextMenu", () => {
});
it("does show copy link button when supplied a link", () => {
const eventContent = MessageEvent.from("hello");
const eventContent = createMessageEventContent("hello");
const props = {
link: "https://google.com/",
};
@ -75,7 +76,7 @@ describe("MessageContextMenu", () => {
});
it("does not show copy link button when not supplied a link", () => {
const eventContent = MessageEvent.from("hello");
const eventContent = createMessageEventContent("hello");
const menu = createMenuWithContent(eventContent);
const copyLinkButton = menu.find('a[aria-label="Copy link"]');
expect(copyLinkButton).toHaveLength(0);
@ -91,8 +92,8 @@ describe("MessageContextMenu", () => {
});
it("does not show pin option when user does not have rights to pin", () => {
const eventContent = MessageEvent.from("hello");
const event = new MatrixEvent(eventContent.serialize());
const eventContent = createMessageEventContent("hello");
const event = new MatrixEvent({ type: EventType.RoomMessage, content: eventContent });
const room = makeDefaultRoom();
// mock permission to disallow adding pinned messages to room
@ -116,8 +117,12 @@ describe("MessageContextMenu", () => {
});
it("does not show pin option when pinning feature is disabled", () => {
const eventContent = MessageEvent.from("hello");
const pinnableEvent = new MatrixEvent({ ...eventContent.serialize(), room_id: roomId });
const eventContent = createMessageEventContent("hello");
const pinnableEvent = new MatrixEvent({
type: EventType.RoomMessage,
content: eventContent,
room_id: roomId,
});
const room = makeDefaultRoom();
// mock permission to allow adding pinned messages to room
@ -131,8 +136,12 @@ describe("MessageContextMenu", () => {
});
it("shows pin option when pinning feature is enabled", () => {
const eventContent = MessageEvent.from("hello");
const pinnableEvent = new MatrixEvent({ ...eventContent.serialize(), room_id: roomId });
const eventContent = createMessageEventContent("hello");
const pinnableEvent = new MatrixEvent({
type: EventType.RoomMessage,
content: eventContent,
room_id: roomId,
});
const room = makeDefaultRoom();
// mock permission to allow adding pinned messages to room
@ -145,8 +154,12 @@ describe("MessageContextMenu", () => {
it("pins event on pin option click", () => {
const onFinished = jest.fn();
const eventContent = MessageEvent.from("hello");
const pinnableEvent = new MatrixEvent({ ...eventContent.serialize(), room_id: roomId });
const eventContent = createMessageEventContent("hello");
const pinnableEvent = new MatrixEvent({
type: EventType.RoomMessage,
content: eventContent,
room_id: roomId,
});
pinnableEvent.event.event_id = "!3";
const client = MatrixClientPeg.get();
const room = makeDefaultRoom();
@ -188,8 +201,12 @@ describe("MessageContextMenu", () => {
});
it("unpins event on pin option click when event is pinned", () => {
const eventContent = MessageEvent.from("hello");
const pinnableEvent = new MatrixEvent({ ...eventContent.serialize(), room_id: roomId });
const eventContent = createMessageEventContent("hello");
const pinnableEvent = new MatrixEvent({
type: EventType.RoomMessage,
content: eventContent,
room_id: roomId,
});
pinnableEvent.event.event_id = "!3";
const client = MatrixClientPeg.get();
const room = makeDefaultRoom();
@ -231,7 +248,7 @@ describe("MessageContextMenu", () => {
describe("message forwarding", () => {
it("allows forwarding a room message", () => {
const eventContent = MessageEvent.from("hello");
const eventContent = createMessageEventContent("hello");
const menu = createMenuWithContent(eventContent);
expect(menu.find('div[aria-label="Forward"]')).toHaveLength(1);
});
@ -335,7 +352,7 @@ describe("MessageContextMenu", () => {
describe("open as map link", () => {
it("does not allow opening a plain message in open street maps", () => {
const eventContent = MessageEvent.from("hello");
const eventContent = createMessageEventContent("hello");
const menu = createMenuWithContent(eventContent);
expect(menu.find('a[aria-label="Open in OpenStreetMap"]')).toHaveLength(0);
});
@ -380,7 +397,7 @@ describe("MessageContextMenu", () => {
describe("right click", () => {
it("copy button does work as expected", () => {
const text = "hello";
const eventContent = MessageEvent.from(text);
const eventContent = createMessageEventContent(text);
mocked(getSelectedText).mockReturnValue(text);
const menu = createRightClickMenuWithContent(eventContent);
@ -391,7 +408,7 @@ describe("MessageContextMenu", () => {
it("copy button is not shown when there is nothing to copy", () => {
const text = "hello";
const eventContent = MessageEvent.from(text);
const eventContent = createMessageEventContent(text);
mocked(getSelectedText).mockReturnValue("");
const menu = createRightClickMenuWithContent(eventContent);
@ -400,7 +417,7 @@ describe("MessageContextMenu", () => {
});
it("shows edit button when we can edit", () => {
const eventContent = MessageEvent.from("hello");
const eventContent = createMessageEventContent("hello");
mocked(canEditContent).mockReturnValue(true);
const menu = createRightClickMenuWithContent(eventContent);
@ -409,7 +426,7 @@ describe("MessageContextMenu", () => {
});
it("does not show edit button when we cannot edit", () => {
const eventContent = MessageEvent.from("hello");
const eventContent = createMessageEventContent("hello");
mocked(canEditContent).mockReturnValue(false);
const menu = createRightClickMenuWithContent(eventContent);
@ -418,7 +435,7 @@ describe("MessageContextMenu", () => {
});
it("shows reply button when we can reply", () => {
const eventContent = MessageEvent.from("hello");
const eventContent = createMessageEventContent("hello");
const context = {
canSendMessages: true,
};
@ -429,11 +446,11 @@ describe("MessageContextMenu", () => {
});
it("does not show reply button when we cannot reply", () => {
const eventContent = MessageEvent.from("hello");
const eventContent = createMessageEventContent("hello");
const context = {
canSendMessages: true,
};
const unsentMessage = new MatrixEvent(eventContent.serialize());
const unsentMessage = new MatrixEvent({ type: EventType.RoomMessage, content: eventContent });
// queued messages are not actionable
unsentMessage.setStatus(EventStatus.QUEUED);
@ -443,7 +460,7 @@ describe("MessageContextMenu", () => {
});
it("shows react button when we can react", () => {
const eventContent = MessageEvent.from("hello");
const eventContent = createMessageEventContent("hello");
const context = {
canReact: true,
};
@ -454,7 +471,7 @@ describe("MessageContextMenu", () => {
});
it("does not show react button when we cannot react", () => {
const eventContent = MessageEvent.from("hello");
const eventContent = createMessageEventContent("hello");
const context = {
canReact: false,
};
@ -465,8 +482,8 @@ describe("MessageContextMenu", () => {
});
it("shows view in room button when the event is a thread root", () => {
const eventContent = MessageEvent.from("hello");
const mxEvent = new MatrixEvent(eventContent.serialize());
const eventContent = createMessageEventContent("hello");
const mxEvent = new MatrixEvent({ type: EventType.RoomMessage, content: eventContent });
mxEvent.getThread = () => ({ rootEvent: mxEvent } as Thread);
const props = {
rightClick: true,
@ -481,7 +498,7 @@ describe("MessageContextMenu", () => {
});
it("does not show view in room button when the event is not a thread root", () => {
const eventContent = MessageEvent.from("hello");
const eventContent = createMessageEventContent("hello");
const menu = createRightClickMenuWithContent(eventContent);
const reactButton = menu.find('div[aria-label="View in room"]');
@ -489,8 +506,8 @@ describe("MessageContextMenu", () => {
});
it("creates a new thread on reply in thread click", () => {
const eventContent = MessageEvent.from("hello");
const mxEvent = new MatrixEvent(eventContent.serialize());
const eventContent = createMessageEventContent("hello");
const mxEvent = new MatrixEvent({ type: EventType.RoomMessage, content: eventContent });
Thread.hasServerSideSupport = FeatureSupport.Stable;
const context = {
@ -513,7 +530,7 @@ describe("MessageContextMenu", () => {
});
});
function createRightClickMenuWithContent(eventContent: ExtensibleEvent, context?: Partial<IRoomState>): ReactWrapper {
function createRightClickMenuWithContent(eventContent: object, context?: Partial<IRoomState>): ReactWrapper {
return createMenuWithContent(eventContent, { rightClick: true }, context);
}
@ -522,11 +539,13 @@ function createRightClickMenu(mxEvent: MatrixEvent, context?: Partial<IRoomState
}
function createMenuWithContent(
eventContent: ExtensibleEvent,
eventContent: object,
props?: Partial<React.ComponentProps<typeof MessageContextMenu>>,
context?: Partial<IRoomState>,
): ReactWrapper {
const mxEvent = new MatrixEvent(eventContent.serialize());
// XXX: We probably shouldn't be assuming all events are going to be message events, but considering this
// test is for the Message context menu, it's a fairly safe assumption.
const mxEvent = new MatrixEvent({ type: EventType.RoomMessage, content: eventContent });
return createMenu(mxEvent, props, context);
}

42
test/test-utils/events.ts Normal file
View File

@ -0,0 +1,42 @@
/*
Copyright 2023 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 { MsgType } from "matrix-js-sdk/src/@types/event";
interface MessageContent {
msgtype: MsgType;
body: string;
format?: string;
formatted_body?: string;
}
/**
* Creates the `content` for an `m.room.message` event based on input.
* @param text The text to put in the event.
* @param html Optional HTML to put in the event.
* @returns A complete `content` object for an `m.room.message` event.
*/
export function createMessageEventContent(text: string, html?: string): MessageContent {
const content: MessageContent = {
msgtype: MsgType.Text,
body: text,
};
if (html) {
content.format = "org.matrix.custom.html";
content.formatted_body = html;
}
return content;
}