Skip to content

Commit 2d13901

Browse files
committed
test(desktop): the raw upload routes serve nothing on the dedicated MCP host
1 parent e92ad8c commit 2d13901

2 files changed

Lines changed: 38 additions & 2 deletions

File tree

‎apps/sim/app/api/desktop/tool/file/route.test.ts‎

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { authMockFns } from '@sim/testing'
2+
import { resetEnvMock, setEnv } from '@sim/testing/mocks/env.mock'
23
import { NextRequest } from 'next/server'
3-
import { beforeEach, describe, expect, it, vi } from 'vitest'
4+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
45
import { OrchestrationError } from '@/lib/core/orchestration/types'
56

67
const { 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

4446
describe('/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)

‎apps/sim/app/api/desktop/tool/import/route.test.ts‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { authMockFns } from '@sim/testing'
2+
import { resetEnvMock, setEnv } from '@sim/testing/mocks/env.mock'
23
import { NextRequest } from 'next/server'
3-
import { beforeEach, describe, expect, it, vi } from 'vitest'
4+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
45
import { DesktopDeviceUnrecognizedError } from '@/lib/desktop/executor/errors'
56

67
const { admitted, stored, admitError } = vi.hoisted(() => ({
@@ -78,6 +79,19 @@ describe('PUT /api/desktop/tool/import', () => {
7879
admitError.next = null
7980
})
8081

82+
afterEach(() => {
83+
resetEnvMock()
84+
})
85+
86+
it('serves nothing on the dedicated MCP host, reading no body', async () => {
87+
setEnv({ SIM_MCP_URL: 'https://mcp.sim.test/mcp' })
88+
const { request, pulled } = put({ host: 'mcp.sim.test' })
89+
90+
expect((await PUT(request, {})).status).toBe(404)
91+
expect(pulled()).toBe(0)
92+
expect(stored).toEqual([])
93+
})
94+
8195
it('stores a whole file under the claim the token header names', async () => {
8296
const { request } = put({})
8397

0 commit comments

Comments
 (0)