testing.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /**
  2. * @license Angular v8.1.0
  3. * (c) 2010-2019 Google LLC. https://angular.io/
  4. * License: MIT
  5. */
  6. import { __decorate } from 'tslib';
  7. import { HttpHeaders, HttpResponse, HttpErrorResponse, HttpEventType, HttpClientModule, HttpBackend } from '@angular/common/http';
  8. import { Injectable, NgModule } from '@angular/core';
  9. import { Observable } from 'rxjs';
  10. /**
  11. * @license
  12. * Copyright Google Inc. All Rights Reserved.
  13. *
  14. * Use of this source code is governed by an MIT-style license that can be
  15. * found in the LICENSE file at https://angular.io/license
  16. */
  17. /**
  18. * Controller to be injected into tests, that allows for mocking and flushing
  19. * of requests.
  20. *
  21. * @publicApi
  22. */
  23. var HttpTestingController = /** @class */ (function () {
  24. function HttpTestingController() {
  25. }
  26. return HttpTestingController;
  27. }());
  28. /**
  29. * @license
  30. * Copyright Google Inc. All Rights Reserved.
  31. *
  32. * Use of this source code is governed by an MIT-style license that can be
  33. * found in the LICENSE file at https://angular.io/license
  34. */
  35. /**
  36. * A mock requests that was received and is ready to be answered.
  37. *
  38. * This interface allows access to the underlying `HttpRequest`, and allows
  39. * responding with `HttpEvent`s or `HttpErrorResponse`s.
  40. *
  41. * @publicApi
  42. */
  43. var TestRequest = /** @class */ (function () {
  44. function TestRequest(request, observer) {
  45. this.request = request;
  46. this.observer = observer;
  47. /**
  48. * @internal set by `HttpClientTestingBackend`
  49. */
  50. this._cancelled = false;
  51. }
  52. Object.defineProperty(TestRequest.prototype, "cancelled", {
  53. /**
  54. * Whether the request was cancelled after it was sent.
  55. */
  56. get: function () { return this._cancelled; },
  57. enumerable: true,
  58. configurable: true
  59. });
  60. /**
  61. * Resolve the request by returning a body plus additional HTTP information (such as response
  62. * headers) if provided.
  63. * If the request specifies an expected body type, the body is converted into the requested type.
  64. * Otherwise, the body is converted to `JSON` by default.
  65. *
  66. * Both successful and unsuccessful responses can be delivered via `flush()`.
  67. */
  68. TestRequest.prototype.flush = function (body, opts) {
  69. if (opts === void 0) { opts = {}; }
  70. if (this.cancelled) {
  71. throw new Error("Cannot flush a cancelled request.");
  72. }
  73. var url = this.request.urlWithParams;
  74. var headers = (opts.headers instanceof HttpHeaders) ? opts.headers : new HttpHeaders(opts.headers);
  75. body = _maybeConvertBody(this.request.responseType, body);
  76. var statusText = opts.statusText;
  77. var status = opts.status !== undefined ? opts.status : 200;
  78. if (opts.status === undefined) {
  79. if (body === null) {
  80. status = 204;
  81. statusText = statusText || 'No Content';
  82. }
  83. else {
  84. statusText = statusText || 'OK';
  85. }
  86. }
  87. if (statusText === undefined) {
  88. throw new Error('statusText is required when setting a custom status.');
  89. }
  90. if (status >= 200 && status < 300) {
  91. this.observer.next(new HttpResponse({ body: body, headers: headers, status: status, statusText: statusText, url: url }));
  92. this.observer.complete();
  93. }
  94. else {
  95. this.observer.error(new HttpErrorResponse({ error: body, headers: headers, status: status, statusText: statusText, url: url }));
  96. }
  97. };
  98. /**
  99. * Resolve the request by returning an `ErrorEvent` (e.g. simulating a network failure).
  100. */
  101. TestRequest.prototype.error = function (error, opts) {
  102. if (opts === void 0) { opts = {}; }
  103. if (this.cancelled) {
  104. throw new Error("Cannot return an error for a cancelled request.");
  105. }
  106. if (opts.status && opts.status >= 200 && opts.status < 300) {
  107. throw new Error("error() called with a successful status.");
  108. }
  109. var headers = (opts.headers instanceof HttpHeaders) ? opts.headers : new HttpHeaders(opts.headers);
  110. this.observer.error(new HttpErrorResponse({
  111. error: error,
  112. headers: headers,
  113. status: opts.status || 0,
  114. statusText: opts.statusText || '',
  115. url: this.request.urlWithParams,
  116. }));
  117. };
  118. /**
  119. * Deliver an arbitrary `HttpEvent` (such as a progress event) on the response stream for this
  120. * request.
  121. */
  122. TestRequest.prototype.event = function (event) {
  123. if (this.cancelled) {
  124. throw new Error("Cannot send events to a cancelled request.");
  125. }
  126. this.observer.next(event);
  127. };
  128. return TestRequest;
  129. }());
  130. /**
  131. * Helper function to convert a response body to an ArrayBuffer.
  132. */
  133. function _toArrayBufferBody(body) {
  134. if (typeof ArrayBuffer === 'undefined') {
  135. throw new Error('ArrayBuffer responses are not supported on this platform.');
  136. }
  137. if (body instanceof ArrayBuffer) {
  138. return body;
  139. }
  140. throw new Error('Automatic conversion to ArrayBuffer is not supported for response type.');
  141. }
  142. /**
  143. * Helper function to convert a response body to a Blob.
  144. */
  145. function _toBlob(body) {
  146. if (typeof Blob === 'undefined') {
  147. throw new Error('Blob responses are not supported on this platform.');
  148. }
  149. if (body instanceof Blob) {
  150. return body;
  151. }
  152. if (ArrayBuffer && body instanceof ArrayBuffer) {
  153. return new Blob([body]);
  154. }
  155. throw new Error('Automatic conversion to Blob is not supported for response type.');
  156. }
  157. /**
  158. * Helper function to convert a response body to JSON data.
  159. */
  160. function _toJsonBody(body, format) {
  161. if (format === void 0) { format = 'JSON'; }
  162. if (typeof ArrayBuffer !== 'undefined' && body instanceof ArrayBuffer) {
  163. throw new Error("Automatic conversion to " + format + " is not supported for ArrayBuffers.");
  164. }
  165. if (typeof Blob !== 'undefined' && body instanceof Blob) {
  166. throw new Error("Automatic conversion to " + format + " is not supported for Blobs.");
  167. }
  168. if (typeof body === 'string' || typeof body === 'number' || typeof body === 'object' ||
  169. Array.isArray(body)) {
  170. return body;
  171. }
  172. throw new Error("Automatic conversion to " + format + " is not supported for response type.");
  173. }
  174. /**
  175. * Helper function to convert a response body to a string.
  176. */
  177. function _toTextBody(body) {
  178. if (typeof body === 'string') {
  179. return body;
  180. }
  181. if (typeof ArrayBuffer !== 'undefined' && body instanceof ArrayBuffer) {
  182. throw new Error('Automatic conversion to text is not supported for ArrayBuffers.');
  183. }
  184. if (typeof Blob !== 'undefined' && body instanceof Blob) {
  185. throw new Error('Automatic conversion to text is not supported for Blobs.');
  186. }
  187. return JSON.stringify(_toJsonBody(body, 'text'));
  188. }
  189. /**
  190. * Convert a response body to the requested type.
  191. */
  192. function _maybeConvertBody(responseType, body) {
  193. if (body === null) {
  194. return null;
  195. }
  196. switch (responseType) {
  197. case 'arraybuffer':
  198. return _toArrayBufferBody(body);
  199. case 'blob':
  200. return _toBlob(body);
  201. case 'json':
  202. return _toJsonBody(body);
  203. case 'text':
  204. return _toTextBody(body);
  205. default:
  206. throw new Error("Unsupported responseType: " + responseType);
  207. }
  208. }
  209. /**
  210. * @license
  211. * Copyright Google Inc. All Rights Reserved.
  212. *
  213. * Use of this source code is governed by an MIT-style license that can be
  214. * found in the LICENSE file at https://angular.io/license
  215. */
  216. /**
  217. * A testing backend for `HttpClient` which both acts as an `HttpBackend`
  218. * and as the `HttpTestingController`.
  219. *
  220. * `HttpClientTestingBackend` works by keeping a list of all open requests.
  221. * As requests come in, they're added to the list. Users can assert that specific
  222. * requests were made and then flush them. In the end, a verify() method asserts
  223. * that no unexpected requests were made.
  224. *
  225. *
  226. */
  227. var HttpClientTestingBackend = /** @class */ (function () {
  228. function HttpClientTestingBackend() {
  229. /**
  230. * List of pending requests which have not yet been expected.
  231. */
  232. this.open = [];
  233. }
  234. /**
  235. * Handle an incoming request by queueing it in the list of open requests.
  236. */
  237. HttpClientTestingBackend.prototype.handle = function (req) {
  238. var _this = this;
  239. return new Observable(function (observer) {
  240. var testReq = new TestRequest(req, observer);
  241. _this.open.push(testReq);
  242. observer.next({ type: HttpEventType.Sent });
  243. return function () { testReq._cancelled = true; };
  244. });
  245. };
  246. /**
  247. * Helper function to search for requests in the list of open requests.
  248. */
  249. HttpClientTestingBackend.prototype._match = function (match) {
  250. if (typeof match === 'string') {
  251. return this.open.filter(function (testReq) { return testReq.request.urlWithParams === match; });
  252. }
  253. else if (typeof match === 'function') {
  254. return this.open.filter(function (testReq) { return match(testReq.request); });
  255. }
  256. else {
  257. return this.open.filter(function (testReq) { return (!match.method || testReq.request.method === match.method.toUpperCase()) &&
  258. (!match.url || testReq.request.urlWithParams === match.url); });
  259. }
  260. };
  261. /**
  262. * Search for requests in the list of open requests, and return all that match
  263. * without asserting anything about the number of matches.
  264. */
  265. HttpClientTestingBackend.prototype.match = function (match) {
  266. var _this = this;
  267. var results = this._match(match);
  268. results.forEach(function (result) {
  269. var index = _this.open.indexOf(result);
  270. if (index !== -1) {
  271. _this.open.splice(index, 1);
  272. }
  273. });
  274. return results;
  275. };
  276. /**
  277. * Expect that a single outstanding request matches the given matcher, and return
  278. * it.
  279. *
  280. * Requests returned through this API will no longer be in the list of open requests,
  281. * and thus will not match twice.
  282. */
  283. HttpClientTestingBackend.prototype.expectOne = function (match, description) {
  284. description = description || this.descriptionFromMatcher(match);
  285. var matches = this.match(match);
  286. if (matches.length > 1) {
  287. throw new Error("Expected one matching request for criteria \"" + description + "\", found " + matches.length + " requests.");
  288. }
  289. if (matches.length === 0) {
  290. throw new Error("Expected one matching request for criteria \"" + description + "\", found none.");
  291. }
  292. return matches[0];
  293. };
  294. /**
  295. * Expect that no outstanding requests match the given matcher, and throw an error
  296. * if any do.
  297. */
  298. HttpClientTestingBackend.prototype.expectNone = function (match, description) {
  299. description = description || this.descriptionFromMatcher(match);
  300. var matches = this.match(match);
  301. if (matches.length > 0) {
  302. throw new Error("Expected zero matching requests for criteria \"" + description + "\", found " + matches.length + ".");
  303. }
  304. };
  305. /**
  306. * Validate that there are no outstanding requests.
  307. */
  308. HttpClientTestingBackend.prototype.verify = function (opts) {
  309. if (opts === void 0) { opts = {}; }
  310. var open = this.open;
  311. // It's possible that some requests may be cancelled, and this is expected.
  312. // The user can ask to ignore open requests which have been cancelled.
  313. if (opts.ignoreCancelled) {
  314. open = open.filter(function (testReq) { return !testReq.cancelled; });
  315. }
  316. if (open.length > 0) {
  317. // Show the methods and URLs of open requests in the error, for convenience.
  318. var requests = open.map(function (testReq) {
  319. var url = testReq.request.urlWithParams.split('?')[0];
  320. var method = testReq.request.method;
  321. return method + " " + url;
  322. })
  323. .join(', ');
  324. throw new Error("Expected no open requests, found " + open.length + ": " + requests);
  325. }
  326. };
  327. HttpClientTestingBackend.prototype.descriptionFromMatcher = function (matcher) {
  328. if (typeof matcher === 'string') {
  329. return "Match URL: " + matcher;
  330. }
  331. else if (typeof matcher === 'object') {
  332. var method = matcher.method || '(any)';
  333. var url = matcher.url || '(any)';
  334. return "Match method: " + method + ", URL: " + url;
  335. }
  336. else {
  337. return "Match by function: " + matcher.name;
  338. }
  339. };
  340. HttpClientTestingBackend = __decorate([
  341. Injectable()
  342. ], HttpClientTestingBackend);
  343. return HttpClientTestingBackend;
  344. }());
  345. /**
  346. * @license
  347. * Copyright Google Inc. All Rights Reserved.
  348. *
  349. * Use of this source code is governed by an MIT-style license that can be
  350. * found in the LICENSE file at https://angular.io/license
  351. */
  352. /**
  353. * Configures `HttpClientTestingBackend` as the `HttpBackend` used by `HttpClient`.
  354. *
  355. * Inject `HttpTestingController` to expect and flush requests in your tests.
  356. *
  357. * @publicApi
  358. */
  359. var HttpClientTestingModule = /** @class */ (function () {
  360. function HttpClientTestingModule() {
  361. }
  362. HttpClientTestingModule = __decorate([
  363. NgModule({
  364. imports: [
  365. HttpClientModule,
  366. ],
  367. providers: [
  368. HttpClientTestingBackend,
  369. { provide: HttpBackend, useExisting: HttpClientTestingBackend },
  370. { provide: HttpTestingController, useExisting: HttpClientTestingBackend },
  371. ],
  372. })
  373. ], HttpClientTestingModule);
  374. return HttpClientTestingModule;
  375. }());
  376. /**
  377. * @license
  378. * Copyright Google Inc. All Rights Reserved.
  379. *
  380. * Use of this source code is governed by an MIT-style license that can be
  381. * found in the LICENSE file at https://angular.io/license
  382. */
  383. /**
  384. * @license
  385. * Copyright Google Inc. All Rights Reserved.
  386. *
  387. * Use of this source code is governed by an MIT-style license that can be
  388. * found in the LICENSE file at https://angular.io/license
  389. */
  390. /**
  391. * Generated bundle index. Do not edit.
  392. */
  393. export { HttpClientTestingBackend as ɵangular_packages_common_http_testing_testing_a, HttpTestingController, HttpClientTestingModule, TestRequest };
  394. //# sourceMappingURL=testing.js.map