@@ -28,10 +28,18 @@ jest.mock("@modelcontextprotocol/sdk/client/index.js", () => ({
28
28
} ) ) ;
29
29
30
30
jest . mock ( "@modelcontextprotocol/sdk/client/sse.js" , ( ) => ( {
31
- SSEClientTransport : jest . fn ( ) ,
31
+ SSEClientTransport : jest . fn ( ( url ) => ( {
32
+ toString : ( ) => url ,
33
+ } ) ) ,
32
34
SseError : jest . fn ( ) ,
33
35
} ) ) ;
34
36
37
+ jest . mock ( "@modelcontextprotocol/sdk/client/streamableHttp.js" , ( ) => ( {
38
+ StreamableHTTPClientTransport : jest . fn ( ( url ) => ( {
39
+ toString : ( ) => url ,
40
+ } ) ) ,
41
+ } ) ) ;
42
+
35
43
jest . mock ( "@modelcontextprotocol/sdk/client/auth.js" , ( ) => ( {
36
44
auth : jest . fn ( ) . mockResolvedValue ( "AUTHORIZED" ) ,
37
45
} ) ) ;
@@ -163,4 +171,82 @@ describe("useConnection", () => {
163
171
result . current . makeRequest ( mockRequest , mockSchema ) ,
164
172
) . rejects . toThrow ( "MCP client not connected" ) ;
165
173
} ) ;
174
+
175
+ describe ( "URL Port Handling" , ( ) => {
176
+ const SSEClientTransport = jest . requireMock ( "@modelcontextprotocol/sdk/client/sse.js" ) . SSEClientTransport ;
177
+ const StreamableHTTPClientTransport = jest . requireMock ( "@modelcontextprotocol/sdk/client/streamableHttp.js" ) . StreamableHTTPClientTransport ;
178
+
179
+ beforeEach ( ( ) => {
180
+ jest . clearAllMocks ( ) ;
181
+ } ) ;
182
+
183
+ test ( "preserves HTTPS port number when connecting" , async ( ) => {
184
+ const props = {
185
+ ...defaultProps ,
186
+ sseUrl : "https://example.com:8443/api" ,
187
+ transportType : "sse" as const ,
188
+ } ;
189
+
190
+ const { result } = renderHook ( ( ) => useConnection ( props ) ) ;
191
+
192
+ await act ( async ( ) => {
193
+ await result . current . connect ( ) ;
194
+ } ) ;
195
+
196
+ const call = SSEClientTransport . mock . calls [ 0 ] [ 0 ] ;
197
+ expect ( call . toString ( ) ) . toContain ( "url=https%3A%2F%2Fexample.com%3A8443%2Fapi" ) ;
198
+ } ) ;
199
+
200
+ test ( "preserves HTTP port number when connecting" , async ( ) => {
201
+ const props = {
202
+ ...defaultProps ,
203
+ sseUrl : "http://localhost:3000/api" ,
204
+ transportType : "sse" as const ,
205
+ } ;
206
+
207
+ const { result } = renderHook ( ( ) => useConnection ( props ) ) ;
208
+
209
+ await act ( async ( ) => {
210
+ await result . current . connect ( ) ;
211
+ } ) ;
212
+
213
+ const call = SSEClientTransport . mock . calls [ 0 ] [ 0 ] ;
214
+ expect ( call . toString ( ) ) . toContain ( "url=http%3A%2F%2Flocalhost%3A3000%2Fapi" ) ;
215
+ } ) ;
216
+
217
+ test ( "uses default port for HTTPS when not specified" , async ( ) => {
218
+ const props = {
219
+ ...defaultProps ,
220
+ sseUrl : "https://example.com/api" ,
221
+ transportType : "sse" as const ,
222
+ } ;
223
+
224
+ const { result } = renderHook ( ( ) => useConnection ( props ) ) ;
225
+
226
+ await act ( async ( ) => {
227
+ await result . current . connect ( ) ;
228
+ } ) ;
229
+
230
+ const call = SSEClientTransport . mock . calls [ 0 ] [ 0 ] ;
231
+ expect ( call . toString ( ) ) . toContain ( "url=https%3A%2F%2Fexample.com%2Fapi" ) ;
232
+ expect ( call . toString ( ) ) . not . toContain ( "%3A443" ) ;
233
+ } ) ;
234
+
235
+ test ( "preserves port number in streamable-http transport" , async ( ) => {
236
+ const props = {
237
+ ...defaultProps ,
238
+ sseUrl : "https://example.com:8443/api" ,
239
+ transportType : "streamable-http" as const ,
240
+ } ;
241
+
242
+ const { result } = renderHook ( ( ) => useConnection ( props ) ) ;
243
+
244
+ await act ( async ( ) => {
245
+ await result . current . connect ( ) ;
246
+ } ) ;
247
+
248
+ const call = StreamableHTTPClientTransport . mock . calls [ 0 ] [ 0 ] ;
249
+ expect ( call . toString ( ) ) . toContain ( "url=https%3A%2F%2Fexample.com%3A8443%2Fapi" ) ;
250
+ } ) ;
251
+ } ) ;
166
252
} ) ;
0 commit comments