test(session): cover cold attachment without workspace

This commit is contained in:
imccyu committed 2026-10-23 16:01:29 +08:00
1 parent 05f94de1f9
commit 9d7cd67a51
1 file changed
+19 -1
@@ -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<SessionHeader, 'cwd'> = { 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)