| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved.sonpCallbackContext | 
					
						
							| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-15 11:35:08 -08:00
										 |  |  | import {HttpHandler} from '@angular/common/http/src/backend'; | 
					
						
							|  |  |  | import {HttpClient} from '@angular/common/http/src/client'; | 
					
						
							| 
									
										
										
										
											2021-03-09 21:20:48 +01:00
										 |  |  | import {HttpContext, HttpContextToken} from '@angular/common/http/src/context'; | 
					
						
							| 
									
										
										
										
											2018-11-15 11:35:08 -08:00
										 |  |  | import {HTTP_INTERCEPTORS, HttpInterceptor} from '@angular/common/http/src/interceptor'; | 
					
						
							|  |  |  | import {HttpRequest} from '@angular/common/http/src/request'; | 
					
						
							|  |  |  | import {HttpEvent, HttpResponse} from '@angular/common/http/src/response'; | 
					
						
							|  |  |  | import {HttpTestingController} from '@angular/common/http/testing/src/api'; | 
					
						
							|  |  |  | import {HttpClientTestingModule} from '@angular/common/http/testing/src/module'; | 
					
						
							|  |  |  | import {TestRequest} from '@angular/common/http/testing/src/request'; | 
					
						
							| 
									
										
										
										
											2017-10-19 09:31:10 -07:00
										 |  |  | import {Injectable, Injector} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  | import {TestBed} from '@angular/core/testing'; | 
					
						
							| 
									
										
										
										
											2018-02-27 17:06:06 -05:00
										 |  |  | import {Observable} from 'rxjs'; | 
					
						
							|  |  |  | import {map} from 'rxjs/operators'; | 
					
						
							| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-09 21:20:48 +01:00
										 |  |  | const IS_INTERCEPTOR_C_ENABLED = new HttpContextToken<boolean|undefined>(() => undefined); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  | class TestInterceptor implements HttpInterceptor { | 
					
						
							|  |  |  |   constructor(private value: string) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   intercept(req: HttpRequest<any>, delegate: HttpHandler): Observable<HttpEvent<any>> { | 
					
						
							|  |  |  |     const existing = req.headers.get('Intercepted'); | 
					
						
							|  |  |  |     const next = !!existing ? existing + ',' + this.value : this.value; | 
					
						
							|  |  |  |     req = req.clone({setHeaders: {'Intercepted': next}}); | 
					
						
							| 
									
										
										
										
											2018-02-27 17:06:06 -05:00
										 |  |  |     return delegate.handle(req).pipe(map(event => { | 
					
						
							| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  |       if (event instanceof HttpResponse) { | 
					
						
							|  |  |  |         const existing = event.headers.get('Intercepted'); | 
					
						
							|  |  |  |         const next = !!existing ? existing + ',' + this.value : this.value; | 
					
						
							|  |  |  |         return event.clone({headers: event.headers.set('Intercepted', next)}); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return event; | 
					
						
							| 
									
										
										
										
											2018-02-27 17:06:06 -05:00
										 |  |  |     })); | 
					
						
							| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class InterceptorA extends TestInterceptor { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   constructor() { | 
					
						
							|  |  |  |     super('A'); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class InterceptorB extends TestInterceptor { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   constructor() { | 
					
						
							|  |  |  |     super('B'); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-09 21:20:48 +01:00
										 |  |  | class InterceptorC extends TestInterceptor { | 
					
						
							|  |  |  |   constructor() { | 
					
						
							|  |  |  |     super('C'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   intercept(req: HttpRequest<any>, delegate: HttpHandler): Observable<HttpEvent<any>> { | 
					
						
							|  |  |  |     if (req.context.get(IS_INTERCEPTOR_C_ENABLED) === true) { | 
					
						
							|  |  |  |       return super.intercept(req, delegate); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return delegate.handle(req); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-19 09:31:10 -07:00
										 |  |  | @Injectable() | 
					
						
							|  |  |  | class ReentrantInterceptor implements HttpInterceptor { | 
					
						
							|  |  |  |   constructor(private client: HttpClient) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | 
					
						
							|  |  |  |     return next.handle(req); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-09 21:20:48 +01:00
										 |  |  | describe('HttpClientModule', () => { | 
					
						
							|  |  |  |   let injector: Injector; | 
					
						
							|  |  |  |   beforeEach(() => { | 
					
						
							|  |  |  |     injector = TestBed.configureTestingModule({ | 
					
						
							|  |  |  |       imports: [HttpClientTestingModule], | 
					
						
							|  |  |  |       providers: [ | 
					
						
							|  |  |  |         {provide: HTTP_INTERCEPTORS, useClass: InterceptorA, multi: true}, | 
					
						
							|  |  |  |         {provide: HTTP_INTERCEPTORS, useClass: InterceptorB, multi: true}, | 
					
						
							|  |  |  |         {provide: HTTP_INTERCEPTORS, useClass: InterceptorC, multi: true}, | 
					
						
							|  |  |  |       ], | 
					
						
							| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-03-09 21:20:48 +01:00
										 |  |  |   }); | 
					
						
							|  |  |  |   it('initializes HttpClient properly', done => { | 
					
						
							|  |  |  |     injector.get(HttpClient).get('/test', {responseType: 'text'}).subscribe((value: string) => { | 
					
						
							|  |  |  |       expect(value).toBe('ok!'); | 
					
						
							|  |  |  |       done(); | 
					
						
							| 
									
										
										
										
											2018-07-05 18:10:09 +03:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-03-09 21:20:48 +01:00
										 |  |  |     injector.get(HttpTestingController).expectOne('/test').flush('ok!'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   it('intercepts outbound responses in the order in which interceptors were bound', done => { | 
					
						
							|  |  |  |     injector.get(HttpClient) | 
					
						
							|  |  |  |         .get('/test', {observe: 'response', responseType: 'text'}) | 
					
						
							|  |  |  |         .subscribe(() => done()); | 
					
						
							|  |  |  |     const req = injector.get(HttpTestingController).expectOne('/test') as TestRequest; | 
					
						
							|  |  |  |     expect(req.request.headers.get('Intercepted')).toEqual('A,B'); | 
					
						
							|  |  |  |     req.flush('ok!'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   it('intercepts outbound responses in the order in which interceptors were bound and include specifically enabled interceptor', | 
					
						
							|  |  |  |      done => { | 
					
						
							|  |  |  |        injector.get(HttpClient) | 
					
						
							|  |  |  |            .get('/test', { | 
					
						
							|  |  |  |              observe: 'response', | 
					
						
							|  |  |  |              responseType: 'text', | 
					
						
							|  |  |  |              context: new HttpContext().set(IS_INTERCEPTOR_C_ENABLED, true) | 
					
						
							|  |  |  |            }) | 
					
						
							|  |  |  |            .subscribe(value => done()); | 
					
						
							|  |  |  |        const req = injector.get(HttpTestingController).expectOne('/test') as TestRequest; | 
					
						
							|  |  |  |        expect(req.request.headers.get('Intercepted')).toEqual('A,B,C'); | 
					
						
							|  |  |  |        req.flush('ok!'); | 
					
						
							|  |  |  |      }); | 
					
						
							|  |  |  |   it('intercepts inbound responses in the right (reverse binding) order', done => { | 
					
						
							|  |  |  |     injector.get(HttpClient) | 
					
						
							|  |  |  |         .get('/test', {observe: 'response', responseType: 'text'}) | 
					
						
							|  |  |  |         .subscribe((value: HttpResponse<string>) => { | 
					
						
							|  |  |  |           expect(value.headers.get('Intercepted')).toEqual('B,A'); | 
					
						
							|  |  |  |           done(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     injector.get(HttpTestingController).expectOne('/test').flush('ok!'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   it('allows interceptors to inject HttpClient', done => { | 
					
						
							|  |  |  |     TestBed.resetTestingModule(); | 
					
						
							|  |  |  |     injector = TestBed.configureTestingModule({ | 
					
						
							|  |  |  |       imports: [HttpClientTestingModule], | 
					
						
							|  |  |  |       providers: [ | 
					
						
							|  |  |  |         {provide: HTTP_INTERCEPTORS, useClass: ReentrantInterceptor, multi: true}, | 
					
						
							|  |  |  |       ], | 
					
						
							| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-03-09 21:20:48 +01:00
										 |  |  |     injector.get(HttpClient).get('/test').subscribe(() => { | 
					
						
							|  |  |  |       done(); | 
					
						
							| 
									
										
										
										
											2017-10-19 09:31:10 -07:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-03-09 21:20:48 +01:00
										 |  |  |     injector.get(HttpTestingController).expectOne('/test').flush('ok!'); | 
					
						
							| 
									
										
										
										
											2017-03-22 17:13:24 -07:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2021-03-09 21:20:48 +01:00
										 |  |  | }); |