-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add
app.agent.mockHttpclient()
for agent (#82)
- Loading branch information
1 parent
a29977e
commit 283eef3
Showing
5 changed files
with
428 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
'use strict'; | ||
const mm = require('mm'); | ||
const mockHttpclient = require('../../lib/mock_httpclient'); | ||
|
||
module.exports = { | ||
|
||
/** | ||
* mock httpclient | ||
* @method Agent#mockHttpclient | ||
* @return {Context} this | ||
*/ | ||
mockHttpclient(...args) { | ||
if (!this._mockHttpclient) { | ||
this._mockHttpclient = mockHttpclient(this); | ||
} | ||
return this._mockHttpclient(...args); | ||
}, | ||
|
||
/** | ||
* @see mm#restore | ||
* @method Agent#mockRestore | ||
*/ | ||
mockRestore: mm.restore, | ||
|
||
/** | ||
* @see mm | ||
* @method Agent#mm | ||
*/ | ||
mm, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
'use strict'; | ||
const mm = require('mm'); | ||
const extend = require('extend2'); | ||
|
||
module.exports = function(app) { | ||
/** | ||
* mock httpclient | ||
* @method 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()); | ||
|
||
if (!mockResult.status) { | ||
mockResult.status = 200; | ||
} | ||
|
||
mockResult.data = mockResult.data || ''; | ||
if (Buffer.isBuffer(mockResult.data)) { | ||
// do nothing | ||
} else if (typeof mockResult.data === 'object') { | ||
// json | ||
mockResult.data = new Buffer(JSON.stringify(mockResult.data)); | ||
} else if (typeof mockResult.data === 'string') { | ||
// string | ||
mockResult.data = new Buffer(mockResult.data); | ||
} else { | ||
throw new Error('`mockResult.data` must be buffer, string or json'); | ||
} | ||
|
||
if (!mockResult.res) { | ||
mockResult.res = { | ||
status: mockResult.status, | ||
}; | ||
} | ||
mockResult.responseSize = mockResult.responseSize || 0; | ||
if (mockResult.data) { | ||
mockResult.responseSize = mockResult.data.length; | ||
} | ||
mockResult.headers = mockResult.headers || {}; | ||
|
||
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; | ||
} | ||
|
||
// 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 result = extend(true, {}, mockResult); | ||
const response = { | ||
status: result.status, | ||
statusCode: result.status, | ||
headers: result.headers, | ||
size: result.responseSize, | ||
aborted: false, | ||
rt: 1, | ||
keepAliveSocket: result.keepAliveSocket || false, | ||
}; | ||
|
||
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); | ||
} | ||
}; | ||
}; |
Oops, something went wrong.