{"version":3,"file":"common-http-testing.umd.min.js","sources":["../../../../packages/common/http/testing/src/module.ts","../../../../packages/common/http/testing/src/request.ts","../../../../packages/common/http/testing/src/backend.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nimport {HttpBackend, HttpClientModule} from '@angular/common/http';\nimport {NgModule} from '@angular/core';\n\nimport {HttpTestingController} from './api';\nimport {HttpClientTestingBackend} from './backend';\n/**\n * Configures `HttpClientTestingBackend` as the `HttpBackend` used by `HttpClient`.\n * \n * Inject `HttpTestingController` to expect and flush requests in your tests.\n * \n * \\@experimental\n */\nexport class HttpClientTestingModule {\nstatic decorators: DecoratorInvocation[] = [\n{ type: NgModule, args: [{\n imports: [\n HttpClientModule,\n ],\n providers: [\n HttpClientTestingBackend,\n {provide: HttpBackend, useExisting: HttpClientTestingBackend},\n {provide: HttpTestingController, useExisting: HttpClientTestingBackend},\n ],\n}, ] },\n];\n/**\n * @nocollapse\n */\nstatic ctorParameters: () => ({type: any, decorators?: DecoratorInvocation[]}|null)[] = () => [\n];\n}\n\nfunction HttpClientTestingModule_tsickle_Closure_declarations() {\n/** @type {?} */\nHttpClientTestingModule.decorators;\n/**\n * @nocollapse\n * @type {?}\n */\nHttpClientTestingModule.ctorParameters;\n}\n\n\ninterface DecoratorInvocation {\n type: Function;\n args?: any[];\n}\n","/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nimport {HttpErrorResponse, HttpEvent, HttpEventType, HttpHeaders, HttpRequest, HttpResponse} from '@angular/common/http';\nimport {Observer} from 'rxjs/Observer';\n/**\n * A mock requests that was received and is ready to be answered.\n * \n * This interface allows access to the underlying `HttpRequest`, and allows\n * responding with `HttpEvent`s or `HttpErrorResponse`s.\n * \n * \\@experimental\n */\nexport class TestRequest {\n/**\n * Whether the request was cancelled after it was sent.\n * @return {?}\n */\nget cancelled(): boolean { return this._cancelled; }\n/**\n * \\@internal set by `HttpClientTestingBackend`\n */\n_cancelled = false;\n/**\n * @param {?} request\n * @param {?} observer\n */\nconstructor(public request: HttpRequest,\nprivate observer: Observer>) {}\n/**\n * Resolve the request by returning a body plus additional HTTP information (such as response\n * headers) if provided.\n * \n * Both successful and unsuccessful responses can be delivered via `flush()`.\n * @param {?} body\n * @param {?=} opts\n * @return {?}\n */\nflush(body: ArrayBuffer|Blob|string|number|Object|(string|number|Object|null)[]|null, opts: {\n headers?: HttpHeaders | {[name: string]: string | string[]},\n status?: number,\n statusText?: string,\n } = {}): void {\n if (this.cancelled) {\n throw new Error(`Cannot flush a cancelled request.`);\n }\n const /** @type {?} */ url = this.request.urlWithParams;\n const /** @type {?} */ headers =\n (opts.headers instanceof HttpHeaders) ? opts.headers : new HttpHeaders(opts.headers);\n body = _maybeConvertBody(this.request.responseType, body);\n let /** @type {?} */ statusText: string|undefined = opts.statusText;\n let /** @type {?} */ status: number = opts.status !== undefined ? opts.status : 200;\n if (opts.status === undefined) {\n if (body === null) {\n status = 204;\n statusText = statusText || 'No Content';\n } else {\n statusText = statusText || 'OK';\n }\n }\n if (statusText === undefined) {\n throw new Error('statusText is required when setting a custom status.');\n }\n if (status >= 200 && status < 300) {\n this.observer.next(new HttpResponse({body, headers, status, statusText, url}));\n this.observer.complete();\n } else {\n this.observer.error(new HttpErrorResponse({error: body, headers, status, statusText, url}));\n }\n }\n/**\n * Resolve the request by returning an `ErrorEvent` (e.g. simulating a network failure).\n * @param {?} error\n * @param {?=} opts\n * @return {?}\n */\nerror(error: ErrorEvent, opts: {\n headers?: HttpHeaders | {[name: string]: string | string[]},\n status?: number,\n statusText?: string,\n } = {}): void {\n if (this.cancelled) {\n throw new Error(`Cannot return an error for a cancelled request.`);\n }\n if (opts.status && opts.status >= 200 && opts.status < 300) {\n throw new Error(`error() called with a successful status.`);\n }\n const /** @type {?} */ headers =\n (opts.headers instanceof HttpHeaders) ? opts.headers : new HttpHeaders(opts.headers);\n this.observer.error(new HttpErrorResponse({\n error,\n headers,\n status: opts.status || 0,\n statusText: opts.statusText || '',\n url: this.request.urlWithParams,\n }));\n }\n/**\n * Deliver an arbitrary `HttpEvent` (such as a progress event) on the response stream for this\n * request.\n * @param {?} event\n * @return {?}\n */\nevent(event: HttpEvent): void {\n if (this.cancelled) {\n throw new Error(`Cannot send events to a cancelled request.`);\n }\n this.observer.next(event);\n }\n}\n\nfunction TestRequest_tsickle_Closure_declarations() {\n/**\n * \\@internal set by `HttpClientTestingBackend`\n * @type {?}\n */\nTestRequest.prototype._cancelled;\n/** @type {?} */\nTestRequest.prototype.request;\n/** @type {?} */\nTestRequest.prototype.observer;\n}\n\n/**\n * Helper function to convert a response body to an ArrayBuffer.\n * @param {?} body\n * @return {?}\n */\nfunction _toArrayBufferBody(\n body: ArrayBuffer | Blob | string | number | Object |\n (string | number | Object | null)[]): ArrayBuffer {\n if (typeof ArrayBuffer === 'undefined') {\n throw new Error('ArrayBuffer responses are not supported on this platform.');\n }\n if (body instanceof ArrayBuffer) {\n return body;\n }\n throw new Error('Automatic conversion to ArrayBuffer is not supported for response type.');\n}\n/**\n * Helper function to convert a response body to a Blob.\n * @param {?} body\n * @return {?}\n */\nfunction _toBlob(\n body: ArrayBuffer | Blob | string | number | Object |\n (string | number | Object | null)[]): Blob {\n if (typeof Blob === 'undefined') {\n throw new Error('Blob responses are not supported on this platform.');\n }\n if (body instanceof Blob) {\n return body;\n }\n if (ArrayBuffer && body instanceof ArrayBuffer) {\n return new Blob([body]);\n }\n throw new Error('Automatic conversion to Blob is not supported for response type.');\n}\n/**\n * Helper function to convert a response body to JSON data.\n * @param {?} body\n * @param {?=} format\n * @return {?}\n */\nfunction _toJsonBody(\n body: ArrayBuffer | Blob | string | number | Object | (string | number | Object | null)[],\n format: string = 'JSON'): Object|string|number|(Object | string | number)[] {\n if (typeof ArrayBuffer !== 'undefined' && body instanceof ArrayBuffer) {\n throw new Error(`Automatic conversion to ${format} is not supported for ArrayBuffers.`);\n }\n if (typeof Blob !== 'undefined' && body instanceof Blob) {\n throw new Error(`Automatic conversion to ${format} is not supported for Blobs.`);\n }\n if (typeof body === 'string' || typeof body === 'number' || typeof body === 'object' ||\n Array.isArray(body)) {\n return body;\n }\n throw new Error(`Automatic conversion to ${format} is not supported for response type.`);\n}\n/**\n * Helper function to convert a response body to a string.\n * @param {?} body\n * @return {?}\n */\nfunction _toTextBody(\n body: ArrayBuffer | Blob | string | number | Object |\n (string | number | Object | null)[]): string {\n if (typeof body === 'string') {\n return body;\n }\n if (typeof ArrayBuffer !== 'undefined' && body instanceof ArrayBuffer) {\n throw new Error('Automatic conversion to text is not supported for ArrayBuffers.');\n }\n if (typeof Blob !== 'undefined' && body instanceof Blob) {\n throw new Error('Automatic conversion to text is not supported for Blobs.');\n }\n return JSON.stringify(_toJsonBody(body, 'text'));\n}\n/**\n * Convert a response body to the requested type.\n * @param {?} responseType\n * @param {?} body\n * @return {?}\n */\nfunction _maybeConvertBody(\n responseType: string, body: ArrayBuffer | Blob | string | number | Object |\n (string | number | Object | null)[] | null): ArrayBuffer|Blob|string|number|Object|\n (string | number | Object | null)[]|null {\n switch (responseType) {\n case 'arraybuffer':\n if (body === null) {\n return null;\n }\n return _toArrayBufferBody(body);\n case 'blob':\n if (body === null) {\n return null;\n }\n return _toBlob(body);\n case 'json':\n if (body === null) {\n return 'null';\n }\n return _toJsonBody(body);\n case 'text':\n if (body === null) {\n return null;\n }\n return _toTextBody(body);\n default:\n throw new Error(`Unsupported responseType: ${responseType}`);\n }\n}\n","/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nimport {HttpBackend, HttpEvent, HttpEventType, HttpRequest} from '@angular/common/http';\nimport {Injectable} from '@angular/core';\nimport {Observable} from 'rxjs/Observable';\nimport {Observer} from 'rxjs/Observer';\nimport {startWith} from 'rxjs/operator/startWith';\n\nimport {HttpTestingController, RequestMatch} from './api';\nimport {TestRequest} from './request';\n/**\n * A testing backend for `HttpClient` which both acts as an `HttpBackend`\n * and as the `HttpTestingController`.\n * \n * `HttpClientTestingBackend` works by keeping a list of all open requests.\n * As requests come in, they're added to the list. Users can assert that specific\n * requests were made and then flush them. In the end, a verify() method asserts\n * that no unexpected requests were made.\n * \n * \\@experimental\n */\nexport class HttpClientTestingBackend implements HttpBackend, HttpTestingController {\n/**\n * List of pending requests which have not yet been expected.\n */\nprivate open: TestRequest[] = [];\n/**\n * Handle an incoming request by queueing it in the list of open requests.\n * @param {?} req\n * @return {?}\n */\nhandle(req: HttpRequest): Observable> {\n return new Observable((observer: Observer) => {\n const /** @type {?} */ testReq = new TestRequest(req, observer);\n this.open.push(testReq);\n observer.next( /** @type {?} */(({ type: HttpEventType.Sent } as HttpEvent)));\n return () => { testReq._cancelled = true; };\n });\n }\n/**\n * Helper function to search for requests in the list of open requests.\n * @param {?} match\n * @return {?}\n */\nprivate _match(match: string|RequestMatch|((req: HttpRequest) => boolean)): TestRequest[] {\n if (typeof match === 'string') {\n return this.open.filter(testReq => testReq.request.urlWithParams === match);\n } else if (typeof match === 'function') {\n return this.open.filter(testReq => match(testReq.request));\n } else {\n return this.open.filter(\n testReq => (!match.method || testReq.request.method === match.method.toUpperCase()) &&\n (!match.url || testReq.request.urlWithParams === match.url));\n }\n }\n/**\n * Search for requests in the list of open requests, and return all that match\n * without asserting anything about the number of matches.\n * @param {?} match\n * @return {?}\n */\nmatch(match: string|RequestMatch|((req: HttpRequest) => boolean)): TestRequest[] {\n const /** @type {?} */ results = this._match(match);\n results.forEach(result => {\n const /** @type {?} */ index = this.open.indexOf(result);\n if (index !== -1) {\n this.open.splice(index, 1);\n }\n });\n return results;\n }\n/**\n * Expect that a single outstanding request matches the given matcher, and return\n * it.\n * \n * Requests returned through this API will no longer be in the list of open requests,\n * and thus will not match twice.\n * @param {?} match\n * @param {?=} description\n * @return {?}\n */\nexpectOne(match: string|RequestMatch|((req: HttpRequest) => boolean), description?: string):\n TestRequest {\n description = description || this.descriptionFromMatcher(match);\n const /** @type {?} */ matches = this.match(match);\n if (matches.length > 1) {\n throw new Error(\n `Expected one matching request for criteria \"${description}\", found ${matches.length} requests.`);\n }\n if (matches.length === 0) {\n throw new Error(`Expected one matching request for criteria \"${description}\", found none.`);\n }\n return matches[0];\n }\n/**\n * Expect that no outstanding requests match the given matcher, and throw an error\n * if any do.\n * @param {?} match\n * @param {?=} description\n * @return {?}\n */\nexpectNone(match: string|RequestMatch|((req: HttpRequest) => boolean), description?: string):\n void {\n description = description || this.descriptionFromMatcher(match);\n const /** @type {?} */ matches = this.match(match);\n if (matches.length > 0) {\n throw new Error(\n `Expected zero matching requests for criteria \"${description}\", found ${matches.length}.`);\n }\n }\n/**\n * Validate that there are no outstanding requests.\n * @param {?=} opts\n * @return {?}\n */\nverify(opts: {ignoreCancelled?: boolean} = {}): void {\n let /** @type {?} */ open = this.open;\n // It's possible that some requests may be cancelled, and this is expected.\n // The user can ask to ignore open requests which have been cancelled.\n if (opts.ignoreCancelled) {\n open = open.filter(testReq => !testReq.cancelled);\n }\n if (open.length > 0) {\n // Show the methods and URLs of open requests in the error, for convenience.\n const /** @type {?} */ requests = open.map(testReq => {\n const /** @type {?} */ url = testReq.request.urlWithParams.split('?')[0];\n const /** @type {?} */ method = testReq.request.method;\n return `${method} ${url}`;\n })\n .join(', ');\n throw new Error(`Expected no open requests, found ${open.length}: ${requests}`);\n }\n }\n/**\n * @param {?} matcher\n * @return {?}\n */\nprivate descriptionFromMatcher(matcher: string|RequestMatch|\n ((req: HttpRequest) => boolean)): string {\n if (typeof matcher === 'string') {\n return `Match URL: ${matcher}`;\n } else if (typeof matcher === 'object') {\n const /** @type {?} */ method = matcher.method || '(any)';\n const /** @type {?} */ url = matcher.url || '(any)';\n return `Match method: ${method}, URL: ${url}`;\n } else {\n return `Match by function: ${matcher.name}`;\n }\n }\nstatic decorators: DecoratorInvocation[] = [\n{ type: Injectable },\n];\n/**\n * @nocollapse\n */\nstatic ctorParameters: () => ({type: any, decorators?: DecoratorInvocation[]}|null)[] = () => [\n];\n}\n\nfunction HttpClientTestingBackend_tsickle_Closure_declarations() {\n/** @type {?} */\nHttpClientTestingBackend.decorators;\n/**\n * @nocollapse\n * @type {?}\n */\nHttpClientTestingBackend.ctorParameters;\n/**\n * List of pending requests which have not yet been expected.\n * @type {?}\n */\nHttpClientTestingBackend.prototype.open;\n}\n\n\ninterface DecoratorInvocation {\n type: Function;\n args?: any[];\n}\n"],"names":["HttpClientTestingModule","HttpClientModule","decorators","type","_angular_core","NgModule","args","providers","this","observer","TestRequest","prototype","flush","body","opts","cancelled","Error","url","request","urlWithParams","headers","_angular_common_http","HttpHeaders","_maybeConvertBody","responseType","statusText","status","undefined","error","HttpClientTestingBackend","_match","match","expectOne","description","verify","open","ignoreCancelled","filter","testReq","length","descriptionFromMatcher","matcher","method","_toBlob","Blob","_toJsonBody","format","ArrayBuffer","_toTextBody","_toArrayBufferBody"],"mappings":";;;;;u4BCkKA,QAAA2C,SAAA9B,MACA,GAAA,mBAAA+B,wQAkBA,QAAAC,aAAAhC,KAAAiC,QAEA,OADA,KAAAA,SAAAA,OAAA,QACA,mBAAAC,cAAAlC,eAAAkC,aACA,KAAA,IAAA/B,OAAA,2BAAA8B,OAAA,6WAkBA,QAAAE,aAAAnC,MACA,GAAA,gBAAAA,mVAoBA,QAAAU,mBAAAC,aAAAX,MACA,OAAMW,cACF,IA5BK,cA6BH,MA5Ba,QA4BTX,KA3BK,KAEFoC,mBA4BbpC,KACI,KA5BK,OA6BH,MA5Ba,QA4BTA,KA3BK,KAEF8B,QA4Bb9B,KACI,KAAJ,OACM,MAAN,QAAAA,KACA,wBC7OA,KAAA;;;;;;;;;;;;g3BDwBAL,KAAAC,SAAAA,mKAkCAC,YAAAC,UAAAC,MAAA,SAAAC,KAAAC,MAEA,OADA,KAAAA,OAAAA,SACAN,KAAAO,UACA,KAAA,IAAAC,OAAA,oCALA,IAAAC,KAAAT,KAAAU,QAAAC,cACqBC,QAMrBN,KAAAM,kBAAAC,sBAAAC,YAAAR,KAAAM,QAAA,GAAAC,sBAAAC,YAAAR,KAAAM,QACAP,MAAAU,kBAAAf,KAAAU,QAAAM,aAAAX,KACA,IAAAY,YAAAX,KAAAW,WACAC,WAAAC,KAAAb,KAAAY,OAAAZ,KAAAY,OAAA,GASA,QARAC,KAAAb,KAAAY,SACA,OAAAb,MACAa,OAAA,IACAD,WAAAA,YAAA,cAJAA,WAAAA,YAAA,UASAE,KAAAF,oZAqBAf,YAAAC,UAAAiB,MAAA,SAAAA,MAAAd,MAEA,OADA,KAAMA,OAANA,SACAN,KAAAO,UACA,KAAA,IAAAC,OAAA,kDANA,IAAQF,KAQRY,QARAZ,KAAAY,QAAA,KAAAZ,KAAAY,OAAA,IASA,KAAA,IAAAV,OAAA,maArEA,KAAA,IAAAA,OAAA,ieC2BAa,yBAAAlB,UAAAmB,OAAA,SAAAC,OACA,MAAA,gBAAAA,4VAgBAF,yBAAAlB,UAAAoB,MAAA,SAAAA,gLAuBAF,yBAAAlB,UAAAqB,UAAA,SAAAD,MAAAE,2pBA+BAJ,yBAAAlB,UAAAuB,OAAA,SAAApB,UACA,KAAAA,OAAAA,QACA,IAAAqB,MAAA3B,KAAA2B,IAMA,IAHArB,KAAAsB,kBACAD,KAAAA,KAAAE,OAAA,SAAAC,SAAA,OAAAA,QAAAvB,aAEAoB,KAAAI,OAAA,EAAA,4FAJA,+BAAA,IAAAtB,kGAYAY,yBAAAlB,UAHa6B,uBAGb,SAAAC,SAOA,GAAA,gBAAAA,SACA,MAAA,cAAAA,OARA,IAAA,gBAAAA,SAAA,yBACAA,QASAC,QATA,oBAUAD,QAAAxB,KAAA;;;;;;;AFnIA,GAAAjB,yBAAA,WACA,QAAAA,4BAEAC,MAAAA,2BAEAD,yBAAAE,aACAC,KAAAC,cAAAC,SAAAC,uDAIAC"}