11

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 ?

Joe Allen
  • 1,267
  • 4
  • 24
  • 41
  • can you post the http code? – LLai Sep 26 '17 at 15:44
  • I edited my post – Joe Allen Sep 26 '17 at 16:04
  • Anyone ? I'm still stuck :( – Joe Allen Sep 28 '17 at 08:55
  • It's odd the Accept-Language header is undefined (in lazyUpdate) & doesn't show up in headers. I wonder if this has anything to do with localStorage & Karma. What happens if you remove the x-auth-token? – LLai Sep 28 '17 at 14:17
  • Hi @Joe Allen, I know this has been a while ago. Did you find the solution? I am having similar difficulty with other headers. Cheers – Witold Kaczurba May 01 '19 at 06:45
  • 1
    I just had the same problem. For me it was the ´Accept-Language´ header being undefined during tests. My translation service in the interceptor was not mocked correctly. When this header has a value the request headers are all there in tests. – Rocco Feb 01 '21 at 07:49

1 Answers1

0

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.

Andrei Roba
  • 2,156
  • 2
  • 16
  • 33