diff --git a/aio/src/app/app.component.spec.ts b/aio/src/app/app.component.spec.ts
index 6353be5f80..1765cd85e1 100644
--- a/aio/src/app/app.component.spec.ts
+++ b/aio/src/app/app.component.spec.ts
@@ -2,7 +2,7 @@ import { NO_ERRORS_SCHEMA, DebugElement } from '@angular/core';
import { async, inject, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { Title } from '@angular/platform-browser';
import { APP_BASE_HREF } from '@angular/common';
-import { Http } from '@angular/http';
+import { HttpClient } from '@angular/common/http';
import { MdProgressBar, MdSidenav } from '@angular/material';
import { By } from '@angular/platform-browser';
@@ -650,7 +650,7 @@ describe('AppComponent', () => {
describe('footer', () => {
it('should have version number', () => {
const versionEl: HTMLElement = fixture.debugElement.query(By.css('aio-footer')).nativeElement;
- expect(versionEl.textContent).toContain(TestHttp.versionInfo.full);
+ expect(versionEl.textContent).toContain(TestHttpClient.versionInfo.full);
});
});
@@ -1027,7 +1027,7 @@ function createTestingModule(initialUrl: string, mode: string = 'stable') {
providers: [
{ provide: APP_BASE_HREF, useValue: '/' },
{ provide: GaService, useClass: TestGaService },
- { provide: Http, useClass: TestHttp },
+ { provide: HttpClient, useClass: TestHttpClient },
{ provide: LocationService, useFactory: () => mockLocationService },
{ provide: Logger, useClass: MockLogger },
{ provide: SearchService, useClass: MockSearchService },
@@ -1049,7 +1049,7 @@ class TestSearchService {
loadIndex = jasmine.createSpy('loadIndex');
}
-class TestHttp {
+class TestHttpClient {
static versionInfo = {
raw: '4.0.0-rc.6',
@@ -1105,9 +1105,9 @@ class TestHttp {
"tooltip": "Details of the Angular classes and values."
}
],
- "docVersions": TestHttp.docVersions,
+ "docVersions": TestHttpClient.docVersions,
- "__versionInfo": TestHttp.versionInfo,
+ "__versionInfo": TestHttpClient.versionInfo,
};
get(url: string) {
@@ -1123,6 +1123,6 @@ class TestHttp {
const contents = `${h1}
Some heading
`;
data = { id, contents };
}
- return of({ json: () => data });
+ return of(data);
}
}
diff --git a/aio/src/app/app.module.ts b/aio/src/app/app.module.ts
index ca9545ab5b..2cc2c33aa6 100644
--- a/aio/src/app/app.module.ts
+++ b/aio/src/app/app.module.ts
@@ -1,6 +1,6 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
-import { HttpModule } from '@angular/http';
+import { HttpClientModule } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { Location, LocationStrategy, PathLocationStrategy } from '@angular/common';
@@ -75,7 +75,7 @@ export const svgIconProviders = [
imports: [
BrowserModule,
EmbeddedModule,
- HttpModule,
+ HttpClientModule,
BrowserAnimationsModule,
MdButtonModule,
MdIconModule,
diff --git a/aio/src/app/documents/document.service.spec.ts b/aio/src/app/documents/document.service.spec.ts
index 7b9a660515..8f7116bcc7 100644
--- a/aio/src/app/documents/document.service.spec.ts
+++ b/aio/src/app/documents/document.service.spec.ts
@@ -1,11 +1,11 @@
-import { ReflectiveInjector } from '@angular/core';
-import { Http, ConnectionBackend, RequestOptions, BaseRequestOptions, Response, ResponseOptions } from '@angular/http';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { Injector } from '@angular/core';
+import { TestBed } from '@angular/core/testing';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
-import { MockBackend } from '@angular/http/testing';
import { LocationService } from 'app/shared/location.service';
import { MockLocationService } from 'testing/location.service';
import { Logger } from 'app/shared/logger.service';
@@ -16,113 +16,123 @@ import { DocumentService, DocumentContents,
const CONTENT_URL_PREFIX = 'generated/docs/';
-function createResponse(body: any) {
- return new Response(new ResponseOptions({ body: JSON.stringify(body) }));
-}
-
-function createInjector(initialUrl: string) {
- return ReflectiveInjector.resolveAndCreate([
- DocumentService,
- { provide: LocationService, useFactory: () => new MockLocationService(initialUrl) },
- { provide: ConnectionBackend, useClass: MockBackend },
- { provide: RequestOptions, useClass: BaseRequestOptions },
- { provide: Logger, useClass: MockLogger },
- Http,
- ]);
-}
-
-function getServices(initialUrl: string = '') {
- const injector = createInjector(initialUrl);
- return {
- backend: injector.get(ConnectionBackend) as MockBackend,
- locationService: injector.get(LocationService) as MockLocationService,
- docService: injector.get(DocumentService) as DocumentService,
- logger: injector.get(Logger) as MockLogger
- };
-}
-
describe('DocumentService', () => {
- it('should be creatable', () => {
- const { docService } = getServices();
- expect(docService).toBeTruthy();
- });
+ let httpMock: HttpTestingController;
+
+ function createInjector(initialUrl: string) {
+ return TestBed.configureTestingModule({
+ imports: [HttpClientTestingModule],
+ providers: [
+ DocumentService,
+ { provide: LocationService, useFactory: () => new MockLocationService(initialUrl) },
+ { provide: Logger, useClass: MockLogger },
+ ]
+ });
+ }
+
+ function getServices(initialUrl: string = '') {
+ const injector = createInjector(initialUrl);
+ httpMock = injector.get(HttpTestingController) as HttpTestingController;
+ return {
+ locationService: injector.get(LocationService) as MockLocationService,
+ docService: injector.get(DocumentService) as DocumentService,
+ logger: injector.get(Logger) as MockLogger
+ };
+ }
+
+ afterEach(() => httpMock.verify());
describe('currentDocument', () => {
it('should fetch a document for the initial location', () => {
- const { docService, backend } = getServices('initial/doc');
- const connections = backend.connectionsArray;
+ const { docService } = getServices('initial/doc');
docService.currentDocument.subscribe();
- expect(connections.length).toEqual(1);
- expect(connections[0].request.url).toEqual(CONTENT_URL_PREFIX + 'initial/doc.json');
- expect(backend.connectionsArray[0].request.url).toEqual(CONTENT_URL_PREFIX + 'initial/doc.json');
+ httpMock.expectOne(CONTENT_URL_PREFIX + 'initial/doc.json');
});
it('should emit a document each time the location changes', () => {
let latestDocument: DocumentContents;
const doc0 = { contents: 'doc 0', id: 'initial/doc' };
- const doc1 = { contents: 'doc 1', id: 'new/doc' };
- const { docService, backend, locationService } = getServices('initial/doc');
- const connections = backend.connectionsArray;
+ const doc1 = { contents: 'doc 1', id: 'new/doc' };
+ const { docService, locationService } = getServices('initial/doc');
docService.currentDocument.subscribe(doc => latestDocument = doc);
expect(latestDocument).toBeUndefined();
- connections[0].mockRespond(createResponse(doc0));
+ httpMock.expectOne({}).flush(doc0);
expect(latestDocument).toEqual(doc0);
locationService.go('new/doc');
- connections[1].mockRespond(createResponse(doc1));
+ httpMock.expectOne({}).flush(doc1);
expect(latestDocument).toEqual(doc1);
});
it('should emit the not-found document if the document is not found on the server', () => {
- const { docService, backend } = getServices('missing/doc');
- const connections = backend.connectionsArray;
let currentDocument: DocumentContents;
+ const notFoundDoc = { id: FILE_NOT_FOUND_ID, contents: 'Page Not Found
' };
+ const { docService } = getServices('missing/doc');
docService.currentDocument.subscribe(doc => currentDocument = doc);
- connections[0].mockError(new Response(new ResponseOptions({ status: 404, statusText: 'NOT FOUND'})) as any);
- expect(connections.length).toEqual(2);
- expect(connections[1].request.url).toEqual(CONTENT_URL_PREFIX + 'file-not-found.json');
- const fileNotFoundDoc = { id: FILE_NOT_FOUND_ID, contents: 'Page Not Found
' };
- connections[1].mockRespond(createResponse(fileNotFoundDoc));
- expect(currentDocument).toEqual(fileNotFoundDoc);
+ // Initial request return 404.
+ httpMock.expectOne({}).flush(null, {status: 404, statusText: 'NOT FOUND'});
+
+ // Subsequent request for not-found document.
+ httpMock.expectOne(CONTENT_URL_PREFIX + 'file-not-found.json').flush(notFoundDoc);
+
+ expect(currentDocument).toEqual(notFoundDoc);
});
it('should emit a hard-coded not-found document if the not-found document is not found on the server', () => {
let currentDocument: DocumentContents;
- const notFoundDoc: DocumentContents = { contents: 'Document not found', id: FILE_NOT_FOUND_ID };
+ const hardCodedNotFoundDoc = { contents: 'Document not found', id: FILE_NOT_FOUND_ID };
const nextDoc = { contents: 'Next Doc', id: 'new/doc' };
- const { docService, backend, locationService } = getServices(FILE_NOT_FOUND_ID);
- const connections = backend.connectionsArray;
+ const { docService, locationService } = getServices(FILE_NOT_FOUND_ID);
+
docService.currentDocument.subscribe(doc => currentDocument = doc);
- connections[0].mockError(new Response(new ResponseOptions({ status: 404, statusText: 'NOT FOUND'})) as any);
- expect(connections.length).toEqual(1);
- expect(currentDocument).toEqual(notFoundDoc);
+ httpMock.expectOne({}).flush(null, { status: 404, statusText: 'NOT FOUND'});
+ expect(currentDocument).toEqual(hardCodedNotFoundDoc);
// now check that we haven't killed the currentDocument observable sequence
locationService.go('new/doc');
- connections[1].mockRespond(createResponse(nextDoc));
+ httpMock.expectOne({}).flush(nextDoc);
expect(currentDocument).toEqual(nextDoc);
});
+ it('should use a hard-coded error doc if the request fails (but not cache it)', () => {
+ let latestDocument: DocumentContents;
+ const doc1 = { contents: 'doc 1' };
+ const doc2 = { contents: 'doc 2' };
+ const { docService, locationService } = getServices('initial/doc');
+
+ docService.currentDocument.subscribe(doc => latestDocument = doc);
+
+ httpMock.expectOne({}).flush(null, {status: 500, statusText: 'Server Error'});
+ expect(latestDocument.id).toEqual(FETCHING_ERROR_ID);
+
+ locationService.go('new/doc');
+ httpMock.expectOne({}).flush(doc1);
+ expect(latestDocument).toEqual(jasmine.objectContaining(doc1));
+
+ locationService.go('initial/doc');
+ httpMock.expectOne({}).flush(doc2);
+ expect(latestDocument).toEqual(jasmine.objectContaining(doc2));
+ });
+
it('should not crash the app if the response is invalid JSON', () => {
let latestDocument: DocumentContents;
- const { docService, backend, locationService} = getServices('initial/doc');
- const connections = backend.connectionsArray;
+ const doc1 = { contents: 'doc 1' };
+ const { docService, locationService } = getServices('initial/doc');
docService.currentDocument.subscribe(doc => latestDocument = doc);
- connections[0].mockRespond(new Response(new ResponseOptions({ body: 'this is invalid JSON' })));
+ httpMock.expectOne({}).flush('this is invalid JSON');
expect(latestDocument.id).toEqual(FETCHING_ERROR_ID);
- const doc1 = { contents: 'doc 1' };
locationService.go('new/doc');
- connections[1].mockRespond(createResponse(doc1));
+ httpMock.expectOne({}).flush(doc1);
expect(latestDocument).toEqual(jasmine.objectContaining(doc1));
});
@@ -132,37 +142,30 @@ describe('DocumentService', () => {
const doc0 = { contents: 'doc 0' };
const doc1 = { contents: 'doc 1' };
- const { docService, backend, locationService} = getServices('url/0');
- const connections = backend.connectionsArray;
+ const { docService, locationService } = getServices('url/0');
subscription = docService.currentDocument.subscribe(doc => latestDocument = doc);
- expect(connections.length).toEqual(1);
- connections[0].mockRespond(createResponse(doc0));
+ httpMock.expectOne({}).flush(doc0);
expect(latestDocument).toEqual(jasmine.objectContaining(doc0));
subscription.unsubscribe();
- // modify the response so we can check that future subscriptions do not trigger another request
- connections[0].response.next(createResponse({ contents: 'error 0' }));
-
subscription = docService.currentDocument.subscribe(doc => latestDocument = doc);
locationService.go('url/1');
- expect(connections.length).toEqual(2);
- connections[1].mockRespond(createResponse(doc1));
+ httpMock.expectOne({}).flush(doc1);
expect(latestDocument).toEqual(jasmine.objectContaining(doc1));
subscription.unsubscribe();
- // modify the response so we can check that future subscriptions do not trigger another request
- connections[1].response.next(createResponse({ contents: 'error 1' }));
-
+ // This should not trigger a new request.
subscription = docService.currentDocument.subscribe(doc => latestDocument = doc);
locationService.go('url/0');
- expect(connections.length).toEqual(2);
+ httpMock.expectNone({});
expect(latestDocument).toEqual(jasmine.objectContaining(doc0));
subscription.unsubscribe();
+ // This should not trigger a new request.
subscription = docService.currentDocument.subscribe(doc => latestDocument = doc);
locationService.go('url/1');
- expect(connections.length).toEqual(2);
+ httpMock.expectNone({});
expect(latestDocument).toEqual(jasmine.objectContaining(doc1));
subscription.unsubscribe();
});
@@ -171,17 +174,18 @@ describe('DocumentService', () => {
describe('computeMap', () => {
it('should map the "empty" location to the correct document request', () => {
let latestDocument: DocumentContents;
- const { docService, backend } = getServices();
+ const { docService } = getServices();
+
docService.currentDocument.subscribe(doc => latestDocument = doc);
- expect(backend.connectionsArray[0].request.url).toEqual(CONTENT_URL_PREFIX + 'index.json');
+ httpMock.expectOne(CONTENT_URL_PREFIX + 'index.json');
});
it('should map the "folder" locations to the correct document request', () => {
- const { docService, backend, locationService} = getServices('guide');
+ const { docService } = getServices('guide');
docService.currentDocument.subscribe();
- expect(backend.connectionsArray[0].request.url).toEqual(CONTENT_URL_PREFIX + 'guide.json');
+ httpMock.expectOne(CONTENT_URL_PREFIX + 'guide.json');
});
});
});
diff --git a/aio/src/app/documents/document.service.ts b/aio/src/app/documents/document.service.ts
index c7617465f2..6ef931127f 100644
--- a/aio/src/app/documents/document.service.ts
+++ b/aio/src/app/documents/document.service.ts
@@ -1,11 +1,10 @@
import { Injectable } from '@angular/core';
-import { Http, Response } from '@angular/http';
+import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { AsyncSubject } from 'rxjs/AsyncSubject';
import { of } from 'rxjs/observable/of';
import 'rxjs/add/operator/catch';
-import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import { DocumentContents } from './document-contents';
@@ -41,7 +40,7 @@ export class DocumentService {
constructor(
private logger: Logger,
- private http: Http,
+ private http: HttpClient,
location: LocationService) {
// Whenever the URL changes we try to get the appropriate doc
this.currentDocument = location.currentPath.switchMap(path => this.getDocument(path));
@@ -58,15 +57,22 @@ export class DocumentService {
private fetchDocument(id: string): Observable {
const requestPath = `${DOC_CONTENT_URL_PREFIX}${id}.json`;
+ const subject = new AsyncSubject();
+
this.logger.log('fetching document from', requestPath);
- const subject = new AsyncSubject();
this.http
- .get(requestPath)
- .map(response => response.json())
- .catch((error: Response) => {
+ .get(requestPath, {responseType: 'json'})
+ .do(data => {
+ if (!data || typeof data !== 'object') {
+ this.logger.log('received invalid data:', data);
+ throw Error('Invalid data');
+ }
+ })
+ .catch((error: HttpErrorResponse) => {
return error.status === 404 ? this.getFileNotFoundDoc(id) : this.getErrorDoc(id, error);
})
.subscribe(subject);
+
return subject.asObservable();
}
@@ -83,7 +89,7 @@ export class DocumentService {
}
}
- private getErrorDoc(id: string, error: Response): Observable {
+ private getErrorDoc(id: string, error: HttpErrorResponse): Observable {
this.logger.error('Error fetching document', error);
this.cache.delete(id);
return Observable.of({
diff --git a/aio/src/app/embedded/api/api-list.component.spec.ts b/aio/src/app/embedded/api/api-list.component.spec.ts
index 118906a231..c62618c85c 100644
--- a/aio/src/app/embedded/api/api-list.component.spec.ts
+++ b/aio/src/app/embedded/api/api-list.component.spec.ts
@@ -26,10 +26,6 @@ describe('ApiListComponent', () => {
sections = getApiSections();
});
- it('should be creatable', () => {
- expect(component).toBeDefined();
- });
-
/**
* Expectation Utility: Assert that filteredSections has the expected result for this test
* @param itemTest - return true if the item passes the match test
diff --git a/aio/src/app/embedded/api/api.service.spec.ts b/aio/src/app/embedded/api/api.service.spec.ts
index c7bf9b060c..a8452c5469 100644
--- a/aio/src/app/embedded/api/api.service.spec.ts
+++ b/aio/src/app/embedded/api/api.service.spec.ts
@@ -1,6 +1,6 @@
-import { ReflectiveInjector } from '@angular/core';
-import { Http, ConnectionBackend, RequestOptions, BaseRequestOptions, Response, ResponseOptions } from '@angular/http';
-import { MockBackend, MockConnection } from '@angular/http/testing';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { Injector } from '@angular/core';
+import { TestBed, inject } from '@angular/core/testing';
import { Logger } from 'app/shared/logger.service';
@@ -8,35 +8,27 @@ import { ApiService } from './api.service';
describe('ApiService', () => {
- let injector: ReflectiveInjector;
+ let injector: Injector;
let service: ApiService;
- let backend: MockBackend;
-
- function createResponse(body: any) {
- return new Response(new ResponseOptions({ body: JSON.stringify(body) }));
- }
+ let httpMock: HttpTestingController;
beforeEach(() => {
- injector = ReflectiveInjector.resolveAndCreate([
- ApiService,
- { provide: ConnectionBackend, useClass: MockBackend },
- { provide: RequestOptions, useClass: BaseRequestOptions },
- Http,
- { provide: Logger, useClass: TestLogger }
- ]);
- });
+ injector = TestBed.configureTestingModule({
+ imports: [HttpClientTestingModule],
+ providers: [
+ ApiService,
+ { provide: Logger, useClass: TestLogger }
+ ]
+ });
- beforeEach(() => {
- backend = injector.get(ConnectionBackend);
service = injector.get(ApiService);
+ httpMock = injector.get(HttpTestingController);
});
- it('should be creatable', () => {
- expect(service).toBeTruthy();
- });
+ afterEach(() => httpMock.verify());
it('should not immediately connect to the server', () => {
- expect(backend.connectionsArray.length).toEqual(0);
+ httpMock.expectNone({});
});
it('subscribers should be completed/unsubscribed when service destroyed', () => {
@@ -50,9 +42,13 @@ describe('ApiService', () => {
service.ngOnDestroy();
expect(completed).toBe(true);
+
+ // Stop `httpMock.verify()` from complaining.
+ httpMock.expectOne({});
});
describe('#sections', () => {
+
it('first subscriber should fetch sections', () => {
const data = [{name: 'a', title: 'A', items: []}, {name: 'b', title: 'B', items: []}];
@@ -60,7 +56,7 @@ describe('ApiService', () => {
expect(sections).toEqual(data);
});
- backend.connectionsArray[0].mockRespond(createResponse(data));
+ httpMock.expectOne({}).flush(data);
});
it('second subscriber should get previous sections and NOT trigger refetch', () => {
@@ -77,27 +73,20 @@ describe('ApiService', () => {
expect(sections).toEqual(data);
});
- backend.connectionsArray[0].mockRespond(createResponse(data));
-
- expect(backend.connectionsArray.length).toBe(1, 'server connections');
- expect(subscriptions).toBe(2, 'subscriptions');
+ httpMock.expectOne({}).flush(data);
});
-
});
describe('#fetchSections', () => {
it('should connect to the server w/ expected URL', () => {
service.fetchSections();
- expect(backend.connectionsArray.length).toEqual(1);
- expect(backend.connectionsArray[0].request.url).toEqual('generated/docs/api/api-list.json');
+ httpMock.expectOne('generated/docs/api/api-list.json');
});
it('should refresh the #sections observable w/ new content on second call', () => {
let call = 0;
- let connection: MockConnection;
- backend.connections.subscribe(c => connection = c);
let data = [{name: 'a', title: 'A', items: []}, {name: 'b', title: 'B', items: []}];
@@ -107,12 +96,13 @@ describe('ApiService', () => {
// (2) after refresh
expect(sections).toEqual(data, 'call ' + call++);
});
- connection.mockRespond(createResponse(data));
+
+ httpMock.expectOne({}).flush(data);
// refresh/refetch
data = [{name: 'c', title: 'C', items: []}];
service.fetchSections();
- connection.mockRespond(createResponse(data));
+ httpMock.expectOne({}).flush(data);
expect(call).toBe(2, 'should be called twice');
});
diff --git a/aio/src/app/embedded/api/api.service.ts b/aio/src/app/embedded/api/api.service.ts
index 7c708d3265..32ee99baba 100644
--- a/aio/src/app/embedded/api/api.service.ts
+++ b/aio/src/app/embedded/api/api.service.ts
@@ -1,5 +1,5 @@
import { Injectable, OnDestroy } from '@angular/core';
-import { Http } from '@angular/http';
+import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { Subject } from 'rxjs/Subject';
@@ -54,7 +54,7 @@ export class ApiService implements OnDestroy {
return this._sections;
};
- constructor(private http: Http, private logger: Logger) { }
+ constructor(private http: HttpClient, private logger: Logger) { }
ngOnDestroy() {
this.onDestroy.next();
@@ -70,13 +70,12 @@ export class ApiService implements OnDestroy {
fetchSections(src?: string) {
// TODO: get URL by configuration?
const url = this.apiBase + (src || this.apiListJsonDefault);
- this.http.get(url)
+ this.http.get(url)
.takeUntil(this.onDestroy)
- .map(response => response.json())
.do(() => this.logger.log(`Got API sections from ${url}`))
.subscribe(
sections => this.sectionsSubject.next(sections),
- err => {
+ (err: HttpErrorResponse) => {
// Todo: handle error
this.logger.error(err);
throw err; // rethrow for now.
diff --git a/aio/src/app/embedded/contributor/contributor.service.spec.ts b/aio/src/app/embedded/contributor/contributor.service.spec.ts
index 8911f5d991..02b575a812 100644
--- a/aio/src/app/embedded/contributor/contributor.service.spec.ts
+++ b/aio/src/app/embedded/contributor/contributor.service.spec.ts
@@ -1,39 +1,33 @@
-import { ReflectiveInjector } from '@angular/core';
-import { Http, ConnectionBackend, RequestOptions, BaseRequestOptions, Response, ResponseOptions } from '@angular/http';
-import { MockBackend } from '@angular/http/testing';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { Injector } from '@angular/core';
+import { TestBed } from '@angular/core/testing';
import { ContributorService } from './contributor.service';
import { Contributor, ContributorGroup } from './contributors.model';
describe('ContributorService', () => {
- let injector: ReflectiveInjector;
- let backend: MockBackend;
+ let injector: Injector;
let contribService: ContributorService;
-
- function createResponse(body: any) {
- return new Response(new ResponseOptions({ body: JSON.stringify(body) }));
- }
+ let httpMock: HttpTestingController;
beforeEach(() => {
- injector = ReflectiveInjector.resolveAndCreate([
- ContributorService,
- { provide: ConnectionBackend, useClass: MockBackend },
- { provide: RequestOptions, useClass: BaseRequestOptions },
- Http
- ]);
+ injector = TestBed.configureTestingModule({
+ imports: [HttpClientTestingModule],
+ providers: [
+ ContributorService
+ ]
+ });
- backend = injector.get(ConnectionBackend);
contribService = injector.get(ContributorService);
+ httpMock = injector.get(HttpTestingController);
});
- it('should be creatable', () => {
- expect(contribService).toBeTruthy();
- });
+ afterEach(() => httpMock.verify());
it('should make a single connection to the server', () => {
- expect(backend.connectionsArray.length).toEqual(1);
- expect(backend.connectionsArray[0].request.url).toEqual('generated/contributors.json');
+ const req = httpMock.expectOne({});
+ expect(req.request.url).toBe('generated/contributors.json');
});
describe('#contributors', () => {
@@ -43,7 +37,7 @@ describe('ContributorService', () => {
beforeEach(() => {
testData = getTestContribs();
- backend.connectionsArray[0].mockRespond(createResponse(testData));
+ httpMock.expectOne({}).flush(testData);
contribService.contributors.subscribe(results => contribs = results);
});
@@ -70,55 +64,54 @@ describe('ContributorService', () => {
});
function getTestContribs() {
- // tslint:disable:quotemark
return {
- "kapunahelewong": {
- "name": "Kapunahele Wong",
- "picture": "kapunahelewong.jpg",
- "website": " https://github.com/kapunahelewong",
- "twitter": "kapunahele",
- "bio": "Kapunahele is a front-end developer and contributor to angular.io",
- "group": "GDE"
+ kapunahelewong: {
+ name: 'Kapunahele Wong',
+ picture: 'kapunahelewong.jpg',
+ website: 'https://github.com/kapunahelewong',
+ twitter: 'kapunahele',
+ bio: 'Kapunahele is a front-end developer and contributor to angular.io',
+ group: 'GDE'
},
- "misko": {
- "name": "Miško Hevery",
- "picture": "misko.jpg",
- "twitter": "mhevery",
- "website": "http://misko.hevery.com",
- "bio": "Miško Hevery is the creator of AngularJS framework.",
- "group": "Angular"
+ misko: {
+ name: 'Miško Hevery',
+ picture: 'misko.jpg',
+ twitter: 'mhevery',
+ website: 'http://misko.hevery.com',
+ bio: 'Miško Hevery is the creator of AngularJS framework.',
+ group: 'Angular'
},
- "igor": {
- "name": "Igor Minar",
- "picture": "igor-minar.jpg",
- "twitter": "IgorMinar",
- "website": "https://google.com/+IgorMinar",
- "bio": "Igor is a software engineer at Angular.",
- "group": "Angular"
+ igor: {
+ name: 'Igor Minar',
+ picture: 'igor-minar.jpg',
+ twitter: 'IgorMinar',
+ website: 'https://google.com/+IgorMinar',
+ bio: 'Igor is a software engineer at Angular.',
+ group: 'Angular'
},
- "kara": {
- "name": "Kara Erickson",
- "picture": "kara-erickson.jpg",
- "twitter": "karaforthewin",
- "website": "https://github.com/kara",
- "bio": "Kara is a software engineer on the Angular team at Angular and a co-organizer of the Angular-SF Meetup. ",
- "group": "Angular"
+ kara: {
+ name: 'Kara Erickson',
+ picture: 'kara-erickson.jpg',
+ twitter: 'karaforthewin',
+ website: 'https://github.com/kara',
+ bio: 'Kara is a software engineer on the Angular team at Angular and a co-organizer of the Angular-SF Meetup. ',
+ group: 'Angular'
},
- "jeffcross": {
- "name": "Jeff Cross",
- "picture": "jeff-cross.jpg",
- "twitter": "jeffbcross",
- "website": "https://twitter.com/jeffbcross",
- "bio": "Jeff was one of the earliest core team members on AngularJS.",
- "group": "GDE"
+ jeffcross: {
+ name: 'Jeff Cross',
+ picture: 'jeff-cross.jpg',
+ twitter: 'jeffbcross',
+ website: 'https://twitter.com/jeffbcross',
+ bio: 'Jeff was one of the earliest core team members on AngularJS.',
+ group: 'GDE'
},
- "naomi": {
- "name": "Naomi Black",
- "picture": "naomi.jpg",
- "twitter": "naomitraveller",
- "website": "http://google.com/+NaomiBlack",
- "bio": "Naomi is Angular's TPM generalist and jack-of-all-trades.",
- "group": "Angular"
+ naomi: {
+ name: 'Naomi Black',
+ picture: 'naomi.jpg',
+ twitter: 'naomitraveller',
+ website: 'http://google.com/+NaomiBlack',
+ bio: 'Naomi is Angular\'s TPM generalist and jack-of-all-trades.',
+ group: 'Angular'
}
};
}
diff --git a/aio/src/app/embedded/contributor/contributor.service.ts b/aio/src/app/embedded/contributor/contributor.service.ts
index 08cbb010ab..3ae09b353b 100644
--- a/aio/src/app/embedded/contributor/contributor.service.ts
+++ b/aio/src/app/embedded/contributor/contributor.service.ts
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
-import { Http } from '@angular/http';
+import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
@@ -15,14 +15,12 @@ const knownGroups = ['Angular', 'GDE'];
export class ContributorService {
contributors: Observable;
- constructor(private http: Http) {
+ constructor(private http: HttpClient) {
this.contributors = this.getContributors();
}
private getContributors() {
- const contributors = this.http.get(contributorsPath)
- .map(res => res.json())
-
+ const contributors = this.http.get<{[key: string]: Contributor}>(contributorsPath)
// Create group map
.map(contribs => {
const contribMap = new Map();
diff --git a/aio/src/app/embedded/resource/resource.service.spec.ts b/aio/src/app/embedded/resource/resource.service.spec.ts
index 273a8847da..e08e2ace26 100644
--- a/aio/src/app/embedded/resource/resource.service.spec.ts
+++ b/aio/src/app/embedded/resource/resource.service.spec.ts
@@ -1,39 +1,33 @@
-import { ReflectiveInjector } from '@angular/core';
-import { Http, ConnectionBackend, RequestOptions, BaseRequestOptions, Response, ResponseOptions } from '@angular/http';
-import { MockBackend } from '@angular/http/testing';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { Injector } from '@angular/core';
+import { TestBed } from '@angular/core/testing';
import { ResourceService } from './resource.service';
import { Category, SubCategory, Resource } from './resource.model';
describe('ResourceService', () => {
- let injector: ReflectiveInjector;
- let backend: MockBackend;
+ let injector: Injector;
let resourceService: ResourceService;
-
- function createResponse(body: any) {
- return new Response(new ResponseOptions({ body: JSON.stringify(body) }));
- }
+ let httpMock: HttpTestingController;
beforeEach(() => {
- injector = ReflectiveInjector.resolveAndCreate([
- ResourceService,
- { provide: ConnectionBackend, useClass: MockBackend },
- { provide: RequestOptions, useClass: BaseRequestOptions },
- Http
- ]);
+ injector = TestBed.configureTestingModule({
+ imports: [HttpClientTestingModule],
+ providers: [
+ ResourceService
+ ]
+ });
- backend = injector.get(ConnectionBackend);
resourceService = injector.get(ResourceService);
+ httpMock = injector.get(HttpTestingController);
});
- it('should be creatable', () => {
- expect(resourceService).toBeTruthy();
- });
+ afterEach(() => httpMock.verify());
it('should make a single connection to the server', () => {
- expect(backend.connectionsArray.length).toEqual(1);
- expect(backend.connectionsArray[0].request.url).toEqual('generated/resources.json');
+ const req = httpMock.expectOne({});
+ expect(req.request.url).toBe('generated/resources.json');
});
describe('#categories', () => {
@@ -43,7 +37,7 @@ describe('ResourceService', () => {
beforeEach(() => {
testData = getTestResources();
- backend.connectionsArray[0].mockRespond(createResponse(testData));
+ httpMock.expectOne({}).flush(testData);
resourceService.categories.subscribe(results => categories = results);
});
diff --git a/aio/src/app/embedded/resource/resource.service.ts b/aio/src/app/embedded/resource/resource.service.ts
index 3ce85a1b55..ff64c51e6f 100644
--- a/aio/src/app/embedded/resource/resource.service.ts
+++ b/aio/src/app/embedded/resource/resource.service.ts
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
-import { Http } from '@angular/http';
+import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
@@ -14,14 +14,13 @@ const resourcesPath = CONTENT_URL_PREFIX + 'resources.json';
export class ResourceService {
categories: Observable;
- constructor(private http: Http) {
+ constructor(private http: HttpClient) {
this.categories = this.getCategories();
}
private getCategories(): Observable {
- const categories = this.http.get(resourcesPath)
- .map(res => res.json())
+ const categories = this.http.get(resourcesPath)
.map(data => mkCategories(data))
.publishLast();
diff --git a/aio/src/app/navigation/navigation.service.spec.ts b/aio/src/app/navigation/navigation.service.spec.ts
index 09e1d2dcde..9a4e3dc7cd 100644
--- a/aio/src/app/navigation/navigation.service.spec.ts
+++ b/aio/src/app/navigation/navigation.service.spec.ts
@@ -1,44 +1,37 @@
-import { ReflectiveInjector } from '@angular/core';
-import { Http, ConnectionBackend, RequestOptions, BaseRequestOptions, Response, ResponseOptions } from '@angular/http';
-import { MockBackend } from '@angular/http/testing';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { Injector } from '@angular/core';
+import { TestBed } from '@angular/core/testing';
+
import { CurrentNodes, NavigationService, NavigationViews, NavigationNode, VersionInfo } from 'app/navigation/navigation.service';
import { LocationService } from 'app/shared/location.service';
import { MockLocationService } from 'testing/location.service';
describe('NavigationService', () => {
- let injector: ReflectiveInjector;
- let backend: MockBackend;
+ let injector: Injector;
let navService: NavigationService;
-
- function createResponse(body: any) {
- return new Response(new ResponseOptions({ body: JSON.stringify(body) }));
- }
+ let httpMock: HttpTestingController;
beforeEach(() => {
- injector = ReflectiveInjector.resolveAndCreate([
+ injector = TestBed.configureTestingModule({
+ imports: [HttpClientTestingModule],
+ providers: [
NavigationService,
- { provide: LocationService, useFactory: () => new MockLocationService('a') },
- { provide: ConnectionBackend, useClass: MockBackend },
- { provide: RequestOptions, useClass: BaseRequestOptions },
- Http
- ]);
- });
+ { provide: LocationService, useFactory: () => new MockLocationService('a') }
+ ]
+ });
- beforeEach(() => {
- backend = injector.get(ConnectionBackend);
navService = injector.get(NavigationService);
+ httpMock = injector.get(HttpTestingController);
});
- it('should be creatable', () => {
- expect(navService).toBeTruthy();
- });
+ afterEach(() => httpMock.verify());
describe('navigationViews', () => {
it('should make a single connection to the server', () => {
- expect(backend.connectionsArray.length).toEqual(1);
- expect(backend.connectionsArray[0].request.url).toEqual('generated/navigation.json');
+ const req = httpMock.expectOne({});
+ expect(req.request.url).toBe('generated/navigation.json');
});
it('should expose the server response', () => {
@@ -46,7 +39,7 @@ describe('NavigationService', () => {
navService.navigationViews.subscribe(views => viewsEvents.push(views));
expect(viewsEvents).toEqual([]);
- backend.connectionsArray[0].mockRespond(createResponse({ TopBar: [ { url: 'a' }] }));
+ httpMock.expectOne({}).flush({ TopBar: [ { url: 'a' }] });
expect(viewsEvents).toEqual([{ TopBar: [ { url: 'a' }] }]);
});
@@ -54,6 +47,9 @@ describe('NavigationService', () => {
let completed = false;
navService.navigationViews.subscribe(null, null, () => completed = true);
expect(true).toBe(true, 'observable completed');
+
+ // Stop `$httpMock.verify()` from complaining.
+ httpMock.expectOne({});
});
it('should return the same object to all subscribers', () => {
@@ -63,16 +59,16 @@ describe('NavigationService', () => {
let views2: NavigationViews;
navService.navigationViews.subscribe(views => views2 = views);
- backend.connectionsArray[0].mockRespond(createResponse({ TopBar: [{ url: 'a' }] }));
-
- // modify the response so we can check that future subscriptions do not trigger another request
- backend.connectionsArray[0].response.next(createResponse({ TopBar: [{ url: 'error 1' }] }));
+ httpMock.expectOne({}).flush({ TopBar: [{ url: 'a' }] });
let views3: NavigationViews;
navService.navigationViews.subscribe(views => views3 = views);
expect(views2).toBe(views1);
expect(views3).toBe(views1);
+
+ // Verfy that subsequent subscriptions did not trigger another request.
+ httpMock.expectNone({});
});
it('should do WHAT(?) if the request fails');
@@ -90,7 +86,7 @@ describe('NavigationService', () => {
beforeEach(() => {
navService.navigationViews.subscribe(views => view = views['sideNav']);
- backend.connectionsArray[0].mockRespond(createResponse({sideNav}));
+ httpMock.expectOne({}).flush({sideNav});
});
it('should have the supplied tooltip', () => {
@@ -135,9 +131,9 @@ describe('NavigationService', () => {
};
beforeEach(() => {
- locationService = injector.get(LocationService);
+ locationService = injector.get(LocationService) as any as MockLocationService;
navService.currentNodes.subscribe(selected => currentNodes = selected);
- backend.connectionsArray[0].mockRespond(createResponse(navJson));
+ httpMock.expectOne({}).flush(navJson);
});
it('should list the side navigation node that matches the current location, and all its ancestors', () => {
@@ -231,9 +227,9 @@ describe('NavigationService', () => {
beforeEach(() => {
navService.versionInfo.subscribe(info => versionInfo = info);
- backend.connectionsArray[0].mockRespond(createResponse({
+ httpMock.expectOne({}).flush({
__versionInfo: expectedVersionInfo
- }));
+ });
});
it('should extract the version info', () => {
@@ -261,7 +257,7 @@ describe('NavigationService', () => {
});
it('should extract the docVersions', () => {
- backend.connectionsArray[0].mockRespond(createResponse({ docVersions }));
+ httpMock.expectOne({}).flush({ docVersions });
expect(actualDocVersions).toEqual(expectedDocVersions);
});
});
diff --git a/aio/src/app/navigation/navigation.service.ts b/aio/src/app/navigation/navigation.service.ts
index 3c665f4ef2..eddcbca91c 100644
--- a/aio/src/app/navigation/navigation.service.ts
+++ b/aio/src/app/navigation/navigation.service.ts
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
-import { Http } from '@angular/http';
+import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { AsyncSubject } from 'rxjs/AsyncSubject';
@@ -36,7 +36,7 @@ export class NavigationService {
*/
currentNodes: Observable;
- constructor(private http: Http, private location: LocationService) {
+ constructor(private http: HttpClient, private location: LocationService) {
const navigationInfo = this.fetchNavigationInfo();
this.navigationViews = this.getNavigationViews(navigationInfo);
@@ -57,8 +57,7 @@ export class NavigationService {
* We are not storing the subscription from connecting as we do not expect this service to be destroyed.
*/
private fetchNavigationInfo(): Observable {
- const navigationInfo = this.http.get(navigationPath)
- .map(res => res.json() as NavigationResponse)
+ const navigationInfo = this.http.get(navigationPath)
.publishLast();
navigationInfo.connect();
return navigationInfo;
diff --git a/aio/src/app/shared/custom-md-icon-registry.spec.ts b/aio/src/app/shared/custom-md-icon-registry.spec.ts
index d7a1db03b0..30480555bd 100644
--- a/aio/src/app/shared/custom-md-icon-registry.spec.ts
+++ b/aio/src/app/shared/custom-md-icon-registry.spec.ts
@@ -12,7 +12,7 @@ describe('CustomMdIconRegistry', () => {
];
const registry = new CustomMdIconRegistry(mockHttp, mockSanitizer, svgIcons);
let svgElement: SVGElement;
- registry.getNamedSvgIcon('test_icon', null).subscribe(el => svgElement = el as SVGElement);
+ registry.getNamedSvgIcon('test_icon').subscribe(el => svgElement = el);
expect(svgElement).toEqual(createSvg(svgSrc));
});
@@ -27,8 +27,12 @@ describe('CustomMdIconRegistry', () => {
spyOn(MdIconRegistry.prototype, 'getNamedSvgIcon');
const registry = new CustomMdIconRegistry(mockHttp, mockSanitizer, svgIcons);
- registry.getNamedSvgIcon('other_icon', null);
- expect(MdIconRegistry.prototype.getNamedSvgIcon).toHaveBeenCalledWith('other_icon', null);
+
+ registry.getNamedSvgIcon('other_icon');
+ expect(MdIconRegistry.prototype.getNamedSvgIcon).toHaveBeenCalledWith('other_icon', undefined);
+
+ registry.getNamedSvgIcon('other_icon', 'foo');
+ expect(MdIconRegistry.prototype.getNamedSvgIcon).toHaveBeenCalledWith('other_icon', 'foo');
});
});
diff --git a/aio/src/app/shared/custom-md-icon-registry.ts b/aio/src/app/shared/custom-md-icon-registry.ts
index 77b05d9169..e2a901d464 100644
--- a/aio/src/app/shared/custom-md-icon-registry.ts
+++ b/aio/src/app/shared/custom-md-icon-registry.ts
@@ -1,7 +1,7 @@
import { InjectionToken, Inject, Injectable } from '@angular/core';
import { of } from 'rxjs/observable/of';
import { MdIconRegistry } from '@angular/material';
-import { Http } from '@angular/http';
+import { HttpClient } from '@angular/common/http';
import { DomSanitizer } from '@angular/platform-browser';
/**
@@ -27,6 +27,19 @@ interface SvgIconMap {
[iconName: string]: SVGElement;
}
+//
+// @angular/material's `MdIconRegitry` currently (v2.0.0-beta.8) requires an instance of `Http`
+// (from @angular/http). It is only used to [get some text content][1], so we can create a wrapper
+// around `HttpClient` and pretend it is `Http`.
+// [1]: https://github.com/angular/material2/blob/2.0.0-beta.8/src/lib/icon/icon-registry.ts#L465-L466
+//
+function createFakeHttp(http: HttpClient): any {
+ return {
+ get: (url: string) => http.get(url, {responseType: 'text'})
+ .map(data => ({text: () => data}))
+ };
+}
+
/**
* A custom replacement for Angular Material's `MdIconRegistry`, which allows
* us to provide preloaded icon SVG sources.
@@ -35,14 +48,14 @@ interface SvgIconMap {
export class CustomMdIconRegistry extends MdIconRegistry {
private preloadedSvgElements: SvgIconMap = {};
- constructor(http: Http, sanitizer: DomSanitizer, @Inject(SVG_ICONS) svgIcons: SvgIconInfo[]) {
- super(http, sanitizer);
+ constructor(http: HttpClient, sanitizer: DomSanitizer, @Inject(SVG_ICONS) svgIcons: SvgIconInfo[]) {
+ super(createFakeHttp(http), sanitizer);
this.loadSvgElements(svgIcons);
}
- getNamedSvgIcon(iconName, namespace) {
+ getNamedSvgIcon(iconName: string, namespace?: string) {
if (this.preloadedSvgElements[iconName]) {
- return of(this.preloadedSvgElements[iconName].cloneNode(true));
+ return of(this.preloadedSvgElements[iconName].cloneNode(true) as SVGElement);
}
return super.getNamedSvgIcon(iconName, namespace);
}
diff --git a/aio/src/app/shared/scroll-spy.service.spec.ts b/aio/src/app/shared/scroll-spy.service.spec.ts
index 7c7702fa3f..c08f0d0e52 100644
--- a/aio/src/app/shared/scroll-spy.service.spec.ts
+++ b/aio/src/app/shared/scroll-spy.service.spec.ts
@@ -160,10 +160,6 @@ describe('ScrollSpyService', () => {
});
- it('should be creatable', () => {
- expect(scrollSpyService).toBeTruthy();
- });
-
describe('#spyOn()', () => {
let getSpiedElemGroups: () => ScrollSpiedElementGroup[];
diff --git a/aio/src/app/shared/toc.service.spec.ts b/aio/src/app/shared/toc.service.spec.ts
index a40385f4e1..85ca45480b 100644
--- a/aio/src/app/shared/toc.service.spec.ts
+++ b/aio/src/app/shared/toc.service.spec.ts
@@ -31,10 +31,6 @@ describe('TocService', () => {
tocService.tocList.subscribe(tocList => lastTocList = tocList);
});
- it('should be creatable', () => {
- expect(tocService).toBeTruthy();
- });
-
describe('tocList', () => {
it('should emit the latest value to new subscribers', () => {
const expectedValue1 = tocItem('Heading A');
diff --git a/aio/src/test.ts b/aio/src/test.ts
index 722acc0395..949eddf8d7 100644
--- a/aio/src/test.ts
+++ b/aio/src/test.ts
@@ -14,19 +14,19 @@ import {
} from '@angular/platform-browser-dynamic/testing';
// List vendors here to increase test rebuild performance.
+import '@angular/animations';
import '@angular/common';
import '@angular/common/testing';
+import '@angular/common/http';
+import '@angular/common/http/testing';
import '@angular/core/';
import '@angular/core/testing';
+import '@angular/material';
import '@angular/platform-browser';
import '@angular/platform-browser/testing';
import '@angular/platform-browser/animations';
import '@angular/platform-browser-dynamic';
import '@angular/platform-browser-dynamic/testing';
-import '@angular/http';
-import '@angular/http/testing';
-import '@angular/animations';
-import '@angular/material';
import '@angular/service-worker';
import 'rxjs'; // tslint:disable-line
diff --git a/aio/src/testing/nav-map-json-response.ts b/aio/src/testing/nav-map-json-response.ts
deleted file mode 100644
index a55acb6b50..0000000000
--- a/aio/src/testing/nav-map-json-response.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import { Response } from '@angular/http';
-
-// tslint:disable:quotemark
-export function getTestNavMapResponse(): Response {
-
- const navMapJson = { "nodes": [
- {
- "docId": "guide/quickstart",
- "navTitle": "Quickstart",
- "tooltip": "A quick look at an Angular app."
- },
-
- {
- "docId": "guide/cli-quickstart",
- "navTitle": "CLI Quickstart",
- "tooltip": "A quick look at an Angular app built with the Angular CLI.",
- "hide": true // <----- SHOULD BE FILTERED OUT
- },
-
- {
- "navTitle": "Tutorial",
- "children": [
- {
- "docId": " tutorial/",
- "navTitle": "Introduction",
- "tooltip": "Introduction to the Tour of Heroes tutorial"
- },
- {
- "docId": "tutorial/toh-pt1",
- "navTitle": "The Hero Editor",
- "tooltip": "Build a simple hero editor."
- }
- ]
- },
-
- {
- "navTitle": "Getting started",
- "tooltip": "A gentle introduction to Angular",
- "children": [
- {
- "docId": "guide/docs-overview",
- "navTitle": "Overview",
- "tooltip": "How to read and use this documentation."
- },
- {
- "docId": "guide/setup",
- "navTitle": "Setup",
- "tooltip": "Install the Angular QuickStart seed for faster, more efficient development on your machine."
- }
- ]
- },
-
- {
- "navTitle": "Core",
- "tooltip": "Learn the core capabilities of Angular",
- "children": [
- {
- "docId": "guide/NgModule",
- "navTitle": "Angular Modules (NgModule)",
- "tooltip": "Define application modules with @NgModule."
- },
- {
- "docId": "guide/directives",
- "navTitle": "Directives",
- "tooltip": "Learn how directives modify the layout and behavior of elements.",
- "children": [
- {
- "docId": "guide/attribute-directives",
- "navTitle": "Attribute directives",
- "tooltip": "Attribute directives attach behavior to elements."
- },
- {
- "docId": "guide/structural-directives",
- "navTitle": "Structural directives",
- "tooltip": "Structural directives manipulate the layout of the page."
- }
- ]
- }
- ]
- },
- {
- "navTitle": "Empty Heading",
- "children": [ ]
- },
- {
- "navTitle": "External",
- "children": [
- {
- "url": "https://gitter.im/angular/angular",
- "navTitle": "Gitter",
- "tooltip": "Chat about Angular with other birds of a feather"
- }
- ]
- }
- ]};
-
- // tslint:enable:quotemark
- return {
- status: 200,
- json: () => navMapJson
- } as Response;
-}
diff --git a/aio/yarn.lock b/aio/yarn.lock
index 9f6de42c1f..6efafbcf82 100644
--- a/aio/yarn.lock
+++ b/aio/yarn.lock
@@ -168,7 +168,7 @@
base64-js "^1.1.2"
jshashes "^1.0.5"
-"@angular/tsc-wrapped@^5.0.0-beta.3":
+"@angular/tsc-wrapped@5.0.0-beta.3":
version "5.0.0-beta.3"
resolved "https://registry.yarnpkg.com/@angular/tsc-wrapped/-/tsc-wrapped-5.0.0-beta.3.tgz#d71c607b02eb6fe7091b908ef2ec97180ec52618"
dependencies: