mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
This commit updates scripts within `packages/common` to relative imports as a prep work to the upcoming infra updates. PR Close #60623
149 lines
5 KiB
TypeScript
149 lines
5 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.sonpCallbackContext
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.dev/license
|
|
*/
|
|
|
|
import {HttpHandler} from '../src/backend';
|
|
import {HttpClient} from '../src/client';
|
|
import {HttpContext, HttpContextToken} from '../src/context';
|
|
import {HTTP_INTERCEPTORS, HttpInterceptor} from '../src/interceptor';
|
|
import {HttpRequest} from '../src/request';
|
|
import {HttpEvent, HttpResponse} from '../src/response';
|
|
import {HttpTestingController} from '../testing/src/api';
|
|
import {HttpClientTestingModule} from '../testing/src/module';
|
|
import {TestRequest} from '../testing/src/request';
|
|
import {Injectable, Injector} from '@angular/core';
|
|
import {TestBed} from '@angular/core/testing';
|
|
import {Observable} from 'rxjs';
|
|
import {map} from 'rxjs/operators';
|
|
|
|
const IS_INTERCEPTOR_C_ENABLED = new HttpContextToken<boolean | undefined>(() => undefined);
|
|
|
|
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}});
|
|
return delegate.handle(req).pipe(
|
|
map((event) => {
|
|
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;
|
|
}),
|
|
);
|
|
}
|
|
}
|
|
|
|
class InterceptorA extends TestInterceptor {
|
|
constructor() {
|
|
super('A');
|
|
}
|
|
}
|
|
|
|
class InterceptorB extends TestInterceptor {
|
|
constructor() {
|
|
super('B');
|
|
}
|
|
}
|
|
|
|
class InterceptorC extends TestInterceptor {
|
|
constructor() {
|
|
super('C');
|
|
}
|
|
|
|
override 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);
|
|
}
|
|
}
|
|
|
|
@Injectable()
|
|
class ReentrantInterceptor implements HttpInterceptor {
|
|
constructor(private client: HttpClient) {}
|
|
|
|
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
|
return next.handle(req);
|
|
}
|
|
}
|
|
|
|
describe('HttpClientModule', () => {
|
|
let injector: Injector;
|
|
beforeEach(() => {
|
|
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},
|
|
],
|
|
});
|
|
injector = TestBed.inject(Injector);
|
|
});
|
|
it('initializes HttpClient properly', (done) => {
|
|
injector
|
|
.get(HttpClient)
|
|
.get('/test', {responseType: 'text'})
|
|
.subscribe((value: string) => {
|
|
expect(value).toBe('ok!');
|
|
done();
|
|
});
|
|
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();
|
|
TestBed.configureTestingModule({
|
|
imports: [HttpClientTestingModule],
|
|
providers: [{provide: HTTP_INTERCEPTORS, useClass: ReentrantInterceptor, multi: true}],
|
|
});
|
|
injector = TestBed.inject(Injector);
|
|
injector
|
|
.get(HttpClient)
|
|
.get('/test')
|
|
.subscribe(() => {
|
|
done();
|
|
});
|
|
injector.get(HttpTestingController).expectOne('/test').flush('ok!');
|
|
});
|
|
});
|