From ef37adea0e308528a108c6f17350a41dcfe70fd2 Mon Sep 17 00:00:00 2001 From: Ram Date: Wed, 17 Apr 2019 10:24:53 -0400 Subject: [PATCH] Added new Option to configure yakbak to record only successful requests (#1) --- README.md | 1 + index.js | 16 +++++++++++++--- test/helpers/server.js | 6 +++--- test/yakbak.js | 29 +++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 36d00f9..4e114c0 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ var handler = yakbak('http://api.flickr.com', { - `dirname` the path where recorded responses will be written (required). - `noRecord` if true, requests will return a 404 error if the tape doesn't exist +- `recordOnlySuccess` if true, only successful requests (response status code = 2XX) will be recorded - `hash(req, body)` provide your own IncomingMessage hash function ### with node's http module diff --git a/index.js b/index.js index 6a1fdea..7a5fdf8 100644 --- a/index.js +++ b/index.js @@ -18,6 +18,7 @@ var debug = require('debug')('yakbak:server'); * @param {Object} opts * @param {String} opts.dirname The tapes directory * @param {Boolean} opts.noRecord if true, requests will return a 404 error if the tape doesn't exist + * @param {Boolean} opts.recordOnlySuccess if true, only successful requests will be recorded * @returns {Function} */ @@ -31,6 +32,7 @@ module.exports = function (host, opts) { return buffer(req).then(function (body) { var file = path.join(opts.dirname, tapename(req, body)); + var successfulResCodePattern = /^[2][0|2][0-8]$/; return Promise.try(function () { return require.resolve(file); @@ -40,7 +42,15 @@ module.exports = function (host, opts) { throw new RecordingDisabledError('Recording Disabled'); } else { return proxy(req, body, host).then(function (pres) { - return record(pres.req, pres, file); + if (opts.recordOnlySuccess === true) { + if (successfulResCodePattern.test(pres.statusCode)) { + return record(pres.req, pres, file); + } else { + throw new RecordingDisabledError('Only Successful responses will be recorded'); + } + } else { + return record(pres.req, pres, file); + } }); } @@ -51,7 +61,7 @@ module.exports = function (host, opts) { return tape(req, res); }).catch(RecordingDisabledError, function (err) { /* eslint-disable no-console */ - console.log('An HTTP request has been made that yakbak does not know how to handle'); + console.log(err.message); console.log(curl.request(req)); /* eslint-enable no-console */ res.statusCode = err.status; @@ -87,7 +97,7 @@ function ModuleNotFoundError(err) { /** * Error class that is thrown when an unmatched request - * is encountered in noRecord mode + * is encountered in noRecord mode or when a request failed in recordOnlySuccess mode * @constructor */ diff --git a/test/helpers/server.js b/test/helpers/server.js index c0a07b7..92886aa 100644 --- a/test/helpers/server.js +++ b/test/helpers/server.js @@ -6,13 +6,13 @@ var http = require('http'); /** * Creates a test HTTP server. * @param {Function} done + * @param {boolean} failRequest - Specifies whether response has to be error or not * @returns {http.Server} */ -module.exports = function createServer(cb) { - +module.exports = function createServer(cb, failRequest) { var server = http.createServer(function (req, res) { - res.statusCode = 201; + res.statusCode = failRequest === true ? 404 : 201; res.setHeader('Content-Type', 'text/html'); res.setHeader('Date', 'Sat, 26 Oct 1985 08:20:00 GMT'); diff --git a/test/yakbak.js b/test/yakbak.js index c16bd81..c182ac7 100644 --- a/test/yakbak.js +++ b/test/yakbak.js @@ -135,6 +135,35 @@ describe('yakbak', function () { }); }); }); + + describe("when onlySuccessResponse is enabled", function () { + beforeEach(function (done) { + /* tear down the server created in global scope as we + need different server object which can send response with failed status code*/ + server.teardown(done); + }); + + beforeEach(function (done) { + /* Send the failed response for the requests this server handles */ + server = createServer(done, true); + }); + + beforeEach(function () { + yakbak = subject(server.host, { dirname: tmpdir.dirname, recordOnlySuccess: true }); + }); + + it('does not write the tape to disk if response statusCode is not 2XX', function (done) { + request(yakbak) + .get('/record/2') + .set('host', 'localhost:3001') + .expect(404) + .end(function (err) { + assert.ifError(err); + assert(!fs.existsSync(tmpdir.join('3234ee470c8605a1837e08f218494326.js'))); + done(); + }); + }); + }); }); describe('playback', function () {