From 4a8a6168cd2357868c87e3a728b795aa38c6dd45 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 2 Jun 2021 18:41:03 +0200 Subject: [PATCH] add failing test for race between sync & subscribing after openTimeline --- src/matrix/room/timeline/Timeline.js | 49 ++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/matrix/room/timeline/Timeline.js b/src/matrix/room/timeline/Timeline.js index d6895312..dfb75aca 100644 --- a/src/matrix/room/timeline/Timeline.js +++ b/src/matrix/room/timeline/Timeline.js @@ -232,3 +232,52 @@ export class Timeline { return this._ownMember; } } + +import {FragmentIdComparer} from "./FragmentIdComparer.js"; +import {Clock as MockClock} from "../../../mocks/Clock.js"; +import {createMockStorage} from "../../../mocks/Storage.js"; +import {createEvent, withTextBody, withSender} from "../../../mocks/event.js"; +import {NullLogItem} from "../../../logging/NullLogger.js"; +import {EventEntry} from "./entries/EventEntry.js"; +import {User} from "../../User.js"; +import {PendingEvent} from "../sending/PendingEvent.js"; + +export function tests() { + const fragmentIdComparer = new FragmentIdComparer([]); + const roomId = "$abc"; + return { + "adding or replacing entries before subscribing to entries does not loose local relations": async assert => { + const pendingEvents = new ObservableArray(); + const timeline = new Timeline({ + roomId, + storage: await createMockStorage(), + closeCallback: () => {}, + fragmentIdComparer, + pendingEvents, + clock: new MockClock(), + }); + // 1. load timeline + await timeline.load(new User("@alice:hs.tld"), "join", new NullLogItem()); + // 2. test replaceEntries and addOrReplaceEntries don't fail + const event1 = withTextBody("hi!", withSender("@bob:hs.tld", createEvent("m.room.message", "!abc"))); + const entry1 = new EventEntry({event: event1, fragmentId: 1, eventIndex: 1}, fragmentIdComparer); + timeline.replaceEntries([entry1]); + const event2 = withTextBody("hi bob!", withSender("@alice:hs.tld", createEvent("m.room.message", "!def"))); + const entry2 = new EventEntry({event: event2, fragmentId: 1, eventIndex: 2}, fragmentIdComparer); + timeline.addOrReplaceEntries([entry2]); + // 3. add local relation (redaction) + pendingEvents.append(new PendingEvent({data: { + roomId, + queueIndex: 1, + eventType: "m.room.redaction", + txnId: "t123", + content: {}, + relatedEventId: event2.event_id + }})); + // 4. subscribe (it's now safe to iterate timeline.entries) + timeline.entries.subscribe({}); + // 5. check the local relation got correctly aggregated + assert.equal(Array.from(timeline.entries)[0].isRedacting, true); + } + } +} \ No newline at end of file