Skip to content

Commit

Permalink
Use promised request for blockchainInfo module
Browse files Browse the repository at this point in the history
  • Loading branch information
selaux committed May 13, 2014
1 parent 3a4ef88 commit c6e74c3
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 104 deletions.
61 changes: 17 additions & 44 deletions lib/modules/technical/blockchainInfo.js
@@ -1,9 +1,7 @@
'use strict';

var async = require('async'),
_ = require('lodash'),
request = require('request'),

var Bluebird = require('bluebird'),
request = require('../../utils/request'),
Module =require('../../Module');

module.exports = Module.extend({
Expand All @@ -26,54 +24,29 @@ module.exports = Module.extend({
updateTechnicalStats: function () {
var self = this;

async.parallel([
function (callback) {
request({
uri: 'http://blockchain.info/stats?format=json',
json: true
}, function (err, res) { callback(err, res); });
},
function (callback) {
request({
uri: 'http://blockchain.info/q/bcperblock',
json: true
}, function (err, res) { callback(err, res); });
}
], function (err, responses) {
Bluebird.all([
request('https://blockchain.info/stats?format=json'),
request('https://blockchain.info/q/bcperblock')
]).then(function (responses) {
/*jshint sub:true*/

var allRequestsSucceeded,
difficulty;

if (err) {
self.app.logger.info('%s - error fetching data from blockchain.info', self.id, err);
return;
}

self.app.logger.debug(
'%s - fetched data from blockchain.info',
self.id,
JSON.stringify(_.pluck(responses, 'statusCode')),
JSON.stringify(_.pluck(responses, 'body'))
JSON.stringify(responses)
);
allRequestsSucceeded = _.all(responses, function (res) {
return res.statusCode === 200;
});
if (!allRequestsSucceeded) {
return;
}

difficulty = responses[0].body.difficulty;
self.set({
blockReward: responses[1].body / 1e8,
probability: 1 / (4295032833 * difficulty),
difficulty: difficulty,
networkHashrate: responses[0].body['hash_rate'] * 1e3,
blockChainLength: responses[0].body['n_blocks_total'],
timeBetweenBlocks: responses[0].body['minutes_between_blocks'],
numberOfTransactions: responses[0].body['n_tx'],
totalTransactionValue: responses[0].body['total_btc_sent']
blockReward: responses[1] / 1e8,
probability: 1 / (4295032833 * responses[0].difficulty),
difficulty: responses[0].difficulty,
networkHashrate: responses[0]['hash_rate'] * 1e3,
blockChainLength: responses[0]['n_blocks_total'],
timeBetweenBlocks: responses[0]['minutes_between_blocks'],
numberOfTransactions: responses[0]['n_tx'],
totalTransactionValue: responses[0]['total_btc_sent']
});
}).catch(function (err) {
self.app.logger.info('%s - error fetching data from blockchain.info', self.id, err.toString());
});
}

Expand Down
105 changes: 45 additions & 60 deletions test/specs/lib/modules/technical/blockchainInfoSpec.js
Expand Up @@ -5,8 +5,8 @@ var chai = require('chai'),
sinonChai = require('sinon-chai'),
expect = chai.expect,
SandboxedModule = require('sandboxed-module'),
Bluebird = require('bluebird'),

responses = {},
statsAnswer = {
'n_blocks_total': 123,
'minutes_between_blocks': 12,
Expand All @@ -15,90 +15,75 @@ var chai = require('chai'),
difficulty: 100 * (1 / 4295032833),
'hash_rate': 123
},
btcPerBlockAnswer = 2500000000,
BlockchainInfo = SandboxedModule.require('../../../../../lib/modules/technical/blockchainInfo', {
requires: {
request: require('../../../../utils/requestStub')(responses)
}
});
btcPerBlockAnswer = 2500000000;

chai.use(sinonChai);

describe('modules/technical/blockchainInfo', function () {
var app;
var BlockchainInfo,
app,
requestStub;

beforeEach(function () {
requestStub = sinon.stub();
requestStub.withArgs('https://blockchain.info/stats?format=json').returns(Bluebird.resolve(statsAnswer));
requestStub.withArgs('https://blockchain.info/q/bcperblock').returns(Bluebird.resolve(btcPerBlockAnswer));

BlockchainInfo = SandboxedModule.require('../../../../../lib/modules/technical/blockchainInfo', {
requires: {
'../../utils/request': requestStub
}
});
app = { logger: { debug: sinon.stub(), info: sinon.stub() } };
responses['http://blockchain.info/stats?format=json'] = {
statusCode: 200,
body: statsAnswer
};
responses['http://blockchain.info/q/bcperblock'] = {
statusCode: 200,
body: btcPerBlockAnswer
};
});

it('should get data from blockchainInfo correctly', function (done) {
var blockchainInfo = new BlockchainInfo(app);
var blockchainInfo;

blockchainInfo = new BlockchainInfo(app);
blockchainInfo.on('change', function () {
expect(blockchainInfo.toJSON()).to.deep.equal({
blockReward: 25,
probability: 0.01,
difficulty: 100 * (1 / 4295032833),
networkHashrate: 123000,
blockChainLength: 123,
timeBetweenBlocks: 12,
numberOfTransactions: 10,
totalTransactionValue: 1
setImmediate(function () {
expect(blockchainInfo.toJSON()).to.deep.equal({
blockReward: 25,
probability: 0.01,
difficulty: 100 * (1 / 4295032833),
networkHashrate: 123000,
blockChainLength: 123,
timeBetweenBlocks: 12,
numberOfTransactions: 10,
totalTransactionValue: 1
});

expect(app.logger.debug).to.have.been.calledOnce;
expect(app.logger.debug).to.have.been.calledWith(
'%s - fetched data from blockchain.info',
blockchainInfo.id,
JSON.stringify([ statsAnswer, btcPerBlockAnswer ])
);

done();
});
expect(app.logger.debug).to.have.been.calledOnce;
expect(app.logger.debug).to.have.been.calledWith(
'%s - fetched data from blockchain.info',
blockchainInfo.id,
JSON.stringify([ 200, 200 ]),
JSON.stringify([ statsAnswer, btcPerBlockAnswer ])
);
done();
});
});

[
'http://blockchain.info/stats?format=json',
'http://blockchain.info/q/bcperblock'
].forEach(function (url) {
it('should not throw an error if the request to ' + url + 'fails with an error and log the incident', function (done) {
var blockchainInfo;
'https://blockchain.info/stats?format=json',
'https://blockchain.info/q/bcperblock'
].forEach(function (testCase) {
it('should log the incident if the request to ' + testCase.failing + 'fails with an error', function (done) {
var error = new Error('Test Error'),
blockchainInfo;

responses[url] = null;
requestStub.withArgs(testCase).returns(Bluebird.reject(error));

blockchainInfo = new BlockchainInfo(app);

setTimeout(function () {
expect(blockchainInfo.toJSON()).to.be.empty;
expect(app.logger.info).to.have.been.calledOnce;
expect(app.logger.info).to.have.been.calledWith('%s - error fetching data from blockchain.info', blockchainInfo.id, new Error('Test Error'));
done();
}, 50);
});

it('should not throw an error if the request to ' + url + 'returns a non 200 http status code and no data', function (done) {
var blockchainInfo;

responses[url] = {
statusCode: 500,
body: 'Internal Server Error'
};

blockchainInfo = new BlockchainInfo(app);

setTimeout(function () {
expect(blockchainInfo.toJSON()).to.be.empty;
expect(app.logger.info).to.have.been.calledWith('%s - error fetching data from blockchain.info', blockchainInfo.id, error.toString());
done();
}, 50);
}, 10);
});

});

it('should have the title set correctly', function () {
Expand Down

0 comments on commit c6e74c3

Please sign in to comment.