From 5db61703b4bbd2d93883e28f7050712489cfad50 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Wed, 27 Jul 2016 09:46:20 -0300 Subject: [PATCH] better tests --- lib/server.js | 7 +- lib/storage.js | 34 +++++--- test/integration/helpers.js | 57 ++++++++++++- test/integration/server.js | 77 +++++++++++++----- test/testdata.js | 158 ------------------------------------ 5 files changed, 137 insertions(+), 196 deletions(-) diff --git a/lib/server.js b/lib/server.js index 91e5b84..c471b64 100644 --- a/lib/server.js +++ b/lib/server.js @@ -2789,10 +2789,11 @@ WalletService.prototype.getTxHistory = function(opts, cb) { bc.getTransactions(addressStrs, from, to, function(err, txs, total) { if (err) return cb(err); var txsNormalized = self._normalizeTxHistory(txs); - var txsToCache = _.filter(txsNormalized, function(i){ + var txsToCache = _.filter(txsNormalized, function(i) { return i.confirmations >= self.confirmationsToStartCaching; - }); - var index = total - from; + }).reverse(); + var index = total - to; + if (index < 0) index = 0; self.storage.storeTxHistoryCache(self.walletId, total, index, txsToCache, function(err) { next(err, txsNormalized); }) diff --git a/lib/storage.js b/lib/storage.js index ad2e788..bf68348 100644 --- a/lib/storage.js +++ b/lib/storage.js @@ -652,12 +652,15 @@ Storage.prototype.getTxHistoryCache = function(walletId, from, to, cb) { }; Storage.prototype.softResetTxHistoryCache = function(walletId, cb) { - this.db.collection(collections.CACHE).remove({ + this.db.collection(collections.CACHE).update({ walletId: walletId, type: 'historyCacheStatus', key: null }, { - w: 1 + cacheIsUpdated: false, + }, { + w: 1, + upsert: true, }, cb); }; @@ -681,7 +684,9 @@ Storage.prototype.clearTxHistoryCache = function(walletId, cb) { }); }; -Storage.prototype.storeTxHistoryCache = function(walletId, totalItems, firstPosition, itemsLastFirst, cb) { +// items should be in CHRONOLOGICAL order +// firstPosition, is the +Storage.prototype.storeTxHistoryCache = function(walletId, totalItems, firstPosition, items, cb) { $.shouldBeNumber(firstPosition); $.checkArgument(firstPosition >= 0); $.shouldBeNumber(totalItems); @@ -697,33 +702,37 @@ Storage.prototype.storeTxHistoryCache = function(walletId, totalItems, firstPosi if (err) return cb(err); result = result || []; - //create a sparce array, from the reversed input - _.each(itemsLastFirst.reverse(), function(i) { + //create a sparce array, from the input + _.each(items, function(i) { result[firstPosition++] = i; }); - var cacheIsReady = !!result[0]; - var now = Date.now(); + // TODO: check txid uniqness? self.db.collection(collections.CACHE).update({ walletId: walletId, - type: 'historyCacheStatus', + type: 'historyCache', key: null }, { - totalItems: totalItems, - updatedOn: now, + history: result }, { w: 1, upsert: true, }, function(err) { if (err) return cb(err); + var cacheIsComplete = !!result[0]; + var now = Date.now(); + self.db.collection(collections.CACHE).update({ walletId: walletId, - type: 'historyCache', + type: 'historyCacheStatus', key: null }, { - history: result + totalItems: totalItems, + updatedOn: now, + cacheIsComplete: cacheIsComplete, + cacheIsUpdated: true, }, { w: 1, upsert: true, @@ -731,6 +740,7 @@ Storage.prototype.storeTxHistoryCache = function(walletId, totalItems, firstPosi }); + }); }; diff --git a/test/integration/helpers.js b/test/integration/helpers.js index 2f66e3b..e533926 100644 --- a/test/integration/helpers.js +++ b/test/integration/helpers.js @@ -233,9 +233,9 @@ helpers._parseAmount = function(str) { switch (match[3]) { default: - case 'btc': + case 'btc': result.amount = Utils.strip(+match[2] * 1e8); - break; + break; case 'bit': result.amount = Utils.strip(+match[2] * 1e2); break @@ -322,8 +322,8 @@ helpers.stubBroadcast = function(thirdPartyBroadcast) { blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, null, null); }; -helpers.stubHistory = function(txs, totalItems) { - totalItems = totalItems || 100; +helpers.stubHistory = function(txs) { + var totalItems = txs.length; blockchainExplorer.getTransactions = function(addresses, from, to, cb) { var MAX_BATCH_SIZE = 100; var nbTxs = txs.length; @@ -511,4 +511,53 @@ helpers.createAndPublishTx = function(server, txOpts, signingKey, cb) { }); }; + +helpers.historyCacheTest = function(items) { + var template = { + txid: "fad88682ccd2ff34cac6f7355fe9ecd8addd9ef167e3788455972010e0d9d0de", + vin: [{ + txid: "0279ef7b21630f859deb723e28beac9e7011660bd1346c2da40321d2f7e34f04", + vout: 0, + n: 0, + addr: "2NAVFnsHqy5JvqDJydbHPx393LFqFFBQ89V", + valueSat: 45753, + value: 0.00045753, + }], + vout: [{ + value: "0.00011454", + n: 0, + scriptPubKey: { + addresses: [ + "2N7GT7XaN637eBFMmeczton2aZz5rfRdZso" + ] + } + }, { + value: "0.00020000", + n: 1, + scriptPubKey: { + addresses: [ + "mq4D3Va5mYHohMEHrgHNGzCjKhBKvuEhPE" + ] + } + }], + confirmations: 1, + time: 1424472242, + blocktime: 1424472242, + valueOut: 0.00031454, + valueIn: 0.00045753, + fees: 0.00014299 + }; + + var ret = []; + _.each(_.range(0, items), function(i) { + var t = _.clone(template); + t.txid = 'txid:' + i; + t.confirmations = items - i - 1; + t.time = t.blocktime = i; + ret.unshift(t); + }); + + return ret; +}; + module.exports = helpers; diff --git a/test/integration/server.js b/test/integration/server.js index b4555b1..1bf91c8 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -5895,7 +5895,7 @@ describe('Wallet service', function() { }); }); - describe('#getTxHistory', function() { + describe.only('#getTxHistory', function() { var server, wallet, mainAddresses, changeAddresses; beforeEach(function(done) { helpers.createAndJoinWallet(1, 1, function(s, w) { @@ -5924,16 +5924,19 @@ describe('Wallet service', function() { }); }); - it('should cache tx history from insight', function(done) { - helpers.stubHistory(TestData.historyToCache); + it('should store partial cache tx history from insight', function(done) { + var h = helpers.historyCacheTest(200); + helpers.stubHistory(h); var spy = sinon.spy(server.storage, 'storeTxHistoryCache'); - var toCache = _.filter(TestData.historyToCache, function(i) { + var toCache = _.filter(h, function(i) { return i.confirmations >= server.confirmationsToStartCaching; }); - var skip = 1; + var skip = 95; + var limit = 10; server.getTxHistory({ skip: skip, + limit: limit, }, function(err, txs) { // FROM the END, we are getting items @@ -5941,15 +5944,17 @@ describe('Wallet service', function() { should.not.exist(err); should.exist(txs); - txs.length.should.equal(TestData.historyToCache.length - skip); + txs.length.should.equal(limit); var calls = spy.getCalls(); calls.length.should.equal(1); - calls[0].args[1].should.equal(100); // total - calls[0].args[2].should.equal(100 - skip); // position - calls[0].args[3].length.should.equal(toCache.length - skip); + + calls[0].args[1].should.equal(200); // total + calls[0].args[2].should.equal(200 - skip - limit); // position + calls[0].args[3].length.should.equal(5); // 5 txs have confirmations>= 100 // should be reversed! - calls[0].args[3][0].txid.should.equal(toCache[toCache.length-1].txid); + calls[0].args[3][0].confirmations.should.equal(104); + calls[0].args[3][0].txid.should.equal(h[104].txid); server.storage.storeTxHistoryCache.restore(); done(); }); @@ -5957,25 +5962,59 @@ describe('Wallet service', function() { it('should not cache tx history from insight', function(done) { - helpers.stubHistory(TestData.history); + var h = helpers.historyCacheTest(200); + helpers.stubHistory(h); var spy = sinon.spy(server.storage, 'storeTxHistoryCache'); - var total = _.filter(TestData.history, function(i) { - return i.confirmations >= server.confirmationsToStartCaching; - }); - server.getTxHistory({}, function(err, txs) { + server.getTxHistory({ + skip:0, + limit: 10, + }, function(err, txs) { should.not.exist(err); should.exist(txs); - txs.length.should.equal(TestData.history.length); var calls = spy.getCalls(); calls.length.should.equal(1); - calls[0].args[1].should.equal(100); - calls[0].args[2].should.equal(100); - calls[0].args[3].length.should.deep.equal(total.length); + calls[0].args[3].length.should.equal(0); server.storage.storeTxHistoryCache.restore(); done(); }); }); + + it('should store cache all tx history from insight', function(done) { + var h = helpers.historyCacheTest(200); + helpers.stubHistory(h); + var spy = sinon.spy(server.storage, 'storeTxHistoryCache'); + var toCache = _.filter(h, function(i) { + return i.confirmations >= server.confirmationsToStartCaching; + }); + var skip = 195; + var limit = 5; + + server.getTxHistory({ + skip: skip, + limit: limit, + }, function(err, txs) { + + should.not.exist(err); + should.exist(txs); + txs.length.should.equal(limit); + var calls = spy.getCalls(); + calls.length.should.equal(1); + + calls[0].args[1].should.equal(200); // total + calls[0].args[2].should.equal(200 - skip - limit); // position + calls[0].args[3].length.should.equal(5); + + // should be reversed! + calls[0].args[3][0].confirmations.should.equal(199); + calls[0].args[3][0].txid.should.equal(h[199].txid); + server.storage.storeTxHistoryCache.restore(); + done(); + }); + }); + + + it('should get tx history for incoming txs', function(done) { server._normalizeTxHistory = sinon.stub().returnsArg(0); var txs = [{ diff --git a/test/testdata.js b/test/testdata.js index 3ebfd01..97eb999 100644 --- a/test/testdata.js +++ b/test/testdata.js @@ -251,165 +251,7 @@ var history = [ fees: 0.00014299 }]; -var historyToCache = [ - { - txid: "0279ef7b21630f859deb723e28beac9e7011660bd1346c2da40321d2f7e34f04", - vin: [{ - txid: "c8e221141e8bb60977896561b77fa59d6dacfcc10db82bf6f5f923048b11c70d", - vout: 0, - n: 0, - addr: "2N6Zutg26LEC4iYVxi7SHhopVLP1iZPU1rZ", - valueSat: 485645, - value: 0.00485645, - }, { - txid: "6e599eea3e2898b91087eb87e041c5d8dec5362447a8efba185ed593f6dc64c0", - vout: 1, - n: 1, - addr: "2MyqmcWjmVxW8i39wdk1CVPdEqKyFSY9H1S", - valueSat: 885590, - value: 0.0088559, - }], - vout: [{ - value: "0.00045753", - n: 0, - scriptPubKey: { - addresses: [ - "2NAVFnsHqy5JvqDJydbHPx393LFqFFBQ89V" - ] - }, - }, { - value: "0.01300000", - n: 1, - scriptPubKey: { - addresses: [ - "mq4D3Va5mYHohMEHrgHNGzCjKhBKvuEhPE" - ] - } - }], - confirmations: 120, - firstSeenTs: 1424471000, - valueOut: 0.01345753, - valueIn: 0.01371235, - fees: 0.00025482 -}, - { - txid: "0279ef7b21630f959deb723e28beac9e7011660bd1346c2da40321d2f7e34f04", - vin: [{ - txid: "c8e221141e8bb60977896561b77fa59d6dacfcc10db82bf6f5f923048b11c70d", - vout: 0, - n: 0, - addr: "2N6Zutg26LEC4iYVxi7SHhopVLP1iZPU1rZ", - valueSat: 485645, - value: 0.00485645, - }, { - txid: "6e599eea3e2898b91087eb87e041c5d8dec5362447a8efba185ed593f6dc64c0", - vout: 1, - n: 1, - addr: "2MyqmcWjmVxW8i39wdk1CVPdEqKyFSY9H1S", - valueSat: 885590, - value: 0.0088559, - }], - vout: [{ - value: "0.00045753", - n: 0, - scriptPubKey: { - addresses: [ - "2NAVFnsHqy5JvqDJydbHPx393LFqFFBQ89V" - ] - }, - }, { - value: "0.01300000", - n: 1, - scriptPubKey: { - addresses: [ - "mq4D3Va5mYHohMEHrgHNGzCjKhBKvuEhPE" - ] - } - }], - confirmations: 120, - firstSeenTs: 1424471000, - valueOut: 0.01345753, - valueIn: 0.01371235, - fees: 0.00025482 -}, - - { - txid: "0279ef7b21630f859deb723e28beac9e7011660bd1346c2da40321d2f7e34f04", - vin: [{ - txid: "c8e221141e8bb60977896561b77fa59d6dacfcc10db82bf6f5f923048b11c70d", - vout: 0, - n: 0, - addr: "2N6Zutg26LEC4iYVxi7SHhopVLP1iZPU1rZ", - valueSat: 485645, - value: 0.00485645, - }, { - txid: "6e599eea3e2898b91087eb87e041c5d8dec5362447a8efba185ed593f6dc64c0", - vout: 1, - n: 1, - addr: "2MyqmcWjmVxW8i39wdk1CVPdEqKyFSY9H1S", - valueSat: 885590, - value: 0.0088559, - }], - vout: [{ - value: "0.00045753", - n: 0, - scriptPubKey: { - addresses: [ - "2NAVFnsHqy5JvqDJydbHPx393LFqFFBQ89V" - ] - }, - }, { - value: "0.01300000", - n: 1, - scriptPubKey: { - addresses: [ - "mq4D3Va5mYHohMEHrgHNGzCjKhBKvuEhPE" - ] - } - }], - confirmations: 2, - firstSeenTs: 1424471041, - blocktime: 1424471051, - valueOut: 0.01345753, - valueIn: 0.01371235, - fees: 0.00025482 -}, { - txid: "fad88682ccd2ff34cac6f7355fe9ecd8addd9ef167e3788455972010e0d9d0de", - vin: [{ - txid: "0279ef7b21630f859deb723e28beac9e7011660bd1346c2da40321d2f7e34f04", - vout: 0, - n: 0, - addr: "2NAVFnsHqy5JvqDJydbHPx393LFqFFBQ89V", - valueSat: 45753, - value: 0.00045753, - }], - vout: [{ - value: "0.00011454", - n: 0, - scriptPubKey: { - addresses: [ - "2N7GT7XaN637eBFMmeczton2aZz5rfRdZso" - ] - } - }, { - value: "0.00020000", - n: 1, - scriptPubKey: { - addresses: [ - "mq4D3Va5mYHohMEHrgHNGzCjKhBKvuEhPE" - ] - } - }], - confirmations: 101, - time: 1424472242, - blocktime: 1424472242, - valueOut: 0.00031454, - valueIn: 0.00045753, - fees: 0.00014299 -}]; - module.exports.keyPair = keyPair; module.exports.copayers = copayers; module.exports.history = history; -module.exports.historyToCache = historyToCache;