I am unit testing global HTTP interceptor that gets the XSCRF token from a service call getReponse() and appends it to the header only in POSTS request postResponse() call ( service call mentioned below )
So far I tried testing it but i am not able to pass the test case. Any help would be much appreciated.
This is the optout.service.ts file which contains two methods
getResponse() method uses mergeMap to chain two calls, first service call is to get the token for XCSRF and the second to get the form response
getReponse():Observable<optout>{
return this.httpClient.get<any>(`https://thisIsGetTokenApi.com`).pipe(
mergeMap(token=>this.httpClient.get<optout>(`https://someurlenpoint2.com`))
)
postResponse(data:optout):Observable<optout>{
return this.httpClient.post<optout>('https://api-endpoint',data)
}
Here is global-http-interceptor.ts file
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { Observable } from "rxjs";
import { tap } from 'rxjs/operators';
import { Router } from '@angular/router';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root'
})
export class GlobalHttpInterceptorService implements HttpInterceptor {
public hostURL=environment.hostURL;
public apiURL=environment.apiURL;
constructor(public router: Router) { }
token:string='';
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if(this.token && req.method== "POST"){
req=req.clone({headers:req.headers.append('X-CSRF-TOKEN',this.token)});
}
return next.handle(req)
.pipe(
tap(event => {
if (event instanceof HttpResponse) {
if(req.url.includes('/getToken')){
this.token=event.body.XCSRFTOKEN;
}
}
}, (error:any) => {
if(error instanceof HttpErrorResponse){
if(error.status === 400 || error.status === 401 || error.status === 402){
window.location.href=`https://some-direct-url.com`;
}
}
})
)
}
}
This is test spec file global-http-interceptor.spec.ts that i tried
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { GlobalHttpInterceptorService } from './global-http-interceptor.service';
import { RouterTestingModule } from '@angular/router/testing';
import { OptoutService } from './optout.service';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { API_CONFIG_TOKEN } from '../token';
import { GlobalConstants } from '../global-constants';
import { environment } from 'src/environments/environment';
import { optout } from '../model/optoutModel';
describe('GlobalHttpInterceptorService', () => {
let apiURL=environment.apiURL;
let httpController: HttpTestingController;
let getPreferenceApi='http://somegetrequestapi/v1/get';
let updatePreferenceApi='http://getpostrequest/v1/post';
let service: GlobalHttpInterceptorService;
let optoutService: OptoutService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports:[RouterTestingModule, HttpClientTestingModule ],
providers:[
OptoutService,
{provide:HTTP_INTERCEPTORS,useClass:GlobalHttpInterceptorService,multi:true},
{provide:API_CONFIG_TOKEN,useValue:{useFcvApi:false}},
]
});
service = TestBed.inject(GlobalHttpInterceptorService);
optoutService =TestBed.inject(OptoutService);
httpMock=TestBed.get(HttpTestingController);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should add an XCSRF header',() => {
const optoutMock:optout={
"output": {
"somevar1": "somvalue",
"somevar2": false
},{
"somevar1": "somvalue2",
"somevar2": false
}
}
optoutService.getResponse().subscribe(res=>{
expect(res).toBeTruthy();
})
optoutService.postResponse(optoutMock).subscribe(res=>{
expect(res).toBeTruthy();
})
const httpRequest=httpMock.expectOne(getTokenApi);
expect(httpRequest.request.headers.has('X-CSRF-TOKEN')).toEqual(true);
});
});
Could it be that the addition of the token is being blocked because
this.token
is falsy (not truthy)?If so, try setting it and see if the test passes: