From 807648251f14cddd56c297012c845beed1ec0f0b Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Tue, 18 Jul 2017 12:45:47 -0700 Subject: [PATCH] fix(platform-server): provide XhrFactory for HttpClient --- packages/platform-server/src/http.ts | 10 ++-- .../platform-server/test/integration_spec.ts | 50 +++++++++++++++++++ 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/packages/platform-server/src/http.ts b/packages/platform-server/src/http.ts index dd77fb06c9..b2ad9bd7b8 100644 --- a/packages/platform-server/src/http.ts +++ b/packages/platform-server/src/http.ts @@ -11,7 +11,7 @@ const xhr2: any = require('xhr2'); import {Injectable, Optional, Provider} from '@angular/core'; import {BrowserXhr, Connection, ConnectionBackend, Http, ReadyState, Request, RequestOptions, Response, XHRBackend, XSRFStrategy} from '@angular/http'; -import {HttpClient, HttpRequest, HttpHandler, HttpInterceptor, HttpResponse, HTTP_INTERCEPTORS, HttpBackend, XhrFactory, ɵinterceptingHandler as interceptingHandler} from '@angular/common/http'; +import {HttpClient, HttpEvent, HttpRequest, HttpHandler, HttpInterceptor, HttpResponse, HTTP_INTERCEPTORS, HttpBackend, XhrFactory, ɵinterceptingHandler as interceptingHandler} from '@angular/common/http'; import {Observable} from 'rxjs/Observable'; import {Observer} from 'rxjs/Observer'; @@ -143,12 +143,12 @@ export class ZoneMacroTaskBackend implements ConnectionBackend { } export class ZoneClientBackend extends - ZoneMacroTaskWrapper, HttpResponse> implements HttpBackend { + ZoneMacroTaskWrapper, HttpEvent> implements HttpBackend { constructor(private backend: HttpBackend) { super(); } - handle(request: HttpRequest): Observable> { return this.wrap(request); } + handle(request: HttpRequest): Observable> { return this.wrap(request); } - protected delegate(request: HttpRequest): Observable> { + protected delegate(request: HttpRequest): Observable> { return this.backend.handle(request); } } @@ -167,7 +167,7 @@ export function zoneWrappedInterceptingHandler( export const SERVER_HTTP_PROVIDERS: Provider[] = [ {provide: Http, useFactory: httpFactory, deps: [XHRBackend, RequestOptions]}, {provide: BrowserXhr, useClass: ServerXhr}, {provide: XSRFStrategy, useClass: ServerXsrfStrategy}, - { + {provide: XhrFactory, useClass: ServerXhr}, { provide: HttpHandler, useFactory: zoneWrappedInterceptingHandler, deps: [HttpBackend, [new Optional(), HTTP_INTERCEPTORS]] diff --git a/packages/platform-server/test/integration_spec.ts b/packages/platform-server/test/integration_spec.ts index 920f221ffd..92992bcff9 100644 --- a/packages/platform-server/test/integration_spec.ts +++ b/packages/platform-server/test/integration_spec.ts @@ -8,6 +8,8 @@ import {animate, style, transition, trigger} from '@angular/animations'; import {APP_BASE_HREF, PlatformLocation, isPlatformServer} from '@angular/common'; +import {HttpClient, HttpClientModule} from '@angular/common/http'; +import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; import {ApplicationRef, CompilerFactory, Component, HostListener, Input, NgModule, NgModuleRef, NgZone, PLATFORM_ID, PlatformRef, ViewEncapsulation, destroyPlatform, getPlatform} from '@angular/core'; import {TestBed, async, inject} from '@angular/core/testing'; import {Http, HttpModule, Response, ResponseOptions, XHRBackend} from '@angular/http'; @@ -145,6 +147,14 @@ export class HttpBeforeExampleModule { export class HttpAfterExampleModule { } +@NgModule({ + bootstrap: [MyServerApp], + declarations: [MyServerApp], + imports: [ServerModule, HttpClientModule, HttpClientTestingModule], +}) +export class HttpClientExmapleModule { +} + @Component({selector: 'app', template: ``}) class ImageApp { } @@ -534,5 +544,45 @@ export function main() { }); })); }); + describe('HttpClient', () => { + it('can inject HttpClient', async(() => { + const platform = platformDynamicServer( + [{provide: INITIAL_CONFIG, useValue: {document: ''}}]); + platform.bootstrapModule(HttpClientExmapleModule).then(ref => { + expect(ref.injector.get(HttpClient) instanceof HttpClient).toBeTruthy(); + }); + })); + it('can make HttpClient requests', async(() => { + const platform = platformDynamicServer( + [{provide: INITIAL_CONFIG, useValue: {document: ''}}]); + platform.bootstrapModule(HttpClientExmapleModule).then(ref => { + const mock = ref.injector.get(HttpTestingController) as HttpTestingController; + const http = ref.injector.get(HttpClient); + ref.injector.get(NgZone).run(() => { + http.get('http://localhost/testing').subscribe(body => { + NgZone.assertInAngularZone(); + expect(body).toEqual('success!'); + }); + mock.expectOne('http://localhost/testing').flush('success!'); + }); + }); + })); + it('requests are macrotasks', async(() => { + const platform = platformDynamicServer( + [{provide: INITIAL_CONFIG, useValue: {document: ''}}]); + platform.bootstrapModule(HttpClientExmapleModule).then(ref => { + const mock = ref.injector.get(HttpTestingController) as HttpTestingController; + const http = ref.injector.get(HttpClient); + ref.injector.get(NgZone).run(() => { + http.get('http://localhost/testing').subscribe(body => { + expect(body).toEqual('success!'); + }); + expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeTruthy(); + mock.expectOne('http://localhost/testing').flush('success!'); + expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeFalsy(); + }); + }); + })); + }); }); }