diff --git a/spec/unit/sync-accumulator.spec.js b/spec/unit/sync-accumulator.spec.js index f52bc847a..1a857fe65 100644 --- a/spec/unit/sync-accumulator.spec.js +++ b/spec/unit/sync-accumulator.spec.js @@ -141,6 +141,41 @@ describe("SyncAccumulator", function() { expect(output.timeline.prev_batch).toEqual("pinned_to_8"); }); + it("should remove the stored timeline on limited syncs", () => { + sa.accumulate(syncSkeleton({ + state: { events: [member("alice", "join")] }, + timeline: { + events: [ + msg("alice", "1"), + msg("alice", "2"), + msg("alice", "3"), + ], + prev_batch: "pinned_to_1", + }, + })); + // some time passes and now we get a limited sync + sa.accumulate(syncSkeleton({ + state: { events: [] }, + timeline: { + limited: true, + events: [ + msg("alice", "51"), + msg("alice", "52"), + msg("alice", "53"), + ], + prev_batch: "pinned_to_51", + }, + })); + + const output = sa.getJSON().roomsData.join["!foo:bar"]; + + expect(output.timeline.events.length).toEqual(3); + output.timeline.events.forEach((e, i) => { + expect(e.content.body).toEqual(""+(i+51)); + }); + expect(output.timeline.prev_batch).toEqual("pinned_to_51"); + }); + it("should drop typing notifications", () => { const res = syncSkeleton({ ephemeral: { diff --git a/src/sync-accumulator.js b/src/sync-accumulator.js index 3b65cfe09..e32e277c2 100644 --- a/src/sync-accumulator.js +++ b/src/sync-accumulator.js @@ -290,6 +290,12 @@ class SyncAccumulator { }); } + // if we got a limited sync, we need to remove all timeline entries or else + // we will have gaps in the timeline. + if (data.timeline && data.timeline.limited) { + currentData._timeline = []; + } + // Work out the current state. The deltas need to be applied in the order: // - existing state which didn't come down /sync. // - State events under the 'state' key.