Skip to content

Commit

Permalink
Emit events on request and response
Browse files Browse the repository at this point in the history
  • Loading branch information
jlomas-stripe committed Aug 8, 2017
1 parent f165b40 commit 07ab7aa
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 4 deletions.
36 changes: 32 additions & 4 deletions lib/StripeResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,26 @@ StripeResource.prototype = {
res.on('end', function() {
var headers = res.headers || {};

// For convenience, make Request-Id easily accessible on
// lastResponse.
res.requestId = headers['request-id'];

var responseEvent = utils.removeEmpty({
api_version: req._requestEvent.api_version,
account: headers['Stripe-Account'],
idempotency_key: headers['Idempotency-Key'],
method: req._requestEvent.method,
path: req._requestEvent.path,
status: res.statusCode,
request_id: res.requestId,
elapsed: Date.now() - req._requestStart,
});

self._stripe._emitter.emit('response', responseEvent);

try {
response = JSON.parse(response);

// For convenience, make Request-Id easily accessible on
// lastResponse.
res.requestId = headers['request-id'];

if (response.error) {
var err;

Expand Down Expand Up @@ -262,6 +275,20 @@ StripeResource.prototype = {
ciphers: 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:!MD5',
});

var requestEvent = utils.removeEmpty({
api_version: apiVersion,
account: headers['Stripe-Account'],
idempotency_key: headers['Idempotency-Key'],
method: method,
path: path,
});

req._requestEvent = requestEvent;

req._requestStart = Date.now();

self._stripe._emitter.emit('request', requestEvent);

req.setTimeout(timeout, self._timeoutHandler(timeout, req, callback));
req.on('response', self._responseHandler(req, callback));
req.on('error', self._errorHandler(req, callback));
Expand All @@ -270,6 +297,7 @@ StripeResource.prototype = {
socket.on((isInsecureConnection ? 'connect' : 'secureConnect'), function() {
// Send payload; we're safe:
req.write(requestData);

req.end();
});
});
Expand Down
13 changes: 13 additions & 0 deletions lib/stripe.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ Stripe.USER_AGENT_SERIALIZED = null;
var APP_INFO_PROPERTIES = ['name', 'version', 'url'];

var exec = require('child_process').exec;
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var objectAssign = require('object-assign');

var resources = {
// Support Accounts for consistency, Account for backwards compat
Expand Down Expand Up @@ -77,6 +80,16 @@ function Stripe(key, version) {
return new Stripe(key, version);
}

Object.defineProperty(this, '_emitter', {
value: new EventEmitter(),
enumerable: false,
configurable: false,
writeable: false,
});

this.on = this._emitter.on.bind(this._emitter);
this.off = this.removeListener = this._emitter.removeListener.bind(this._emitter);

this._api = {
auth: null,
host: Stripe.DEFAULT_HOST,
Expand Down
17 changes: 17 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,23 @@ var utils = module.exports = {
}
return result === 0;
},

/**
* Remove empty values from an object
*/
removeEmpty: function(obj) {
if (typeof obj !== 'object') {
throw new Error('Argument must be an object');
}

Object.keys(obj).forEach(function(key) {
if (obj[key] === null || obj[key] === undefined) {
delete obj[key];
}
});

return obj;
},
};

function asBuffer(thing) {
Expand Down
71 changes: 71 additions & 0 deletions test/flows.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -410,4 +410,75 @@ describe('Flows', function() {
).to.eventually.have.property('object', 'three_d_secure');
});
});

describe('Request/Response Events', function() {
it('should emit a `request` event to listeners on request', function(done) {
var idempotency_key = Math.random().toString(36).slice(2);

function onRequest(request) {
stripe.removeListener('request', onRequest);

expect(request).to.eql({
api_version: 'latest',
idempotency_key: idempotency_key,
method: 'POST',
path: '/v1/charges',
});

done();
}

stripe.on('request', onRequest);

stripe.charges.create({
amount: 1234,
currency: 'usd',
card: 'tok_chargeDeclined',
}, {
idempotency_key: idempotency_key,
}).then(null, function() {});
});

it('should emit a `response` event to listeners on response', function(done) {
function onResponse(response) {
stripe.removeListener('response', onResponse);

expect(response.api_version).to.equal('latest');
expect(response.method).to.equal('POST');
expect(response.path).to.equal('/v1/charges');
expect(response.request_id).to.match(/req_[\w\d]/);
expect(response.status).to.equal(402);
expect(response.elapsed).to.be.within(50, 30000);;

done();
}

stripe.on('response', onResponse);

stripe.charges.create({
amount: 1234,
currency: 'usd',
card: 'tok_chargeDeclined',
}).then(null, function() {
// I expect there to be an error here.
});
});

it('should not emit a `response` event to removed listeners on response', function(done) {
function onResponse(response) {
done(new Error('How did you get here?'));
}

stripe.on('response', onResponse);
stripe.removeListener('response', onResponse);

stripe.charges.create({
amount: 1234,
currency: 'usd',
card: 'tok_visa',
}).then(function() {
done();
});
});
});
});
18 changes: 18 additions & 0 deletions test/utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,4 +224,22 @@ describe('utils', function() {
expect(function() { utils.secureCompare('potato'); }).to.throw();
});
});

describe('removeEmpty', function() {
it('removes empty properties and leave non-empty ones', function() {
expect(utils.removeEmpty({
cat: 3,
dog: false,
rabbit: undefined,
pointer: null,
})).to.eql({
cat: 3,
dog: false,
});
});

it('throws an error if not given two things to compare', function() {
expect(function() { utils.removeEmpty('potato'); }).to.throw();
});
});
});

0 comments on commit 07ab7aa

Please sign in to comment.