External redirect in Angular

How to testably redirect to an external url in Angular.

Working in versions

  • @angular/*: ^4.2.4

Do this.

Inject the global `document`

import { Inject } from '@angular/core'; import { DOCUMENT } from '@angular/common'; export class FooService () { constructor(@Inject(DOCUMENT) private doc: any) {} redirect () => this.doc.location.assign("//google.com"); }

Then provide a spyObject in the tests.

document = { location: jasmine.createSpyObj('document', ['assign']) }; TestBed.configureTestingModule({ providers: [ { provide: DOCUMENT, useValue: document } //… expect(document.location.assign).toHaveBeenCalledWith('http://external-url.com');

You can try these

Out of the box Angular's Location, LocationPath Services

`import { Location, PathLocationStrategy } from '@angular/common';`

`location.go` since the default locations strategies (hash, location) available are made for modifying paths.

`redirect () => this.location.go("//google.com");`

`location.go` expects a path.

'http:/external-url.com' will set the url to `http://my-angular-app.com/http://external-url.com`. Even `//external-url.com` doesn't work, Angular's call to `history.pushState` won't allow the domain mismatch.

Change the global `window` or `document

`window.location.href = 'http://external-url.com` `document.location.href = 'http://external-url.com`

Without injecting the window/document or using a facade, this will hijack your tests and send jasmine to `http://external-url.com`

Write your own LocationStrategy.

Don't forget the tests when you do this.