@@ -62,6 +62,162 @@ describe("protocol tests", () => {
6262 await  transport . close ( ) ; 
6363 expect ( oncloseMock ) . toHaveBeenCalled ( ) ; 
6464 } ) ; 
65+ 
66+  describe ( "progress notification timeout behavior" ,  ( )  =>  { 
67+  beforeEach ( ( )  =>  { 
68+  jest . useFakeTimers ( ) ; 
69+  } ) ; 
70+  afterEach ( ( )  =>  { 
71+  jest . useRealTimers ( ) ; 
72+  } ) ; 
73+ 
74+  test ( "should reset timeout when progress notification is received" ,  async  ( )  =>  { 
75+  await  protocol . connect ( transport ) ; 
76+  const  request  =  {  method : "example" ,  params : { }  } ; 
77+  const  mockSchema : ZodType < {  result : string  } >  =  z . object ( { 
78+  result : z . string ( ) , 
79+  } ) ; 
80+  const  onProgressMock  =  jest . fn ( ) ; 
81+  const  requestPromise  =  protocol . request ( request ,  mockSchema ,  { 
82+  timeout : 1000 , 
83+  resetTimeoutOnProgress : true , 
84+  onprogress : onProgressMock , 
85+  } ) ; 
86+  jest . advanceTimersByTime ( 800 ) ; 
87+  if  ( transport . onmessage )  { 
88+  transport . onmessage ( { 
89+  jsonrpc : "2.0" , 
90+  method : "notifications/progress" , 
91+  params : { 
92+  progressToken : 0 , 
93+  progress : 50 , 
94+  total : 100 , 
95+  } , 
96+  } ) ; 
97+  } 
98+  await  Promise . resolve ( ) ; 
99+  expect ( onProgressMock ) . toHaveBeenCalledWith ( { 
100+  progress : 50 , 
101+  total : 100 , 
102+  } ) ; 
103+  jest . advanceTimersByTime ( 800 ) ; 
104+  if  ( transport . onmessage )  { 
105+  transport . onmessage ( { 
106+  jsonrpc : "2.0" , 
107+  id : 0 , 
108+  result : {  result : "success"  } , 
109+  } ) ; 
110+  } 
111+  await  Promise . resolve ( ) ; 
112+  await  expect ( requestPromise ) . resolves . toEqual ( {  result : "success"  } ) ; 
113+  } ) ; 
114+ 
115+  test ( "should respect maxTotalTimeout" ,  async  ( )  =>  { 
116+  await  protocol . connect ( transport ) ; 
117+  const  request  =  {  method : "example" ,  params : { }  } ; 
118+  const  mockSchema : ZodType < {  result : string  } >  =  z . object ( { 
119+  result : z . string ( ) , 
120+  } ) ; 
121+  const  onProgressMock  =  jest . fn ( ) ; 
122+  const  requestPromise  =  protocol . request ( request ,  mockSchema ,  { 
123+  timeout : 1000 , 
124+  maxTotalTimeout : 150 , 
125+  resetTimeoutOnProgress : true , 
126+  onprogress : onProgressMock , 
127+  } ) ; 
128+ 
129+  // First progress notification should work 
130+  jest . advanceTimersByTime ( 80 ) ; 
131+  if  ( transport . onmessage )  { 
132+  transport . onmessage ( { 
133+  jsonrpc : "2.0" , 
134+  method : "notifications/progress" , 
135+  params : { 
136+  progressToken : 0 , 
137+  progress : 50 , 
138+  total : 100 , 
139+  } , 
140+  } ) ; 
141+  } 
142+  await  Promise . resolve ( ) ; 
143+  expect ( onProgressMock ) . toHaveBeenCalledWith ( { 
144+  progress : 50 , 
145+  total : 100 , 
146+  } ) ; 
147+  jest . advanceTimersByTime ( 80 ) ; 
148+  if  ( transport . onmessage )  { 
149+  transport . onmessage ( { 
150+  jsonrpc : "2.0" , 
151+  method : "notifications/progress" , 
152+  params : { 
153+  progressToken : 0 , 
154+  progress : 75 , 
155+  total : 100 , 
156+  } , 
157+  } ) ; 
158+  } 
159+  await  expect ( requestPromise ) . rejects . toThrow ( "Maximum total timeout exceeded" ) ; 
160+  expect ( onProgressMock ) . toHaveBeenCalledTimes ( 1 ) ; 
161+  } ) ; 
162+ 
163+  test ( "should timeout if no progress received within timeout period" ,  async  ( )  =>  { 
164+  await  protocol . connect ( transport ) ; 
165+  const  request  =  {  method : "example" ,  params : { }  } ; 
166+  const  mockSchema : ZodType < {  result : string  } >  =  z . object ( { 
167+  result : z . string ( ) , 
168+  } ) ; 
169+  const  requestPromise  =  protocol . request ( request ,  mockSchema ,  { 
170+  timeout : 100 , 
171+  resetTimeoutOnProgress : true , 
172+  } ) ; 
173+  jest . advanceTimersByTime ( 101 ) ; 
174+  await  expect ( requestPromise ) . rejects . toThrow ( "Request timed out" ) ; 
175+  } ) ; 
176+ 
177+  test ( "should handle multiple progress notifications correctly" ,  async  ( )  =>  { 
178+  await  protocol . connect ( transport ) ; 
179+  const  request  =  {  method : "example" ,  params : { }  } ; 
180+  const  mockSchema : ZodType < {  result : string  } >  =  z . object ( { 
181+  result : z . string ( ) , 
182+  } ) ; 
183+  const  onProgressMock  =  jest . fn ( ) ; 
184+  const  requestPromise  =  protocol . request ( request ,  mockSchema ,  { 
185+  timeout : 1000 , 
186+  resetTimeoutOnProgress : true , 
187+  onprogress : onProgressMock , 
188+  } ) ; 
189+ 
190+  // Simulate multiple progress updates 
191+  for  ( let  i  =  1 ;  i  <=  3 ;  i ++ )  { 
192+  jest . advanceTimersByTime ( 800 ) ; 
193+  if  ( transport . onmessage )  { 
194+  transport . onmessage ( { 
195+  jsonrpc : "2.0" , 
196+  method : "notifications/progress" , 
197+  params : { 
198+  progressToken : 0 , 
199+  progress : i  *  25 , 
200+  total : 100 , 
201+  } , 
202+  } ) ; 
203+  } 
204+  await  Promise . resolve ( ) ; 
205+  expect ( onProgressMock ) . toHaveBeenNthCalledWith ( i ,  { 
206+  progress : i  *  25 , 
207+  total : 100 , 
208+  } ) ; 
209+  } 
210+  if  ( transport . onmessage )  { 
211+  transport . onmessage ( { 
212+  jsonrpc : "2.0" , 
213+  id : 0 , 
214+  result : {  result : "success"  } , 
215+  } ) ; 
216+  } 
217+  await  Promise . resolve ( ) ; 
218+  await  expect ( requestPromise ) . resolves . toEqual ( {  result : "success"  } ) ; 
219+  } ) ; 
220+  } ) ; 
65221} ) ; 
66222
67223describe ( "mergeCapabilities" ,  ( )  =>  { 
0 commit comments