@@ -40,6 +40,8 @@ import {EMPTY, Observable, from} from 'rxjs';
4040
4141import  { HttpInterceptorFn ,  resetFetchBackendWarningFlag }  from  '../src/interceptor' ; 
4242import  { 
43+   HttpFeature , 
44+   HttpFeatureKind , 
4345  provideHttpClient , 
4446  withFetch , 
4547  withInterceptors , 
@@ -339,94 +341,107 @@ describe('provideHttpClient', () => {
339341  } ) ; 
340342
341343  describe ( 'withRequestsMadeViaParent()' ,  ( )  =>  { 
342-     it ( 'should have independent HTTP setups if not explicitly specified' ,  async  ( )  =>  { 
343-       TestBed . configureTestingModule ( { 
344-         providers : [ provideHttpClient ( ) ,  provideHttpClientTesting ( ) ] , 
345-       } ) ; 
346- 
347-       const  child  =  createEnvironmentInjector ( 
348-         [ 
349-           provideHttpClient ( ) , 
350-           { 
351-             provide : XhrFactory , 
352-             useValue : { 
353-               build : ( )  =>  { 
354-                 throw  new  Error ( 'Request reached the "backend".' ) ; 
344+     for  ( const  backend  of  [ 'fetch' ,  'xhr' ] )  { 
345+       describe ( `given '${ backend }  ' backend` ,  ( )  =>  { 
346+         const  commonHttpFeatures : HttpFeature < HttpFeatureKind > [ ]  =  [ ] ; 
347+         if  ( backend  ===  'fetch' )  { 
348+           commonHttpFeatures . push ( withFetch ( ) ) ; 
349+         } 
350+ 
351+         it ( 'should have independent HTTP setups if not explicitly specified' ,  async  ( )  =>  { 
352+           TestBed . configureTestingModule ( { 
353+             providers : [ provideHttpClient ( ...commonHttpFeatures ) ,  provideHttpClientTesting ( ) ] , 
354+           } ) ; 
355+ 
356+           const  child  =  createEnvironmentInjector ( 
357+             [ 
358+               provideHttpClient ( ) , 
359+               { 
360+                 provide : XhrFactory , 
361+                 useValue : { 
362+                   build : ( )  =>  { 
363+                     throw  new  Error ( 'Request reached the "backend".' ) ; 
364+                   } , 
365+                 } , 
355366              } , 
356-             } , 
357-           } , 
358-         ] , 
359-         TestBed . inject ( EnvironmentInjector ) , 
360-       ) ; 
361- 
362-       // Because `child` is an entirely independent HTTP context, it is not connected to the 
363-       // HTTP testing backend from the parent injector, and requests attempted via the child's 
364-       // `HttpClient` will fail. 
365-       await  expectAsync ( child . get ( HttpClient ) . get ( '/test' ) . toPromise ( ) ) . toBeRejected ( ) ; 
366-     } ) ; 
367- 
368-     it ( 'should connect child to parent configuration if specified' ,  ( )  =>  { 
369-       TestBed . configureTestingModule ( { 
370-         providers : [ provideHttpClient ( ) ,  provideHttpClientTesting ( ) ] , 
371-       } ) ; 
372- 
373-       const  child  =  createEnvironmentInjector ( 
374-         [ provideHttpClient ( withRequestsMadeViaParent ( ) ) ] , 
375-         TestBed . inject ( EnvironmentInjector ) , 
376-       ) ; 
377- 
378-       // `child` is now to the parent HTTP context and therefore the testing backend, and so a 
379-       // request made via its `HttpClient` can be made. 
380-       child . get ( HttpClient ) . get ( '/test' ,  { responseType : 'text' } ) . subscribe ( ) ; 
381-       const  req  =  TestBed . inject ( HttpTestingController ) . expectOne ( '/test' ) ; 
382-       req . flush ( '' ) ; 
383-     } ) ; 
384- 
385-     it ( 'should include interceptors from both parent and child contexts' ,  ( )  =>  { 
386-       TestBed . configureTestingModule ( { 
387-         providers : [ 
388-           provideHttpClient ( withInterceptors ( [ makeLiteralTagInterceptorFn ( 'parent' ) ] ) ) , 
389-           provideHttpClientTesting ( ) , 
390-         ] , 
391-       } ) ; 
367+             ] , 
368+             TestBed . inject ( EnvironmentInjector ) , 
369+           ) ; 
370+ 
371+           // Because `child` is an entirely independent HTTP context, it is not connected to the 
372+           // HTTP testing backend from the parent injector, and requests attempted via the child's 
373+           // `HttpClient` will fail. 
374+           await  expectAsync ( child . get ( HttpClient ) . get ( '/test' ) . toPromise ( ) ) . toBeRejected ( ) ; 
375+         } ) ; 
392376
393-       const  child  =  createEnvironmentInjector ( 
394-         [ 
395-           provideHttpClient ( 
396-             withRequestsMadeViaParent ( ) , 
397-             withInterceptors ( [ makeLiteralTagInterceptorFn ( 'child' ) ] ) , 
398-           ) , 
399-         ] , 
400-         TestBed . inject ( EnvironmentInjector ) , 
401-       ) ; 
377+         it ( 'should connect child to parent configuration if specified' ,  ( )  =>  { 
378+           TestBed . configureTestingModule ( { 
379+             providers : [ provideHttpClient ( ...commonHttpFeatures ) ,  provideHttpClientTesting ( ) ] , 
380+           } ) ; 
381+ 
382+           const  child  =  createEnvironmentInjector ( 
383+             [ provideHttpClient ( withRequestsMadeViaParent ( ) ) ] , 
384+             TestBed . inject ( EnvironmentInjector ) , 
385+           ) ; 
386+ 
387+           // `child` is now to the parent HTTP context and therefore the testing backend, and so a 
388+           // request made via its `HttpClient` can be made. 
389+           child . get ( HttpClient ) . get ( '/test' ,  { responseType : 'text' } ) . subscribe ( ) ; 
390+           const  req  =  TestBed . inject ( HttpTestingController ) . expectOne ( '/test' ) ; 
391+           req . flush ( '' ) ; 
392+         } ) ; 
402393
403-       child . get ( HttpClient ) . get ( '/test' ,  { responseType : 'text' } ) . subscribe ( ) ; 
404-       const  req  =  TestBed . inject ( HttpTestingController ) . expectOne ( '/test' ) ; 
405-       expect ( req . request . headers . get ( 'X-Tag' ) ) . toEqual ( 'child,parent' ) ; 
406-       req . flush ( '' ) ; 
407-     } ) ; 
394+         it ( 'should include interceptors from both parent and child contexts' ,  ( )  =>  { 
395+           TestBed . configureTestingModule ( { 
396+             providers : [ 
397+               provideHttpClient ( 
398+                 ...commonHttpFeatures , 
399+                 withInterceptors ( [ makeLiteralTagInterceptorFn ( 'parent' ) ] ) , 
400+               ) , 
401+               provideHttpClientTesting ( ) , 
402+             ] , 
403+           } ) ; 
404+ 
405+           const  child  =  createEnvironmentInjector ( 
406+             [ 
407+               provideHttpClient ( 
408+                 withRequestsMadeViaParent ( ) , 
409+                 withInterceptors ( [ makeLiteralTagInterceptorFn ( 'child' ) ] ) , 
410+               ) , 
411+             ] , 
412+             TestBed . inject ( EnvironmentInjector ) , 
413+           ) ; 
414+ 
415+           child . get ( HttpClient ) . get ( '/test' ,  { responseType : 'text' } ) . subscribe ( ) ; 
416+           const  req  =  TestBed . inject ( HttpTestingController ) . expectOne ( '/test' ) ; 
417+           expect ( req . request . headers . get ( 'X-Tag' ) ) . toEqual ( 'child,parent' ) ; 
418+           req . flush ( '' ) ; 
419+         } ) ; 
408420
409-     it ( 'should be able to connect to a legacy-provided HttpClient context' ,  ( )  =>  { 
410-       TestBed . configureTestingModule ( { 
411-         imports : [ HttpClientTestingModule ] , 
412-         providers : [ provideLegacyInterceptor ( 'parent' ) ] , 
421+         it ( 'should be able to connect to a legacy-provided HttpClient context' ,  ( )  =>  { 
422+           TestBed . configureTestingModule ( { 
423+             imports : [ HttpClientTestingModule ] , 
424+             providers : [ provideLegacyInterceptor ( 'parent' ) ] , 
425+           } ) ; 
426+ 
427+           const  child  =  createEnvironmentInjector ( 
428+             [ 
429+               provideHttpClient ( 
430+                 ...commonHttpFeatures , 
431+                 withRequestsMadeViaParent ( ) , 
432+                 withInterceptors ( [ makeLiteralTagInterceptorFn ( 'child' ) ] ) , 
433+               ) , 
434+             ] , 
435+             TestBed . inject ( EnvironmentInjector ) , 
436+           ) ; 
437+ 
438+           child . get ( HttpClient ) . get ( '/test' ,  { responseType : 'text' } ) . subscribe ( ) ; 
439+           const  req  =  TestBed . inject ( HttpTestingController ) . expectOne ( '/test' ) ; 
440+           expect ( req . request . headers . get ( 'X-Tag' ) ) . toEqual ( 'child,parent' ) ; 
441+           req . flush ( '' ) ; 
442+         } ) ; 
413443      } ) ; 
414- 
415-       const  child  =  createEnvironmentInjector ( 
416-         [ 
417-           provideHttpClient ( 
418-             withRequestsMadeViaParent ( ) , 
419-             withInterceptors ( [ makeLiteralTagInterceptorFn ( 'child' ) ] ) , 
420-           ) , 
421-         ] , 
422-         TestBed . inject ( EnvironmentInjector ) , 
423-       ) ; 
424- 
425-       child . get ( HttpClient ) . get ( '/test' ,  { responseType : 'text' } ) . subscribe ( ) ; 
426-       const  req  =  TestBed . inject ( HttpTestingController ) . expectOne ( '/test' ) ; 
427-       expect ( req . request . headers . get ( 'X-Tag' ) ) . toEqual ( 'child,parent' ) ; 
428-       req . flush ( '' ) ; 
429-     } ) ; 
444+     } 
430445  } ) ; 
431446
432447  describe ( 'compatibility with Http NgModules' ,  ( )  =>  { 
@@ -472,20 +487,33 @@ describe('provideHttpClient', () => {
472487      expect ( consoleWarnSpy . calls . count ( ) ) . toBe ( 0 ) ; 
473488    } ) ; 
474489
475-     it ( 'withFetch should always override the backend' ,  ( )  =>  { 
490+     it ( `'withFetch' should not override provided backend` ,  ( )  =>  { 
491+       class  CustomBackendExtends  extends  HttpXhrBackend  { } 
492+ 
476493      TestBed . resetTestingModule ( ) ; 
477494      TestBed . configureTestingModule ( { 
478495        providers : [ 
479496          provideHttpClient ( withFetch ( ) ) , 
480-           // This emulates a situation when `provideHttpClient()` is used 
481-           // later in a different part of an app. We want to make sure that 
482-           // the `FetchBackend` is enabled in that case as well. 
483-           { provide : HttpBackend ,  useClass : HttpXhrBackend } , 
497+           { provide : HttpBackend ,  useClass : CustomBackendExtends } , 
484498        ] , 
485499      } ) ; 
486500
487-       const  handler  =  TestBed . inject ( HttpHandler ) ; 
488-       expect ( ( handler  as  any ) . backend ) . toBeInstanceOf ( FetchBackend ) ; 
501+       const  backend  =  TestBed . inject ( HttpBackend ) ; 
502+       expect ( backend ) . toBeInstanceOf ( CustomBackendExtends ) ; 
503+     } ) ; 
504+ 
505+     it ( `fetch API should be used in child when 'withFetch' was used in parent injector` ,  ( )  =>  { 
506+       TestBed . configureTestingModule ( { 
507+         providers : [ provideHttpClient ( withFetch ( ) ) ,  provideHttpClientTesting ( ) ] , 
508+       } ) ; 
509+ 
510+       const  child  =  createEnvironmentInjector ( 
511+         [ provideHttpClient ( ) ] , 
512+         TestBed . inject ( EnvironmentInjector ) , 
513+       ) ; 
514+ 
515+       const  backend  =  child . get ( HttpBackend ) ; 
516+       expect ( backend ) . toBeInstanceOf ( FetchBackend ) ; 
489517    } ) ; 
490518
491519    it ( 'should not warn if fetch is not configured when running in a browser' ,  ( )  =>  { 
0 commit comments