mirror of
https://github.com/zhigang1992/interfake.git
synced 2026-06-10 07:00:03 +08:00
192 lines
5.4 KiB
JavaScript
192 lines
5.4 KiB
JavaScript
var util = require('core-util-is');
|
|
var url = require('url');
|
|
var merge = require('merge');
|
|
var deepmerge = require('deepmerge');
|
|
|
|
function Route(descriptor, o) {
|
|
o = o || { debug: false };
|
|
this.debug = require('./debug')('interfake-route', o.debug);
|
|
this.request = descriptor.request;
|
|
this.response = descriptor.response;
|
|
this.afterResponse = descriptor.afterResponse;
|
|
this.o = o;
|
|
|
|
if (!this.response) {
|
|
this.response = {
|
|
delay: 0,
|
|
code: 200,
|
|
body: {},
|
|
headers: {}
|
|
};
|
|
} else {
|
|
this.response = merge({
|
|
delay: 0,
|
|
code: 200,
|
|
body: {},
|
|
headers: {}
|
|
}, this.response);
|
|
}
|
|
|
|
this.response.query = {};
|
|
|
|
var path = url.parse(this.request.url, true);
|
|
|
|
this.request.url = path.pathname;
|
|
|
|
this.setQueryStrings(path.query);
|
|
|
|
if (this.afterResponse && util.isArray(this.afterResponse.endpoints)) {
|
|
this.afterResponse.endpoints = (this.afterResponse.endpoints || []).map(function (descriptor) {
|
|
return new Route(descriptor);
|
|
});
|
|
} else {
|
|
this.afterResponse = {
|
|
endpoints: []
|
|
};
|
|
}
|
|
|
|
this.debug('Creating route: ' + this.request.method + ' ' + this.request.url + ' to return ' + this.response.code + ' with a body of length ' + JSON.stringify(this.response.body).length + ' and ' + this.afterResponse.endpoints.length + ' after-responses');
|
|
}
|
|
|
|
Route.prototype.setQueryStrings = function (query) {
|
|
this.request.query = merge(this.request.query, query || {});
|
|
};
|
|
|
|
Route.prototype.setStatusCode = function (statusCode) {
|
|
this.debug('Now returning', statusCode);
|
|
this.response.code = statusCode;
|
|
};
|
|
|
|
Route.prototype.setResponseBody = function (body) {
|
|
this.debug('Now returning body of length', JSON.stringify(body).length);
|
|
this.response.body = body;
|
|
};
|
|
|
|
Route.prototype.mergeResponseBody = function (body) {
|
|
this.debug('Merging', body, 'into', this.response.body);
|
|
this.response.body = deepmerge(this.response.body, body, { alwaysPush: true });
|
|
this.debug('Response body is now', this.response.body);
|
|
};
|
|
|
|
Route.prototype.mergeResponseHeaders = function (headers) {
|
|
this.debug('Merging', headers, 'into', this.response.headers);
|
|
this.response.headers = deepmerge(this.response.headers, headers);
|
|
this.debug('Response headers is now', this.response.headers);
|
|
};
|
|
|
|
Route.prototype.setResponseDelay = function (delay) {
|
|
this.debug('New delay is', delay);
|
|
this.response.delay = delay;
|
|
};
|
|
|
|
Route.prototype.setResponseHeaders = function (headers) {
|
|
this.debug('Setting response headers to', headers);
|
|
this.response.headers = headers;
|
|
};
|
|
|
|
Route.prototype.addAfterResponse = function (descriptors) {
|
|
var newRoute = new Route(descriptors, this.o);
|
|
this.debug('Adding after response', newRoute.hash());
|
|
this.afterResponse.endpoints.push(newRoute);
|
|
return newRoute;
|
|
};
|
|
|
|
Route.prototype.addModification = function (modifyDescriptor) {
|
|
if (!this.afterResponse.modifications) {
|
|
this.afterResponse.modifications = [];
|
|
}
|
|
|
|
this.afterResponse.modifications.push(modifyDescriptor);
|
|
};
|
|
|
|
Route.prototype.creates = function (routeDescriptor) {
|
|
var newRoute = new Route(routeDescriptor, this.o);
|
|
if (!this.afterResponse) {
|
|
this.afterResponse = {};
|
|
}
|
|
if (!this.afterResponse.endpoints) {
|
|
this.afterResponse.endpoints = [];
|
|
}
|
|
this.afterResponse.endpoints.push(newRoute);
|
|
return newRoute;
|
|
};
|
|
|
|
Route.prototype.simpleHash = function () {
|
|
var routeHash = this.request.method.toUpperCase() + ' ' + this.request.url;
|
|
return routeHash;
|
|
};
|
|
|
|
Route.prototype.queryKeys = function () {
|
|
var queryKeys = Object.keys(this.request.query || {}).filter(function (key) {
|
|
return key !== 'callback';
|
|
});
|
|
return queryKeys;
|
|
};
|
|
|
|
Route.prototype.hash = function () {
|
|
var routeHash = this.request.method.toUpperCase() + ' ' + this.request.url;
|
|
var fullQuerystring, querystringArray = [];
|
|
if (this.request.query) {
|
|
var queryKeys = this.queryKeys();
|
|
|
|
if (queryKeys.length) {
|
|
this.debug('Query keys are', queryKeys);
|
|
|
|
fullQuerystring = this.request.query;
|
|
delete fullQuerystring.callback;
|
|
|
|
queryKeys.sort().forEach(function (k) {
|
|
querystringArray.push(k + '=' + fullQuerystring[k]);
|
|
});
|
|
|
|
this.debug('Full query string items are', querystringArray);
|
|
|
|
routeHash += '?' + querystringArray.join('&');
|
|
this.debug('Final route is', routeHash);
|
|
}
|
|
}
|
|
|
|
this.debug('Lookup hash key will be: ' + routeHash);
|
|
return routeHash;
|
|
};
|
|
|
|
Route.prototype.compare = function (route) {
|
|
var queryKeys;
|
|
var routeQueryKeys;
|
|
var same = true;
|
|
|
|
this.debug('1. Comparing', route.simpleHash(), 'and', this.simpleHash());
|
|
if (route.simpleHash() !== this.simpleHash()) {
|
|
this.debug('No match');
|
|
return false;
|
|
}
|
|
|
|
queryKeys = this.queryKeys();
|
|
routeQueryKeys = route.queryKeys();
|
|
|
|
this.debug('2. Comparing', queryKeys.length, 'and', routeQueryKeys.length);
|
|
if (queryKeys.length !== routeQueryKeys.length) {
|
|
this.debug('No match');
|
|
return false;
|
|
}
|
|
|
|
this.debug('3. Comparing', this.request.query, 'and', route.request.query);
|
|
queryKeys.forEach(function (key) {
|
|
var routeQueryValue = route.request.query[key];
|
|
if (util.isRegExp(this.request.query[key])) {
|
|
this.debug('4b. Testing', routeQueryValue, 'matches', this.request.query[key]);
|
|
same = same && this.request.query[key].test(routeQueryValue);
|
|
this.debug('4c. Result is', same);
|
|
} else {
|
|
// Not checking type because 1 and '1' are the same in this case
|
|
this.debug('4b. Comparing', this.request.query[key], 'and', routeQueryValue);
|
|
same = same && this.request.query[key] == routeQueryValue;
|
|
this.debug('4c. Result is', same);
|
|
}
|
|
}.bind(this));
|
|
|
|
return same;
|
|
};
|
|
|
|
module.exports = Route;
|