From 62eb7d082fb1ff25757189f02d354809418d15cb Mon Sep 17 00:00:00 2001 From: claude_code Date: Sun, 28 Jun 2026 23:45:06 +0300 Subject: [PATCH] test(ai-chat): stub sandboxStore.asSink in AiChatToolsService spec The blob-sandbox feature (#243/#250) made AiChatToolsService.forUser() eagerly call this.sandboxStore.asSink() while wiring the stash tool, but the spec still passed an empty {} as the sandboxStore constructor arg. That object has no asSink method, so all 19 tests in the suite failed in CI with 'TypeError: this.sandboxStore.asSink is not a function'. Replace the stale {} mock at all 4 constructor sites with a no-op sink exposing asSink() -> { put, has, evict } (jest.fn()). These tests never execute the stash tool, so a no-op sink is sufficient for forUser() to wire successfully. Test-only change; production code is unchanged. Co-Authored-By: Claude Opus 4.8 --- .../tools/ai-chat-tools.service.spec.ts | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/apps/server/src/core/ai-chat/tools/ai-chat-tools.service.spec.ts b/apps/server/src/core/ai-chat/tools/ai-chat-tools.service.spec.ts index ea820041..33960a3f 100644 --- a/apps/server/src/core/ai-chat/tools/ai-chat-tools.service.spec.ts +++ b/apps/server/src/core/ai-chat/tools/ai-chat-tools.service.spec.ts @@ -63,9 +63,12 @@ describe('AiChatToolsService deletePage guardrail (H4)', () => { {} as never, {} as never, {} as never, - // sandboxStore (only used by the stash tool closure, which these tests do - // not execute). - {} as never, + // sandboxStore: forUser() eagerly calls asSink() to wire the stash tool, + // even though these tests never execute it — return a no-op sink so the + // tool wiring in forUser() succeeds. + { + asSink: () => ({ put: jest.fn(), has: jest.fn(), evict: jest.fn() }), + } as never, ); }); @@ -178,9 +181,12 @@ describe('AiChatToolsService expanded toolset guardrails', () => { {} as never, {} as never, {} as never, - // sandboxStore (only used by the stash tool closure, which these tests do - // not execute). - {} as never, + // sandboxStore: forUser() eagerly calls asSink() to wire the stash tool, + // even though these tests never execute it — return a no-op sink so the + // tool wiring in forUser() succeeds. + { + asSink: () => ({ put: jest.fn(), has: jest.fn(), evict: jest.fn() }), + } as never, ); }); @@ -296,9 +302,12 @@ describe('AiChatToolsService node-arg JSON-string coercion', () => { {} as never, {} as never, {} as never, - // sandboxStore (only used by the stash tool closure, which these tests do - // not execute). - {} as never, + // sandboxStore: forUser() eagerly calls asSink() to wire the stash tool, + // even though these tests never execute it — return a no-op sink so the + // tool wiring in forUser() succeeds. + { + asSink: () => ({ put: jest.fn(), has: jest.fn(), evict: jest.fn() }), + } as never, ); }); @@ -449,9 +458,12 @@ describe('AiChatToolsService model-friendly input validation (#190)', () => { {} as never, {} as never, {} as never, - // sandboxStore (only used by the stash tool closure, which these tests do - // not execute). - {} as never, + // sandboxStore: forUser() eagerly calls asSink() to wire the stash tool, + // even though these tests never execute it — return a no-op sink so the + // tool wiring in forUser() succeeds. + { + asSink: () => ({ put: jest.fn(), has: jest.fn(), evict: jest.fn() }), + } as never, ); });