From 904d1b37aca034d816832d2882fbe07cd01cf450 Mon Sep 17 00:00:00 2001 From: Gregor Date: Tue, 20 Feb 2018 11:29:08 -0800 Subject: [PATCH] feat: support replay of recorded binary responses --- lib/recorder.js | 56 ++++++++++++++++++++++++++++++++----------------- lib/scope.js | 2 ++ 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/lib/recorder.js b/lib/recorder.js index 43bd74b08..33aca01c8 100644 --- a/lib/recorder.js +++ b/lib/recorder.js @@ -52,17 +52,19 @@ var getBodyFromChunks = function(chunks, headers) { // the body shouldn't be merged but instead persisted as an array // of hex strings so that the responses can be mocked one by one. if(common.isContentEncoded(headers)) { - return _.map(chunks, function(chunk) { - if(!Buffer.isBuffer(chunk)) { - if (typeof chunk === 'string') { - chunk = new Buffer(chunk); - } else { - throw new Error('content-encoded responses must all be binary buffers'); + return { + body: _.map(chunks, function(chunk) { + if(!Buffer.isBuffer(chunk)) { + if (typeof chunk === 'string') { + chunk = new Buffer(chunk); + } else { + throw new Error('content-encoded responses must all be binary buffers'); + } } - } - return chunk.toString('hex'); - }); + return chunk.toString('hex'); + }) + }; } var mergedBuffer = common.mergeChunks(chunks); @@ -72,39 +74,55 @@ var getBodyFromChunks = function(chunks, headers) { // 2. A string buffer which represents a JSON object. // 3. A string buffer which doesn't represent a JSON object. - if(common.isBinaryBuffer(mergedBuffer)) { - return mergedBuffer.toString('hex'); + var isBinary = common.isBinaryBuffer(mergedBuffer) + if(isBinary) { + return { + body: mergedBuffer.toString('hex'), + isBinary + } } else { var maybeStringifiedJson = mergedBuffer.toString('utf8'); try { - return JSON.parse(maybeStringifiedJson); + return { + body: JSON.parse(maybeStringifiedJson), + isBinary: false + }; } catch(err) { - return maybeStringifiedJson; + return { + body: maybeStringifiedJson, + isBinary: false + }; } } - }; function generateRequestAndResponseObject(req, bodyChunks, options, res, dataChunks) { + var response = getBodyFromChunks(dataChunks, res.headers) options.path = req.path; - return { + + var nockDef = { scope: getScope(options), method: getMethod(options), path: options.path, - body: getBodyFromChunks(bodyChunks), + body: getBodyFromChunks(bodyChunks).body, status: res.statusCode, - response: getBodyFromChunks(dataChunks, res.headers), + response: response.body, rawHeaders: res.rawHeaders || res.headers, reqheaders: req._headers }; + if (response.isBinary) { + nockDef.responseIsBinary = true + } + + return nockDef; } function generateRequestAndResponse(req, bodyChunks, options, res, dataChunks) { - var requestBody = getBodyFromChunks(bodyChunks); - var responseBody = getBodyFromChunks(dataChunks, res.headers); + var requestBody = getBodyFromChunks(bodyChunks).body; + var responseBody = getBodyFromChunks(dataChunks, res.headers).body; // Remove any query params from options.path so they can be added in the query() function var path = options.path; diff --git a/lib/scope.js b/lib/scope.js index f8b07be08..39804c1d5 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -314,6 +314,8 @@ function define(nockDefs) { var response; if (!nockDef.response) { response = ''; + } else if (nockDef.responseIsBinary) { + response = Buffer.from(nockDef.response, 'hex') } else { response = _.isString(nockDef.response) ? tryJsonParse(nockDef.response) : nockDef.response; }