update tests

This commit is contained in:
Patrick Nagurny 2015-07-30 17:45:55 -04:00
parent 4a4e71797a
commit 2a55c900ce
3 changed files with 178 additions and 34 deletions

View File

@ -346,7 +346,6 @@ AddressModule.prototype.getAddressHistory = function(address, queryMempool, call
}); });
} }
this.getOutputs(address, queryMempool, function(err, outputs) { this.getOutputs(address, queryMempool, function(err, outputs) {
if(err) { if(err) {
return callback(err); return callback(err);
@ -395,7 +394,7 @@ AddressModule.prototype.getAddressHistory = function(address, queryMempool, call
// sort by height // sort by height
history.sort(function(a, b) { history.sort(function(a, b) {
return a.height < b.height; return a.height > b.height;
}); });
callback(null, history); callback(null, history);

View File

@ -8,6 +8,8 @@ var blockData = require('../data/livenet-345003.json');
var bitcore = require('bitcore'); var bitcore = require('bitcore');
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var errors = bitcoindjs.errors; var errors = bitcoindjs.errors;
var chainlib = require('chainlib');
var levelup = chainlib.deps.levelup;
describe('AddressModule', function() { describe('AddressModule', function() {
@ -15,7 +17,7 @@ describe('AddressModule', function() {
it('should return the correct methods', function() { it('should return the correct methods', function() {
var am = new AddressModule({}); var am = new AddressModule({});
var methods = am.getAPIMethods(); var methods = am.getAPIMethods();
methods.length.should.equal(6); methods.length.should.equal(5);
}); });
}); });
@ -119,7 +121,7 @@ describe('AddressModule', function() {
operations[3].type.should.equal('put'); operations[3].type.should.equal('put');
var expected3 = ['sp', key3.prevTxId, key3.prevOutputIndex].join('-'); var expected3 = ['sp', key3.prevTxId, key3.prevOutputIndex].join('-');
operations[3].key.should.equal(expected3); operations[3].key.should.equal(expected3);
operations[3].value.should.equal([value3.txid].join(':')); operations[3].value.should.equal([value3.txid, value3.inputIndex].join(':'));
operations[64].type.should.equal('put'); operations[64].type.should.equal('put');
var expected64 = ['outs', key64.address, key64.timestamp, key64.txid, key64.outputIndex].join('-'); var expected64 = ['outs', key64.address, key64.timestamp, key64.txid, key64.outputIndex].join('-');
operations[64].key.should.equal(expected64); operations[64].key.should.equal(expected64);
@ -136,7 +138,7 @@ describe('AddressModule', function() {
operations[0].value.should.equal([value0.satoshis, value0.script, value0.blockHeight].join(':')); operations[0].value.should.equal([value0.satoshis, value0.script, value0.blockHeight].join(':'));
operations[3].type.should.equal('del'); operations[3].type.should.equal('del');
operations[3].key.should.equal(['sp', key3.prevTxId, key3.prevOutputIndex].join('-')); operations[3].key.should.equal(['sp', key3.prevTxId, key3.prevOutputIndex].join('-'));
operations[3].value.should.equal([value3.txid].join(':')); operations[3].value.should.equal([value3.txid, value3.inputIndex].join(':'));
operations[64].type.should.equal('del'); operations[64].type.should.equal('del');
operations[64].key.should.equal(['outs', key64.address, key64.timestamp, key64.txid, key64.outputIndex].join('-')); operations[64].key.should.equal(['outs', key64.address, key64.timestamp, key64.txid, key64.outputIndex].join('-'));
operations[64].value.should.equal([value64.satoshis, value64.script, value64.blockHeight].join(':')); operations[64].value.should.equal([value64.satoshis, value64.script, value64.blockHeight].join(':'));
@ -495,66 +497,208 @@ describe('AddressModule', function() {
}); });
}); });
describe('#getSpendTxForOutput', function() { describe('#getSpendInfoForOutput', function() {
it('should call store.get and db.getTransaction with the right values', function(done) { it('should call store.get the right values', function(done) {
var db = { var db = {
store: { store: {
get: sinon.stub().callsArgWith(1, null, 'spendtxid') get: sinon.stub().callsArgWith(1, null, 'spendtxid:1')
}, }
getTransaction: sinon.stub().callsArgWith(2, null, 'spendtx')
}; };
var am = new AddressModule({db: db}); var am = new AddressModule({db: db});
am.getSpendTxForOutput('txid', 'outputindex', true, function(err, tx) { am.getSpendInfoForOutput('txid', 3, function(err, info) {
should.not.exist(err); should.not.exist(err);
tx.should.equal('spendtx'); info.txid.should.equal('spendtxid');
db.store.get.args[0][0].should.equal('sp-txid-outputindex'); info.inputIndex.should.equal('1');
db.getTransaction.args[0][0].should.equal('spendtxid'); db.store.get.args[0][0].should.equal('sp-txid-3');
db.getTransaction.args[0][1].should.equal(true);
done(); done();
}); });
}); });
}); });
describe('#getTransactionsForAddress', function() { describe('#getAddressHistory', function() {
var outputs = [ var incoming = [
{ {
txid: 'tx1', txid: 'tx1',
outputIndex: 0, outputIndex: 0,
spentTx: 'tx2' spentTx: 'tx2',
inputIndex: 0,
height: 1,
timestamp: 1438289011844,
satoshis: 5000
}, },
{ {
txid: 'tx3', txid: 'tx3',
outputIndex: 1 outputIndex: 1,
height: 3,
timestamp: 1438289031844,
satoshis: 2000
}, },
{ {
txid: 'tx4', txid: 'tx4',
outputIndex: 2, outputIndex: 2,
spentTx: 'tx5' spentTx: 'tx5',
inputIndex: 1,
height: 4,
timestamp: 1438289041844,
satoshis: 3000
},
];
var outgoing = [
{
txid: 'tx2',
height: 2,
timestamp: 1438289021844,
inputs: [
{
output: {
satoshis: 5000
}
}
]
},
{
txid: 'tx5',
height: 5,
timestamp: 1438289051844,
inputs: [
{},
{
output: {
satoshis: 3000
}
}
]
} }
]; ];
var db = { var db = {
getTransaction: function(txid, queryMempool, callback) { getTransactionWithBlockInfo: function(txid, queryMempool, callback) {
callback(null, txid); var transaction = {
populateInputs: sinon.stub().callsArg(2)
};
for(var i = 0; i < incoming.length; i++) {
if(incoming[i].txid === txid) {
if(incoming[i].error) {
return callback(new Error(incoming[i].error));
}
transaction.hash = txid;
transaction.__height = incoming[i].height;
transaction.__timestamp = incoming[i].timestamp;
return callback(null, transaction);
}
}
for(var i = 0; i < outgoing.length; i++) {
if(outgoing[i].txid === txid) {
if(outgoing[i].error) {
return callback(new Error(outgoing[i].error));
}
transaction.hash = txid;
transaction.__height = outgoing[i].height;
transaction.__timestamp = outgoing[i].timestamp;
transaction.inputs = outgoing[i].inputs;
return callback(null, transaction);
}
}
callback(new Error('tx ' + txid + ' not found'));
} }
}; };
var am = new AddressModule({db: db}); var am = new AddressModule({db: db});
am.getOutputs = sinon.stub().callsArgWith(2, null, outputs); am.getOutputs = sinon.stub().callsArgWith(2, null, incoming);
am.getSpendTxForOutput = function(txid, outputIndex, queryMempool, callback) { am.getSpendInfoForOutput = function(txid, outputIndex, callback) {
for(var i = 0; i < outputs.length; i++) { for(var i = 0; i < incoming.length; i++) {
if(outputs[i].txid === txid && outputs[i].outputIndex === outputIndex && outputs[i].spentTx) { if(incoming[i].txid === txid && incoming[i].outputIndex === outputIndex && incoming[i].spentTx) {
return callback(null, outputs[i].spentTx); if(incoming[i].spendError) {
return callback(new Error(incoming[i].spendError));
}
return callback(null, {
txid: incoming[i].spentTx,
inputIndex: incoming[i].inputIndex
});
} }
} }
callback(new levelup.errors.NotFoundError()); callback(new levelup.errors.NotFoundError());
}; };
it('should give transactions containing address as an output and an input', function(done) { it('should give transaction history for an address', function(done) {
am.getTransactionsForAddress('address', true, function(err, txs) { am.getAddressHistory('address', true, function(err, history) {
should.not.exist(err); should.not.exist(err);
txs.should.deep.equal(['tx1', 'tx2', 'tx3', 'tx4', 'tx5']); console.log(history);
history[0].transaction.hash.should.equal('tx1');
history[0].satoshis.should.equal(5000);
history[0].height.should.equal(1);
history[0].timestamp.should.equal(1438289011844);
history[1].transaction.hash.should.equal('tx2');
history[1].satoshis.should.equal(-5000);
history[1].height.should.equal(2);
history[1].timestamp.should.equal(1438289021844);
history[2].transaction.hash.should.equal('tx3');
history[2].satoshis.should.equal(2000);
history[2].height.should.equal(3);
history[2].timestamp.should.equal(1438289031844);
history[3].transaction.hash.should.equal('tx4');
history[3].satoshis.should.equal(3000);
history[3].height.should.equal(4);
history[3].timestamp.should.equal(1438289041844);
history[4].transaction.hash.should.equal('tx5');
history[4].satoshis.should.equal(-3000);
history[4].height.should.equal(5);
history[4].timestamp.should.equal(1438289051844);
done();
});
});
it('should give an error if the second getTransactionInfo gives an error', function(done) {
outgoing[0].error = 'txinfo2err';
am.getAddressHistory('address', true, function(err, history) {
should.exist(err);
err.message.should.equal('txinfo2err');
outgoing[0].error = null;
done();
});
});
it('should give an error if getSpendInfoForOutput gives an error', function(done) {
incoming[0].spendError = 'spenderr';
am.getAddressHistory('address', true, function(err, history) {
should.exist(err);
err.message.should.equal('spenderr');
incoming[0].spendError = null;
done();
});
});
it('should give an error if the first getTransactionInfo gives an error', function(done) {
incoming[1].error = 'txinfo1err';
am.getAddressHistory('address', true, function(err, history) {
should.exist(err);
err.message.should.equal('txinfo1err');
incoming[1].error = null;
done();
});
});
it('should give an error if populateInputs gives an error', function(done) {
var populateStub = sinon.stub().callsArgWith(2, new Error('populateerr'));
sinon.stub(db, 'getTransactionWithBlockInfo').callsArgWith(2, null, {
populateInputs: populateStub
});
am.getAddressHistory('address', true, function(err, history) {
should.exist(err);
err.message.should.equal('populateerr');
db.getTransactionWithBlockInfo.restore();
done();
});
});
it('should give an error if getOutputs gives an error', function(done) {
am.getOutputs = sinon.stub().callsArgWith(2, new Error('getoutputserr'));
am.getAddressHistory('address', true, function(err, history) {
should.exist(err);
err.message.should.equal('getoutputserr');
done(); done();
}); });
}); });

View File

@ -106,6 +106,7 @@ describe('Bitcoin Transaction', function() {
describe('#populateInputs', function() { describe('#populateInputs', function() {
it('will call _populateInput with transactions', function() { it('will call _populateInput with transactions', function() {
var tx = new Transaction(); var tx = new Transaction();
tx.isCoinbase = sinon.stub().returns(false);
tx._populateInput = sinon.stub().callsArg(3); tx._populateInput = sinon.stub().callsArg(3);
tx.inputs = ['input']; tx.inputs = ['input'];
var transactions = []; var transactions = [];
@ -138,7 +139,7 @@ describe('Bitcoin Transaction', function() {
it('if an error happened it should pass it along', function(done) { it('if an error happened it should pass it along', function(done) {
var tx = new Transaction(); var tx = new Transaction();
var db = { var db = {
getTransactionFromDB: sinon.stub().callsArgWith(1, new Error('error')) getTransaction: sinon.stub().callsArgWith(2, new Error('error'))
}; };
tx._populateInput(db, input, [], function(err) { tx._populateInput(db, input, [], function(err) {
should.exist(err); should.exist(err);
@ -149,7 +150,7 @@ describe('Bitcoin Transaction', function() {
it('should return an error if the transaction for the input does not exist', function(done) { it('should return an error if the transaction for the input does not exist', function(done) {
var tx = new Transaction(); var tx = new Transaction();
var db = { var db = {
getTransactionFromDB: sinon.stub().callsArgWith(1, new levelup.errors.NotFoundError()) getTransaction: sinon.stub().callsArgWith(2, new levelup.errors.NotFoundError())
}; };
tx._populateInput(db, input, [], function(err) { tx._populateInput(db, input, [], function(err) {
should.exist(err); should.exist(err);
@ -160,7 +161,7 @@ describe('Bitcoin Transaction', function() {
it('should look through poolTransactions if database does not have transaction', function(done) { it('should look through poolTransactions if database does not have transaction', function(done) {
var tx = new Transaction(); var tx = new Transaction();
var db = { var db = {
getTransactionFromDB: sinon.stub().callsArgWith(1, new levelup.errors.NotFoundError()) getTransaction: sinon.stub().callsArgWith(2, new levelup.errors.NotFoundError())
}; };
var transactions = [ var transactions = [
{ {
@ -179,7 +180,7 @@ describe('Bitcoin Transaction', function() {
prevTx.outputs = ['output']; prevTx.outputs = ['output'];
var tx = new Transaction(); var tx = new Transaction();
var db = { var db = {
getTransactionFromDB: sinon.stub().callsArgWith(1, null, prevTx) getTransaction: sinon.stub().callsArgWith(2, null, prevTx)
}; };
tx._populateInput(db, input, [], function(err) { tx._populateInput(db, input, [], function(err) {
should.not.exist(err); should.not.exist(err);