/* Copyright 2024 New Vector Ltd. Copyright 2022 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 { IContent, MatrixEvent, MsgType, M_BEACON_INFO, LocationAssetType, M_ASSET, M_POLL_END, Room, } from "matrix-js-sdk/src/matrix"; import { getNestedReplyText, getParentEventId, shouldDisplayReply, stripHTMLReply, stripPlainReply, } from "../../src/utils/Reply"; import { makePollStartEvent, mkEvent, stubClient } from "../test-utils"; import { RoomPermalinkCreator } from "../../src/utils/permalinks/Permalinks"; function makeTestEvent(type: string, content: IContent): MatrixEvent { return mkEvent({ event: true, type: type, user: "@user1:server", room: "!room1:server", content, }); } const mockPermalinkGenerator = { forEvent(eventId: string): string { return "$$permalink$$"; }, } as RoomPermalinkCreator; // don't litter test console with logs jest.mock("matrix-js-sdk/src/logger"); describe("Reply", () => { describe("getParentEventId", () => { it("returns undefined if given a falsey value", async () => { expect(getParentEventId()).toBeUndefined(); }); it("returns undefined if given a redacted event", async () => { const event = mkEvent({ event: true, type: "m.room.message", user: "@user1:server", room: "!room1:server", content: {}, }); event.makeRedacted(event, new Room(event.getRoomId()!, stubClient(), event.getSender()!)); expect(getParentEventId(event)).toBeUndefined(); }); it("returns undefined if the given event is not a reply", async () => { const event = mkEvent({ event: true, type: "m.room.message", user: "@user1:server", room: "!room1:server", content: {}, }); expect(getParentEventId(event)).toBeUndefined(); }); it("returns id of the event being replied to", async () => { const event = mkEvent({ event: true, type: "m.room.message", user: "@user1:server", room: "!room1:server", content: { "m.relates_to": { "m.in_reply_to": { event_id: "$event1", }, }, }, }); expect(getParentEventId(event)).toBe("$event1"); }); }); describe("stripPlainReply", () => { it("Removes leading quotes until the first blank line", () => { expect( stripPlainReply( ` > This is part > of the quote But this is not `.trim(), ), ).toBe("But this is not"); }); }); describe("stripHTMLReply", () => { it("Removes from the input", () => { expect( stripHTMLReply(` This is part of the quote But this is not `).trim(), ).toBe("But this is not"); }); }); describe("getNestedReplyText", () => { it("Returns valid reply fallback text for m.text msgtypes", () => { const event = makeTestEvent(MsgType.Text, { body: "body", msgtype: "m.text", }); expect(getNestedReplyText(event, mockPermalinkGenerator)).toMatchSnapshot(); }); ( [ ["m.room.message", MsgType.Location, LocationAssetType.Pin], ["m.room.message", MsgType.Location, LocationAssetType.Self], [M_BEACON_INFO.name, undefined, LocationAssetType.Pin], [M_BEACON_INFO.name, undefined, LocationAssetType.Self], ] as const ).forEach(([type, msgType, assetType]) => { it(`should create the expected fallback text for ${assetType} ${type}/${msgType}`, () => { const event = makeTestEvent(type, { body: "body", msgtype: msgType, [M_ASSET.name]: { type: assetType }, }); expect(getNestedReplyText(event, mockPermalinkGenerator)).toMatchSnapshot(); }); }); it("should create the expected fallback text for poll end events", () => { const event = makeTestEvent(M_POLL_END.name, { body: "body", }); expect(getNestedReplyText(event, mockPermalinkGenerator)).toMatchSnapshot(); }); it("should create the expected fallback text for poll start events", () => { const event = makePollStartEvent("Will this test pass?", "@user:server.org"); expect(getNestedReplyText(event, mockPermalinkGenerator)).toMatchSnapshot(); }); }); describe("shouldDisplayReply", () => { it("Returns false for redacted events", () => { const event = mkEvent({ event: true, type: "m.room.message", user: "@user1:server", room: "!room1:server", content: {}, }); event.makeRedacted(event, new Room(event.getRoomId()!, stubClient(), event.getSender()!)); expect(shouldDisplayReply(event)).toBe(false); }); it("Returns false for non-reply events", () => { const event = mkEvent({ event: true, type: "m.room.message", user: "@user1:server", room: "!room1:server", content: {}, }); expect(shouldDisplayReply(event)).toBe(false); }); }); });