fix(plan): reject legacy mode events on load
This commit is contained in:
@@ -125,6 +125,11 @@ function assertSupportedEvents(events: readonly SessionEvent[], id: SessionId):
|
|||||||
if (legacy !== undefined) {
|
if (legacy !== undefined) {
|
||||||
throw new Error(`session "${id}" contains unsupported legacy request/header-delta event at seq ${legacy.seq}`)
|
throw new Error(`session "${id}" contains unsupported legacy request/header-delta event at seq ${legacy.seq}`)
|
||||||
}
|
}
|
||||||
|
const legacyModeType: string = 'mode/set'
|
||||||
|
const legacyMode = events.find(event => event.type === legacyModeType)
|
||||||
|
if (legacyMode !== undefined) {
|
||||||
|
throw new Error(`session "${id}" contains unsupported legacy mode/set event at seq ${legacyMode.seq}`)
|
||||||
|
}
|
||||||
const fallback = events.find(event => event.type === 'request/header'
|
const fallback = events.find(event => event.type === 'request/header'
|
||||||
&& (event.data as { reason?: string }).reason === 'fallback')
|
&& (event.data as { reason?: string }).reason === 'fallback')
|
||||||
if (fallback !== undefined) {
|
if (fallback !== undefined) {
|
||||||
|
|||||||
@@ -22,6 +22,16 @@ function legacyHeaderDelta(seq = 0): SessionEvent {
|
|||||||
} as unknown as SessionEvent
|
} as unknown as SessionEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** An unsupported named-mode fixture emulating an untyped producer. */
|
||||||
|
function legacyModeSet(seq = 0): SessionEvent {
|
||||||
|
return {
|
||||||
|
type: 'mode/set',
|
||||||
|
seq,
|
||||||
|
time: 1,
|
||||||
|
data: { mode: 'plan' },
|
||||||
|
} as unknown as SessionEvent
|
||||||
|
}
|
||||||
|
|
||||||
/** An obsolete full-header reason fixture from the removed delta codec. */
|
/** An obsolete full-header reason fixture from the removed delta codec. */
|
||||||
function legacyFallbackHeader(seq = 0): SessionEvent {
|
function legacyFallbackHeader(seq = 0): SessionEvent {
|
||||||
return {
|
return {
|
||||||
@@ -510,6 +520,19 @@ describe('SessionPersistence service registration', () => {
|
|||||||
await fiber.dispose()
|
await fiber.dispose()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('rejects a stored legacy named-mode event during load', async () => {
|
||||||
|
const id = SessionId('legacy-mode-load')
|
||||||
|
const m = meta(id, '/legacy')
|
||||||
|
const store: MemoryStore = new Map([[id, { meta: m, events: [legacyModeSet()] }]])
|
||||||
|
const ctx = new Context()
|
||||||
|
await ctx.plugin(SessionStore)
|
||||||
|
const fiber = await ctx.plugin(MemoryPersistence, { store })
|
||||||
|
|
||||||
|
await expect(ctx.sessionPersistence.load(id))
|
||||||
|
.rejects.toThrow('unsupported legacy mode/set event at seq 0')
|
||||||
|
await fiber.dispose()
|
||||||
|
})
|
||||||
|
|
||||||
it('retires all coordinator bookkeeping for disposed sessions', async () => {
|
it('retires all coordinator bookkeeping for disposed sessions', async () => {
|
||||||
const ctx = new Context()
|
const ctx = new Context()
|
||||||
await ctx.plugin(SessionStore)
|
await ctx.plugin(SessionStore)
|
||||||
|
|||||||
Reference in New Issue
Block a user