123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- 'use strict';
- const mm = require('mm');
- const extend = require('extend2');
- const is = require('is-type-of');
- module.exports = function(app) {
- /**
- * mock httpclient
- * @function mockHttpclient
- * @param {String} mockUrl - url
- * @param {String|Array} mockMethod - http method
- * @param {Object} mockResult - you data
- * - data - buffer / string / json
- * - status - http status
- * - headers - response header
- * @return {Context} this
- */
- return function mockHttpclient(mockUrl, mockMethod, mockResult) {
- if (!mockResult) {
- // app.mockHttpclient(mockUrl, mockResult)
- mockResult = mockMethod;
- mockMethod = '*';
- }
- if (!Array.isArray(mockMethod)) mockMethod = [ mockMethod ];
- mockMethod = mockMethod.map(method => (method || 'GET').toUpperCase());
- const httpclient = app.httpclient;
- const rawRequest = httpclient.request;
- mm(httpclient, 'requestThunk', _request);
- mm(httpclient, 'request', _request);
- mm(httpclient, 'curl', _request);
- return app;
- function matchMethod(method) {
- return mockMethod.some(m => m === '*' || m === method);
- }
- function matchUrl(url) {
- if (url === mockUrl) return true;
- if (mockUrl instanceof RegExp && url.match(mockUrl)) return true;
- return false;
- }
- function normalizeResult(result) {
- if (is.string(result)) {
- result = { data: result };
- }
- if (!result.status) {
- result.status = 200;
- }
- result.data = result.data || '';
- if (Buffer.isBuffer(result.data)) {
- // do nothing
- } else if (typeof result.data === 'object') {
- // json
- result.data = Buffer.from(JSON.stringify(result.data));
- } else if (typeof result.data === 'string') {
- // string
- result.data = Buffer.from(result.data);
- } else {
- throw new Error('`mockResult.data` must be buffer, string or json');
- }
- if (!result.res) {
- result.res = {
- status: result.status,
- };
- }
- result.responseSize = result.responseSize || 0;
- if (result.data) {
- result.responseSize = result.data.length;
- }
- result.headers = result.headers || {};
- return result;
- }
- // support generator rather than callback and promise
- function _request(url, opt) {
- opt = opt || {};
- opt.method = (opt.method || 'GET').toUpperCase();
- opt.headers = opt.headers || {};
- if (matchUrl(url) && matchMethod(opt.method)) {
- const mockRequestResult = is.function(mockResult) ? mockResult(url, opt) : mockResult;
- const result = extend(true, {}, normalizeResult(mockRequestResult));
- const response = {
- status: result.status,
- statusCode: result.status,
- headers: result.headers,
- size: result.responseSize,
- aborted: false,
- rt: 1,
- keepAliveSocket: result.keepAliveSocket || false,
- };
- httpclient.emit('request', {
- reqId: Date.now(),
- url,
- args: opt,
- ctx: opt.ctx,
- });
- httpclient.emit('response', {
- error: null,
- ctx: opt.ctx,
- req: {
- url,
- options: opt,
- size: result.requestSize,
- },
- res: response,
- });
- if (opt.dataType === 'json') {
- try {
- result.data = JSON.parse(result.data);
- } catch (err) {
- err.name = 'JSONResponseFormatError';
- throw err;
- }
- } else if (opt.dataType === 'text') {
- result.data = result.data.toString();
- }
- return Promise.resolve(result);
- }
- return rawRequest.call(httpclient, url, opt);
- }
- };
- };
|