diff --git a/mobile/src/session/mobile-native-chat-stream-frame.test.ts b/mobile/src/session/mobile-native-chat-stream-frame.test.ts index ef94c83a7f1..4fa0b924b43 100644 --- a/mobile/src/session/mobile-native-chat-stream-frame.test.ts +++ b/mobile/src/session/mobile-native-chat-stream-frame.test.ts @@ -103,6 +103,27 @@ describe('applyMobileNativeChatStreamFrame', () => { }) }) + it('ignores replay paging metadata that describes a row other than our oldest', () => { + const merger = createNativeChatMerger() + replaceList(merger, ['p1', 'p2', 'a', 'b'].map(message)) + + // `beforeOffset` here points before 'a', not before 'p1'. Adopting it would + // make the next loadEarlier re-fetch 'p1'/'p2' and prepend them twice. + expect( + applyMobileNativeChatStreamFrame({ + merger, + frame: { + type: 'snapshot', + messages: [message('a'), message('b')], + hasMore: true, + beforeOffset: 500 + }, + limit: 100, + replaceSnapshot: false + }) + ).toEqual({ kind: 'messages', messages: ['p1', 'p2', 'a', 'b'].map(message) }) + }) + it('replaces the window when a reconnect replay is disjoint from history', () => { const merger = createNativeChatMerger() replaceList(merger, [message('old-1'), message('old-2')]) @@ -249,6 +270,33 @@ describe('applyMobileNativeChatStreamFrame', () => { }) }) + it('still treats the base snapshot as authoritative after a replacement frame', () => { + const merger = createNativeChatMerger() + replaceList(merger, ['a', 'b'].map(message)) + + // A replacement is not this subscription's base snapshot, so the first real + // snapshot still replaces — merging would keep 'a', which it does not carry. + expect( + applyMobileNativeChatStreamFrame({ + merger, + frame: { + type: 'snapshot', + messages: [message('b'), message('c')], + hasMore: true, + beforeOffset: 77 + }, + limit: 100, + replaceSnapshot: true + }) + ).toEqual({ + kind: 'messages', + messages: [message('b'), message('c')], + hasMore: true, + beforeOffset: 77, + windowReplaced: true + }) + }) + it('surfaces snapshot errors and ignores unrelated frames', () => { const merger = createNativeChatMerger() expect(