HttpHeaders and lazyupdate Angular 4 and Karma

Viewed 5628

I have a problem with HttpHeaders (angular 4.3.0) and Karma. I write some tests and when I run them with npm test command, the http queries are unauthorized because the token (X-Auth-Token) is not set. when I run the same part in my browser with the console, the X-Auth-Token is set and everything works well.

The only difference I can see is in the HttpHeaders object and precisely in lazyUpdate.

no test mode

enter image description here

With karma

enter image description here

The code :

category.service.spec.ts

    describe('Service : Category', () => {

  // setup
  beforeEach(() => TestBed.configureTestingModule({
      imports: [ HttpClientModule, LocalStorageModule.withConfig(localStorageConfig), TranslateModule.forRoot({
        loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
      })],
      providers: [CategoryService, LoaderService, LocalStorageService
      ]
    }));


    it('should list the categories', () => {

        let categoryService = TestBed.get(CategoryService);

        categoryService.apiRoutes = ApiCategoryRoutes;
        categoryService.modelName = "category";

        let actualCategories = [];

        // categoryService expends APIResolverService
        let observable = categoryService.find(); 

        observable.subscribe(data => {

            actualCategories = data;
        });

        console.log("actualCategories");
        console.log(actualCategories);

    });

 });

apiResolver.service.ts (categoryService extends it, category service has no specific code)

export abstract class APIResolverService {

...

  public find() {

      this.showLoader();

      let url = this.getUrl(0, true);

      let headers = this.setHttpHeaders(); 

      console.log("headers");
      console.log(headers);

      let observable = this.http.get(url, {headers : headers})
      .map(res => this.manageResponse(res, true, true)).share();

      observable.subscribe(data => this.hideLoader(), error => this.hideLoader());

      return observable;
  }

  ...

    public setHttpHeaders(){

      let valueToken: string = JSON.stringify(this.localStorage.get('token'));

      let myHeaders = new HttpHeaders()
      .set('Content-Type', 'application/json')
      .set('Accept', 'application/json')
      .set('Accept-Language', "en")
      .set('X-Auth-Token', valueToken.replace(/['"]+/g, ''));

      return myHeaders;
  }

}

Somebody could explain this ?

1 Answers

I had a similar problem while testing an interceptor which was setting some request headers. What I was doing wrong during the test was not setting one of the headers (leaving it undefined) - I haven't looked that deep into the Angular code but this seems to leave out the 'lazyInit' property set to null which in place will stop triggering the 'init' call (that basically sets the headers):

    HttpHeaders.prototype.init = function () {
        var _this = this;
        if (!!this.lazyInit) {
            if (this.lazyInit instanceof HttpHeaders) {
                this.copyFrom(this.lazyInit);
            }
            else {
                this.lazyInit();
            }
            this.lazyInit = null;
            if (!!this.lazyUpdate) {
                this.lazyUpdate.forEach(function (update) { return _this.applyUpdate(update); });
                this.lazyUpdate = null;
            }
        }
    };

There's an issue on github which refers to this. See this comment.

Related