@@ -40,6 +40,8 @@ import {EMPTY, Observable, from} from 'rxjs';
40
40
41
41
import { HttpInterceptorFn , resetFetchBackendWarningFlag } from '../src/interceptor' ;
42
42
import {
43
+ HttpFeature ,
44
+ HttpFeatureKind ,
43
45
provideHttpClient ,
44
46
withFetch ,
45
47
withInterceptors ,
@@ -339,94 +341,107 @@ describe('provideHttpClient', () => {
339
341
} ) ;
340
342
341
343
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
+ } ,
355
366
} ,
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
+ } ) ;
392
376
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
+ } ) ;
402
393
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
+ } ) ;
408
420
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
+ } ) ;
413
443
} ) ;
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
+ }
430
445
} ) ;
431
446
432
447
describe ( 'compatibility with Http NgModules' , ( ) => {
@@ -472,20 +487,33 @@ describe('provideHttpClient', () => {
472
487
expect ( consoleWarnSpy . calls . count ( ) ) . toBe ( 0 ) ;
473
488
} ) ;
474
489
475
- it ( 'withFetch should always override the backend' , ( ) => {
490
+ it ( `'withFetch' should not override provided backend` , ( ) => {
491
+ class CustomBackendExtends extends HttpXhrBackend { }
492
+
476
493
TestBed . resetTestingModule ( ) ;
477
494
TestBed . configureTestingModule ( {
478
495
providers : [
479
496
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 } ,
484
498
] ,
485
499
} ) ;
486
500
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 ) ;
489
517
} ) ;
490
518
491
519
it ( 'should not warn if fetch is not configured when running in a browser' , ( ) => {
0 commit comments