From 5a64f243dd4ac513f8ef4ce4669cdf1ce54d83d4 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Thu, 23 Apr 2026 17:49:56 +0100 Subject: [PATCH] cleanup --- .../src/components/structures/ThreadView.tsx | 5 +- .../components/structures/RoomView-test.tsx | 30 ++++++- .../components/structures/ThreadView-test.tsx | 87 +++++++++++++++++++ 3 files changed, 117 insertions(+), 5 deletions(-) diff --git a/apps/web/src/components/structures/ThreadView.tsx b/apps/web/src/components/structures/ThreadView.tsx index 38860d5231..18179e417f 100644 --- a/apps/web/src/components/structures/ThreadView.tsx +++ b/apps/web/src/components/structures/ThreadView.tsx @@ -168,14 +168,13 @@ export default class ThreadView extends React.Component { switch (payload.action) { case Action.ComposerInsert: { const insertPayload = payload as ComposerInsertPayload; - const timelineRenderingType = insertPayload.timelineRenderingType; if (insertPayload.composerType) break; - if (timelineRenderingType !== TimelineRenderingType.Thread) break; + if (insertPayload.timelineRenderingType !== TimelineRenderingType.Thread) break; // re-dispatch to the correct composer dis.dispatch({ ...insertPayload, - timelineRenderingType, + timelineRenderingType: TimelineRenderingType.Thread, composerType: this.state.editState ? ComposerType.Edit : ComposerType.Send, }); break; diff --git a/apps/web/test/unit-tests/components/structures/RoomView-test.tsx b/apps/web/test/unit-tests/components/structures/RoomView-test.tsx index b25ce0c3e8..c9092d7aa1 100644 --- a/apps/web/test/unit-tests/components/structures/RoomView-test.tsx +++ b/apps/web/test/unit-tests/components/structures/RoomView-test.tsx @@ -1078,7 +1078,6 @@ describe("RoomView", () => { describe("handles Action.ComposerInsert", () => { it("redispatches an empty composerType, timelineRenderingType with the current state", async () => { - jest.spyOn(defaultDispatcher, "dispatch"); await mountRoomView(); const promise = untilDispatch((payload) => { try { @@ -1100,7 +1099,6 @@ describe("RoomView", () => { await promise; }); it("redispatches an empty composerType with the current state", async () => { - jest.spyOn(defaultDispatcher, "dispatch"); await mountRoomView(); const promise = untilDispatch((payload) => { try { @@ -1122,6 +1120,34 @@ describe("RoomView", () => { } satisfies ComposerInsertPayload); await promise; }); + it("ignores payloads with a timelineRenderingType != TimelineRenderingType.Thread", async () => { + await mountRoomView(); + const promise = untilDispatch( + (payload) => { + try { + expect(payload).toStrictEqual({ + action: Action.ComposerInsert, + text: "Hello world", + timelineRenderingType: TimelineRenderingType.Thread, + composerType: ComposerType.Send, + }); + } catch { + return false; + } + return true; + }, + defaultDispatcher, + 500, + ); + defaultDispatcher.dispatch({ + action: Action.ComposerInsert, + text: "Hello world", + composerType: ComposerType.Send, + timelineRenderingType: TimelineRenderingType.Room, + viaTest: true, + } satisfies ComposerInsertPayload); + await expect(promise).rejects.toThrow(); + }); }); describe("when there is a RoomView", () => { diff --git a/apps/web/test/unit-tests/components/structures/ThreadView-test.tsx b/apps/web/test/unit-tests/components/structures/ThreadView-test.tsx index 365e72b3db..4cd0629e14 100644 --- a/apps/web/test/unit-tests/components/structures/ThreadView-test.tsx +++ b/apps/web/test/unit-tests/components/structures/ThreadView-test.tsx @@ -34,6 +34,10 @@ import { getRoomContext } from "../../../test-utils/room"; import { mkMessage, stubClient } from "../../../test-utils/test-utils"; import { mkThread } from "../../../test-utils/threads"; import { ScopedRoomContextProvider } from "../../../../src/contexts/ScopedRoomContext.tsx"; +import defaultDispatcher from "../../../../src/dispatcher/dispatcher"; +import { untilDispatch } from "../../../test-utils/utilities.ts"; +import { TimelineRenderingType } from "../../../../src/contexts/RoomContext.ts"; +import { ComposerInsertPayload, ComposerType } from "../../../../src/dispatcher/payloads/ComposerInsertPayload.ts"; describe("ThreadView", () => { const ROOM_ID = "!roomId:example.org"; @@ -209,4 +213,87 @@ describe("ThreadView", () => { metricsTrigger: undefined, }); }); + + describe("handles Action.ComposerInsert", () => { + it("redispatches a payload of timelineRenderingType=Thread", async () => { + await getComponent(); + const promise = untilDispatch((payload) => { + try { + expect(payload).toEqual({ + action: Action.ComposerInsert, + text: "Hello world", + timelineRenderingType: TimelineRenderingType.Thread, + composerType: ComposerType.Send, + }); + } catch { + return false; + } + return true; + }, defaultDispatcher); + defaultDispatcher.dispatch({ + action: Action.ComposerInsert, + text: "Hello world", + timelineRenderingType: TimelineRenderingType.Thread, + } satisfies ComposerInsertPayload); + await promise; + }); + it("ignores payloads with a composerType", async () => { + await getComponent(); + const promise = untilDispatch( + (payload) => { + try { + expect(payload).toStrictEqual({ + action: Action.ComposerInsert, + text: "Hello world", + timelineRenderingType: TimelineRenderingType.Thread, + composerType: ComposerType.Send, + }); + } catch { + return false; + } + return true; + }, + defaultDispatcher, + 500, + ); + defaultDispatcher.dispatch({ + action: Action.ComposerInsert, + text: "Hello world", + composerType: ComposerType.Send, + timelineRenderingType: TimelineRenderingType.Thread, + // Ensure we don't accidentally pick up this emit by strictly checking above. + viaTest: true, + } satisfies ComposerInsertPayload); + await expect(promise).rejects.toThrow(); + }); + it("ignores payloads with a timelineRenderingType != TimelineRenderingType.Thread", async () => { + await getComponent(); + const promise = untilDispatch( + (payload) => { + try { + expect(payload).toStrictEqual({ + action: Action.ComposerInsert, + text: "Hello world", + timelineRenderingType: TimelineRenderingType.Thread, + composerType: ComposerType.Send, + }); + } catch { + return false; + } + return true; + }, + defaultDispatcher, + 500, + ); + defaultDispatcher.dispatch({ + action: Action.ComposerInsert, + text: "Hello world", + composerType: ComposerType.Send, + timelineRenderingType: TimelineRenderingType.Room, + // Ensure we don't accidentally pick up this emit by strictly checking above. + viaTest: true, + } satisfies ComposerInsertPayload); + await expect(promise).rejects.toThrow(); + }); + }); });