index.test.ts102 lines · main
1import { createMocks } from 'node-mocks-http'
2import { beforeEach, describe, expect, it, vi } from 'vitest'
3
4import handler from '../../../../pages/api/mcp/index'
5import { mswServer } from '@/tests/lib/msw'
6
7// Mock the MCP SDK and Briven MCP server to avoid Hono/node-mocks-http compatibility issues.
8//
9// Starting with MCP SDK v1.25.x (required by @supabase/mcp-server-supabase@0.6.2), the SDK
10// uses @hono/node-server for converting between Node.js HTTP and Web Standard APIs. This is
11// incompatible with the node-mocks-http library used in these tests.
12//
13// Since these tests focus on query parameter validation in the API handler rather than
14// testing the MCP transport implementation, we mock both packages to avoid hitting the
15// incompatible Hono code paths.
16vi.mock('@modelcontextprotocol/sdk/server/streamableHttp.js', () => ({
17 StreamableHTTPServerTransport: vi.fn().mockImplementation(function () {
18 return { handleRequest: vi.fn().mockResolvedValue(undefined) }
19 }),
20}))
21
22vi.mock('@supabase/mcp-server-supabase', () => ({
23 createBrivenMcpServer: vi.fn().mockReturnValue({
24 connect: vi.fn().mockResolvedValue(undefined),
25 }),
26}))
27
28describe('/api/mcp', () => {
29 beforeEach(() => {
30 // Disable MSW for these tests
31 mswServer.close()
32 // Clear mock state between tests
33 vi.clearAllMocks()
34 })
35
36 describe('Method handling', async () => {
37 it('should handle POST requests', async () => {
38 const { req, res } = createMocks({
39 method: 'POST',
40 query: {},
41 body: {},
42 })
43
44 await handler(req, res)
45
46 expect(res._getStatusCode()).not.toBe(405)
47 })
48
49 it('should return 405 for non-POST methods', async () => {
50 const { req, res } = createMocks({
51 method: 'GET',
52 })
53
54 await handler(req, res)
55
56 expect(res._getStatusCode()).toBe(405)
57 expect(JSON.parse(res._getData())).toEqual({
58 error: { message: 'Method GET Not Allowed' },
59 })
60 expect(res._getHeaders()).toEqual({ allow: ['POST'], 'content-type': 'application/json' })
61 })
62 })
63
64 describe('Query validation', async () => {
65 it('should accept valid feature groups', async () => {
66 const { req, res } = createMocks({
67 method: 'POST',
68 query: { features: 'docs,database' },
69 body: {},
70 })
71
72 await handler(req, res)
73
74 expect(res._getStatusCode()).not.toBe(400)
75 })
76
77 it('should reject invalid feature groups', async () => {
78 const { req, res } = createMocks({
79 method: 'POST',
80 query: { features: 'invalid,unknown' },
81 body: {},
82 })
83
84 await handler(req, res)
85
86 expect(res._getStatusCode()).toBe(400)
87 expect(JSON.parse(res._getData())).toHaveProperty('error')
88 })
89
90 it('should work without features parameter', async () => {
91 const { req, res } = createMocks({
92 method: 'POST',
93 query: {},
94 body: {},
95 })
96
97 await handler(req, res)
98
99 expect(res._getStatusCode()).not.toBe(400)
100 })
101 })
102})