Skip to content

Commit

Permalink
Fix messages loaded during initial fetch ending up out of order (#2971)
Browse files Browse the repository at this point in the history
* Fix messages loaded during initial fetch ending up out of order
  • Loading branch information
justjanne authored Dec 13, 2022
1 parent acd220b commit 193c385
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 8 deletions.
68 changes: 66 additions & 2 deletions spec/integ/matrix-client-event-timeline.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,7 @@ describe("MatrixClient event timelines", function () {
},
event: true,
});
THREAD_REPLY2.localTimestamp += 1000;

// Test data for the first thread, with the second reply
const THREAD_ROOT_UPDATED = {
Expand Down Expand Up @@ -1305,6 +1306,7 @@ describe("MatrixClient event timelines", function () {

// Test adding a second event to the first thread
const thread = room.getThread(THREAD_ROOT.event_id!)!;
thread.initialEventsFetched = true;
const prom = emitPromise(room, ThreadEvent.NewReply);
respondToEvent(THREAD_ROOT_UPDATED);
respondToEvent(THREAD_ROOT_UPDATED);
Expand Down Expand Up @@ -1624,10 +1626,35 @@ describe("MatrixClient event timelines", function () {
},
},
});
httpBackend
.when("GET", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!))
.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)!;
const thread = room.getThread(THREAD_ROOT.event_id!)!;
expect(thread.initialEventsFetched).toBeTruthy();
const timelineSet = thread.timelineSet;

httpBackend
Expand All @@ -1645,20 +1672,57 @@ 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", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!))
.respond(200, function () {
return THREAD_ROOT;
});
httpBackend
.when("GET", "/rooms/!foo%3Abar/context/" + encodeURIComponent(THREAD_ROOT.event_id!))
.respond(200, function () {
return {
start: "start_token",
events_before: [],
event: THREAD_ROOT,
events_after: [],
end: "end_token",
state: [],
};
});
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 }),
buildRelationPaginationQuery({ dir: Direction.Backward, from: "start_token" }),
)
.respond(200, function () {
return {
chunk: [THREAD_ROOT],
chunk: [],
};
});
httpBackend
.when(
"GET",
"/_matrix/client/v1/rooms/!foo%3Abar/relations/" +
encodeURIComponent(THREAD_ROOT.event_id!) +
"/" +
encodeURIComponent(THREAD_RELATION_TYPE.name) +
buildRelationPaginationQuery({ dir: Direction.Forward, from: "end_token" }),
)
.respond(200, function () {
return {
chunk: [THREAD_REPLY],
};
});

const timeline = await flushHttp(client.getEventTimeline(timelineSet, THREAD_ROOT.event_id!));

httpBackend.when("GET", "/sync").respond(200, {
Expand Down
39 changes: 34 additions & 5 deletions spec/unit/room.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import {
EventTimelineSet,
EventType,
IContent,
IEvent,
IRelationsRequestOpts,
IStateEventWithRoomId,
JoinRule,
MatrixEvent,
Expand Down Expand Up @@ -2489,11 +2491,24 @@ describe("Room", function () {
},
});

room.client.fetchRelations = (
roomId: string,
eventId: string,
relationType?: RelationType | string | null,
eventType?: EventType | string | null,
opts: IRelationsRequestOpts = { dir: Direction.Backward },
) =>
Promise.resolve({
chunk: [threadResponse.event] as IEvent[],
next_batch: "start_token",
});

let prom = emitPromise(room, ThreadEvent.New);
room.addLiveEvents([randomMessage, threadRoot, threadResponse]);
const thread: Thread = await prom;
await emitPromise(room, ThreadEvent.Update);

expect(thread.initialEventsFetched).toBeTruthy();
expect(thread.replyToEvent!.event).toEqual(threadResponse.event);
expect(thread.replyToEvent!.getContent().body).toBe(threadResponse.getContent().body);

Expand Down Expand Up @@ -2704,13 +2719,27 @@ describe("Room", function () {
},
});

room.client.fetchRelations = (
roomId: string,
eventId: string,
relationType?: RelationType | string | null,
eventType?: EventType | string | null,
opts: IRelationsRequestOpts = { dir: Direction.Backward },
) =>
Promise.resolve({
chunk: [threadResponse1.event] as IEvent[],
next_batch: "start_token",
});

let prom = emitPromise(room, ThreadEvent.New);
room.addLiveEvents([threadRoot, threadResponse1, threadResponse2]);
const thread = await prom;
room.addLiveEvents([threadRoot, threadResponse1]);
const thread: Thread = await prom;
await emitPromise(room, ThreadEvent.Update);

expect(thread.initialEventsFetched).toBeTruthy();
room.addLiveEvents([threadResponse2]);
expect(thread).toHaveLength(2);
expect(thread.replyToEvent.getId()).toBe(threadResponse2.getId());
expect(thread.replyToEvent!.getId()).toBe(threadResponse2.getId());

room.client.fetchRoomEvent = (eventId: string) =>
Promise.resolve({
Expand All @@ -2733,7 +2762,7 @@ describe("Room", function () {
await prom;
await emitPromise(room, ThreadEvent.Update);
expect(thread).toHaveLength(1);
expect(thread.replyToEvent.getId()).toBe(threadResponse1.getId());
expect(thread.replyToEvent!.getId()).toBe(threadResponse1.getId());

room.client.fetchRoomEvent = (eventId: string) =>
Promise.resolve({
Expand All @@ -2757,7 +2786,7 @@ describe("Room", function () {
await prom;
await prom2;
expect(thread).toHaveLength(0);
expect(thread.replyToEvent.getId()).toBe(threadRoot.getId());
expect(thread.replyToEvent!.getId()).toBe(threadRoot.getId());
});
});

Expand Down
2 changes: 1 addition & 1 deletion src/models/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
this.addEventToTimeline(event, toStartOfTimeline);

this.client.decryptEventIfNeeded(event, {});
} else if (!toStartOfTimeline && isNewestReply) {
} else if (!toStartOfTimeline && this.initialEventsFetched && isNewestReply) {
this.addEventToTimeline(event, false);
this.fetchEditsWhereNeeded(event);
} else if (event.isRelation(RelationType.Annotation) || event.isRelation(RelationType.Replace)) {
Expand Down

0 comments on commit 193c385

Please sign in to comment.