UNPKG

@4c/fetch-mock

Version:

Mock http requests made using fetch (or isomorphic-fetch)

200 lines (168 loc) 7.24 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault"); var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/json/stringify")); var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/typeof")); var _parseInt2 = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/parse-int")); var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes")); var _keys = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/keys")); var _every = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/every")); var _some = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/some")); var _assign = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/assign")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass")); var responseConfigProps = ['body', 'headers', 'throws', 'status', 'redirectUrl']; var ResponseBuilder = /*#__PURE__*/ function () { function ResponseBuilder(options) { (0, _classCallCheck2["default"])(this, ResponseBuilder); (0, _assign["default"])(this, options); } (0, _createClass2["default"])(ResponseBuilder, [{ key: "exec", value: function exec() { this.normalizeResponseConfig(); this.constructFetchOpts(); this.constructResponseBody(); return this.buildObservableResponse(new this.fetchMock.config.Response(this.body, this.options)); } }, { key: "sendAsObject", value: function sendAsObject() { var _this = this; if ((0, _some["default"])(responseConfigProps).call(responseConfigProps, function (prop) { return _this.responseConfig[prop]; })) { var _context; if ((0, _every["default"])(_context = (0, _keys["default"])(this.responseConfig)).call(_context, function (key) { return (0, _includes["default"])(responseConfigProps).call(responseConfigProps, key); })) { return false; } else { return true; } } else { return true; } } }, { key: "normalizeResponseConfig", value: function normalizeResponseConfig() { // If the response config looks like a status, start to generate a simple response if (typeof this.responseConfig === 'number') { this.responseConfig = { status: this.responseConfig }; // If the response config is not an object, or is an object that doesn't use // any reserved properties, assume it is meant to be the body of the response } else if (typeof this.responseConfig === 'string' || this.sendAsObject()) { this.responseConfig = { body: this.responseConfig }; } } }, { key: "validateStatus", value: function validateStatus(status) { if (!status) { return 200; } if (typeof status === 'number' && (0, _parseInt2["default"])(status, 10) !== status && status >= 200 || status < 600) { return status; } throw new TypeError("fetch-mock: Invalid status ".concat(status, " passed on response object.\nTo respond with a JSON object that has status as a property assign the object to body\ne.g. {\"body\": {\"status: \"registered\"}}")); } }, { key: "constructFetchOpts", value: function constructFetchOpts() { this.options = this.responseConfig.options || {}; this.options.url = this.responseConfig.redirectUrl || this.url; this.options.status = this.validateStatus(this.responseConfig.status); this.options.statusText = this.fetchMock.statusTextMap['' + this.options.status]; // Set up response headers. The empty object is to cope with // new Headers(undefined) throwing in Chrome // https://code.google.com/p/chromium/issues/detail?id=335871 this.options.headers = new this.fetchMock.config.Headers(this.responseConfig.headers || {}); } }, { key: "getOption", value: function getOption(name) { return name in this.route ? this.route[name] : this.fetchMock.config[name]; } }, { key: "convertToJson", value: function convertToJson() { // convert to json if we need to if (this.getOption('sendAsJson') && this.responseConfig.body != null && //eslint-disable-line (0, _typeof2["default"])(this.body) === 'object') { this.body = (0, _stringify["default"])(this.body); if (!this.options.headers.has('Content-Type')) { this.options.headers.set('Content-Type', 'application/json'); } } } }, { key: "setContentLength", value: function setContentLength() { // add a Content-Length header if we need to if (this.getOption('includeContentLength') && typeof this.body === 'string' && !this.options.headers.has('Content-Length')) { this.options.headers.set('Content-Length', this.body.length.toString()); } } }, { key: "constructResponseBody", value: function constructResponseBody() { // start to construct the body this.body = this.responseConfig.body; this.convertToJson(); this.setContentLength(); // On the server we need to manually construct the readable stream for the // Response object (on the client this done automatically) if (this.Stream) { var stream = new this.Stream.Readable(); if (this.body != null) { //eslint-disable-line stream.push(this.body, 'utf-8'); } stream.push(null); this.body = stream; } this.body = this.body; } }, { key: "buildObservableResponse", value: function buildObservableResponse(response) { var _this2 = this; var fetchMock = this.fetchMock; // Using a proxy means we can set properties that may not be writable on // the original Response. It also means we can track the resolution of // promises returned by res.json(), res.text() etc return new Proxy(response, { get: function get(originalResponse, name) { if (_this2.responseConfig.redirectUrl) { if (name === 'url') { return _this2.responseConfig.redirectUrl; } if (name === 'redirected') { return true; } } if (typeof originalResponse[name] === 'function') { return new Proxy(originalResponse[name], { apply: function apply(func, thisArg, args) { var result = func.apply(response, args); if (result.then) { fetchMock._holdingPromises.push(result["catch"](function () { return null; })); } return result; } }); } return originalResponse[name]; } }); } }]); return ResponseBuilder; }(); module.exports = function (options) { return new ResponseBuilder(options).exec(); };