@@ -5,6 +5,7 @@ import { MockRedisClient, setRedisClient } from '../redis.js';
55import { handleStreamableHTTP } from './shttp.js' ;
66import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js' ;
77import { randomUUID } from 'crypto' ;
8+ import { shutdownSession } from '../services/redisTransport.js' ;
89
910describe ( 'Streamable HTTP Handler Integration Tests' , ( ) => {
1011 let mockRedis : MockRedisClient ;
@@ -21,20 +22,26 @@ describe('Streamable HTTP Handler Integration Tests', () => {
2122 status : jest . fn ( ) . mockReturnThis ( ) ,
2223 json : jest . fn ( ) . mockReturnThis ( ) ,
2324 on : jest . fn ( ) . mockReturnThis ( ) ,
25+ once : jest . fn ( ) . mockReturnThis ( ) ,
26+ emit : jest . fn ( ) . mockReturnThis ( ) ,
2427 headersSent : false ,
2528 setHeader : jest . fn ( ) . mockReturnThis ( ) ,
2629 writeHead : jest . fn ( ) . mockReturnThis ( ) ,
2730 write : jest . fn ( ) . mockReturnThis ( ) ,
2831 end : jest . fn ( ) . mockReturnThis ( ) ,
2932 getHeader : jest . fn ( ) ,
3033 removeHeader : jest . fn ( ) . mockReturnThis ( ) ,
31- } as Partial < Response > ;
34+ socket : {
35+ setTimeout : jest . fn ( ) ,
36+ } ,
37+ } as unknown as Partial < Response > ;
3238
3339 // Create mock request
3440 mockReq = {
3541 method : 'POST' ,
3642 headers : {
3743 'content-type' : 'application/json' ,
44+ 'accept' : 'application/json, text/event-stream' ,
3845 'mcp-protocol-version' : '2024-11-05' ,
3946 } ,
4047 body : { } ,
@@ -57,12 +64,12 @@ describe('Streamable HTTP Handler Integration Tests', () => {
5764 } ;
5865
5966 // Helper to extract session ID from test context
60- const getSessionIdFromTest = ( ) => {
67+ const getSessionIdFromTest = ( ) : string | undefined => {
6168 // Try to get from response headers first
6269 const setHeaderCalls = ( mockRes . setHeader as jest . Mock ) . mock . calls ;
6370 const sessionIdHeader = setHeaderCalls . find ( ( [ name ] ) => name === 'mcp-session-id' ) ;
6471 if ( sessionIdHeader ?. [ 1 ] ) {
65- return sessionIdHeader [ 1 ] ;
72+ return sessionIdHeader [ 1 ] as string ;
6673 }
6774
6875 // Fall back to extracting from Redis channels
@@ -105,6 +112,10 @@ describe('Streamable HTTP Handler Integration Tests', () => {
105112
106113 // Wait longer for async initialization to complete
107114 await new Promise ( resolve => setTimeout ( resolve , 200 ) ) ;
115+
116+ // get the sessionId from the response
117+ const sessionId = getSessionIdFromTest ( ) ;
118+ expect ( sessionId ) . toBeDefined ( ) ;
108119
109120 // Check if any subscriptions were created on any channels
110121 // Since we don't know the exact sessionId generated, check all channels
@@ -129,6 +140,10 @@ describe('Streamable HTTP Handler Integration Tests', () => {
129140
130141 // Verify cleanup handler was registered
131142 expect ( mockRes . on ) . toHaveBeenCalledWith ( 'finish' , expect . any ( Function ) ) ;
143+
144+ if ( sessionId ) {
145+ await shutdownSession ( sessionId )
146+ }
132147 } ) ;
133148
134149 it ( 'should handle cleanup errors gracefully' , async ( ) => {
@@ -175,7 +190,9 @@ describe('Streamable HTTP Handler Integration Tests', () => {
175190 // Send DELETE request to clean up MCP server
176191 jest . clearAllMocks ( ) ;
177192 mockReq . method = 'DELETE' ;
178- mockReq . headers [ 'mcp-session-id' ] = cleanupSessionId ;
193+ if ( mockReq . headers ) {
194+ mockReq . headers [ 'mcp-session-id' ] = cleanupSessionId ;
195+ }
179196 mockReq . body = { } ;
180197
181198 await handleStreamableHTTP ( mockReq as Request , mockRes as Response ) ;
@@ -223,7 +240,7 @@ describe('Streamable HTTP Handler Integration Tests', () => {
223240 let sessionId : string | undefined ;
224241
225242 if ( jsonCalls . length > 0 ) {
226- const response = jsonCalls [ 0 ] [ 0 ] ;
243+ const response = jsonCalls [ 0 ] [ 0 ] as any ;
227244 if ( response ?. result ?. _meta ?. sessionId ) {
228245 sessionId = response . result . _meta . sessionId ;
229246 }
@@ -237,7 +254,7 @@ describe('Streamable HTTP Handler Integration Tests', () => {
237254 try {
238255 // SSE data format: "data: {...}\n\n"
239256 const jsonStr = data . replace ( / ^ d a t a : / , '' ) . trim ( ) ;
240- const parsed = JSON . parse ( jsonStr ) ;
257+ const parsed = JSON . parse ( jsonStr ) as any ;
241258 if ( parsed ?. result ?. _meta ?. sessionId ) {
242259 sessionId = parsed . result . _meta . sessionId ;
243260 }
@@ -327,7 +344,7 @@ describe('Streamable HTTP Handler Integration Tests', () => {
327344 // Check JSON responses
328345 const jsonCalls = ( mockRes . json as jest . Mock ) . mock . calls ;
329346 if ( jsonCalls . length > 0 ) {
330- const response = jsonCalls [ 0 ] [ 0 ] ;
347+ const response = jsonCalls [ 0 ] [ 0 ] as any ;
331348 if ( response ?. result ?. _meta ?. sessionId ) {
332349 sessionId = response . result . _meta . sessionId ;
333350 }
@@ -340,7 +357,7 @@ describe('Streamable HTTP Handler Integration Tests', () => {
340357 if ( typeof data === 'string' && data . includes ( 'sessionId' ) ) {
341358 try {
342359 const jsonStr = data . replace ( / ^ d a t a : / , '' ) . trim ( ) ;
343- const parsed = JSON . parse ( jsonStr ) ;
360+ const parsed = JSON . parse ( jsonStr ) as any ;
344361 if ( parsed ?. result ?. _meta ?. sessionId ) {
345362 sessionId = parsed . result . _meta . sessionId ;
346363 }
@@ -374,13 +391,17 @@ describe('Streamable HTTP Handler Integration Tests', () => {
374391
375392 // Should return 401 for unauthorized access to another user's session
376393 expect ( mockRes . status ) . toHaveBeenCalledWith ( 401 ) ;
394+
395+ // shutdown the session
396+ if ( sessionId ) {
397+ await shutdownSession ( sessionId )
398+ }
377399 } ) ;
378400 } ) ;
379401
380402 describe ( 'User Session Isolation' , ( ) => {
381403 it ( 'should prevent users from accessing sessions created by other users' , async ( ) => {
382404 // Create session for user 1
383- const sessionId = randomUUID ( ) ;
384405 const user1Auth : AuthInfo = {
385406 clientId : 'user1-client' ,
386407 token : 'user1-token' ,
@@ -421,7 +442,7 @@ describe('Streamable HTTP Handler Integration Tests', () => {
421442 // Check JSON responses
422443 const jsonCalls = ( mockRes . json as jest . Mock ) . mock . calls ;
423444 if ( jsonCalls . length > 0 ) {
424- const response = jsonCalls [ 0 ] [ 0 ] ;
445+ const response = jsonCalls [ 0 ] [ 0 ] as any ;
425446 if ( response ?. result ?. _meta ?. sessionId ) {
426447 actualSessionId = response . result . _meta . sessionId ;
427448 }
0 commit comments