|
|
@@ -119,6 +119,36 @@ describe('list lifecycle', () => {
|
|
|
manager.handleHostEnvelope({ rpcId: 'readded' as never, payload: { type: 'host/session-added', sessionId: S1 } })
|
|
|
expect(manager.getListSnapshot().items.find(item => item.sessionId === S1)?.title).toBeUndefined()
|
|
|
})
|
|
|
+
|
|
|
+ it('drops a retained title beyond the subscription baseline before accepting its durable replay', async () => {
|
|
|
+ const api = new FakeApiClient()
|
|
|
+ api.onList = () => Promise.resolve(ok({ items: [summary(S1)] as never[] }))
|
|
|
+ const manager = new SessionManager(api)
|
|
|
+ await manager.refreshList()
|
|
|
+ manager.handleMuxEnvelope({
|
|
|
+ rpcId: 'title-unflushed' as never,
|
|
|
+ payload: { type: 'session/title', sessionId: S1, title: 'Unflushed', eventSeq: 4, updatedAt: 400 },
|
|
|
+ })
|
|
|
+
|
|
|
+ manager.handleMuxEnvelope({
|
|
|
+ rpcId: 'subscribed-recovered' as never,
|
|
|
+ payload: { type: 'session/subscribed', sessionId: S1, lastSeq: 2 },
|
|
|
+ })
|
|
|
+ expect(manager.getListSnapshot().items[0]?.title).toBeUndefined()
|
|
|
+ expect(manager.getListSnapshot().items[0]?.updatedAt).toBe(100)
|
|
|
+
|
|
|
+ manager.handleMuxEnvelope({
|
|
|
+ rpcId: 'title-durable' as never,
|
|
|
+ payload: { type: 'session/title', sessionId: S1, title: 'Durable', eventSeq: 2, updatedAt: 200 },
|
|
|
+ })
|
|
|
+ expect(manager.getListSnapshot().items[0]).toMatchObject({ title: 'Durable', updatedAt: 200 })
|
|
|
+
|
|
|
+ manager.handleMuxEnvelope({
|
|
|
+ rpcId: 'subscribed-current' as never,
|
|
|
+ payload: { type: 'session/subscribed', sessionId: S1, lastSeq: 2 },
|
|
|
+ })
|
|
|
+ expect(manager.getListSnapshot().items[0]).toMatchObject({ title: 'Durable', updatedAt: 200 })
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
describe('host frame routing', () => {
|