From 78495003f86a4b03c465bff2140525a873c1695b Mon Sep 17 00:00:00 2001 From: Justin Kook Date: Tue, 26 Feb 2019 16:03:59 -0500 Subject: [PATCH 1/5] replaced deprecated orderBy with .sort() mongo query for getBalanceAtTime() --- packages/bitcore-node/src/models/coin.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/bitcore-node/src/models/coin.ts b/packages/bitcore-node/src/models/coin.ts index f73ac282a79..7c59dfe93d8 100644 --- a/packages/bitcore-node/src/models/coin.ts +++ b/packages/bitcore-node/src/models/coin.ts @@ -100,14 +100,17 @@ class CoinModel extends BaseModel { async getBalanceAtTime(params: { query: any; time: string; chain: string; network: string }) { let { query, time, chain, network } = params; - const block = await BlockStorage.collection.findOne({ - $query: { - chain, - network, - timeNormalized: { $lte: new Date(time) } - }, - $orderBy: { timeNormalized: -1 } - }); + const [block] = await BlockStorage.collection + .find({ + $query: { + chain, + network, + timeNormalized: { $lte: new Date(time) } + } + }) + .limit(1) + .sort({ timeNormalized: -1 }) + .toArray(); const blockHeight = block!.height; const combinedQuery = Object.assign( {}, From 3e53dd638d46eb48e92350c8b04c58041761d334 Mon Sep 17 00:00:00 2001 From: Justin Kook Date: Tue, 26 Feb 2019 16:10:28 -0500 Subject: [PATCH 2/5] changed coin unit test BlockStorage.findOne to .find --- .../test/unit/models/coin.unit.ts | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/packages/bitcore-node/test/unit/models/coin.unit.ts b/packages/bitcore-node/test/unit/models/coin.unit.ts index f6f6f30b3b7..6df7425a959 100644 --- a/packages/bitcore-node/test/unit/models/coin.unit.ts +++ b/packages/bitcore-node/test/unit/models/coin.unit.ts @@ -6,7 +6,7 @@ import sinon from 'sinon'; import { BlockStorage } from '../../../src/models/block'; import { mockStorage } from '../../helpers/index.js'; -describe('Coin Model', function () { +describe('Coin Model', function() { describe('_apiTransform', () => { it('should return the transform object with coin info', () => { let id = new ObjectId(); @@ -91,40 +91,40 @@ describe('Coin Model', function () { sandbox.restore(); }); - it('should return an object with confirmed, unconfirmed, and balance when additional time parameter is passed in', async () => { - let id = new ObjectId("5c364e342ab5602e97a56f0e"); + it('should return an object with confirmed, unconfirmed, and balance when additional time parameter is passed in', async () => { + let id = new ObjectId('5c364e342ab5602e97a56f0e'); let chain = 'BTC'; let network = 'regtest'; let time = new Date().toISOString(); let query = { wallets: id, 'wallets.0': { $exists: true } }; - let matchObject = { - "$or": [ + let matchObject = { + $or: [ { - "spentHeight": { - "$gt": 123 + spentHeight: { + $gt: 123 } }, { - "spentHeight": { - "$lt": 0 + spentHeight: { + $lt: 0 } } ], - "mintHeight": { - "$lte": 123 + mintHeight: { + $lte: 123 }, - "wallets": new ObjectId('5c364e342ab5602e97a56f0e'), - "wallets.0": { '$exists': true }, - } + wallets: new ObjectId('5c364e342ab5602e97a56f0e'), + 'wallets.0': { $exists: true } + }; let blockModelHeight = { height: 123 }; - mockStorage([{_id: 'confirmed', balance: 123123}, {_id: 'unconfirmed', balance: 1}]); - Object.assign(BlockStorage.collection.findOne, sandbox.stub().resolves(blockModelHeight)); + mockStorage([{ _id: 'confirmed', balance: 123123 }, { _id: 'unconfirmed', balance: 1 }]); + Object.assign(BlockStorage.collection.find, sandbox.stub().resolves(blockModelHeight)); let coinModelAggregateSpy = CoinStorage.collection.aggregate as sinon.SinonSpy; let blockModelFindOneSpy = BlockStorage.collection.findOne as sinon.SinonSpy; - const result = await CoinStorage.getBalanceAtTime({query, time, chain, network}); - expect(coinModelAggregateSpy.called).to.deep.equal(true, "CoinStorage.aggregation should have been called"); + const result = await CoinStorage.getBalanceAtTime({ query, time, chain, network }); + expect(coinModelAggregateSpy.called).to.deep.equal(true, 'CoinStorage.aggregation should have been called'); expect(blockModelFindOneSpy.called).to.deep.equal(true, 'BlockModel.findOne should have been called'); expect(coinModelAggregateSpy.getCall(0).args[0][0].$match).to.deep.equal(matchObject); expect(result).to.has.property('confirmed'); @@ -143,20 +143,20 @@ describe('Coin Model', function () { sandbox.restore(); }); - it('should return an object with confirmed, unconfirmed, and balance', async () => { - let id = new ObjectId("5c364e342ab5602e97a56f0e"); + it('should return an object with confirmed, unconfirmed, and balance', async () => { + let id = new ObjectId('5c364e342ab5602e97a56f0e'); let query = { - "wallets": id, - 'wallets.0': { "$exists": true }, - "spentHeight": { "$lt": 0 }, - "mintHeight": { "$gt": -3 } + wallets: id, + 'wallets.0': { $exists: true }, + spentHeight: { $lt: 0 }, + mintHeight: { $gt: -3 } }; - mockStorage([{_id: 'confirmed', balance: 123123}, {_id: 'unconfirmed', balance: 1}]); + mockStorage([{ _id: 'confirmed', balance: 123123 }, { _id: 'unconfirmed', balance: 1 }]); let coinModelAggregateSpy = CoinStorage.collection.aggregate as sinon.SinonSpy; - const result = await CoinStorage.getBalance({query}); - expect(coinModelAggregateSpy.called).to.deep.equal(true, "CoinStorage.aggregation should have been called"); + const result = await CoinStorage.getBalance({ query }); + expect(coinModelAggregateSpy.called).to.deep.equal(true, 'CoinStorage.aggregation should have been called'); expect(coinModelAggregateSpy.getCall(0).args[0][0].$match).to.deep.equal(query); expect(result).to.has.property('confirmed'); expect(result).to.has.property('unconfirmed'); From 756e8f186dc88c3c490067f2625f0051c8a18787 Mon Sep 17 00:00:00 2001 From: Justin Kook Date: Tue, 26 Feb 2019 16:11:57 -0500 Subject: [PATCH 3/5] blockModelFindSpy changed findOne to find --- packages/bitcore-node/test/unit/models/coin.unit.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bitcore-node/test/unit/models/coin.unit.ts b/packages/bitcore-node/test/unit/models/coin.unit.ts index 6df7425a959..8d765b1ac9b 100644 --- a/packages/bitcore-node/test/unit/models/coin.unit.ts +++ b/packages/bitcore-node/test/unit/models/coin.unit.ts @@ -121,11 +121,11 @@ describe('Coin Model', function() { mockStorage([{ _id: 'confirmed', balance: 123123 }, { _id: 'unconfirmed', balance: 1 }]); Object.assign(BlockStorage.collection.find, sandbox.stub().resolves(blockModelHeight)); let coinModelAggregateSpy = CoinStorage.collection.aggregate as sinon.SinonSpy; - let blockModelFindOneSpy = BlockStorage.collection.findOne as sinon.SinonSpy; + let blockModelFindSpy = BlockStorage.collection.find as sinon.SinonSpy; const result = await CoinStorage.getBalanceAtTime({ query, time, chain, network }); expect(coinModelAggregateSpy.called).to.deep.equal(true, 'CoinStorage.aggregation should have been called'); - expect(blockModelFindOneSpy.called).to.deep.equal(true, 'BlockModel.findOne should have been called'); + expect(blockModelFindSpy.called).to.deep.equal(true, 'BlockModel.find should have been called'); expect(coinModelAggregateSpy.getCall(0).args[0][0].$match).to.deep.equal(matchObject); expect(result).to.has.property('confirmed'); expect(result).to.has.property('unconfirmed'); From c3866e6533962aec36d9f1be4d774a1606311a33 Mon Sep 17 00:00:00 2001 From: Justin Kook Date: Tue, 26 Feb 2019 16:50:38 -0500 Subject: [PATCH 4/5] added mockModel function, mock BlockModel and return block height in coin unit tests --- packages/bitcore-node/test/helpers/index.ts | 6 ++++++ packages/bitcore-node/test/unit/models/coin.unit.ts | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/bitcore-node/test/helpers/index.ts b/packages/bitcore-node/test/helpers/index.ts index b8ff39804a9..d74dcc0c40d 100644 --- a/packages/bitcore-node/test/helpers/index.ts +++ b/packages/bitcore-node/test/helpers/index.ts @@ -58,3 +58,9 @@ export function mockStorage(toReturn, collectionMethods = {}) { } as any; return Storage; } + +export function mockModel(model, toReturn, collectionMethods = {}) { + model.db = { + collection: sinon.stub().returns(mockCollection(toReturn, collectionMethods)) + }; +} diff --git a/packages/bitcore-node/test/unit/models/coin.unit.ts b/packages/bitcore-node/test/unit/models/coin.unit.ts index 8d765b1ac9b..1aba5eebbfd 100644 --- a/packages/bitcore-node/test/unit/models/coin.unit.ts +++ b/packages/bitcore-node/test/unit/models/coin.unit.ts @@ -4,7 +4,7 @@ import { SpentHeightIndicators } from '../../../src/types/Coin'; import { ObjectId } from 'mongodb'; import sinon from 'sinon'; import { BlockStorage } from '../../../src/models/block'; -import { mockStorage } from '../../helpers/index.js'; +import { mockStorage, mockModel } from '../../helpers/index.js'; describe('Coin Model', function() { describe('_apiTransform', () => { @@ -119,7 +119,7 @@ describe('Coin Model', function() { let blockModelHeight = { height: 123 }; mockStorage([{ _id: 'confirmed', balance: 123123 }, { _id: 'unconfirmed', balance: 1 }]); - Object.assign(BlockStorage.collection.find, sandbox.stub().resolves(blockModelHeight)); + mockModel(BlockStorage, blockModelHeight); let coinModelAggregateSpy = CoinStorage.collection.aggregate as sinon.SinonSpy; let blockModelFindSpy = BlockStorage.collection.find as sinon.SinonSpy; From 62b9bb22bfaa4dcb7fb87aeb20bfb52c9aa67440 Mon Sep 17 00:00:00 2001 From: Justin Kook Date: Tue, 26 Feb 2019 17:44:06 -0500 Subject: [PATCH 5/5] added mockModel function, with isStubbed conditional --- packages/bitcore-node/test/helpers/index.ts | 11 ++++++----- packages/bitcore-node/test/unit/models/coin.unit.ts | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/bitcore-node/test/helpers/index.ts b/packages/bitcore-node/test/helpers/index.ts index d74dcc0c40d..ac9d9badfb6 100644 --- a/packages/bitcore-node/test/helpers/index.ts +++ b/packages/bitcore-node/test/helpers/index.ts @@ -1,5 +1,5 @@ import { StateStorage } from '../../src/models/state'; -import * as sinon from 'sinon'; +import sinon from 'sinon'; import { BlockStorage } from '../../src/models/block'; import { TransactionStorage } from '../../src/models/transaction'; import { CoinStorage } from '../../src/models/coin'; @@ -59,8 +59,9 @@ export function mockStorage(toReturn, collectionMethods = {}) { return Storage; } -export function mockModel(model, toReturn, collectionMethods = {}) { - model.db = { - collection: sinon.stub().returns(mockCollection(toReturn, collectionMethods)) - }; +export function mockModel(collectionName: string, toReturn: any, collectionMethods = {}) { + const isStubbed: sinon.SinonStub = Storage.db!.collection as sinon.SinonStub; + if (isStubbed.withArgs) { + isStubbed.withArgs(collectionName).returns(mockCollection(toReturn, collectionMethods)); + } } diff --git a/packages/bitcore-node/test/unit/models/coin.unit.ts b/packages/bitcore-node/test/unit/models/coin.unit.ts index 1aba5eebbfd..2a2207e069c 100644 --- a/packages/bitcore-node/test/unit/models/coin.unit.ts +++ b/packages/bitcore-node/test/unit/models/coin.unit.ts @@ -118,8 +118,8 @@ describe('Coin Model', function() { }; let blockModelHeight = { height: 123 }; - mockStorage([{ _id: 'confirmed', balance: 123123 }, { _id: 'unconfirmed', balance: 1 }]); - mockModel(BlockStorage, blockModelHeight); + mockModel('coins', [{ _id: 'confirmed', balance: 123123 }, { _id: 'unconfirmed', balance: 1 }]); + mockModel('blocks', blockModelHeight); let coinModelAggregateSpy = CoinStorage.collection.aggregate as sinon.SinonSpy; let blockModelFindSpy = BlockStorage.collection.find as sinon.SinonSpy;