Skip to content

Commit

Permalink
Fix threads ending up with chunks of their timelines missing (#3618)
Browse files Browse the repository at this point in the history
* Fix threads ending up with chunks of their timelines missing

* delint
  • Loading branch information
t3chguy authored Jul 25, 2023
1 parent de7959d commit 8a80886
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 15 deletions.
19 changes: 19 additions & 0 deletions spec/integ/matrix-client-event-timeline.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2026,6 +2026,25 @@ describe("MatrixClient event timelines", function () {
.respond(200, function () {
return THREAD_ROOT;
});
httpBackend
.when("GET", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!))
.respond(200, function () {
return THREAD_ROOT;
});
httpBackend
.when(
"GET",
"/_matrix/client/v1/rooms/!foo%3Abar/relations/" +
encodeURIComponent(THREAD_ROOT.event_id!) +
"/" +
encodeURIComponent(THREAD_RELATION_TYPE.name) +
buildRelationPaginationQuery({ dir: Direction.Backward, limit: 1 }),
)
.respond(200, function () {
return {
chunk: [THREAD_REPLY],
};
});
await Promise.all([httpBackend.flushAllExpected(), utils.syncPromise(client)]);

const room = client.getRoom(roomId)!;
Expand Down
6 changes: 5 additions & 1 deletion spec/unit/models/thread.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,11 @@ async function createThread(client: MatrixClient, user: string, roomId: string):
root.setThreadId(root.getId());
await room.addLiveEvents([root]);

return room.createThread(root.getId()!, root, [], false);
// Create the thread and wait for it to be initialised
const thread = room.createThread(root.getId()!, root, [], false);
await new Promise<void>((res) => thread.once(RoomEvent.TimelineReset, () => res()));

return thread;
}

/**
Expand Down
19 changes: 10 additions & 9 deletions spec/unit/room.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2556,7 +2556,7 @@ describe("Room", function () {
next_batch: "start_token",
});

let prom = emitPromise(room, ThreadEvent.New);
const prom = emitPromise(room, ThreadEvent.New);
await room.addLiveEvents([randomMessage, threadRoot, threadResponse]);
const thread: Thread = await prom;
await emitPromise(room, ThreadEvent.Update);
Expand All @@ -2583,9 +2583,11 @@ describe("Room", function () {
},
});

prom = emitPromise(room, ThreadEvent.Update);
await room.addLiveEvents([threadResponseEdit]);
await prom;
// XXX: If we add the relation to the thread response before the thread finishes fetching via /relations
// then the test will fail
await emitPromise(room, ThreadEvent.Update);
await emitPromise(room, ThreadEvent.Update);
await Promise.all([emitPromise(room, ThreadEvent.Update), room.addLiveEvents([threadResponseEdit])]);
expect(thread.replyToEvent!.getContent().body).toBe(threadResponseEdit.getContent()["m.new_content"].body);
});

Expand Down Expand Up @@ -2765,7 +2767,7 @@ describe("Room", function () {
"m.relations": {
"m.thread": {
latest_event: threadResponse2.event,
count: 2,
count: 1,
current_user_participated: true,
},
},
Expand All @@ -2787,10 +2789,10 @@ describe("Room", function () {
let prom = emitPromise(room, ThreadEvent.New);
await room.addLiveEvents([threadRoot, threadResponse1]);
const thread: Thread = await prom;
await emitPromise(room, ThreadEvent.Update);

expect(thread.initialEventsFetched).toBeTruthy();
await room.addLiveEvents([threadResponse2]);
await emitPromise(room, ThreadEvent.Update);
expect(thread).toHaveLength(2);
expect(thread.replyToEvent!.getId()).toBe(threadResponse2.getId());

Expand All @@ -2809,11 +2811,10 @@ describe("Room", function () {
},
});

prom = emitPromise(room, ThreadEvent.Update);
await emitPromise(room, ThreadEvent.Update);
const threadResponse2Redaction = mkRedaction(threadResponse2);
await room.addLiveEvents([threadResponse2Redaction]);
await prom;
await emitPromise(room, ThreadEvent.Update);
await room.addLiveEvents([threadResponse2Redaction]);
expect(thread).toHaveLength(1);
expect(thread.replyToEvent!.getId()).toBe(threadResponse1.getId());

Expand Down
5 changes: 0 additions & 5 deletions src/models/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,11 +326,6 @@ export class Thread extends ReadReceipt<ThreadEmittedEvents, ThreadEventHandlerM
public async addEvent(event: MatrixEvent, toStartOfTimeline: boolean, emit = true): Promise<void> {
this.setEventMetadata(event);

if (!this.initialEventsFetched && !toStartOfTimeline && event.getId() === this.id) {
// We're loading the thread organically
this.initialEventsFetched = true;
}

const lastReply = this.lastReply();
const isNewestReply = !lastReply || event.localTimestamp >= lastReply!.localTimestamp;

Expand Down

0 comments on commit 8a80886

Please sign in to comment.