From e43d44753574ea090beb177e7280e1f12eb771fe Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Thu, 2 Feb 2023 13:39:13 +0000 Subject: [PATCH] Support MSC3946 in RoomCreate tile (#10041) --- src/components/views/messages/RoomCreate.tsx | 8 +- .../views/messages/RoomCreate-test.tsx | 79 +++++++++++++++++-- 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/src/components/views/messages/RoomCreate.tsx b/src/components/views/messages/RoomCreate.tsx index ccad5ea11e..ffeb10f3ef 100644 --- a/src/components/views/messages/RoomCreate.tsx +++ b/src/components/views/messages/RoomCreate.tsx @@ -28,6 +28,7 @@ import EventTileBubble from "./EventTileBubble"; import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; import RoomContext from "../../../contexts/RoomContext"; import { useRoomState } from "../../../hooks/useRoomState"; +import SettingsStore from "../../../settings/SettingsStore"; interface IProps { /** The m.room.create MatrixEvent that this tile represents */ @@ -40,6 +41,8 @@ interface IProps { * room. */ export const RoomCreate: React.FC = ({ mxEvent, timestamp }) => { + const msc3946ProcessDynamicPredecessor = SettingsStore.getValue("feature_dynamic_room_predecessors"); + // Note: we ask the room for its predecessor here, instead of directly using // the information inside mxEvent. This allows us the flexibility later to // use a different predecessor (e.g. through MSC3946) and still display it @@ -47,7 +50,10 @@ export const RoomCreate: React.FC = ({ mxEvent, timestamp }) => { const roomContext = useContext(RoomContext); const predecessor = useRoomState( roomContext.room, - useCallback((state) => state.findPredecessor(), []), + useCallback( + (state) => state.findPredecessor(msc3946ProcessDynamicPredecessor), + [msc3946ProcessDynamicPredecessor], + ), ); const onLinkClicked = useCallback( diff --git a/test/components/views/messages/RoomCreate-test.tsx b/test/components/views/messages/RoomCreate-test.tsx index c3fcf51c61..cd5afa7ee2 100644 --- a/test/components/views/messages/RoomCreate-test.tsx +++ b/test/components/views/messages/RoomCreate-test.tsx @@ -52,10 +52,35 @@ describe("", () => { content: {}, event_id: "$create", }); + const predecessorEvent = new MatrixEvent({ + type: EventType.RoomPredecessor, + state_key: "", + sender: userId, + room_id: roomId, + content: { + predecessor_room_id: "old_room_id_from_predecessor", + }, + event_id: "$create", + }); + const predecessorEventWithEventId = new MatrixEvent({ + type: EventType.RoomPredecessor, + state_key: "", + sender: userId, + room_id: roomId, + content: { + predecessor_room_id: "old_room_id_from_predecessor", + last_known_event_id: "tombstone_event_id_from_predecessor", + }, + event_id: "$create", + }); stubClient(); const client = mocked(MatrixClientPeg.get()); - const room = new Room(roomId, client, userId); - upsertRoomStateEvents(room, [createEvent]); + const roomJustCreate = new Room(roomId, client, userId); + upsertRoomStateEvents(roomJustCreate, [createEvent]); + const roomCreateAndPredecessor = new Room(roomId, client, userId); + upsertRoomStateEvents(roomCreateAndPredecessor, [createEvent, predecessorEvent]); + const roomCreateAndPredecessorWithEventId = new Room(roomId, client, userId); + upsertRoomStateEvents(roomCreateAndPredecessorWithEventId, [createEvent, predecessorEventWithEventId]); const roomNoPredecessors = new Room(roomId, client, userId); upsertRoomStateEvents(roomNoPredecessors, [createEventWithoutPredecessor]); @@ -81,12 +106,12 @@ describe("", () => { } it("Renders as expected", () => { - const roomCreate = renderRoomCreate(room); + const roomCreate = renderRoomCreate(roomJustCreate); expect(roomCreate.asFragment()).toMatchSnapshot(); }); it("Links to the old version of the room", () => { - renderRoomCreate(room); + renderRoomCreate(roomJustCreate); expect(screen.getByText("Click here to see older messages.")).toHaveAttribute( "href", "https://matrix.to/#/old_room_id/tombstone_event_id", @@ -99,7 +124,7 @@ describe("", () => { }); it("Opens the old room on click", async () => { - renderRoomCreate(room); + renderRoomCreate(roomJustCreate); const link = screen.getByText("Click here to see older messages."); await act(() => userEvent.click(link)); @@ -115,4 +140,48 @@ describe("", () => { }), ); }); + + it("Ignores m.predecessor if labs flag is off", () => { + renderRoomCreate(roomCreateAndPredecessor); + expect(screen.getByText("Click here to see older messages.")).toHaveAttribute( + "href", + "https://matrix.to/#/old_room_id/tombstone_event_id", + ); + }); + + describe("When feature_dynamic_room_predecessors = true", () => { + beforeEach(() => { + jest.spyOn(SettingsStore, "getValue").mockImplementation( + (settingName) => settingName === "feature_dynamic_room_predecessors", + ); + }); + + afterEach(() => { + jest.spyOn(SettingsStore, "getValue").mockReset(); + }); + + it("Uses the create event if there is no m.predecessor", () => { + renderRoomCreate(roomJustCreate); + expect(screen.getByText("Click here to see older messages.")).toHaveAttribute( + "href", + "https://matrix.to/#/old_room_id/tombstone_event_id", + ); + }); + + it("Uses m.predecessor when it's there", () => { + renderRoomCreate(roomCreateAndPredecessor); + expect(screen.getByText("Click here to see older messages.")).toHaveAttribute( + "href", + "https://matrix.to/#/old_room_id_from_predecessor", + ); + }); + + it("Links to the event in the room if event ID is provided", () => { + renderRoomCreate(roomCreateAndPredecessorWithEventId); + expect(screen.getByText("Click here to see older messages.")).toHaveAttribute( + "href", + "https://matrix.to/#/old_room_id_from_predecessor/tombstone_event_id_from_predecessor", + ); + }); + }); });