diff --git a/spec/unit/models/event.spec.ts b/spec/unit/models/event.spec.ts index 9e7720a14..5ff9d745d 100644 --- a/spec/unit/models/event.spec.ts +++ b/spec/unit/models/event.spec.ts @@ -111,6 +111,29 @@ describe("MatrixEvent", () => { expect(mainTimelineLiveEventIds(room)).toEqual([ev.getId()]); }); + it("should keep thread roots in both timelines when redacted", async () => { + // Given a thread exists + const mockClient = createMockClient(); + const room = new Room("!roomid:e.xyz", mockClient, "myname"); + const threadRoot = createEvent("$threadroot:server"); + const ev = createThreadedEvent("$event1:server", threadRoot.getId()!); + + await room.addLiveEvents([threadRoot, ev]); + await room.createThreadsTimelineSets(); + expect(threadRoot.threadRootId).toEqual(threadRoot.getId()); + expect(mainTimelineLiveEventIds(room)).toEqual([threadRoot.getId()]); + expect(threadLiveEventIds(room, 0)).toEqual([threadRoot.getId(), ev.getId()]); + + // When I redact the thread root + const redaction = createRedaction(ev.getId()!); + threadRoot.makeRedacted(redaction, room); + + // Then it remains in the main timeline and the thread + expect(threadRoot.threadRootId).toEqual(threadRoot.getId()); + expect(mainTimelineLiveEventIds(room)).toEqual([threadRoot.getId()]); + expect(threadLiveEventIds(room, 0)).toEqual([threadRoot.getId(), ev.getId()]); + }); + it("should move into the main timeline when redacted", async () => { // Given an event in a thread const mockClient = createMockClient(); diff --git a/src/models/event.ts b/src/models/event.ts index c76da4a45..d37c98b4a 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -1208,8 +1208,9 @@ export class MatrixEvent extends TypedEventEmitter