I'm working with Angular6 and I'm trying to make my Jasmine test reach the callback inside mergeMap bellow, but after days of work I just can't do it.
My test returns correctly the refresh method, but it just doesn't seem to follow through the pipe.
This is the full method where I'm testing:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<any> {
if (
this.jwtInterceptor.isWhitelistedDomain(req) &&
!this.jwtInterceptor.isBlacklistedRoute(req)
) {
const newRequest = req.clone();
return next.handle(newRequest).pipe(
tap(() => {
const token = this.jwtHelper.tokenGetter();
if (token) {
const expirationTime = this.jwtHelper
.getTokenExpirationDate()
.getTime();
const expirationLeft = expirationTime - Date.now();
const expired =
expirationLeft > 0 && expirationLeft < 5 * 60 * 1000;
if (expired && !this.isUpdating) {
this.isUpdating = true;
return this.refresh().pipe(
mergeMap(() => { // this is the unreachable part
return this.jwtInterceptor.intercept(req, next);
})
);
}
}
}),
catchError(err => {
if (err instanceof HttpErrorResponse && err.status === 401) {
this.router.navigate([this.config.routeToGoIfNotLoggedIn]);
}
return throwError(err);
})
);
} else {
return next.handle(req);
}
}
Here my this.refresh() method returned:
refresh(): Observable<any> {
const refreshObservable = this.authAPI.refreshToken();
const refreshSubject = new ReplaySubject<any>(1);
refreshSubject.subscribe(
data => {
localStorage.setItem('token', data.jwt);
this.isUpdating = false;
},
err => {
this.isUpdating = false;
this.userLoggedService.removeUserLoggedAndToken();
}
);
refreshObservable.subscribe(refreshSubject);
return refreshSubject;
}
}
and this is my this.authAPI.refreshToken() fired inside refresh():
refreshToken() {
return this.http.get(`${this.config.baseAPIUrl}refreshToken`);
}
The http call is correctly catch within my httpTestingController and the final expectation is to have this.jwtInterceptor.intercept(req, next) fired.
This is my spec for the part I'm failing:
it('should call Refresh method if token is expiring in 5 minutes', () => {
const nowInMillisec = Number(new Date());
const FourMinutesFromNow = nowInMillisec + 4 * 60000;
spyOn(
jwtService,
'getTokenExpirationDate'
).and.returnValue(new Date(FourMinutesFromNow));
const jwtInterceptor = TestBed.get(JwtInterceptor);
const spyOnJwtInterceptor = spyOn(jwtInterceptor, 'intercept');
dummyService.fakeHttpCall().subscribe();
httpTestingController.expectOne(
`${MockAuthConfig.baseAPIUrl}user/fake-call`
);
const callbackHttpFired = httpTestingController.expectOne(
`${MockAuthConfig.baseAPIUrl}refreshToken`
);
expect(callbackHttpFired.request.url).toEqual(
`${MockAuthConfig.baseAPIUrl}refreshToken`
);
expect(spyOnJwtInterceptor).toHaveBeenCalled(); // this spy is never fired... :(
});
Any ideas?? Thank you very much!!