@@ -246,35 +246,92 @@ describe(XhrHttpHandler.name, () => {
246246 } ) ;
247247
248248 describe ( "per-request requestTimeout" , ( ) => {
249- it ( "should use per-request timeout over handler config timeout" , ( ) => {
250- const handler1 = new XhrHttpHandler ( { requestTimeout : 5000 } ) ;
251- const handler2 = new XhrHttpHandler ( { requestTimeout : 200 } ) ;
249+ it ( "should use per-request timeout over handler config timeout" , async ( ) => {
250+ const handler = new XhrHttpHandler ( { requestTimeout : 5000 } ) ;
252251
253- const testTimeout = ( handlerTimeout : number , requestTimeout ?: number ) => {
254- const expectedTimeout = Number ( requestTimeout ?? handlerTimeout ) | 0 ;
255- return expectedTimeout ;
256- } ;
252+ const requestTimeoutSpy = vi . spyOn ( await import ( "./request-timeout" ) , "requestTimeout" ) ;
253+
254+ const mockRequest = new HttpRequest ( {
255+ method : "GET" ,
256+ hostname : "example.com" ,
257+ protocol : "https:" ,
258+ path : "/" ,
259+ headers : { } ,
260+ } ) ;
261+
262+ class TimeoutXhrMock extends XhrMock {
263+ send ( ...args : any [ ] ) {
264+ this . captureArgs ( "send" ) ( ...args ) ;
265+ // let it timeout
266+ }
267+ }
268+
269+ ( global as any ) . XMLHttpRequest = TimeoutXhrMock ;
257270
258- // per-request timeout takes precedence
259- expect ( testTimeout ( 5000 , 100 ) ) . toBe ( 100 ) ;
271+ try {
272+ await handler . handle ( mockRequest , { requestTimeout : 100 } ) ;
273+ } catch ( error ) {
274+ // expected to timeout
275+ }
260276
261- // fallback to handler config timeout
262- expect ( testTimeout ( 200 , undefined ) ) . toBe ( 200 ) ;
263- expect ( testTimeout ( 200 ) ) . toBe ( 200 ) ;
277+ // verify requestTimeout function was called with per-request timeout (100), not handler timeout (5000)
278+ expect ( requestTimeoutSpy ) . toHaveBeenCalledWith ( 100 ) ;
279+
280+ requestTimeoutSpy . mockRestore ( ) ;
281+ ( global as any ) . XMLHttpRequest = XhrMock ; // restore original mock
264282 } ) ;
265283
266- it ( "should pass correct timeout values to internal functions" , async ( ) => {
267- const handler = new XhrHttpHandler ( { requestTimeout : 5000 } ) ;
268- ( handler as any ) . config = { requestTimeout : 5000 } ;
284+ it ( "should fall back to handler config timeout when per-request timeout not provided" , async ( ) => {
285+ const handler = new XhrHttpHandler ( { requestTimeout : 200 } ) ;
286+
287+ const requestTimeoutSpy = vi . spyOn ( await import ( "./request-timeout" ) , "requestTimeout" ) ;
288+
289+ const mockRequest = new HttpRequest ( {
290+ method : "GET" ,
291+ hostname : "example.com" ,
292+ protocol : "https:" ,
293+ path : "/" ,
294+ headers : { } ,
295+ } ) ;
296+
297+ class TimeoutXhrMock extends XhrMock {
298+ send ( ...args : any [ ] ) {
299+ this . captureArgs ( "send" ) ( ...args ) ;
300+ }
301+ }
302+
303+ ( global as any ) . XMLHttpRequest = TimeoutXhrMock ;
304+
305+ try {
306+ await handler . handle ( mockRequest , { } ) ;
307+ } catch ( error ) { }
308+
309+ expect ( requestTimeoutSpy ) . toHaveBeenCalledWith ( 200 ) ;
310+
311+ requestTimeoutSpy . mockRestore ( ) ;
312+ ( global as any ) . XMLHttpRequest = XhrMock ;
313+ } ) ;
314+
315+ it ( "should handle zero timeout correctly" , async ( ) => {
316+ const handler = new XhrHttpHandler ( { requestTimeout : 1000 } ) ;
317+
318+ const requestTimeoutSpy = vi . spyOn ( await import ( "./request-timeout" ) , "requestTimeout" ) ;
319+
320+ const mockRequest = new HttpRequest ( {
321+ method : "GET" ,
322+ hostname : "example.com" ,
323+ protocol : "https:" ,
324+ path : "/" ,
325+ headers : { } ,
326+ } ) ;
269327
270- const options1 = { requestTimeout : 100 } ;
271- const options2 : { requestTimeout ?: number } = { } ;
328+ try {
329+ await handler . handle ( mockRequest , { requestTimeout : 0 } ) ;
330+ } catch ( error ) { }
272331
273- const effectiveTimeout1 = Number ( options1 . requestTimeout ?? ( handler as any ) . config . requestTimeout ) | 0 ;
274- const effectiveTimeout2 = Number ( options2 . requestTimeout ?? ( handler as any ) . config . requestTimeout ) | 0 ;
332+ expect ( requestTimeoutSpy ) . toHaveBeenCalledWith ( 0 ) ;
275333
276- expect ( effectiveTimeout1 ) . toBe ( 100 ) ; // per-request timeout used
277- expect ( effectiveTimeout2 ) . toBe ( 5000 ) ; // handler config timeout used
334+ requestTimeoutSpy . mockRestore ( ) ;
278335 } ) ;
279336 } ) ;
280337} ) ;
0 commit comments