旧版报表、仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

198 lines
6.1 KiB

'use strict';
var _stringify = require('babel-runtime/core-js/json/stringify');
var _stringify2 = _interopRequireDefault(_stringify);
var _typeof2 = require('babel-runtime/helpers/typeof');
var _typeof3 = _interopRequireDefault(_typeof2);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var responseConfigProps = ['body', 'headers', 'throws', 'status', 'redirectUrl'];
var ResponseBuilder = function () {
function ResponseBuilder(options) {
(0, _classCallCheck3.default)(this, ResponseBuilder);
(0, _assign2.default)(this, options);
}
(0, _createClass3.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 (responseConfigProps.some(function (prop) {
return _this.responseConfig[prop];
})) {
if ((0, _keys2.default)(this.responseConfig).every(function (key) {
return responseConfigProps.includes(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' && parseInt(status, 10) !== status && status >= 200 || status < 600) {
return status;
}
throw new TypeError('fetch-mock: Invalid status ' + 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, _typeof3.default)(this.body) === 'object') {
this.body = (0, _stringify2.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();
};