improved testing of tx history pagination
This commit is contained in:
parent
95498f5b8b
commit
ffe05c7fc7
|
@ -926,6 +926,10 @@ WalletService.prototype.getTxHistory = function(opts, cb) {
|
|||
var self = this;
|
||||
|
||||
function decorate(txs, addresses, proposals) {
|
||||
|
||||
var indexedAddresses = _.indexBy(addresses, 'address');
|
||||
var indexedProposals = _.indexBy(proposals, 'txid');
|
||||
|
||||
function sum(items, isMine, isChange) {
|
||||
var filter = {};
|
||||
if (_.isBoolean(isMine)) filter.isMine = isMine;
|
||||
|
@ -936,48 +940,64 @@ WalletService.prototype.getTxHistory = function(opts, cb) {
|
|||
}, 0);
|
||||
};
|
||||
|
||||
var indexedAddresses = _.indexBy(addresses, 'address');
|
||||
var indexedProposals = _.indexBy(proposals, 'txid');
|
||||
|
||||
_.each(txs, function(tx) {
|
||||
_.each(tx.inputs.concat(tx.outputs), function(item) {
|
||||
function classify(items) {
|
||||
return _.map(items, function(item) {
|
||||
var address = indexedAddresses[item.address];
|
||||
item.isMine = !!address;
|
||||
item.isChange = address ? address.isChange : false;
|
||||
return {
|
||||
address: item.address,
|
||||
amount: item.amount,
|
||||
isMine: !!address,
|
||||
isChange: address ? address.isChange : false,
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var amountIn = sum(tx.inputs, true);
|
||||
var amountOut = sum(tx.outputs, true, false);
|
||||
var amountOutChange = sum(tx.outputs, true, true);
|
||||
var amount;
|
||||
|
||||
return _.map(txs, function(tx) {
|
||||
var inputs = classify(tx.inputs);
|
||||
var outputs = classify(tx.outputs);
|
||||
|
||||
var amountIn = sum(inputs, true);
|
||||
var amountOut = sum(outputs, true, false);
|
||||
var amountOutChange = sum(outputs, true, true);
|
||||
var amount, action, addressTo;
|
||||
if (amountIn == (amountOut + amountOutChange + (amountIn > 0 ? tx.fees : 0))) {
|
||||
tx.action = 'moved';
|
||||
amount = amountOut;
|
||||
action = 'moved';
|
||||
} else {
|
||||
amount = amountIn - amountOut - amountOutChange - (amountIn > 0 ? tx.fees : 0);
|
||||
tx.action = amount > 0 ? 'sent' : 'received';
|
||||
action = amount > 0 ? 'sent' : 'received';
|
||||
}
|
||||
|
||||
tx.amount = Math.abs(amount);
|
||||
if (tx.action == 'sent' || tx.action == 'moved') {
|
||||
tx.addressTo = tx.outputs[0].address;
|
||||
amount = Math.abs(amount);
|
||||
if (action == 'sent' || action == 'moved') {
|
||||
addressTo = outputs[0].address;
|
||||
};
|
||||
|
||||
delete tx.inputs;
|
||||
delete tx.outputs;
|
||||
var newTx = {
|
||||
txid: tx.txid,
|
||||
action: action,
|
||||
amount: amount,
|
||||
fees: tx.fees,
|
||||
time: tx.time,
|
||||
addressTo: addressTo,
|
||||
confirmations: tx.confirmations,
|
||||
};
|
||||
|
||||
var proposal = indexedProposals[tx.txid];
|
||||
if (proposal) {
|
||||
tx.proposalId = proposal.id;
|
||||
tx.creatorName = proposal.creatorName;
|
||||
tx.message = proposal.message;
|
||||
tx.actions = _.map(proposal.actions, function(action) {
|
||||
newTx.proposalId = proposal.id;
|
||||
newTx.creatorName = proposal.creatorName;
|
||||
newTx.message = proposal.message;
|
||||
newTx.actions = _.map(proposal.actions, function(action) {
|
||||
return _.pick(action, ['createdOn', 'type', 'copayerId', 'copayerName', 'comment']);
|
||||
});
|
||||
// tx.sentTs = proposal.sentTs;
|
||||
// tx.merchant = proposal.merchant;
|
||||
//tx.paymentAckMemo = proposal.paymentAckMemo;
|
||||
// newTx.sentTs = proposal.sentTs;
|
||||
// newTx.merchant = proposal.merchant;
|
||||
//newTx.paymentAckMemo = proposal.paymentAckMemo;
|
||||
}
|
||||
|
||||
return newTx;
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -1024,8 +1044,7 @@ WalletService.prototype.getTxHistory = function(opts, cb) {
|
|||
var proposals = res[0];
|
||||
var txs = res[1];
|
||||
|
||||
decorate(txs, addresses, proposals);
|
||||
txs = paginate(txs);
|
||||
txs = paginate(decorate(txs, addresses, proposals));
|
||||
|
||||
return cb(null, txs);
|
||||
});
|
||||
|
|
|
@ -2345,54 +2345,66 @@ describe('Copay server', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
describe('Pagination', function() {
|
||||
beforeEach(function() {
|
||||
server._normalizeTxHistory = sinon.stub().returnsArg(0);
|
||||
var timestamps = [10, 50, 30, 40, 20];
|
||||
var txs = _.map(timestamps, function(ts, idx) {
|
||||
return {
|
||||
txid: (idx + 1).toString(),
|
||||
confirmations: ts / 10,
|
||||
fees: 100,
|
||||
time: ts,
|
||||
inputs: [{
|
||||
address: 'external',
|
||||
amount: 500,
|
||||
}],
|
||||
outputs: [{
|
||||
address: mainAddresses[0].address,
|
||||
amount: 200,
|
||||
}],
|
||||
};
|
||||
});
|
||||
|
||||
helpers.stubHistory(txs);
|
||||
});
|
||||
it('should get paginated tx history', function(done) {
|
||||
server.getTxHistory({
|
||||
it('should get various paginated tx history', function(done) {
|
||||
var testCases = [{
|
||||
opts: {
|
||||
minTs: 15,
|
||||
maxTs: 45,
|
||||
}, function(err, txs) {
|
||||
should.not.exist(err);
|
||||
should.exist(txs);
|
||||
txs.length.should.equal(3);
|
||||
_.pluck(txs, 'time').should.deep.equal([20, 30, 40]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should get paginated tx history with limit', function(done) {
|
||||
server.getTxHistory({
|
||||
},
|
||||
expected: [20, 30, 40],
|
||||
}, {
|
||||
opts: {
|
||||
minTs: 15,
|
||||
maxTs: 45,
|
||||
limit: 2,
|
||||
}, function(err, txs) {
|
||||
},
|
||||
expected: [20, 30],
|
||||
}, {
|
||||
opts: {
|
||||
maxTs: 35,
|
||||
},
|
||||
expected: [10, 20, 30],
|
||||
}, {
|
||||
opts: {
|
||||
minTs: 15,
|
||||
},
|
||||
expected: [20, 30, 40, 50],
|
||||
}, {
|
||||
opts: {
|
||||
minTs: 15,
|
||||
limit: 3,
|
||||
},
|
||||
expected: [20, 30, 40],
|
||||
}];
|
||||
|
||||
server._normalizeTxHistory = sinon.stub().returnsArg(0);
|
||||
var timestamps = [10, 50, 30, 40, 20];
|
||||
var txs = _.map(timestamps, function(ts, idx) {
|
||||
return {
|
||||
txid: (idx + 1).toString(),
|
||||
confirmations: ts / 10,
|
||||
fees: 100,
|
||||
time: ts,
|
||||
inputs: [{
|
||||
address: 'external',
|
||||
amount: 500,
|
||||
}],
|
||||
outputs: [{
|
||||
address: mainAddresses[0].address,
|
||||
amount: 200,
|
||||
}],
|
||||
};
|
||||
});
|
||||
helpers.stubHistory(txs);
|
||||
|
||||
async.each(testCases, function(testCase, next) {
|
||||
server.getTxHistory(testCase.opts, function(err, txs) {
|
||||
should.not.exist(err);
|
||||
should.exist(txs);
|
||||
txs.length.should.equal(2);
|
||||
_.pluck(txs, 'time').should.deep.equal([20, 30]);
|
||||
done();
|
||||
_.pluck(txs, 'time').should.deep.equal(testCase.expected);
|
||||
next();
|
||||
});
|
||||
});
|
||||
}, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue