From 43ec2d3b3402aa35db9d4d841be22b712ba083d6 Mon Sep 17 00:00:00 2001 From: Patrick Nagurny Date: Fri, 14 Aug 2015 16:44:40 -0400 Subject: [PATCH] add more tests --- lib/modules/address.js | 2 +- test/db.unit.js | 136 +++++++++++++++++++++++++++++++++++ test/modules/address.unit.js | 94 +++++++++++++++++++++++- 3 files changed, 228 insertions(+), 4 deletions(-) diff --git a/lib/modules/address.js b/lib/modules/address.js index 5f4fecf1..7bddbe7c 100644 --- a/lib/modules/address.js +++ b/lib/modules/address.js @@ -55,7 +55,7 @@ AddressModule.prototype.getPublishEvents = function() { scope: this, subscribe: this.subscribe.bind(this, 'address/balance'), unsubscribe: this.unsubscribe.bind(this, 'address/balance') - }, + } ]; }; diff --git a/test/db.unit.js b/test/db.unit.js index b52a8827..82e00076 100644 --- a/test/db.unit.js +++ b/test/db.unit.js @@ -10,10 +10,25 @@ var errors = bitcoindjs.errors; var memdown = require('memdown'); var inherits = require('util').inherits; var BaseModule = require('../lib/module'); +var bitcore = require('bitcore'); +var Transaction = bitcore.Transaction; describe('Bitcoin DB', function() { var coinbaseAmount = 50 * 1e8; + describe('#initialize', function() { + it('should emit ready', function(done) { + var db = new DB({store: memdown}); + db._modules = ['mod1', 'mod2']; + db.bitcoind = { + on: sinon.spy() + }; + db.addModule = sinon.spy(); + db.on('ready', done); + db.initialize(); + }); + }); + describe('#getTransaction', function() { it('will return a NotFound error', function(done) { var db = new DB({store: memdown}); @@ -89,6 +104,127 @@ describe('Bitcoin DB', function() { }); }); + describe('#getPrevHash', function() { + it('should return prevHash from bitcoind', function(done) { + var db = new DB({store: memdown}); + db.bitcoind = { + getBlockIndex: sinon.stub().returns({ + prevHash: 'prevhash' + }) + }; + + db.getPrevHash('hash', function(err, prevHash) { + should.not.exist(err); + prevHash.should.equal('prevhash'); + done(); + }); + }); + + it('should give an error if bitcoind could not find it', function(done) { + var db = new DB({store: memdown}); + db.bitcoind = { + getBlockIndex: sinon.stub().returns(null) + }; + + db.getPrevHash('hash', function(err, prevHash) { + should.exist(err); + done(); + }); + }); + }); + + describe('#getTransactionWithBlockInfo', function() { + it('should give a transaction with height and timestamp', function(done) { + var txBuffer = new Buffer('01000000016f95980911e01c2c664b3e78299527a47933aac61a515930a8fe0213d1ac9abe01000000da0047304402200e71cda1f71e087c018759ba3427eb968a9ea0b1decd24147f91544629b17b4f0220555ee111ed0fc0f751ffebf097bdf40da0154466eb044e72b6b3dcd5f06807fa01483045022100c86d6c8b417bff6cc3bbf4854c16bba0aaca957e8f73e19f37216e2b06bb7bf802205a37be2f57a83a1b5a8cc511dc61466c11e9ba053c363302e7b99674be6a49fc0147522102632178d046673c9729d828cfee388e121f497707f810c131e0d3fc0fe0bd66d62103a0951ec7d3a9da9de171617026442fcd30f34d66100fab539853b43f508787d452aeffffffff0240420f000000000017a9148a31d53a448c18996e81ce67811e5fb7da21e4468738c9d6f90000000017a9148ce5408cfeaddb7ccb2545ded41ef478109454848700000000', 'hex'); + var info = { + height: 530482, + timestamp: 1439559434000, + buffer: txBuffer + }; + + var db = new DB({store: memdown}); + db.bitcoind = { + getTransactionWithBlockInfo: sinon.stub().callsArgWith(2, null, info) + }; + + db.getTransactionWithBlockInfo('2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f', true, function(err, tx) { + should.not.exist(err); + tx.__height.should.equal(info.height); + tx.__timestamp.should.equal(info.timestamp); + done(); + }); + }); + it('should give an error if one occurred', function(done) { + var db = new DB({store: memdown}); + db.bitcoind = { + getTransactionWithBlockInfo: sinon.stub().callsArgWith(2, new Error('error')) + }; + + db.getTransactionWithBlockInfo('tx', true, function(err, tx) { + should.exist(err); + done(); + }); + }); + }); + + describe('#sendTransaction', function() { + it('should give the txid on success', function(done) { + var db = new DB({store: memdown}); + db.bitcoind = { + sendTransaction: sinon.stub().returns('txid') + }; + + var tx = new Transaction(); + db.sendTransaction(tx, function(err, txid) { + should.not.exist(err); + txid.should.equal('txid'); + done(); + }); + }); + it('should give an error if bitcoind threw an error', function(done) { + var db = new DB({store: memdown}); + db.bitcoind = { + sendTransaction: sinon.stub().throws(new Error('error')) + }; + + var tx = new Transaction(); + db.sendTransaction(tx, function(err, txid) { + should.exist(err); + done(); + }); + }); + }); + + describe("#estimateFee", function() { + // To accommodate weird bitcoind behavior where 1 block always results in -1 + it('should set blocks to 2 if 1 was passed in', function(done) { + var db = new DB({store: memdown}); + db.bitcoind = { + estimateFee: sinon.stub().returns(1000) + }; + + db.estimateFee(1, function(err, fee) { + should.not.exist(err); + fee.should.equal(1000); + db.bitcoind.estimateFee.args[0][0].should.equal(2); + done(); + }); + }); + + it('should pass along the fee from bitcoind', function(done) { + var db = new DB({store: memdown}); + db.bitcoind = { + estimateFee: sinon.stub().returns(1000) + }; + + db.estimateFee(5, function(err, fee) { + should.not.exist(err); + fee.should.equal(1000); + db.bitcoind.estimateFee.args[0][0].should.equal(5); + done(); + }); + }); + }); describe('#buildGenesisData', function() { it('build genisis data', function() { var db = new DB({path: 'path', store: memdown}); diff --git a/test/modules/address.unit.js b/test/modules/address.unit.js index bda520da..4b8653aa 100644 --- a/test/modules/address.unit.js +++ b/test/modules/address.unit.js @@ -2,12 +2,12 @@ var should = require('chai').should(); var sinon = require('sinon'); -var bitcoindjs = require('../../'); -var AddressModule = bitcoindjs.modules.AddressModule; +var bitcorenode = require('../../'); +var AddressModule = bitcorenode.modules.AddressModule; var blockData = require('../data/livenet-345003.json'); var bitcore = require('bitcore'); var EventEmitter = require('events').EventEmitter; -var errors = bitcoindjs.errors; +var errors = bitcorenode.errors; var chainlib = require('chainlib'); var levelup = chainlib.deps.levelup; @@ -494,6 +494,94 @@ describe('AddressModule', function() { }); }); + describe('#getUnspentOutputs', function() { + it('should concatenate utxos for multiple addresses, even those with none found', function(done) { + var addresses = { + 'addr1': ['utxo1', 'utxo2'], + 'addr2': new errors.NoOutputs(), + 'addr3': ['utxo3'] + }; + + var db = { + bitcoind: { + on: sinon.spy() + } + }; + var am = new AddressModule({db: db}); + am.getUnspentOutputsForAddress = function(address, queryMempool, callback) { + var result = addresses[address]; + if(result instanceof Error) { + return callback(result); + } else { + return callback(null, result); + } + }; + + am.getUnspentOutputs(['addr1', 'addr2', 'addr3'], true, function(err, utxos) { + should.not.exist(err); + utxos.should.deep.equal(['utxo1', 'utxo2', 'utxo3']); + done(); + }); + }); + it('should give an error if an error occurred', function(done) { + var addresses = { + 'addr1': ['utxo1', 'utxo2'], + 'addr2': new Error('weird error'), + 'addr3': ['utxo3'] + }; + + var db = { + bitcoind: { + on: sinon.spy() + } + }; + var am = new AddressModule({db: db}); + am.getUnspentOutputsForAddress = function(address, queryMempool, callback) { + var result = addresses[address]; + if(result instanceof Error) { + return callback(result); + } else { + return callback(null, result); + } + }; + + am.getUnspentOutputs(['addr1', 'addr2', 'addr3'], true, function(err, utxos) { + should.exist(err); + err.message.should.equal('weird error'); + done(); + }); + }); + + it('should also work for a single address', function(done) { + var addresses = { + 'addr1': ['utxo1', 'utxo2'], + 'addr2': new Error('weird error'), + 'addr3': ['utxo3'] + }; + + var db = { + bitcoind: { + on: sinon.spy() + } + }; + var am = new AddressModule({db: db}); + am.getUnspentOutputsForAddress = function(address, queryMempool, callback) { + var result = addresses[address]; + if(result instanceof Error) { + return callback(result); + } else { + return callback(null, result); + } + }; + + am.getUnspentOutputs('addr1', true, function(err, utxos) { + should.not.exist(err); + utxos.should.deep.equal(['utxo1', 'utxo2']); + done(); + }); + }); + }); + describe('#getUnspentOutputsForAddress', function() { it('should filter out spent outputs', function(done) { var outputs = [