11import { authMockFns } from '@sim/testing'
2+ import { resetEnvMock , setEnv } from '@sim/testing/mocks/env.mock'
23import { NextRequest } from 'next/server'
3- import { beforeEach , describe , expect , it , vi } from 'vitest'
4+ import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest'
45import { OrchestrationError } from '@/lib/core/orchestration/types'
56
67const { mockAdmit, mockRead, mockSave } = vi . hoisted ( ( ) => ( {
@@ -40,6 +41,7 @@ const put = (query: string, body: Uint8Array, headers: Record<string, string> =
4041 headers : { 'content-length' : String ( body . byteLength ) , ...headers } ,
4142 body,
4243 } )
44+ const MCP_HOST = 'mcp.sim.test'
4345
4446describe ( '/api/desktop/tool/file' , ( ) => {
4547 beforeEach ( ( ) => {
@@ -51,6 +53,26 @@ describe('/api/desktop/tool/file', () => {
5153 } )
5254 } )
5355
56+ afterEach ( ( ) => {
57+ resetEnvMock ( )
58+ } )
59+
60+ it ( 'serves neither a read nor a save on the dedicated MCP host' , async ( ) => {
61+ setEnv ( { SIM_MCP_URL : `https://${ MCP_HOST } /mcp` } )
62+ const onMcpHost = ( request : NextRequest ) =>
63+ new NextRequest ( request . url . replace ( 'localhost' , MCP_HOST ) , {
64+ method : request . method ,
65+ headers : { ...Object . fromEntries ( request . headers ) , host : MCP_HOST } ,
66+ body : request . body ,
67+ duplex : 'half' ,
68+ } )
69+
70+ expect ( ( await POST ( onMcpHost ( post ( { toolCallId : 'call-1' , index : 0 } ) ) , { } ) ) . status ) . toBe ( 404 )
71+ const save = onMcpHost ( put ( 'toolCallId=call-2&name=report.csv' , new Uint8Array ( [ 1 , 2 , 3 ] ) ) )
72+ expect ( ( await PUT ( save ) ) . status ) . toBe ( 404 )
73+ expect ( save . bodyUsed ) . toBe ( false )
74+ } )
75+
5476 it ( 'authenticates before parsing and conceals an unknown transfer' , async ( ) => {
5577 mockGetSession . mockResolvedValueOnce ( null )
5678 expect ( ( await POST ( post ( { toolCallId : 'call-1' , index : 0 } ) , { } ) ) . status ) . toBe ( 401 )
0 commit comments