@mhalder/qdrant-mcp-server 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,202 @@
1
+ import type { Server as HttpServer } from "node:http";
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+
4
+ describe("Transport Configuration", () => {
5
+ let originalEnv: NodeJS.ProcessEnv;
6
+
7
+ beforeEach(() => {
8
+ originalEnv = { ...process.env };
9
+ });
10
+
11
+ afterEach(() => {
12
+ process.env = originalEnv;
13
+ });
14
+
15
+ describe("HTTP Port Validation", () => {
16
+ it("should accept valid port numbers", () => {
17
+ const validPorts = ["1", "80", "443", "3000", "8080", "65535"];
18
+
19
+ validPorts.forEach((port) => {
20
+ const parsed = parseInt(port, 10);
21
+ expect(parsed).toBeGreaterThanOrEqual(1);
22
+ expect(parsed).toBeLessThanOrEqual(65535);
23
+ expect(Number.isNaN(parsed)).toBe(false);
24
+ });
25
+ });
26
+
27
+ it("should reject invalid port numbers", () => {
28
+ const invalidCases = [
29
+ { port: "0", reason: "port 0 is reserved" },
30
+ { port: "-1", reason: "negative ports are invalid" },
31
+ { port: "65536", reason: "exceeds maximum port" },
32
+ { port: "99999", reason: "exceeds maximum port" },
33
+ { port: "abc", reason: "non-numeric input" },
34
+ { port: "", reason: "empty string" },
35
+ ];
36
+
37
+ invalidCases.forEach(({ port, reason }) => {
38
+ const parsed = parseInt(port, 10);
39
+ const isValid = !Number.isNaN(parsed) && parsed >= 1 && parsed <= 65535;
40
+ expect(isValid, `Failed for ${port}: ${reason}`).toBe(false);
41
+ });
42
+ });
43
+
44
+ it("should use default port 3000 when HTTP_PORT is not set", () => {
45
+ const port = parseInt(process.env.HTTP_PORT || "3000", 10);
46
+ expect(port).toBe(3000);
47
+ });
48
+
49
+ it("should parse HTTP_PORT from environment", () => {
50
+ process.env.HTTP_PORT = "8080";
51
+ const port = parseInt(process.env.HTTP_PORT || "3000", 10);
52
+ expect(port).toBe(8080);
53
+ });
54
+ });
55
+
56
+ describe("Transport Mode Validation", () => {
57
+ it("should accept valid transport modes", () => {
58
+ const validModes = ["stdio", "http", "STDIO", "HTTP"];
59
+
60
+ validModes.forEach((mode) => {
61
+ const normalized = mode.toLowerCase();
62
+ expect(["stdio", "http"]).toContain(normalized);
63
+ });
64
+ });
65
+
66
+ it("should reject invalid transport modes", () => {
67
+ const invalidModes = ["tcp", "websocket", "grpc", ""];
68
+
69
+ invalidModes.forEach((mode) => {
70
+ const normalized = mode.toLowerCase();
71
+ expect(["stdio", "http"]).not.toContain(normalized);
72
+ });
73
+ });
74
+
75
+ it("should default to stdio when TRANSPORT_MODE is not set", () => {
76
+ const mode = (process.env.TRANSPORT_MODE || "stdio").toLowerCase();
77
+ expect(mode).toBe("stdio");
78
+ });
79
+ });
80
+
81
+ describe("Request Size Limits", () => {
82
+ it("should define request size limit for HTTP transport", () => {
83
+ const limit = "10mb";
84
+ expect(limit).toMatch(/^\d+mb$/);
85
+ });
86
+
87
+ it("should parse size limit correctly", () => {
88
+ const limit = "10mb";
89
+ const sizeInBytes = parseInt(limit, 10) * 1024 * 1024;
90
+ expect(sizeInBytes).toBe(10485760);
91
+ });
92
+ });
93
+ });
94
+
95
+ describe("HTTP Server Configuration", () => {
96
+ describe("Graceful Shutdown", () => {
97
+ it("should handle shutdown signals", async () => {
98
+ const mockServer = {
99
+ close: vi.fn((callback) => {
100
+ if (callback) callback();
101
+ }),
102
+ } as unknown as HttpServer;
103
+
104
+ const shutdown = () => {
105
+ mockServer.close(() => {
106
+ // Shutdown callback
107
+ });
108
+ };
109
+
110
+ shutdown();
111
+ expect(mockServer.close).toHaveBeenCalled();
112
+ });
113
+
114
+ it("should support timeout for forced shutdown", () => {
115
+ vi.useFakeTimers();
116
+
117
+ let forcedShutdown = false;
118
+ const timeout = setTimeout(() => {
119
+ forcedShutdown = true;
120
+ }, 10000);
121
+
122
+ vi.advanceTimersByTime(9999);
123
+ expect(forcedShutdown).toBe(false);
124
+
125
+ vi.advanceTimersByTime(1);
126
+ expect(forcedShutdown).toBe(true);
127
+
128
+ clearTimeout(timeout);
129
+ vi.useRealTimers();
130
+ });
131
+ });
132
+
133
+ describe("Error Handling", () => {
134
+ it("should return JSON-RPC 2.0 error format", () => {
135
+ const error = {
136
+ jsonrpc: "2.0",
137
+ error: {
138
+ code: -32603,
139
+ message: "Internal server error",
140
+ },
141
+ id: null,
142
+ };
143
+
144
+ expect(error.jsonrpc).toBe("2.0");
145
+ expect(error.error.code).toBe(-32603);
146
+ expect(error.error.message).toBeTruthy();
147
+ expect(error.id).toBeNull();
148
+ });
149
+
150
+ it("should use standard JSON-RPC error codes", () => {
151
+ const errorCodes = {
152
+ parseError: -32700,
153
+ invalidRequest: -32600,
154
+ methodNotFound: -32601,
155
+ invalidParams: -32602,
156
+ internalError: -32603,
157
+ };
158
+
159
+ expect(errorCodes.parseError).toBe(-32700);
160
+ expect(errorCodes.invalidRequest).toBe(-32600);
161
+ expect(errorCodes.methodNotFound).toBe(-32601);
162
+ expect(errorCodes.invalidParams).toBe(-32602);
163
+ expect(errorCodes.internalError).toBe(-32603);
164
+ });
165
+ });
166
+ });
167
+
168
+ describe("Transport Lifecycle", () => {
169
+ it("should close transport on response close", () => {
170
+ const mockTransport = {
171
+ close: vi.fn(),
172
+ };
173
+
174
+ const mockResponse = {
175
+ on: vi.fn((event, callback) => {
176
+ if (event === "close") {
177
+ callback();
178
+ }
179
+ }),
180
+ };
181
+
182
+ mockResponse.on("close", () => {
183
+ mockTransport.close();
184
+ });
185
+
186
+ expect(mockTransport.close).toHaveBeenCalled();
187
+ });
188
+
189
+ it("should handle transport connection", async () => {
190
+ const mockServer = {
191
+ connect: vi.fn().mockResolvedValue(undefined),
192
+ };
193
+
194
+ const mockTransport = {
195
+ handleRequest: vi.fn().mockResolvedValue(undefined),
196
+ close: vi.fn(),
197
+ };
198
+
199
+ await mockServer.connect(mockTransport);
200
+ expect(mockServer.connect).toHaveBeenCalledWith(mockTransport);
201
+ });
202
+ });