From 5d6aa76b13c1edd7dcbe424b2d23a5778b718144 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Mon, 30 Jan 2023 16:23:14 +0000 Subject: [PATCH] Support MSC3946 in RoomCreate tile --- src/components/views/messages/RoomCreate.tsx | 8 +- .../views/messages/RoomCreate-test.tsx | 80 +++++++++++++++++-- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/src/components/views/messages/RoomCreate.tsx b/src/components/views/messages/RoomCreate.tsx index ccad5ea11e20..ffeb10f3efef 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 c3fcf51c616c..3862cf7e38e6 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: "old_tombstone_id", + }, + 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,49 @@ 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", + ); + }); + + /* TODO: enable when findPredecessor looks for this attribute + 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/last_known_event_id", + ); + });*/ + }); });