describe('modules/transactions', () => { let instance: TransactionsModule; let container: Container; let sandbox: SinonSandbox; let accountsModuleStub: AccountsModuleStub; let loggerStub: LoggerStub; let dbHelperStub: DbStub; let genesisBlock: SignedAndChainedBlockType; let transactionPoolStub: TransactionPoolStub; let transactionLogicStub: TransactionLogicStub; beforeEach(() => { sandbox = sinon.createSandbox(); container = createContainer(); container.rebind(Symbols.modules.transactions).to(TransactionsModule); instance = container.get(Symbols.modules.transactions); accountsModuleStub = container.get(Symbols.modules.accounts); loggerStub = container.get(Symbols.helpers.logger); dbHelperStub = container.get(Symbols.helpers.db); genesisBlock = container.get(Symbols.generic.genesisBlock); transactionPoolStub = container.get(Symbols.logic.transactionPool); transactionLogicStub = container.get(Symbols.logic.transaction); // Reset all stubs [accountsModuleStub, loggerStub, dbHelperStub, transactionPoolStub, transactionLogicStub].forEach((stub: any) => { if (typeof stub.reset !== 'undefined') { stub.reset(); } if (typeof stub.stubReset !== 'undefined') { stub.stubReset(); } }); transactionPoolStub.unconfirmed.reset(); transactionPoolStub.multisignature.reset(); transactionPoolStub.bundled.reset(); }); afterEach(() => { sandbox.restore(); }); describe('cleanup', () => { it('should resolve', async () => { await expect(instance.cleanup()).to.be.fulfilled; }); }); describe('transactionInPool', () => { it('should call txPool.transactionInPool and return', () => { transactionPoolStub.stubs.transactionInPool.returns(true); const retVal = instance.transactionInPool('testTxId'); expect(transactionPoolStub.stubs.transactionInPool.calledOnce).to.be.true; expect(transactionPoolStub.stubs.transactionInPool.firstCall.args.length).to.be.equal(1); expect(transactionPoolStub.stubs.transactionInPool.firstCall.args[0]).to.be.equal('testTxId'); expect(retVal).to.be.true; }); }); describe('getUnconfirmedTransaction', () => { it('should call txPool.unconfirmed.get and return', () => { const returnedTx = { test: 'tx' }; transactionPoolStub.unconfirmed.stubs.get.returns(returnedTx); const retVal = instance.getUnconfirmedTransaction('testTxId'); expect(transactionPoolStub.unconfirmed.stubs.get.calledOnce).to.be.true; expect(transactionPoolStub.unconfirmed.stubs.get.firstCall.args.length).to.be.equal(1); expect(transactionPoolStub.unconfirmed.stubs.get.firstCall.args[0]).to.be.equal('testTxId'); expect(retVal).to.be.deep.equal(returnedTx); }); }); describe('getQueuedTransaction', () => { it('should call txPool.queued.get and return', () => { const returnedTx = { test: 'tx' }; transactionPoolStub.queued.stubs.get.returns(returnedTx); const retVal = instance.getQueuedTransaction('testTxId'); expect(transactionPoolStub.queued.stubs.get.calledOnce).to.be.true; expect(transactionPoolStub.queued.stubs.get.firstCall.args.length).to.be.equal(1); expect(transactionPoolStub.queued.stubs.get.firstCall.args[0]).to.be.equal('testTxId'); expect(retVal).to.be.deep.equal(returnedTx); }); }); describe('getQueuedTransaction', () => { it('should call txPool.queued.get and return', () => { it('should call txPool.unconfirmed.get and return', () => { const returnedTx = { test: 'tx' }; transactionPoolStub.queued.stubs.get.returns(returnedTx); const retVal = instance.getQueuedTransaction('testTxId'); expect(transactionPoolStub.queued.stubs.get.calledOnce).to.be.true; expect(transactionPoolStub.queued.stubs.get.firstCall.args.length).to.be.equal(1); expect(transactionPoolStub.queued.stubs.get.firstCall.args[0]).to.be.equal('testTxId'); expect(retVal).to.be.deep.equal(returnedTx); }); }); }); describe('getMultisignatureTransaction', () => { it('should call txPool.multisignature.get and return', () => { const returnedTx = { test: 'tx' }; transactionPoolStub.multisignature.stubs.get.returns(returnedTx); const retVal = instance.getMultisignatureTransaction('testTxId'); expect(transactionPoolStub.multisignature.stubs.get.calledOnce).to.be.true; expect(transactionPoolStub.multisignature.stubs.get.firstCall.args.length).to.be.equal(1); expect(transactionPoolStub.multisignature.stubs.get.firstCall.args[0]).to.be.equal('testTxId'); expect(retVal).to.be.deep.equal(returnedTx); }); }); describe('getUnconfirmedTransactionList', () => { it('should call txPool.unconfirmed.list and return', () => { const returnedAr = [{ test: 'tx' }]; transactionPoolStub.unconfirmed.stubs.list.returns(returnedAr); const retVal = instance.getUnconfirmedTransactionList(false, 10); expect(transactionPoolStub.unconfirmed.stubs.list.calledOnce).to.be.true; expect(transactionPoolStub.unconfirmed.stubs.list.firstCall.args.length).to.be.equal(2); expect(transactionPoolStub.unconfirmed.stubs.list.firstCall.args[0]).to.be.equal(false); expect(transactionPoolStub.unconfirmed.stubs.list.firstCall.args[1]).to.be.equal(10); expect(retVal).to.be.deep.equal(returnedAr); }); }); describe('getQueuedTransactionList', () => { it('should call txPool.queued.list and return', () => { const returnedAr = [{ test: 'tx' }]; transactionPoolStub.queued.stubs.list.returns(returnedAr); const retVal = instance.getQueuedTransactionList(false, 10); expect(transactionPoolStub.queued.stubs.list.calledOnce).to.be.true; expect(transactionPoolStub.queued.stubs.list.firstCall.args.length).to.be.equal(2); expect(transactionPoolStub.queued.stubs.list.firstCall.args[0]).to.be.equal(false); expect(transactionPoolStub.queued.stubs.list.firstCall.args[1]).to.be.equal(10); expect(retVal).to.be.deep.equal(returnedAr); }); }); describe('getMultisignatureTransactionList', () => { it('should call txPool.multisignature.list and return', () => { const returnedAr = [{ test: 'tx' }]; transactionPoolStub.multisignature.stubs.list.returns(returnedAr); const retVal = instance.getMultisignatureTransactionList(false, 10); expect(transactionPoolStub.multisignature.stubs.list.calledOnce).to.be.true; expect(transactionPoolStub.multisignature.stubs.list.firstCall.args.length).to.be.equal(2); expect(transactionPoolStub.multisignature.stubs.list.firstCall.args[0]).to.be.equal(false); expect(transactionPoolStub.multisignature.stubs.list.firstCall.args[1]).to.be.equal(10); expect(retVal).to.be.deep.equal(returnedAr); }); }); describe('getMergedTransactionList', () => { it('should call txPool.getMergedTransactionList and return', () => { const returnedAr = [{ test: 'tx' }]; transactionPoolStub.stubs.getMergedTransactionList.returns(returnedAr); const retVal = instance.getMergedTransactionList(10); expect(transactionPoolStub.stubs.getMergedTransactionList.calledOnce).to.be.true; expect(transactionPoolStub.stubs.getMergedTransactionList.firstCall.args.length).to.be.equal(1); expect(transactionPoolStub.stubs.getMergedTransactionList.firstCall.args[0]).to.be.equal(10); expect(retVal).to.be.deep.equal(returnedAr); }); }); describe('removeUnconfirmedTransaction', () => { it('should call txPool.unconfirmed.remove, txPool.queued.remove, txPool.multisignature.remove', () => { instance.removeUnconfirmedTransaction('txId'); expect(transactionPoolStub.unconfirmed.stubs.remove.calledOnce).to.be.true; expect(transactionPoolStub.unconfirmed.stubs.remove.firstCall.args.length).to.be.equal(1); expect(transactionPoolStub.unconfirmed.stubs.remove.firstCall.args[0]).to.be.equal('txId'); expect(transactionPoolStub.queued.stubs.remove.calledOnce).to.be.true; expect(transactionPoolStub.queued.stubs.remove.firstCall.args.length).to.be.equal(1); expect(transactionPoolStub.queued.stubs.remove.firstCall.args[0]).to.be.equal('txId'); expect(transactionPoolStub.multisignature.stubs.remove.calledOnce).to.be.true; expect(transactionPoolStub.multisignature.stubs.remove.firstCall.args.length).to.be.equal(1); expect(transactionPoolStub.multisignature.stubs.remove.firstCall.args[0]).to.be.equal('txId'); }); }); describe('processUnconfirmedTransaction', () => { it('should call txPool.processNewTransaction and return', () => { const tx = { the: 'tx' }; transactionPoolStub.stubs.processNewTransaction.returns('done'); const retVal = instance.processUnconfirmedTransaction(tx as any, false); expect(transactionPoolStub.stubs.processNewTransaction.calledOnce).to.be.true; expect(transactionPoolStub.stubs.processNewTransaction.firstCall.args.length).to.be.equal(2); expect(transactionPoolStub.stubs.processNewTransaction.firstCall.args[0]).to.be.deep.equal(tx); expect(transactionPoolStub.stubs.processNewTransaction.firstCall.args[1]).to.be.equal(false); expect(retVal).to.be.equal('done'); }); }); describe('applyUnconfirmed', () => { let tx; let sender; const requester = { the: 'requester' }; beforeEach(() => { tx = { the: 'tx', id: 'tx1', blockId: 'blockId' }; sender = { the: 'sender' }; accountsModuleStub.stubs.getAccount.returns(requester); transactionLogicStub.stubs.applyUnconfirmed.returns('done'); dbHelperStub.enqueueResponse('performOps', Promise.resolve()); }); it('should call logger.debug', async () => { await instance.applyUnconfirmed(tx as any, sender as any); expect(loggerStub.stubs.debug.calledOnce).to.be.true; expect(loggerStub.stubs.debug.firstCall.args.length).to.be.equal(1); expect(loggerStub.stubs.debug.firstCall.args[0]).to.contain('Applying unconfirmed transaction'); }); it('should throw if sender not set and tx not in genesis block', async () => { await expect(instance.applyUnconfirmed(tx as any, undefined)).to.be.rejectedWith('Invalid block id'); }); it('should not throw if sender not set and tx IS in genesis block', async () => { tx.blockId = genesisBlock.id; await expect(instance.applyUnconfirmed(tx as any, undefined)).to.be.fulfilled; }); describe('when requesterPublicKey is set', () => { beforeEach(() => { tx.requesterPublicKey = 'requesterPublicKey'; }); it('should call accountsModule.getAccount', async () => { await instance.applyUnconfirmed(tx as any, sender); expect(accountsModuleStub.stubs.getAccount.calledOnce).to.be.true; expect(accountsModuleStub.stubs.getAccount.firstCall.args.length).to.be.equal(1); expect(accountsModuleStub.stubs.getAccount.firstCall.args[0]).to.be.deep .equal({ publicKey: tx.requesterPublicKey }); }); it('should throw if requester not found', async () => { accountsModuleStub.stubs.getAccount.returns(false); await expect(instance.applyUnconfirmed(tx as any, sender)).to.be.rejectedWith('Requester not found'); }); it('should call transactionLogic.applyUnconfirmed with 3 parameters', async () => { await instance.applyUnconfirmed(tx as any, sender); expect(transactionLogicStub.stubs.applyUnconfirmed.calledOnce).to.be.true; expect(transactionLogicStub.stubs.applyUnconfirmed.firstCall.args.length).to.be.equal(3); expect(transactionLogicStub.stubs.applyUnconfirmed.firstCall.args[0]).to.be.deep.equal(tx); expect(transactionLogicStub.stubs.applyUnconfirmed.firstCall.args[1]).to.be.deep.equal(sender); expect(transactionLogicStub.stubs.applyUnconfirmed.firstCall.args[2]).to.be.deep.equal(requester); }); }); describe('when requesterPublicKey is NOT set', () => { it('should call transactionLogic.applyUnconfirmed with 2 parameters', async () => { await instance.applyUnconfirmed(tx as any, sender); expect(transactionLogicStub.stubs.applyUnconfirmed.calledOnce).to.be.true; expect(transactionLogicStub.stubs.applyUnconfirmed.firstCall.args.length).to.be.equal(2); expect(transactionLogicStub.stubs.applyUnconfirmed.firstCall.args[0]).to.be.deep.equal(tx); expect(transactionLogicStub.stubs.applyUnconfirmed.firstCall.args[1]).to.be.deep.equal(sender); }); }); }); describe('undoUnconfirmed', () => { const tx = { id : 'txId', senderPublicKey: 'pubKey', }; const sender = { account: 'id' }; beforeEach(() => { accountsModuleStub.stubs.getAccount.resolves(sender); transactionLogicStub.stubs.undoUnconfirmed.resolves(); dbHelperStub.enqueueResponse('performOps', Promise.resolve()); }); it('should call logger.debug', async () => { await instance.undoUnconfirmed(tx); expect(loggerStub.stubs.debug.calledOnce).to.be.true; expect(loggerStub.stubs.debug.firstCall.args.length).to.be.equal(1); expect(loggerStub.stubs.debug.firstCall.args[0]).to.contain('Undoing unconfirmed transaction'); }); it('should call accountsModule.getAccount', async () => { await instance.undoUnconfirmed(tx); expect(accountsModuleStub.stubs.getAccount.calledOnce).to.be.true; expect(accountsModuleStub.stubs.getAccount.firstCall.args.length).to.be.equal(1); expect(accountsModuleStub.stubs.getAccount.firstCall.args[0]).to.be.deep.equal({ publicKey: tx.senderPublicKey }); }); it('should call transactionLogic.undoUnconfirmed', async () => { await instance.undoUnconfirmed(tx); expect(transactionLogicStub.stubs.undoUnconfirmed.calledOnce).to.be.true; expect(transactionLogicStub.stubs.undoUnconfirmed.firstCall.args.length).to.be.equal(2); expect(transactionLogicStub.stubs.undoUnconfirmed.firstCall.args[0]).to.be.equal(tx); expect(transactionLogicStub.stubs.undoUnconfirmed.firstCall.args[1]).to.be.equal(sender); }); }); describe('count', () => { let txModel: typeof TransactionsModel; let txCountStub: SinonStub; beforeEach(() => { txModel = container.get(Symbols.models.transactions); txCountStub = sandbox.stub(txModel, 'count').resolves(12345); transactionPoolStub.multisignature.count = 1; transactionPoolStub.queued.count = 2; transactionPoolStub.unconfirmed.count = 3; }); it('should call db.query', async () => { await instance.count(); expect(txCountStub.called).is.true; }); it('should return the expected object', async () => { const retVal = await instance.count(); expect(retVal).to.be.deep.equal({ confirmed : 12345, multisignature: transactionPoolStub.multisignature.count, queued : transactionPoolStub.queued.count, unconfirmed : transactionPoolStub.unconfirmed.count, }); }); }); describe('fillPool', () => { const newUnconfirmedTXs = createRandomTransactions({send: 2, vote: 1}) .map((t) => toBufferedTransaction(t)); let filterConfIDsStub: SinonStub; beforeEach(() => { transactionPoolStub.stubs.fillPool.resolves(newUnconfirmedTXs.slice()); transactionPoolStub.stubs.applyUnconfirmedList.resolves(); filterConfIDsStub = sandbox.stub(instance, 'filterConfirmedIds').resolves([]); }); it('should call txPool.fillPool', async () => { await instance.fillPool(); expect(transactionPoolStub.stubs.fillPool.calledOnce).to.be.true; expect(transactionPoolStub.stubs.fillPool.firstCall.args.length).to.be.equal(0); }); it('should call transactionPool.applyUnconfirmedList', async () => { await instance.fillPool(); expect(transactionPoolStub.stubs.applyUnconfirmedList.calledOnce).to.be.true; expect(transactionPoolStub.stubs.applyUnconfirmedList.firstCall.args.length).to.be.equal(2); expect(transactionPoolStub.stubs.applyUnconfirmedList.firstCall.args[0]).to.be.deep.equal(newUnconfirmedTXs); expect(transactionPoolStub.stubs.applyUnconfirmedList.firstCall.args[1]).to.be.deep.equal(instance); }); it('should query for confirmed ids', async () => { await instance.fillPool(); expect(filterConfIDsStub.called).is.true; expect(filterConfIDsStub.firstCall.args[0]).is.deep.eq(newUnconfirmedTXs.map((t) => t.id)); }); it('should exclude already confirmed transaction', async () => { filterConfIDsStub.resolves([newUnconfirmedTXs[1].id]); await instance.fillPool(); expect(transactionPoolStub.stubs.applyUnconfirmedList.calledOnce).to.be.true; expect(transactionPoolStub.stubs.applyUnconfirmedList.firstCall.args.length).to.be.equal(2); expect(transactionPoolStub.stubs.applyUnconfirmedList.firstCall.args[0]).to.be.deep.equal([ newUnconfirmedTXs[0], newUnconfirmedTXs[2], ]); expect(transactionPoolStub.stubs.applyUnconfirmedList.firstCall.args[1]).to.be.deep.equal(instance); }); }); describe('getByID', () => { let txModel: typeof TransactionsModel; let findByIDStub: SinonStub; beforeEach(() => { txModel = container.get(Symbols.models.transactions); findByIDStub = sandbox.stub(txModel, 'findById').resolves('tx'); transactionLogicStub.stubs.dbRead.callsFake((tx) => { return { dbRead: tx }; }); }); it('should call db.query', async () => { await instance.getByID('12345'); expect(findByIDStub.called).is.true; expect(findByIDStub.firstCall.args[0]).to.be.deep.equal('12345'); }); it('should throw if tx not found', async () => { findByIDStub.resolves(null); await expect(instance.getByID('12345')).to.be.rejectedWith('Transaction not found'); }); it('should return tx obj', async () => { const retVal = await instance.getByID('12345'); expect(retVal).to.be.deep.equal('tx'); }); }); describe('checkTransaction', () => { let tx: IBaseTransaction<any>; beforeEach(() => { tx = toBufferedTransaction(createRandomTransactions({send: 1})[0]); }); it ('should throw if account is not found in map', async () => { await expect(instance.checkTransaction(tx, {}, 1)) .to.rejectedWith('Cannot find account from accounts'); }); it('should throw if tx has requesterPublicKey but notin accountsMap', async () => { tx.requesterPublicKey = Buffer.from('abababab', 'hex'); accountsModuleStub.stubs.generateAddressByPublicKey.returns('1111R'); await expect(instance.checkTransaction(tx, {[tx.senderId]: new AccountsModel()}, 1)) .to.rejectedWith('Cannot find requester from accounts'); }); it('should query readyness and throw if not ready', async () => { transactionLogicStub.stubs.ready.returns(false); await expect(instance.checkTransaction(tx, {[tx.senderId]: new AccountsModel()}, 1)) .to.rejectedWith(`Transaction ${tx.id} is not ready`); }); it('should query txLogic.verify with proper data', async () => { tx.requesterPublicKey = Buffer.from('abababab', 'hex'); accountsModuleStub.stubs.generateAddressByPublicKey.returns('1111R'); transactionLogicStub.stubs.ready.returns(true); transactionLogicStub.stubs.verify.resolves(); const account = new AccountsModel({ address: tx.senderId }); const requester = new AccountsModel({address: '1111R'}); await instance.checkTransaction(tx, { [tx.senderId]: account, '1111R' : requester, }, 1); expect(transactionLogicStub.stubs.verify.calledOnce).true; expect(transactionLogicStub.stubs.verify.firstCall.args[0]).deep.eq(tx); expect(transactionLogicStub.stubs.verify.firstCall.args[1]).deep.eq(account); expect(transactionLogicStub.stubs.verify.firstCall.args[2]).deep.eq(requester); expect(transactionLogicStub.stubs.verify.firstCall.args[3]).deep.eq(1); }); }); });
msg.encode = (pl) => { const m = oldEncode(pl); finishSpy = sandbox.spy(m, 'finish'); return m; };
it('should call getMessageInstance', () => { getMsgInstSpy = sandbox.spy(instance as any, 'getMessageInstance'); instance.decode(buf, 'APISuccess'); expect(getMsgInstSpy.calledOnce).to.be.true; expect(getMsgInstSpy.firstCall.args).to.be.deep.equal(['APISuccess', undefined]); });
describe('src/modules/transport.ts', () => { let inst: TransportModule; let container: Container; let sandbox: SinonSandbox; const appConfig = { peers: { options: { timeout: 1000, }, }, }; before(() => { sandbox = sinon.createSandbox(); }); beforeEach(() => { container = createContainer(); container.rebind(Symbols.generic.appConfig).toConstantValue(appConfig); container.rebind(Symbols.modules.transport).to(proxyTransportModule.TransportModule); }); let constants; let io: SocketIOStub; let schemaStub: ZSchemaStub; let balancesSequence: SequenceStub; let jobsQueue: JobsQueueStub; let logger: LoggerStub; let appState: AppStateStub; let broadcasterLogic: BroadcasterLogicStub; let transactionLogic: TransactionLogicStub; let peersLogic: PeersLogicStub; let peersModule: PeersModuleStub; let multisigModule: MultisignaturesModuleStub; let transactionModule: TransactionsModuleStub; let systemModule: SystemModuleStub; let postConstrA: AppStateStub; beforeEach(() => { io = container.get(Symbols.generic.socketIO); schemaStub = container.get(Symbols.generic.zschema); constants = container.get(Symbols.helpers.constants); balancesSequence = container.getTagged(Symbols.helpers.sequence, Symbols.helpers.sequence, Symbols.tags.helpers.balancesSequence); jobsQueue = container.get(Symbols.helpers.jobsQueue); logger = container.get(Symbols.helpers.logger); appState = container.get(Symbols.logic.appState); broadcasterLogic = container.get(Symbols.logic.broadcaster); transactionLogic = container.get(Symbols.logic.transaction); peersLogic = container.get(Symbols.logic.peers); peersModule = container.get(Symbols.modules.peers); multisigModule = container.get(Symbols.modules.multisignatures); transactionModule = container.get(Symbols.modules.transactions); systemModule = container.get(Symbols.modules.system); // set appState.setComputed call for @postConstruct method postConstrA = new AppStateStub(); postConstrA.enqueueResponse('get', 5); postConstrA.enqueueResponse('get', 5); appState.enqueueResponse('setComputed', true); appState.stubs.setComputed.callsArgWith(1, postConstrA); inst = container.get(Symbols.modules.transport); (inst as any).sequence = { addAndPromise: sandbox.spy((w) => Promise.resolve(w())), }; }); afterEach(() => { sandbox.restore(); }); describe('postConstructor', () => { let instPostConstr: TransportModule; beforeEach(() => { postConstrA = new AppStateStub(); }); it('should call appState.setComputed', () => { postConstrA.enqueueResponse('get', 5); postConstrA.enqueueResponse('get', 5); appState.reset(); appState.stubs.setComputed.callsArgWith(1, postConstrA); appState.enqueueResponse('setComputed', true); instPostConstr = container.get(Symbols.modules.transport); expect(appState.stubs.setComputed.calledOnce).to.be.true; expect(appState.stubs.setComputed.firstCall.args.length).to.be.equal(2); expect(appState.stubs.setComputed.firstCall.args[0]).to.be.equal('node.poorConsensus'); expect(appState.stubs.setComputed.firstCall.args[1]).to.be.a('function'); }); it('should call IAppState.get twice', () => { postConstrA.enqueueResponse('get', 5); postConstrA.enqueueResponse('get', 5); appState.reset(); appState.stubs.setComputed.callsArgWith(1, postConstrA); appState.enqueueResponse('setComputed', true); instPostConstr = container.get(Symbols.modules.transport); expect(postConstrA.stubs.get.calledTwice).to.be.true; expect(postConstrA.stubs.get.firstCall.args.length).to.be.equal(1); expect(postConstrA.stubs.get.firstCall.args[0]).to.be.equal('node.consensus'); expect(postConstrA.stubs.get.secondCall.args.length).to.be.equal(1); expect(postConstrA.stubs.get.secondCall.args[0]).to.be.equal('node.consensus'); }); it('check if IAppState.get result is undefined', () => { postConstrA.enqueueResponse('get', undefined); appState.reset(); appState.stubs.setComputed.callsArgWith(1, postConstrA); appState.enqueueResponse('setComputed', true); instPostConstr = container.get(Symbols.modules.transport); expect(postConstrA.stubs.get.calledOnce).to.be.true; }); }); describe('getFromPeer', function () { this.timeout(2100); let peer; let options; let thePeer; let res; let headers; let error; let popsicleUseStub; let removePeerStub: SinonStub; beforeEach(() => { peer = { makeRequest: sandbox.stub()}; options = { method: 'put', url : 'url.com', }; res = { body : {}, headers: {}, method : 'put', status : 200, url : 'example.com', }; headers = { nethash: 'as8776fsg76sd87', version: '1.2.0', }; thePeer = { applyHeaders: sandbox.stub() }; thePeer.applyHeaders.returns(headers); popsicleUseStub = { use: sandbox.stub().resolves(res) }; popsicleStub.plugins = { parse: sandbox.stub().returns(1) }; popsicleStub.request = sandbox.stub().returns(popsicleUseStub); removePeerStub = sandbox.stub(inst as any, 'removePeer'); peersLogic.enqueueResponse('create', thePeer); systemModule.enqueueResponse('networkCompatible', true); systemModule.enqueueResponse('versionCompatible', true); peersModule.enqueueResponse('update', {}); }); it('should call peersLogic.create', async () => { await inst.getFromPeer(peer, options); expect(peersLogic.stubs.create.calledOnce).to.be.true; expect(peersLogic.stubs.create.firstCall.args.length).to.be.equal(1); expect(peersLogic.stubs.create.firstCall.args[0]).to.be.deep.equal(peer); }); it('should call popsicle"s methods', async () => { await inst.getFromPeer(peer, options); expect(popsicleStub.request.calledOnce).to.be.true; expect(popsicleStub.request.firstCall.args.length).to.be.equal(1); expect(popsicleStub.request.firstCall.args[0]).to.be.deep.equal({ body : null, headers: undefined, method : 'put', timeout: 1000, url : 'http://undefined:undefinedurl.com', }); expect(popsicleUseStub.use.calledOnce).to.be.true; expect(popsicleUseStub.use.firstCall.args.length).to.be.equal(1); expect(popsicleUseStub.use.firstCall.args[0]).to.be.equal(1); expect(popsicleStub.plugins.parse.calledOnce).to.be.true; expect(popsicleStub.plugins.parse.firstCall.args.length).to.be.equal(2); expect(popsicleStub.plugins.parse.firstCall.args[0]).to.be.deep.equal(['json']); expect(popsicleStub.plugins.parse.firstCall.args[1]).to.be.equal(false); }); it('check if options.api', async () => { options.api = 'api'; await inst.getFromPeer(peer, options); expect(popsicleStub.request.firstCall.args[0]).to.be.deep.equal({ body : null, headers: undefined, method : 'put', timeout: 1000, url : 'http://undefined:undefined/peerapi', }); }); it('check if options.data', async () => { options.data = 'data'; await inst.getFromPeer(peer, options); expect(popsicleStub.request.firstCall.args[0]).to.be.deep.equal({ body : 'data', headers: undefined, method : 'put', timeout: 1000, url : 'http://undefined:undefinedurl.com', }); }); it('should call popsicle twice (retry) if rejects and return 2nd result', async function () { this.timeout(2100); const start = Date.now(); popsicleUseStub.use.onFirstCall().rejects(error); popsicleUseStub.use.onSecondCall().resolves({status: 500}); await expect(inst.getFromPeer(peer, options)).to.be.rejectedWith('bad response code 500'); expect(popsicleUseStub.use.calledTwice).is.true; expect(Date.now() - start).gt(2000); }); it('should call removePeer and return rejected promise if popsicle throw', async () => { error = new Error('error'); popsicleUseStub.use.rejects(error); await expect(inst.getFromPeer(peer, options)).to.be.rejectedWith(error); expect(removePeerStub.calledOnce).to.be.true; expect(removePeerStub.firstCall.args.length).to.be.equal(2); expect(removePeerStub.firstCall.args[0]).to.be.deep.equal({ peer: thePeer, code: 'HTTPERROR' }); expect(removePeerStub.firstCall.args[1]).to.be.equal(error.message); }); it('should call removePeer and return rejected promise if req.status !== 200', async () => { res.status = 609; popsicleUseStub.use.resolves(res); error = new Error(`Received bad response code ${res.status} ${res.method} ${res.url}`); await expect(inst.getFromPeer(peer, options)).to.be.rejectedWith(error.message); expect(removePeerStub.calledOnce).to.be.true; expect(removePeerStub.firstCall.args.length).to.be.equal(2); expect(removePeerStub.firstCall.args[0]).to.be.deep.equal({ peer: thePeer, code: `ERESPONSE ${res.status}` }); expect(removePeerStub.firstCall.args[1]).to.be.equal('put http://undefined:undefinedurl.com'); }); it('should call thePeer.applyHeaders', async () => { await inst.getFromPeer(peer, options); expect(thePeer.applyHeaders.calledOnce).to.be.true; expect(thePeer.applyHeaders.firstCall.args.length).to.be.equal(1); expect(thePeer.applyHeaders.firstCall.args[0]).to.be.equal(res.headers); }); it('should call schemaStub.validate', async () => { await inst.getFromPeer(peer, options); expect(schemaStub.stubs.validate.calledOnce).to.be.true; expect(schemaStub.stubs.validate.firstCall.args.length).to.be.equal(2); expect(schemaStub.stubs.validate.firstCall.args[0]).to.be.equal(headers); expect(schemaStub.stubs.validate.firstCall.args[1]).to.be.equal(schemaImport.headers); }); it('should call removePeer and return rejected promise if schemaStub.validate returned false', async () => { schemaStub.stubs.validate.returns(false); error = new Error('Invalid response headers {"nethash":"as8776fsg76sd87","version":"1.2.0"} put http://undefined:undefinedurl.com'); await expect(inst.getFromPeer(peer, options)).to.be.rejectedWith(error.message); expect(removePeerStub.calledOnce).to.be.true; expect(removePeerStub.firstCall.args.length).to.be.equal(2); expect(removePeerStub.firstCall.args[0]).to.be.deep.equal({ peer: thePeer, code: 'EHEADERS' }); expect(removePeerStub.firstCall.args[1]).to.be.equal('put http://undefined:undefinedurl.com'); }); it('should call systemModule.networkCompatible', async () => { await inst.getFromPeer(peer, options); expect(systemModule.stubs.networkCompatible.calledOnce).to.be.true; expect(systemModule.stubs.networkCompatible.firstCall.args.length).to.be.equal(1); expect(systemModule.stubs.networkCompatible.firstCall.args[0]).to.be.equal(headers.nethash); }); it('should call removePeer and return rejected promise if systemModule.networkCompatible returned false', async () => { error = new Error('Peer is not on the same network as8776fsg76sd87 put http://undefined:undefinedurl.com'); systemModule.reset(); systemModule.enqueueResponse('networkCompatible', false); await expect(inst.getFromPeer(peer, options)).to.be.rejectedWith(error.message); expect(removePeerStub.calledOnce).to.be.true; expect(removePeerStub.firstCall.args.length).to.be.equal(2); expect(removePeerStub.firstCall.args[0]).to.be.deep.equal({ peer: thePeer, code: 'ENETHASH' }); expect(removePeerStub.firstCall.args[1]).to.be.equal('put http://undefined:undefinedurl.com'); }); it('should call systemModule.versionCompatible', async () => { await inst.getFromPeer(peer, options); expect(systemModule.stubs.versionCompatible.calledOnce).to.be.true; expect(systemModule.stubs.versionCompatible.firstCall.args.length).to.be.equal(1); expect(systemModule.stubs.versionCompatible.firstCall.args[0]).to.be.equal(headers.version); }); it('should call removePeer and return rejected promise if systemModule.versionCompatible returned false', async () => { error = new Error('Peer is using incompatible version 1.2.0 put http://undefined:undefinedurl.com'); systemModule.reset(); systemModule.enqueueResponse('networkCompatible', true); systemModule.enqueueResponse('versionCompatible', false); await expect(inst.getFromPeer(peer, options)).to.be.rejectedWith(error.message); expect(removePeerStub.calledOnce).to.be.true; expect(removePeerStub.firstCall.args.length).to.be.equal(2); expect(removePeerStub.firstCall.args[0]).to.be.deep.equal({ peer: thePeer, code: 'EVERSION 1.2.0' }); expect(removePeerStub.firstCall.args[1]).to.be.equal('put http://undefined:undefinedurl.com'); }); it('should call peersModule.update', async () => { await inst.getFromPeer(peer, options); expect(peersModule.stubs.update.calledOnce).to.be.true; expect(peersModule.stubs.update.firstCall.args.length).to.be.equal(1); expect(peersModule.stubs.update.firstCall.args[0]).to.be.equal(thePeer); }); it('should return an object with body and peer properties if everything is ok', async () => { expect(await inst.getFromPeer(peer, options)).to.be.deep.equal({ body: res.body, peer: thePeer, }); }); }); describe('getFromRandomPeer', () => { let config; let peers; let result; let requestHandler; let getFromPeerStub; beforeEach(() => { requestHandler = new APIRequestStub(); result = 'hehehe'; config = {}; peers = [{makeRequest: sandbox.stub().returns(result)}]; peersModule.enqueueResponse('list', Promise.resolve({ peers })); }); it('should call peersModule.list', async () => { await inst.getFromRandomPeer(config, requestHandler); expect(peersModule.stubs.list.calledOnce).to.be.true; expect(peersModule.stubs.list.firstCall.args.length).to.be.equal(1); expect(peersModule.stubs.list.firstCall.args[0]).to.be.deep.equal({ allowedStates: [PeerState.CONNECTED, PeerState.DISCONNECTED], limit : 1, }); }); it('should call makeRequest and return result', async () => { expect(await inst.getFromRandomPeer(config, requestHandler)).to.be.equal(result); expect(peers[0].makeRequest.calledOnce).to.be.true; expect(peers[0].makeRequest.firstCall.args.length).to.be.equal(1); expect(peers[0].makeRequest.firstCall.args[0]).to.be.deep.equal(requestHandler); expect(peers[0].makeRequest.firstCall.args[0]).to.be.instanceOf(APIRequestStub); }); }); describe('cleanup', () => { it('should set loaded in false and return promise.resolve', () => { expect(inst.cleanup()).to.be.fulfilled; expect((inst as any).loaded).to.be.false; }); }); describe('onBlockchainReady', () => { it('should set loaded in true', () => { inst.onBlockchainReady(); expect((inst as any).loaded).to.be.true; }); }); describe('onPeersReady', () => { let peers; let discoverPeersStub: SinonStub; beforeEach(() => { peers = [{ pingAndUpdate: sandbox.stub(), state : PeerState.CONNECTED, string : 'string', updated : false, }]; throttleStub.all = sandbox.stub().callsFake((fkArray) => { const promiseArray = []; for (const fk of fkArray) { promiseArray.push(fk()); } return Promise.all(promiseArray); }); jobsQueue.stubs.register.callsArg(1); discoverPeersStub = sandbox.stub(inst as any, 'discoverPeers'); peersLogic.enqueueResponse('list', peers); }); it('should call logger.trace', async () => { await inst.onPeersReady(); // use to async call of jobsQueue.register callback process.nextTick(() => { const loggerTraceStub = logger.stubs.trace; expect(loggerTraceStub.callCount).to.be.equal(4); expect(loggerTraceStub.getCall(0).args.length).to.be.equal(1); expect(loggerTraceStub.getCall(0).args[0]).to.be.equal('Peers ready'); expect(loggerTraceStub.getCall(1).args.length).to.be.equal(2); expect(loggerTraceStub.getCall(1).args[0]).to.be.equal('Updating peers'); expect(loggerTraceStub.getCall(1).args[1]).to.be.deep.equal({ count: peers.length }); expect(loggerTraceStub.getCall(2).args.length).to.be.equal(2); expect(loggerTraceStub.getCall(2).args[0]).to.be.equal('Updating peer'); expect(loggerTraceStub.getCall(2).args[1]).to.be.equal(peers[0].string); expect(loggerTraceStub.getCall(3).args.length).to.be.equal(1); expect(loggerTraceStub.getCall(3).args[0]).to.be.equal('Updated Peers'); }); }); it('should call jobsQueue.register', async () => { await inst.onPeersReady(); expect(jobsQueue.stubs.register.calledOnce).to.be.true; expect(jobsQueue.stubs.register.firstCall.args.length).to.be.equal(3); expect(jobsQueue.stubs.register.firstCall.args[0]).to.be.equal('peersDiscoveryAndUpdate'); expect(jobsQueue.stubs.register.firstCall.args[1]).to.be.a('function'); expect(jobsQueue.stubs.register.firstCall.args[2]).to.be.equal(5000); }); it('should call discoverPeers', async () => { await inst.onPeersReady(); expect(discoverPeersStub.calledOnce).to.be.true; expect(discoverPeersStub.firstCall.args.length).to.be.equal(0); }); it('should logger.error if discoverPeers throw', async () => { const error = new Error('error'); discoverPeersStub.rejects(error); await inst.onPeersReady(); process.nextTick(() => { expect(logger.stubs.error.calledOnce).to.be.true; expect(logger.stubs.error.firstCall.args.length).to.be.equal(2); expect(logger.stubs.error.firstCall.args[0]).to.be.equal('Discovering new peers failed'); expect(logger.stubs.error.firstCall.args[1]).to.be.equal(error); }); }); it('should call peersLogic.list', async () => { await inst.onPeersReady(); expect(peersLogic.stubs.list.calledOnce).to.be.true; expect(peersLogic.stubs.list.firstCall.args.length).to.be.equal(1); expect(peersLogic.stubs.list.firstCall.args[0]).to.be.equal(false); }); it('should call Throttle.all', async () => { await inst.onPeersReady(); expect(throttleStub.all.calledOnce).to.be.true; expect(throttleStub.all.firstCall.args.length).to.be.equal(2); expect(throttleStub.all.firstCall.args[0]).to.be.a('array'); expect(throttleStub.all.firstCall.args[1]).to.be.deep.equal({ maxInProgress: 50 }); }); describe('Throttle.all callback(for each peer in peers)', () => { it('should call pingAndUpdate(check on p.updated is false)', async () => { await inst.onPeersReady(); expect(peers[0].pingAndUpdate.calledOnce).to.be.true; expect(peers[0].pingAndUpdate.firstCall.args.length).to.be.equal(0); }); it('should call pingAndUpdate(check on Date.now() - p.updated > 3000)', async () => { peers[0].updated = Date.now() - 3001; await inst.onPeersReady(); await wait(10); expect(peers[0].pingAndUpdate.calledOnce).to.be.true; expect(peers[0].pingAndUpdate.firstCall.args.length).to.be.equal(0); }); it('should call logger.debug if pingAndUpdate throw', async () => { const error = new Error('error'); peers[0].pingAndUpdate.rejects(error); await inst.onPeersReady(); await wait(10); expect(logger.stubs.debug.calledOnce).to.be.true; expect(logger.stubs.debug.firstCall.args.length).to.be.equal(2); expect(logger.stubs.debug.firstCall.args[0]).to.be.equal('Ping failed when updating peer string'); expect(logger.stubs.debug.firstCall.args[1]).to.be.deep.equal(error); }); describe('false in condition of Throttle.all"s callback', () => { it('p in null', async () => { peers[0] = null; await inst.onPeersReady(); await wait(100); expect(logger.stubs.trace.callCount).to.be.equal(3); }); it('p.state === PeerState.BANNED', async () => { peers[0].state = PeerState.BANNED; await inst.onPeersReady(); await wait(10); expect(logger.stubs.trace.callCount).to.be.equal(3); }); it('p.update is true and (Date.now() - p.updated) <= 3000', async () => { peers[0].updated = Date.now() - 2000; await inst.onPeersReady(); await wait(10); expect(logger.stubs.trace.callCount).to.be.equal(3); }); }); }); }); describe('onSignature', () => { let broadcast; let signature; beforeEach(() => { signature = { transaction: '1111111', signature: 'aaaabbbb' }; broadcast = true; broadcasterLogic.enqueueResponse('maxRelays', false); broadcasterLogic.enqueueResponse('enqueue', false); (inst as any).appState = {get: () => 1000}; const p = new PostSignaturesRequest(); (inst as any).psrFactory = (a) => { p.options = a; return p; }; }); it('should call broadcasterLogic.maxRelays', () => { inst.onSignature(signature, broadcast); expect(broadcasterLogic.stubs.maxRelays.calledOnce).to.be.true; expect(broadcasterLogic.stubs.maxRelays.firstCall.args.length).to.be.equal(1); expect(broadcasterLogic.stubs.maxRelays.firstCall.args[0]).to.be.deep.equal(signature); }); it('should call broadcasterLogic.enqueue', async () => { inst.onSignature(signature, broadcast); expect(broadcasterLogic.stubs.enqueue.calledOnce).to.be.true; expect(broadcasterLogic.stubs.enqueue.firstCall.args.length).to.be.equal(2); expect(broadcasterLogic.stubs.enqueue.firstCall.args[0]).to.be.deep.equal({}); expect(broadcasterLogic.stubs.enqueue.firstCall.args[1].requestHandler).to.be.instanceOf(PostSignaturesRequest); expect(broadcasterLogic.stubs.enqueue.firstCall.args[1].requestHandler.options).to.be.deep.equal({data: { signatures: [{ relays: 1, signature: Buffer.from(signature.signature, 'hex'), transaction: signature.transaction, }] }}); }); it('should call io.sockets.emit', async () => { inst.onSignature(signature, broadcast); expect(io.sockets.emit.calledOnce).to.be.true; expect(io.sockets.emit.firstCall.args.length).to.be.equal(2); expect(io.sockets.emit.firstCall.args[0]).to.be.deep.equal('signature/change'); expect(io.sockets.emit.firstCall.args[1]).to.be.deep.equal(signature); }); it('should not call broadcasterLogic.enqueue if broadcast is false', () => { broadcast = false; inst.onSignature(signature, broadcast); expect(broadcasterLogic.stubs.enqueue.notCalled).to.be.true; }); it('should not call broadcasterLogic.enqueue if this.broadcasterLogic.maxRelays returned true', () => { broadcasterLogic.reset(); broadcasterLogic.enqueueResponse('maxRelays', true); inst.onSignature(signature, broadcast); expect(broadcasterLogic.stubs.enqueue.notCalled).to.be.true; }); }); describe('onUnconfirmedTransaction', () => { let broadcast; let transaction; beforeEach(() => { transaction = {}; broadcast = true; broadcasterLogic.enqueueResponse('maxRelays', false); broadcasterLogic.enqueueResponse('enqueue', false); const p = new PostTransactionsRequest(); (inst as any).ptrFactory = (a) => { p.options = a; return p; }; }); it('should call broadcasterLogic.maxRelays', () => { inst.onUnconfirmedTransaction(transaction, broadcast); expect(broadcasterLogic.stubs.maxRelays.calledOnce).to.be.true; expect(broadcasterLogic.stubs.maxRelays.firstCall.args.length).to.be.equal(1); expect(broadcasterLogic.stubs.maxRelays.firstCall.args[0]).to.be.deep.equal(transaction); }); it('should call broadcasterLogic.enqueue', async () => { inst.onUnconfirmedTransaction(transaction, broadcast); expect(broadcasterLogic.stubs.enqueue.calledOnce).to.be.true; expect(broadcasterLogic.stubs.enqueue.firstCall.args.length).to.be.equal(2); expect(broadcasterLogic.stubs.enqueue.firstCall.args[0]).to.be.deep.equal({}); expect(broadcasterLogic.stubs.enqueue.firstCall.args[1].requestHandler.options).to.be.deep.equal({data: {transactions:[transaction]}}); }); it('should call io.sockets.emit', async () => { inst.onUnconfirmedTransaction(transaction, broadcast); expect(io.sockets.emit.calledOnce).to.be.true; expect(io.sockets.emit.firstCall.args.length).to.be.equal(2); expect(io.sockets.emit.firstCall.args[0]).to.be.deep.equal('transactions/change'); expect(io.sockets.emit.firstCall.args[1]).to.be.deep.equal(transaction); }); it('should not call broadcasterLogic.enqueue if broadcast is false', () => { broadcast = false; inst.onUnconfirmedTransaction(transaction, broadcast); expect(broadcasterLogic.stubs.enqueue.notCalled).to.be.true; }); it('should not call broadcasterLogic.enqueue if this.broadcasterLogic.maxRelays returned true', () => { broadcasterLogic.reset(); broadcasterLogic.enqueueResponse('maxRelays', true); inst.onUnconfirmedTransaction(transaction, broadcast); expect(broadcasterLogic.stubs.enqueue.notCalled).to.be.true; }); }); describe('onNewBlock', () => { let broadcast; let block; beforeEach(() => { block = { blockSignature : Buffer.from('aa', 'hex'), generatorPublicKey: Buffer.from('bb', 'hex'), payloadHash : Buffer.from('cc', 'hex'), transactions : [], }; broadcast = true; (inst as any).systemModule.broadhash = 'broadhash'; systemModule.enqueueResponse('update', Promise.resolve()); broadcasterLogic.enqueueResponse('maxRelays', false); broadcasterLogic.enqueueResponse('broadcast', Promise.resolve()); const p = new PostBlocksRequest(); (inst as any).pblocksFactory = (a) => { p.options = a; return p; }; }); it('should call systemModule.update', async () => { await inst.onNewBlock(block, broadcast); expect(systemModule.stubs.update.calledOnce).to.be.true; expect(systemModule.stubs.update.firstCall.args.length).to.be.equal(0); }); it('should call broadcasterLogic.maxRelays', async () => { await inst.onNewBlock(block, broadcast); expect(broadcasterLogic.stubs.maxRelays.calledOnce).to.be.true; expect(broadcasterLogic.stubs.maxRelays.firstCall.args.length).to.be.equal(1); expect(broadcasterLogic.stubs.maxRelays.firstCall.args[0]).to.be.deep.equal(block); }); it('should call broadcasterLogic.broadcast', async () => { await inst.onNewBlock(block, broadcast); expect(broadcasterLogic.stubs.broadcast.calledOnce).to.be.true; expect(broadcasterLogic.stubs.broadcast.firstCall.args.length).to.be.equal(2); expect(broadcasterLogic.stubs.broadcast.firstCall.args[0]).to.be.deep.equal({ broadhash: 'broadhash', limit : constants.maxPeers, }); expect(broadcasterLogic.stubs.broadcast.firstCall.args[1].requestHandler.options).to.be.deep.equal({ data : { block: { blockSignature : Buffer.from('aa', 'hex'), generatorPublicKey: Buffer.from('bb', 'hex'), payloadHash : Buffer.from('cc', 'hex'), transactions : [], }, }, }); }); it('should call io.sockets.emit', async () => { await inst.onNewBlock(block, broadcast); expect(io.sockets.emit.calledOnce).to.be.true; expect(io.sockets.emit.firstCall.args.length).to.be.equal(2); expect(io.sockets.emit.firstCall.args[0]).to.be.deep.equal('blocks/change'); expect(io.sockets.emit.firstCall.args[1]).to.be.deep.equal(block); }); it('should not call broadcasterLogic.broadcast if broadcasterLogic.maxRelays returns true', async () => { broadcasterLogic.reset(); broadcasterLogic.enqueueResponse('maxRelays', true); await inst.onNewBlock(block, broadcast); expect(broadcasterLogic.stubs.broadcast.notCalled).to.be.true; }); it('check if broadcast is false', () => { broadcast = false; const p = inst.onNewBlock(block, broadcast); expect(p).to.be.fulfilled; expect(broadcasterLogic.stubs.enqueue.notCalled).to.be.true; }); it('should ignore broadcast error if any and, more importantly avoid waiting for broadcaster result', async () => { broadcasterLogic.reset(); broadcasterLogic.enqueueResponse('maxRelays', false); let finished = false; const promise = wait(1000) .then(() => finished = true); broadcasterLogic.enqueueResponse('broadcast', promise); await inst.onNewBlock(block, true); expect(finished).to.be.false; await promise; }); }); describe('receiveSignatures', () => { let receiveSignatureStub: SinonStub; let query; beforeEach(() => { query = [{ transaction: 'transaction', signature: 'signature' }]; receiveSignatureStub = sandbox.stub(inst as any, 'receiveSignature'); }); it('should call receiveSignature', async () => { await inst.receiveSignatures(query); expect(receiveSignatureStub.calledOnce).to.be.true; expect(receiveSignatureStub.firstCall.args.length).to.be.equal(1); expect(receiveSignatureStub.firstCall.args[0]).to.be.deep.equal(query[0]); }); it('should call logger.debug if receiveSignature throw error', async () => { const error = new Error('error'); receiveSignatureStub.rejects(error); await inst.receiveSignatures(query); expect(logger.stubs.debug.calledOnce).to.be.true; expect(logger.stubs.debug.firstCall.args.length).to.be.equal(2); expect(logger.stubs.debug.firstCall.args[0]).to.be.equal(error); expect(logger.stubs.debug.firstCall.args[1]).to.be.deep.equal(query[0]); }); }); describe('receiveSignature', () => { let signature; beforeEach(() => { signature = { transaction: 'transaction', signature: 'signature' }; multisigModule.enqueueResponse('processSignature', Promise.resolve()); }); it('should call multisigModule.processSignature', async () => { await inst.receiveSignature(signature); expect(multisigModule.stubs.processSignature.calledOnce).to.be.true; expect(multisigModule.stubs.processSignature.firstCall.args.length).to.be.equal(1); expect(multisigModule.stubs.processSignature.firstCall.args[0]).to.be.deep.equal(signature); }); it('should throw error multisigModule.processSignature throw error', async () => { const error = new Error('error'); multisigModule.reset(); multisigModule.enqueueResponse('processSignature', Promise.reject(error)); await expect(inst.receiveSignature(signature)).to.be.rejectedWith('Error processing signature: error'); }); }); describe('receiveTransactions', () => { let transactions; let peer; let extraLogMessage; beforeEach(() => { transactions = createRandomTransactions({send: 2}); peer = { ip: 'ip', port: 'port' }; extraLogMessage = 'extraLogMessage'; transactionLogic.stubs.objectNormalize.callsFake((tx) => tx); transactionModule.stubs.filterConfirmedIds.resolves([]); transactionModule.stubs.processUnconfirmedTransaction.resolves(); peersModule.stubs.remove.returns(null); }); describe('transactionLogic.objectNormalize throw error', () => { let error; beforeEach(() => { error = new Error('error'); transactionLogic.stubs.objectNormalize.throws(error); }); it('should throw error', async () => { await expect(inst.receiveTransactions(transactions, peer, false)).to.be.rejectedWith('Invalid transaction body error'); }); it('should call removePeer', async () => { await expect(inst.receiveTransactions(transactions, peer, false)).to.be.rejectedWith('Invalid transaction body error'); expect(peersModule.stubs.remove.calledOnce).to.be.true; expect(peersModule.stubs.remove.firstCall.args.length).to.be.equal(2); expect(peersModule.stubs.remove.firstCall.args[0]).to.be.deep.equal(peer.ip); expect(peersModule.stubs.remove.firstCall.args[1]).to.be.deep.equal(peer.port); }); }); it('should call balancesSequence.addAndPromise', async () => { await inst.receiveTransactions(transactions, peer, false); expect(balancesSequence.spies.addAndPromise.calledOnce).to.be.true; expect(balancesSequence.spies.addAndPromise.firstCall.args.length).to.be.equal(1); expect(balancesSequence.spies.addAndPromise.firstCall.args[0]).to.be.a('function'); }); it('should call transactionModule.processUnconfirmedTransaction', async () => { await inst.receiveTransactions(transactions, peer, false); expect(transactionModule.stubs.processUnconfirmedTransaction.calledTwice).to.be.true; expect(transactionModule.stubs.processUnconfirmedTransaction.firstCall.args.length).to.be.equal(2); expect(transactionModule.stubs.processUnconfirmedTransaction.firstCall.args[0]).to.be.deep.equal(transactions[0]); expect(transactionModule.stubs.processUnconfirmedTransaction.firstCall.args[1]).to.be.equal(false); expect(transactionModule.stubs.processUnconfirmedTransaction.secondCall.args.length).to.be.equal(2); expect(transactionModule.stubs.processUnconfirmedTransaction.secondCall.args[0]).to.be.deep.equal(transactions[1]); expect(transactionModule.stubs.processUnconfirmedTransaction.secondCall.args[1]).to.be.equal(false); }); it('should filter out already confirmed ids', async () => { transactionModule.stubs.filterConfirmedIds.resolves([transactions[1].id]); await inst.receiveTransactions(transactions, peer, true); expect(transactionModule.stubs.processUnconfirmedTransaction.calledOnce).is.true; expect(transactionModule.stubs.processUnconfirmedTransaction.firstCall.args).deep.eq([ transactions[0], true, ]); }); describe('peer null', () => { it('should not remove null peer if failed to objectNormalize', async () => { transactionLogic.stubs.objectNormalize.throws(new Error('error')); await expect(inst.receiveTransactions(transactions, null, false)).to.be .rejectedWith('Invalid transaction body error'); expect(peersModule.stubs.remove.calledOnce).to.be.false; }); it('not throw for peer.* access if txs are ok', async () => { await inst.receiveTransactions(transactions, null, false) }); }); }); describe('removePeer', () => { let options; let extraMessage; beforeEach(() => { extraMessage = 'eeeemessage'; options = { code: 'code', peer: { ip : 'ip', port: 'port', }, }; peersModule.enqueueResponse('remove', {}); }); it('should call logger.debug', () => { (inst as any).removePeer(options, extraMessage); expect(logger.stubs.debug.calledOnce).to.be.true; expect(logger.stubs.debug.firstCall.args.length).to.be.equal(1); expect(logger.stubs.debug.firstCall.args[0]).to.be.equal('code Removing peer undefined eeeemessage'); }); it('should call peersModule.remove', () => { (inst as any).removePeer(options, extraMessage); expect(peersModule.stubs.remove.calledOnce).to.be.true; expect(peersModule.stubs.remove.firstCall.args.length).to.be.equal(2); expect(peersModule.stubs.remove.firstCall.args[0]).to.be.equal('ip'); expect(peersModule.stubs.remove.firstCall.args[1]).to.be.equal('port'); }); }); describe('discoverPeers', () => { let response; let acceptablePeers; let peer; let getFromRandomPeerStub: SinonStub; beforeEach(() => { response = { body: { peers: 'peers', }, }; acceptablePeers = [{}]; peer = { string: 'string' }; schemaStub.stubs.validate.onCall(0).callsArg(2); peersLogic.enqueueResponse('acceptable', acceptablePeers); peersLogic.enqueueResponse('create', peer); peersLogic.enqueueResponse('upsert', true); getFromRandomPeerStub = sandbox.stub(inst as any, 'getFromRandomPeer').resolves(response); const p = new PeersListRequest(); (inst as any).plFactory = (a) => { p.options = a; return p; }; }); it('should call logger.trace', async () => { await (inst as any).discoverPeers(); expect(logger.stubs.trace.calledOnce).to.be.true; expect(logger.stubs.trace.firstCall.args.length).to.be.equal(1); expect(logger.stubs.trace.firstCall.args[0]).to.be.equal('Transport->discoverPeers'); }); it('should call getFromRandomPeer', async () => { await (inst as any).discoverPeers(); expect(getFromRandomPeerStub.calledOnce).to.be.true; expect(getFromRandomPeerStub.firstCall.args.length).to.be.equal(2); expect(getFromRandomPeerStub.firstCall.args[0]).to.be.deep.equal({}); expect(getFromRandomPeerStub.firstCall.args[1]).to.be.deep.equal(new PeersListRequest()); }); it('should call schemaStub.validate resolves', async () => { await (inst as any).discoverPeers(); expect(schemaStub.stubs.validate.calledTwice).to.be.true; expect(schemaStub.stubs.validate.firstCall.args.length).to.be.equal(3); expect(schemaStub.stubs.validate.firstCall.args[0]).to.be.equal(response); expect(schemaStub.stubs.validate.firstCall.args[1]).to.be.equal(peersSchema.discover.peers); expect(schemaStub.stubs.validate.firstCall.args[2]).to.be.a('function'); }); it('should call peersLogic.acceptable', async () => { await (inst as any).discoverPeers(); expect(peersLogic.stubs.acceptable.calledOnce).to.be.true; expect(peersLogic.stubs.acceptable.firstCall.args.length).to.be.equal(1); expect(peersLogic.stubs.acceptable.firstCall.args[0]).to.be.equal(response.peers); }); it('should call peersLogic.create', async () => { await (inst as any).discoverPeers(); expect(peersLogic.stubs.create.calledOnce).to.be.true; expect(peersLogic.stubs.create.firstCall.args.length).to.be.equal(1); expect(peersLogic.stubs.create.firstCall.args[0]).to.be.equal(acceptablePeers[0]); }); it('should call schemaStub.validate', async () => { await (inst as any).discoverPeers(); expect(schemaStub.stubs.validate.calledTwice).to.be.true; expect(schemaStub.stubs.validate.secondCall.args.length).to.be.equal(2); expect(schemaStub.stubs.validate.secondCall.args[0]).to.be.equal(peer); expect(schemaStub.stubs.validate.secondCall.args[1]).to.be.equal(peersSchema.discover.peer); }); it('should call peersLogic.upsert', async () => { await (inst as any).discoverPeers(); expect(peersLogic.stubs.upsert.calledOnce).to.be.true; expect(peersLogic.stubs.upsert.firstCall.args.length).to.be.equal(2); expect(peersLogic.stubs.upsert.firstCall.args[0]).to.be.equal(peer); expect(peersLogic.stubs.upsert.firstCall.args[1]).to.be.equal(true); }); it('should call logger.debug', async () => { await (inst as any).discoverPeers(); expect(logger.stubs.debug.calledOnce).to.be.true; expect(logger.stubs.debug.firstCall.args.length).to.be.equal(1); expect(logger.stubs.debug.firstCall.args[0]).to.be.equal('Discovered 1 peers - Rejected 0 - AlreadyKnown 0'); }); it('check if schemaStub.validate returns false then call logger.warn', async () => { schemaStub.stubs.validate.onCall(1).returns(false); await (inst as any).discoverPeers(); expect(logger.stubs.warn.calledOnce).to.be.true; expect(logger.stubs.warn.firstCall.args.length).to.be.equal(1); expect(logger.stubs.warn.firstCall.args[0]).to.be.equal('Rejecting invalid peer: string'); expect(logger.stubs.debug.calledOnce).to.be.true; expect(logger.stubs.debug.firstCall.args.length).to.be.equal(1); expect(logger.stubs.debug.firstCall.args[0]).to.be.equal('Discovered 0 peers - Rejected 1 - AlreadyKnown 0'); }); it('check if peersLogic.upsert check that current peer already known', async () => { peersLogic.reset(); peersLogic.enqueueResponse('acceptable', acceptablePeers); peersLogic.enqueueResponse('create', peer); peersLogic.enqueueResponse('upsert', undefined); await (inst as any).discoverPeers(); expect(logger.stubs.debug.calledOnce).to.be.true; expect(logger.stubs.debug.firstCall.args.length).to.be.equal(1); expect(logger.stubs.debug.firstCall.args[0]).to.be.equal('Discovered 0 peers - Rejected 0 - AlreadyKnown 1'); }); }); });
(instance as any).getMessageInstance = (namespace, messageType) => { msg = (instance2 as any).getMessageInstance(namespace, messageType); verifyStub = sandbox.stub(msg, 'verify').returns('Test Err'); return msg; };
test.afterEach(function () { sandbox.restore(); });
describe('apis/requests/PostBlocksRequest', () => { let options; let instance: PostBlocksRequest; let pbHelperStub: ProtoBufHelperStub; let blocksModelStub: any; let sandbox: SinonSandbox; beforeEach(() => { const container = createContainer(); options = {data: {block: 'b1'}}; sandbox = sinon.createSandbox(); instance = new PostBlocksRequest(); instance.options = options; pbHelperStub = container.get(Symbols.helpers.protoBuf); (instance as any).protoBufHelper = pbHelperStub; blocksModelStub = {toStringBlockType: sandbox.stub().callsFake((a) => a) }; (instance as any).blocksModel = blocksModelStub; (instance as any).generateBytesBlock = sandbox.stub().callsFake((a) => a); pbHelperStub.enqueueResponse('validate', true); pbHelperStub.enqueueResponse('encode', 'encodedValue'); }); afterEach(() => { sandbox.restore(); }); describe('getRequestOptions', () => { describe('protoBuf = false', () => { it('should return request options as json', () => { const reqOpts = instance.getRequestOptions(false); expect(reqOpts).to.be.deep.equal({ data: { block: 'b1' }, isProtoBuf: false, method: 'POST', url: '/peer/blocks', }); }); }); describe('protoBuf = true', () => { it('should call protoBufHelper.validate', () => { instance.getRequestOptions(true); expect(pbHelperStub.stubs.validate.calledOnce) .to.be.true; expect(pbHelperStub.stubs.validate.firstCall.args) .to.be.deep.equal([options.data, 'transportBlocks', 'transportBlock']); }); it('should call protoBufHelper.encode if validate is true', () => { instance.getRequestOptions(true); expect(pbHelperStub.stubs.encode.calledOnce) .to.be.true; expect(pbHelperStub.stubs.encode.firstCall.args) .to.be.deep.equal([options.data, 'transportBlocks', 'transportBlock']); }); it('should return from protoBufHelper.encode into .data if validate is true', () => { const val = instance.getRequestOptions(true); expect(val.data).to.be.equal('encodedValue'); }); it('should throw if validate is false', () => { pbHelperStub.stubs.validate.returns(false); expect(() => { instance.getRequestOptions(true); }).to.throw('Failed to encode ProtoBuf'); }); }); }); describe('getBaseUrl', () => { describe('protoBuf = false', () => { it('should return the right URL', () => { const url = (instance as any).getBaseUrl(false); expect(url).to.be.equal('/peer/blocks'); }); }); describe('protoBuf = true', () => { it('should return the right URL', () => { const url = (instance as any).getBaseUrl(true); expect(url).to.be.equal('/v2/peer/blocks'); }); }); }); describe('getResponseData', () => { let supportsStub: SinonStub; let decodeStub: SinonStub; beforeEach(() => { supportsStub = sandbox.stub(); decodeStub = sandbox.stub().returns('decodedValue'); (instance as any).peerSupportsProtoBuf = supportsStub; (instance as any).decodeProtoBufResponse = decodeStub; }); describe('protoBuf = false', () => { it('should return the response body', () => { supportsStub.returns(false); const ret = instance.getResponseData({body: 'responseBody'}); expect(ret).to.be.equal('responseBody'); }); }); describe('protoBuf = true', () => { it('should return the decoded response body', () => { supportsStub.returns(true); decodeStub.returns('decodedValue'); const ret = instance.getResponseData({body: 'requestBody'}); expect(ret).to.be.equal('decodedValue'); }); }); }); // TODO: Move this test to APIRequest /* describe('generateBytesBlock()', () => { const block = { transactions: ['tx1', 'tx2'], }; beforeEach(() => { blockLogicStub.stubs.getBytes.returns(Buffer.from('112233', 'hex')); generateBytesTransactionStub = sandbox.stub(instance as any, 'generateBytesTransaction') .returns(Buffer.from('0123', 'hex')); }); it('should call getBytes', () => { (instance as any).generateBytesBlock(block); expect(blockLogicStub.stubs.getBytes.calledOnce).to.be.true; expect(blockLogicStub.stubs.getBytes.firstCall.args).to.be.deep.equal([block]); }); it('should call generateBytesTransaction for each tx', () => { (instance as any).generateBytesBlock(block); expect(generateBytesTransactionStub.callCount).to.be.equal(block.transactions.length); expect(generateBytesTransactionStub.args).to.be.deep.equal(block.transactions.map((t) => [t])); }); it('should included all fields', () => { const val = (instance as any).generateBytesBlock(block); expect(val).to.be.deep.equal({ bytes : Buffer.from('112233', 'hex'), height : block.height, transactions: block.transactions.map(() => Buffer.from('0123', 'hex')), }); }); }); */ });
afterEach(function () { sandbox.restore(); mockery.deregisterAll(); mockery.disable(); });
describe('modules/accounts', () => { let sandbox: SinonSandbox; let accountLogicStub: AccountLogicStub; let accountModule: IAccountsModule; let container: Container; beforeEach(() => { sandbox = sinon.createSandbox(); container = createContainer(); accountLogicStub = container.get(Symbols.logic.account); container.rebind<IAccountsModule>(Symbols.modules.accounts).to(AccountsModule).inSingletonScope(); accountModule = container.get<any>(Symbols.modules.accounts); }); afterEach(() => { sandbox.restore(); }); describe('cleanup', () => { it('should return resolved promise', async () => { await expect(accountModule.cleanup()).to.be.fulfilled; }); }); describe('.getAccount', () => { it('should call accountLogic.get', async () => { accountLogicStub.enqueueResponse('get', 'meow'); await accountModule.getAccount({address: '1L'}); expect(accountLogicStub.stubs.get.called).is.true; }); it('should derive address from publicKey if not provided', async () => { accountLogicStub.enqueueResponse('generateAddressByPublicKey', '123L'); accountLogicStub.enqueueResponse('get', 'result'); await accountModule.getAccount({publicKey: Buffer.from('1235', 'hex')}); expect(accountLogicStub.stubs.generateAddressByPublicKey.called).is.true; expect(accountLogicStub.stubs.generateAddressByPublicKey.firstCall.args[0]).is.deep.eq(Buffer.from('1235', 'hex')); expect(accountLogicStub.stubs.get.called).is.true; expect(accountLogicStub.stubs.get.firstCall.args[0]).to.be.deep.eq({ address: '123L', }); }); it('shoul return what accountLogic.get returns', async () => { accountLogicStub.enqueueResponse('get', 'result'); expect(await accountModule.getAccount({address: '123L'})) .to.be.eq('result'); }); }); describe('.getAccounts', () => { it('should directly pass params to accountLogic.getAll', async () => { accountLogicStub.enqueueResponse('getAll', null); await accountModule.getAccounts({address: '1L'}, ['address']); expect(accountLogicStub.stubs.getAll.called).is.true; expect(accountLogicStub.stubs.getAll.firstCall.args.length).is.eq(2); expect(accountLogicStub.stubs.getAll.firstCall.args[0]) .to.be.deep.eq({address: '1L'}); expect(accountLogicStub.stubs.getAll.firstCall.args[1]) .to.be.deep.eq(['address']); }); it('should return what accountLogic.getAll returns', async () => { const theRes = {the: 'result'}; accountLogicStub.enqueueResponse('getAll', theRes); const res = await accountModule.getAccounts({address: '1L'}, ['address']); expect(res).to.be.deep.eq(theRes); }); }); describe('.setAccountAndGet', () => { it('should throw if no publicKey and address is provided', async () => { await expect(accountModule.setAccountAndGet({} as any)) .to.be.rejectedWith('Missing address and public key'); }); it('should derive address from publicKey if not provided', async () => { accountLogicStub.enqueueResponse('generateAddressByPublicKey', '1L'); accountLogicStub.enqueueResponse('set', null); accountLogicStub.enqueueResponse('get', null); await accountModule.setAccountAndGet({publicKey: Buffer.from('public')}); expect(accountLogicStub.stubs.generateAddressByPublicKey.called).is.true; expect(accountLogicStub.stubs.generateAddressByPublicKey.firstCall.args[0]) .to.be.deep.eq(Buffer.from('public')); }); it('should call accountLogic.set with address and data', async () => { accountLogicStub.enqueueResponse('set', null); accountLogicStub.enqueueResponse('get', null); await accountModule.setAccountAndGet({address: '1L'}); expect(accountLogicStub.stubs.set.calledOnce).is.true; expect(accountLogicStub.stubs.get.calledOnce).is.true; expect(accountLogicStub.stubs.set.firstCall.args[0]).to.be.eq('1L'); expect(accountLogicStub.stubs.set.firstCall.args[1]).to.be.deep.eq({}); expect(accountLogicStub.stubs.get.firstCall.args[0]).to.be.deep.eq({address: '1L'}); }); it('should accountLogi.get with address and return its value', async () => { accountLogicStub.enqueueResponse('set', null); accountLogicStub.enqueueResponse('get', 'antani'); const toRet = await accountModule.setAccountAndGet({address: '1L'}); expect(toRet).to.be.eq('antani'); }); }); describe('.mergeAccountAndGetOPs', () => { it('should throw if no publicKey and address is provided', async () => { expect(() => accountModule.mergeAccountAndGetOPs({} as any)) .to.be.throw('Missing address and public key'); }); it('should derive address from publicKey if not provided', () => { accountLogicStub.enqueueResponse('generateAddressByPublicKey', '1L'); accountLogicStub.enqueueResponse('merge', null); accountModule.mergeAccountAndGetOPs({publicKey: Buffer.from('public')}); expect(accountLogicStub.stubs.generateAddressByPublicKey.called).is.true; expect(accountLogicStub.stubs.generateAddressByPublicKey.firstCall.args[0]) .to.be.deep.eq(Buffer.from('public')); }); it('should call accountLogic.merge with address and return its value', async () => { accountLogicStub.enqueueResponse('merge', 'mergeResult'); const toRet = accountModule.mergeAccountAndGetOPs({address: '1L'}); expect(toRet).to.be.eq('mergeResult'); }); }); describe('.generateAddressByPublicKey', () => { it('should call accountLogic.generateAddressByPublicKey', () => { accountLogicStub.enqueueResponse('generateAddressByPublicKey', 'addressResult'); const res = accountModule.generateAddressByPublicKey('pubKey'); expect(res).to.be.eq('addressResult'); expect(accountLogicStub.stubs.generateAddressByPublicKey.called).is.true; expect(accountLogicStub.stubs.generateAddressByPublicKey.firstCall.args[0]).to.be.eq('pubKey'); }); }); describe('resolveAccountsForTransactions', () => { let accountsModel: typeof AccountsModel; let findAllStub: SinonStub; let setAccountAndGetStub: SinonStub; beforeEach(() => { accountsModel = container.get(Symbols.models.accounts); findAllStub = sandbox.stub().resolves([]); sandbox.stub(accountsModel, 'scope') .returns({findAll: findAllStub}); setAccountAndGetStub = sandbox.stub(accountModule, 'setAccountAndGet') .callsFake( ({publicKey}) => Promise .resolve({publicKey, address: `add${publicKey.toString('hex')}`}) ); }); it('shouldnt complain about empty txs array', async () => { const res = await accountModule.resolveAccountsForTransactions([]); expect(res).to.be.deep.eq({}); // should call findAll with empty array expect(findAllStub.calledOnce).is.true; expect(findAllStub.firstCall.args[0]).deep.eq({where: {address: []}}); }); it('should throw if account is not found in db', async () => { await expect(accountModule.resolveAccountsForTransactions([ {senderId: 'add11', senderPublicKey: Buffer.from('11', 'hex')} as any ])).rejectedWith('Account add11 not found in db'); }); it('should throw if account has diff publicKey in db', async () => { findAllStub.resolves([{address: 'add11', publicKey: Buffer.from('22', 'hex')}]); await expect(accountModule.resolveAccountsForTransactions([ {senderId: 'add11', senderPublicKey: Buffer.from('11', 'hex')} as any ])).rejectedWith('Stealing attempt type.2 for add11'); }); it('should setAccountAndGet if nopublickey set in db and throw if address does not match', async () => { findAllStub.resolves([{address: 'add11'}]); await expect(accountModule.resolveAccountsForTransactions([ {senderId: 'add11', senderPublicKey: Buffer.from('22', 'hex')} as any ])).rejectedWith('Stealing attempt type.1 for add11'); expect(setAccountAndGetStub.called).is.true; expect(setAccountAndGetStub.firstCall.args[0]) .is.deep.eq({publicKey: Buffer.from('22', 'hex')}); }); it('should also query for requesterPublicKey', async () => { accountLogicStub.stubs.generateAddressByPublicKey.returns('add33'); findAllStub.resolves([ {address: 'add11', publicKey: Buffer.from('11', 'hex')}, {address: 'add33', publicKey: Buffer.from('33', 'hex')}, ]); await accountModule.resolveAccountsForTransactions([{ senderId: 'add11', senderPublicKey: Buffer.from('11', 'hex'), requesterPublicKey: Buffer.from('33', 'hex')} as any ]); expect(findAllStub.calledOnce).is.true; expect(findAllStub.firstCall.args[0]).is.deep.eq({ where: { address: ['add11', 'add33']} }); }); }); });
describe("bst-test", function() { let globalModule = { Global: { initializeCLI: sinon.spy(async function () { }), config: function () { return { sourceID: () => "mySource" }; }, running : function() { let p = new BSTProcess(); p.port = 9999; return p; }, version: function () { return "0.0.0"; } } }; let sandbox: SinonSandbox = null; beforeEach(function () { mockery.enable({useCleanCache: true}); mockery.warnOnUnregistered(false); mockery.warnOnReplace(false); mockery.registerMock("../lib/core/global", globalModule); sandbox = sinon.sandbox.create(); globalModule.Global.initializeCLI.reset(); }); afterEach(function () { sandbox.restore(); mockery.deregisterAll(); mockery.disable(); }); describe("test command", function() { it("call initializeCLI with false", function() { return new Promise((resolve, reject) => { process.argv = command("node bst-test.js"); mockery.registerMock("skill-testing-ml", { CLI: function() { return { run: async function () { } }; }, ConfigurationKeys: [ { key: "platform", text: "Set platform" }, { key: "type", text: "Set type" } ] }); NodeUtil.load("../../bin/bst-test.js"); assert.equal(globalModule.Global.initializeCLI.getCall(0).args[0], false); resolve(); }); }); it("call with parameters", function() { return new Promise((resolve, reject) => { const mockRun = function(a, b){ assert.equal(b.platform, "google"); resolve(); }; const mockCli = function() { return { run: mockRun }; }; const skillTestingMock = { CLI: mockCli, ConfigurationKeys: [ { key: "platform", text: "Set platform" }, { key: "type", text: "Set type" } ] }; mockery.registerMock("skill-testing-ml", skillTestingMock); process.argv = command("node bst-test.js --platform google"); NodeUtil.load("../../bin/bst-test.js"); assert.equal(globalModule.Global.initializeCLI.getCall(0).args[0], false); }); }); }); });