diff --git a/packages/api/session-controller/tests/commands-queue-attachment.host.spec.ts b/packages/api/session-controller/tests/commands-queue-attachment.host.spec.ts index a23917b312..7d46edda4e 100644 --- a/packages/api/session-controller/tests/commands-queue-attachment.host.spec.ts +++ b/packages/api/session-controller/tests/commands-queue-attachment.host.spec.ts @@ -342,6 +342,7 @@ function event(type: string, seq: SessionSeq, data: unknown): SessionEvent { async function persistedController( events: SessionEvent[], readImage: (ref: ImageAttachmentRef) => Promise<{ ref: ImageAttachmentRef; data: Uint8Array }>, + workspace: Pick = { cwd: '/workspace' }, ): Promise<{ ctx: Context; controller: SessionCommandController; sessionId: SessionId }> { const ctx = new Context() await ctx.plugin(SessionStore) @@ -350,7 +351,7 @@ async function persistedController( version: SESSION_FORMAT_VERSION, id: sessionId, createdAt: 1, - cwd: '/workspace', + ...workspace, isSeeded: false, } ctx.provide('sessionPersistence', testSessionPersistence(ctx, { @@ -563,6 +564,23 @@ describe('Session attachment authorization', () => { } }) + it('rejects a cold Session without cwd before reading its referenced image', async () => { + const ref = imageRef('missing-cwd') + const readImage = vi.fn(async () => ({ ref, data: new Uint8Array([1]) })) + const fixture = await persistedController( + [event('user/message', SessionSeq(0), { id: 'image', role: 'user', source: { kind: 'user' }, content: [{ type: 'image', attachment: ref }] })], + readImage, + {}, + ) + try { + await expect(fixture.controller.attachment({ sessionId: fixture.sessionId, attachmentId: ref.attachmentId })) + .rejects.toMatchObject({ code: 'session/not-found', details: { sessionId: fixture.sessionId } }) + expect(readImage).not.toHaveBeenCalled() + } finally { + await fixture.ctx.fiber.dispose() + } + }) + it('maps a cold observation failure to an internal authorization error', async () => { const ctx = new Context() await ctx.plugin(SessionStore)