How to use busStub method in Cypress

Best JavaScript code snippet using cypress

chain.js

Source:chain.js Github

copy

Full Screen

1/* eslint-disable mocha/no-pending-tests, mocha/no-skipped-tests */2/*3 * Copyright © 2018 Lisk Foundation4 *5 * See the LICENSE file at the top-level directory of this distribution6 * for licensing information.7 *8 * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation,9 * no part of this software, including this file, may be copied, modified,10 * propagated, or distributed except according to the terms contained in the11 * LICENSE file.12 *13 * Removal or modification of this copyright notice is prohibited.14 */15'use strict';16const rewire = require('rewire');17const BlocksChain = rewire('../../../../modules/blocks/chain.js');18describe('blocks/chain', () => {19 let __private;20 let library;21 let modules;22 let blocksChainModule;23 let dbStub;24 let loggerStub;25 let blockStub;26 let transactionStub;27 let busStub;28 let balancesSequenceStub;29 let genesisBlockStub;30 let modulesStub;31 const blockWithEmptyTransactions = {32 id: 1,33 height: 1,34 transactions: [],35 };36 const blockWithUndefinedTransactions = {37 id: 1,38 height: 1,39 transactions: undefined,40 };41 const blockWithTransactions = {42 id: 3,43 height: 3,44 transactions: [45 { id: 5, type: 3, senderPublicKey: 'a', amount: '1000000', fee: '10000' },46 { id: 6, type: 2, senderPublicKey: 'b', amount: '1000000', fee: '10000' },47 { id: 7, type: 1, senderPublicKey: 'c', amount: '1000000', fee: '10000' },48 ],49 };50 const genesisBlockWithTransactions = {51 id: 1,52 height: 1,53 transactions: [54 { id: 5, type: 3, senderPublicKey: 'a', amount: '1000000', fee: '10000' },55 { id: 6, type: 2, senderPublicKey: 'b', amount: '1000000', fee: '10000' },56 { id: 7, type: 1, senderPublicKey: 'c', amount: '1000000', fee: '10000' },57 ],58 };59 const blockReduced = { id: 3, height: 3 };60 beforeEach(done => {61 // Logic62 dbStub = {63 blocks: {64 getGenesisBlockId: sinonSandbox.stub(),65 deleteBlock: sinonSandbox.stub(),66 deleteAfterBlock: sinonSandbox.stub(),67 },68 tx: sinonSandbox.stub(),69 };70 blockStub = sinonSandbox.stub();71 loggerStub = {72 trace: sinonSandbox.spy(),73 info: sinonSandbox.spy(),74 error: sinonSandbox.spy(),75 warn: sinonSandbox.spy(),76 debug: sinonSandbox.spy(),77 };78 busStub = {79 message: sinonSandbox.stub(),80 };81 transactionStub = {82 afterSave: sinonSandbox.stub().callsArgWith(1, null, true),83 undoUnconfirmed: sinonSandbox.stub(),84 };85 balancesSequenceStub = {86 add: (cb, cbp) => {87 cb(cbp);88 },89 };90 genesisBlockStub = {91 block: {92 id: '6524861224470851795',93 height: 1,94 },95 };96 blocksChainModule = new BlocksChain(97 loggerStub,98 blockStub,99 transactionStub,100 dbStub,101 genesisBlockStub,102 busStub,103 balancesSequenceStub104 );105 library = BlocksChain.__get__('library');106 __private = BlocksChain.__get__('__private');107 // Module108 const tracker = {109 applyNext: sinonSandbox.stub(),110 };111 const modulesAccountsStub = {112 getAccount: sinonSandbox.stub(),113 setAccountAndGet: sinonSandbox.stub(),114 };115 const modulesBlocksStub = {116 lastBlock: {117 get: sinonSandbox.stub(),118 set: sinonSandbox.stub(),119 },120 utils: {121 loadBlocksPart: sinonSandbox.stub(),122 getBlockProgressLogger: sinonSandbox.stub().returns(tracker),123 },124 isActive: {125 set: sinonSandbox.stub(),126 },127 };128 const modulesRoundsStub = {129 backwardTick: sinonSandbox.stub(),130 tick: sinonSandbox.stub(),131 };132 const modulesSystemStub = {133 update: sinonSandbox.stub(),134 };135 const modulesTransportStub = {136 broadcastHeaders: sinonSandbox.stub(),137 };138 const modulesTransactionsStub = {139 applyUnconfirmed: sinonSandbox.stub(),140 applyConfirmed: sinonSandbox.stub(),141 receiveTransactions: sinonSandbox.stub(),142 undoConfirmed: sinonSandbox.stub(),143 undoUnconfirmed: sinonSandbox.stub(),144 undoUnconfirmedList: sinonSandbox.stub(),145 removeUnconfirmedTransaction: sinonSandbox.stub(),146 };147 modulesStub = {148 accounts: modulesAccountsStub,149 blocks: modulesBlocksStub,150 rounds: modulesRoundsStub,151 transactions: modulesTransactionsStub,152 system: modulesSystemStub,153 transport: modulesTransportStub,154 };155 process.exit = sinonSandbox.stub().returns(0);156 blocksChainModule.onBind(modulesStub);157 modules = BlocksChain.__get__('modules');158 done();159 });160 afterEach(() => {161 return sinonSandbox.restore();162 });163 describe('constructor', () => {164 it('should assign params to library', () => {165 expect(library.logger).to.eql(loggerStub);166 expect(library.db).to.eql(dbStub);167 expect(library.genesisBlock).to.eql(genesisBlockStub);168 expect(library.bus).to.eql(busStub);169 expect(library.balancesSequence).to.eql(balancesSequenceStub);170 expect(library.logic.block).to.eql(blockStub);171 return expect(library.logic.transaction).to.eql(transactionStub);172 });173 it('should call library.logger.trace with "Blocks->Chain: Submodule initialized."', () => {174 return expect(loggerStub.trace.args[0][0]).to.equal(175 'Blocks->Chain: Submodule initialized.'176 );177 });178 it('should return self', () => {179 expect(blocksChainModule).to.be.an('object');180 expect(blocksChainModule.saveGenesisBlock).to.be.a('function');181 expect(blocksChainModule.saveBlock).to.be.a('function');182 expect(blocksChainModule.deleteBlock).to.be.a('function');183 expect(blocksChainModule.deleteAfterBlock).to.be.a('function');184 expect(blocksChainModule.applyGenesisBlock).to.be.a('function');185 expect(blocksChainModule.applyBlock).to.be.a('function');186 expect(blocksChainModule.broadcastReducedBlock).to.be.a('function');187 expect(blocksChainModule.deleteLastBlock).to.be.a('function');188 expect(blocksChainModule.recoverChain).to.be.a('function');189 return expect(blocksChainModule.onBind).to.be.a('function');190 });191 });192 describe('saveGenesisBlock', () => {193 let saveBlockTemp;194 describe('when library.db.blocks.getGenesisBlockId fails', () => {195 beforeEach(() => {196 return library.db.blocks.getGenesisBlockId.rejects(197 'getGenesisBlockId-ERR'198 );199 });200 it('should call a callback with error', done => {201 blocksChainModule.saveGenesisBlock(err => {202 expect(err).to.equal('Blocks#saveGenesisBlock error');203 expect(loggerStub.error.args[0][0]).to.contains(204 'getGenesisBlockId-ERR'205 );206 done();207 });208 });209 });210 describe('when library.db.blocks.getGenesisBlockId succeeds', () => {211 describe('if returns empty row (genesis block is not in database)', () => {212 beforeEach(done => {213 library.db.blocks.getGenesisBlockId.resolves([]);214 saveBlockTemp = blocksChainModule.saveBlock;215 blocksChainModule.saveBlock = sinonSandbox.stub();216 done();217 });218 afterEach(done => {219 blocksChainModule.saveBlock = saveBlockTemp;220 done();221 });222 describe('when self.saveBlock fails', () => {223 beforeEach(() => {224 return blocksChainModule.saveBlock.callsArgWith(225 1,226 'saveBlock-ERR',227 null228 );229 });230 it('should call a callback with error', done => {231 blocksChainModule.saveGenesisBlock(err => {232 expect(err).to.equal('saveBlock-ERR');233 done();234 });235 });236 });237 describe('when self.saveBlock succeeds', () => {238 beforeEach(() => {239 return blocksChainModule.saveBlock.callsArgWith(1, null, true);240 });241 it('should call a callback with no error', done => {242 blocksChainModule.saveGenesisBlock(cb => {243 expect(cb).to.be.null;244 done();245 });246 });247 });248 });249 describe('if returns row', () => {250 beforeEach(() => {251 return library.db.blocks.getGenesisBlockId.resolves([{ id: 1 }]);252 });253 it('should call a callback with no error', done => {254 blocksChainModule.saveGenesisBlock(err => {255 expect(err).to.be.undefined;256 done();257 });258 });259 });260 });261 });262 describe('saveBlock', () => {263 let afterSaveTemp;264 beforeEach(done => {265 afterSaveTemp = __private.afterSave;266 done();267 });268 afterEach(done => {269 __private.afterSave = afterSaveTemp;270 done();271 });272 describe('when tx param is passed', () => {273 let txStub;274 beforeEach(done => {275 txStub = {276 blocks: {277 save: sinonSandbox.stub(),278 },279 transactions: {280 save: sinonSandbox.stub(),281 },282 batch: sinonSandbox.stub(),283 };284 done();285 });286 describe('when tx.batch fails', () => {287 beforeEach(() => {288 return txStub.batch.rejects('txbatch-ERR');289 });290 it('should call a callback with error', done => {291 blocksChainModule.saveBlock(292 blockWithTransactions,293 err => {294 expect(err).to.equal('Blocks#saveBlock error');295 done();296 },297 txStub298 );299 });300 });301 describe('when tx.batch succeeds', () => {302 beforeEach(done => {303 txStub.batch.resolves();304 __private.afterSave = sinonSandbox.stub().callsArgWith(1, null, true);305 done();306 });307 it('should call __private.afterSave', done => {308 blocksChainModule.saveBlock(309 blockWithTransactions,310 () => {311 expect(__private.afterSave.calledOnce).to.be.true;312 done();313 },314 txStub315 );316 });317 });318 });319 describe('when tx param is not passed', () => {320 let txStub;321 beforeEach(done => {322 txStub = {323 blocks: {324 save: sinonSandbox.stub(),325 },326 transactions: {327 save: sinonSandbox.stub(),328 },329 batch: sinonSandbox.stub(),330 };331 library.db.tx.callsArgWith(1, txStub);332 done();333 });334 describe('when tx.batch fails', () => {335 beforeEach(() => {336 return txStub.batch.rejects('txbatch-ERR');337 });338 it('should call a callback with error', done => {339 blocksChainModule.saveBlock(blockWithTransactions, err => {340 expect(err).to.equal('Blocks#saveBlock error');341 done();342 });343 });344 });345 describe('when tx.batch succeeds', () => {346 beforeEach(done => {347 txStub.batch.resolves();348 __private.afterSave = sinonSandbox.stub().callsArgWith(1, null, true);349 done();350 });351 it('should call __private.afterSave', done => {352 blocksChainModule.saveBlock(blockWithTransactions, () => {353 expect(__private.afterSave.calledOnce).to.be.true;354 done();355 });356 });357 });358 });359 });360 describe('__private.afterSave', () => {361 it('should call afterSave for all transactions', done => {362 __private.afterSave(blockWithTransactions, () => {363 expect(library.logic.transaction.afterSave.callCount).to.equal(3);364 expect(library.bus.message.calledOnce).to.be.true;365 expect(library.bus.message.args[0][0]).to.equal('transactionsSaved');366 expect(library.bus.message.args[0][1]).to.deep.equal(367 blockWithTransactions.transactions368 );369 done();370 });371 });372 });373 describe('deleteBlock', () => {374 describe('when library.db.blocks.deleteBlock fails', () => {375 beforeEach(() => {376 return library.db.blocks.deleteBlock.rejects('deleteBlock-ERR');377 });378 it('should call a callback with error', done => {379 blocksChainModule.deleteBlock(380 1,381 err => {382 expect(err).to.equal('Blocks#deleteBlock error');383 expect(loggerStub.error.args[0][0]).to.contains('deleteBlock-ERR');384 done();385 },386 library.db387 );388 });389 });390 describe('when library.db.blocks.deleteBlock succeeds', () => {391 beforeEach(() => {392 return library.db.blocks.deleteBlock.resolves(true);393 });394 it('should call a callback with no error', done => {395 blocksChainModule.deleteBlock(396 1,397 () => {398 done();399 },400 library.db401 );402 });403 });404 });405 describe('deleteAfterBlock', () => {406 describe('when library.db.blocks.deleteAfterBlock fails', () => {407 beforeEach(() => {408 return library.db.blocks.deleteAfterBlock.rejects(409 'deleteAfterBlock-ERR'410 );411 });412 it('should call a callback with error', done => {413 blocksChainModule.deleteAfterBlock(1, err => {414 expect(err).to.equal('Blocks#deleteAfterBlock error');415 expect(loggerStub.error.args[0][0]).to.contains(416 'deleteAfterBlock-ERR'417 );418 done();419 });420 });421 });422 describe('when library.db.blocks.deleteAfterBlock succeeds', () => {423 beforeEach(() => {424 return library.db.blocks.deleteAfterBlock.resolves(true);425 });426 it('should call a callback with no error and res data', done => {427 blocksChainModule.deleteAfterBlock(1, (err, res) => {428 expect(err).to.be.null;429 expect(res).to.be.true;430 done();431 });432 });433 });434 });435 describe('applyGenesisBlock', () => {436 let applyTransactionTemp;437 beforeEach(done => {438 modules.rounds.tick.callsArgWith(1, null, true);439 applyTransactionTemp = __private.applyTransaction;440 __private.applyTransaction = sinonSandbox.stub();441 done();442 });443 afterEach(done => {444 __private.applyTransaction = applyTransactionTemp;445 done();446 });447 describe('when block.transactions is empty', () => {448 it('modules.rouds.tick should call a callback', done => {449 blocksChainModule.applyGenesisBlock(blockWithEmptyTransactions, () => {450 expect(modules.blocks.utils.getBlockProgressLogger.calledOnce).to.be451 .true;452 expect(modules.blocks.lastBlock.set.calledOnce).to.be.true;453 expect(modules.blocks.lastBlock.set.args[0][0]).to.deep.equal(454 blockWithEmptyTransactions455 );456 expect(modules.rounds.tick.args[0][0]).to.deep.equal(457 blockWithEmptyTransactions458 );459 done();460 });461 });462 });463 describe('when block.transactions is not empty', () => {464 describe('when modules.accounts.setAccountAndGet fails', () => {465 beforeEach(() => {466 process.emit = sinonSandbox.stub();467 return modules.accounts.setAccountAndGet.callsArgWith(468 1,469 'setAccountAndGet-ERR',470 true471 );472 });473 it('should call process.exit with 0', done => {474 blocksChainModule.applyGenesisBlock(blockWithTransactions, result => {475 expect(modules.blocks.utils.getBlockProgressLogger.calledOnce).to.be476 .true;477 expect(process.emit).to.have.been.calledOnce;478 expect(process.emit).to.have.been.calledWith(479 'cleanup',480 'setAccountAndGet-ERR'481 );482 expect(result.message).to.equal('setAccountAndGet-ERR');483 done();484 });485 });486 });487 describe('when modules.accounts.setAccountAndGet succeeds', () => {488 beforeEach(() => {489 return modules.accounts.setAccountAndGet.callsArgWith(1, null, true);490 });491 describe('when __private.applyTransaction fails', () => {492 beforeEach(() => {493 return __private.applyTransaction.callsArgWith(494 3,495 'applyTransaction-ERR',496 null497 );498 });499 it('should call a callback with proper error message', done => {500 blocksChainModule.applyGenesisBlock(501 blockWithTransactions,502 result => {503 expect(504 modules.blocks.utils.getBlockProgressLogger.callCount505 ).to.equal(1);506 expect(result).to.equal('applyTransaction-ERR');507 done();508 }509 );510 });511 });512 describe('when __private.applyTransaction succeeds', () => {513 beforeEach(() => {514 return __private.applyTransaction.callsArgWith(3, null, true);515 });516 it('modules.rouds.tick should call a callback', done => {517 blocksChainModule.applyGenesisBlock(blockWithTransactions, () => {518 expect(modules.blocks.utils.getBlockProgressLogger.calledOnce).to519 .be.true;520 expect(__private.applyTransaction.callCount).to.equal(3);521 expect(modules.blocks.lastBlock.set.calledOnce).to.be.true;522 expect(modules.blocks.lastBlock.set.args[0][0]).to.deep.equal(523 blockWithTransactions524 );525 expect(modules.rounds.tick.args[0][0]).to.deep.equal(526 blockWithTransactions527 );528 done();529 });530 });531 });532 });533 });534 });535 describe('__private.applyTransaction', () => {536 describe('when modules.transactions.applyUnconfirmed fails', () => {537 beforeEach(() => {538 return modules.transactions.applyUnconfirmed.callsArgWith(539 2,540 'applyUnconfirmed-ERR',541 null542 );543 });544 it('should call a callback with error', done => {545 __private.applyTransaction(546 blockWithTransactions,547 { id: 1, type: 1 },548 'a1',549 err => {550 expect(err.message).to.equal('applyUnconfirmed-ERR');551 expect(err.transaction).to.deep.equal({ id: 1, type: 1 });552 expect(err.block).to.deep.equal(blockWithTransactions);553 done();554 }555 );556 });557 });558 describe('when modules.transactions.applyUnconfirmed succeeds', () => {559 beforeEach(() => {560 return modules.transactions.applyUnconfirmed.callsArgWith(561 2,562 null,563 true564 );565 });566 describe('when modules.transactions.applyConfirmed fails', () => {567 beforeEach(() => {568 return modules.transactions.applyConfirmed.callsArgWith(569 3,570 'apply-ERR',571 null572 );573 });574 it('should call a callback with error', done => {575 __private.applyTransaction(576 blockWithTransactions,577 { id: 1, type: 1 },578 'a1',579 err => {580 expect(err.message).to.equal(581 'Failed to apply transaction: 1 to confirmed state of account:'582 );583 expect(err.transaction).to.deep.equal({ id: 1, type: 1 });584 expect(err.block).to.deep.equal(blockWithTransactions);585 done();586 }587 );588 });589 });590 describe('when modules.transactions.applyConfirmed succeeds', () => {591 beforeEach(() => {592 return modules.transactions.applyConfirmed.callsArgWith(593 3,594 null,595 true596 );597 });598 it('should call a callback with no error', done => {599 __private.applyTransaction(600 blockWithTransactions,601 { id: 1, type: 1 },602 'a1',603 () => {604 expect(modules.transactions.applyUnconfirmed.calledOnce).to.be605 .true;606 expect(modules.transactions.applyConfirmed.calledOnce).to.be.true;607 done();608 }609 );610 });611 });612 });613 });614 describe('__private.undoUnconfirmedListStep', () => {615 describe('when modules.transactions.undoUnconfirmedList fails', () => {616 beforeEach(() => {617 return modules.transactions.undoUnconfirmedList.callsArgWith(618 0,619 'undoUnconfirmedList-ERR',620 null621 );622 });623 it('should call a callback with error', done => {624 __private.undoUnconfirmedListStep(err => {625 expect(err).to.equal('Failed to undo unconfirmed list');626 expect(loggerStub.error.args[0][0]).to.be.equal(627 'Failed to undo unconfirmed list'628 );629 expect(loggerStub.error.args[0][1]).to.be.equal(630 'undoUnconfirmedList-ERR'631 );632 done();633 });634 });635 });636 describe('when modules.transactions.undoUnconfirmedList succeeds', () => {637 beforeEach(() => {638 return modules.transactions.undoUnconfirmedList.callsArgWith(639 0,640 null,641 true642 );643 });644 it('should call a callback with no error', done => {645 __private.undoUnconfirmedListStep(err => {646 expect(err).to.be.undefined;647 done();648 });649 });650 });651 });652 describe('__private.applyUnconfirmedStep', () => {653 describe('when block.transactions is undefined', () => {654 it('should return rejected promise with error', done => {655 __private656 .applyUnconfirmedStep(blockWithUndefinedTransactions, dbStub.tx)657 .catch(err => {658 expect(err).instanceOf(Error);659 expect(err.message).to.equal(660 'expecting an array or an iterable object but got [object Null]'661 );662 done();663 });664 });665 });666 describe('when block.transactions is empty', () => {667 it('should return resolved promise with no error', done => {668 __private669 .applyUnconfirmedStep(blockWithEmptyTransactions, dbStub.tx)670 .then(resolved => {671 expect(resolved).to.be.an('array').that.is.empty;672 done();673 });674 });675 });676 describe('when block.transactions is not empty', () => {677 describe('when modules.accounts.setAccountAndGet fails', () => {678 beforeEach(() => {679 return modules.accounts.setAccountAndGet.callsArgWith(680 1,681 'setAccountAndGet-ERR',682 null683 );684 });685 it('should return rejected promise with error', done => {686 __private687 .applyUnconfirmedStep(blockWithTransactions, dbStub.tx)688 .catch(err => {689 expect(err).instanceOf(Error);690 expect(err.message).to.equal(691 'Failed to get account to apply unconfirmed transaction: 6 - setAccountAndGet-ERR'692 );693 expect(loggerStub.error.args[0][0]).to.equal(694 'Failed to get account to apply unconfirmed transaction: 6 - setAccountAndGet-ERR'695 );696 expect(loggerStub.error.args[1][0]).to.equal('Transaction');697 expect(loggerStub.error.args[1][1]).to.deep.equal(698 blockWithTransactions.transactions[0]699 );700 done();701 });702 });703 });704 describe('when modules.accounts.setAccountAndGet succeeds', () => {705 beforeEach(() => {706 return modules.accounts.setAccountAndGet.callsArgWith(707 1,708 null,709 'sender1'710 );711 });712 describe('when modules.transactions.applyUnconfirmed fails', () => {713 beforeEach(() => {714 return modules.transactions.applyUnconfirmed.callsArgWith(715 2,716 'applyUnconfirmed-ERR',717 null718 );719 });720 it('should return rejected promise with error', done => {721 __private722 .applyUnconfirmedStep(blockWithTransactions, dbStub.tx)723 .catch(err => {724 expect(err).instanceOf(Error);725 expect(err.message).to.equal(726 'Failed to apply transaction: 6 to unconfirmed state of account - applyUnconfirmed-ERR'727 );728 expect(loggerStub.error.args[0][0]).to.equal(729 'Failed to apply transaction: 6 to unconfirmed state of account - applyUnconfirmed-ERR'730 );731 expect(loggerStub.error.args[1][0]).to.equal('Transaction');732 expect(loggerStub.error.args[1][1]).to.deep.equal(733 blockWithTransactions.transactions[0]734 );735 done();736 });737 });738 });739 describe('when modules.transactions.applyUnconfirmed succeeds', () => {740 beforeEach(() => {741 return modules.transactions.applyUnconfirmed.callsArgWith(742 2,743 null,744 true745 );746 });747 it('should return resolved promise with no error', done => {748 __private749 .applyUnconfirmedStep(blockWithTransactions, dbStub.tx)750 .then(resolve => {751 expect(resolve).to.deep.equal([752 undefined,753 undefined,754 undefined,755 ]);756 expect(modules.accounts.setAccountAndGet.callCount).to.equal(3);757 expect(758 modules.transactions.applyUnconfirmed.callCount759 ).to.equal(3);760 done();761 });762 });763 });764 });765 });766 });767 describe('__private.applyConfirmedStep', () => {768 describe('when block transaction is undefined', () => {769 it('should return rejected promise with error', done => {770 __private771 .applyConfirmedStep(blockWithUndefinedTransactions, dbStub.tx)772 .catch(err => {773 expect(err).instanceOf(Error);774 expect(err.message).to.equal(775 'expecting an array or an iterable object but got [object Null]'776 );777 done();778 });779 });780 });781 describe('when block transaction is empty', () => {782 it('should return resolved promise with no error', done => {783 __private784 .applyConfirmedStep(blockWithEmptyTransactions, dbStub.tx)785 .then(resolved => {786 expect(resolved).to.be.an('array').that.is.empty;787 done();788 });789 });790 });791 describe('when block.transaction is not empty', () => {792 describe('when modules.accounts.getAccount fails', () => {793 beforeEach(() => {794 return modules.accounts.getAccount.callsArgWith(795 1,796 'getAccount-ERR',797 null798 );799 });800 it('should return rejected promise with error', done => {801 __private802 .applyConfirmedStep(blockWithTransactions, dbStub.tx)803 .catch(err => {804 expect(err).instanceOf(Error);805 expect(err.message).to.equal(806 'Failed to get account for applying transaction to confirmed state: 6 - getAccount-ERR'807 );808 expect(modules.accounts.getAccount.callCount).to.equal(1);809 expect(modules.transactions.applyConfirmed.callCount).to.equal(0);810 expect(loggerStub.error.args[0][0]).to.equal(811 'Failed to get account for applying transaction to confirmed state: 6 - getAccount-ERR'812 );813 expect(loggerStub.error.args[1][0]).to.equal('Transaction');814 expect(loggerStub.error.args[1][1]).to.deep.equal(815 blockWithTransactions.transactions[0]816 );817 done();818 });819 });820 });821 describe('when modules.accounts.getAccount succeeds', () => {822 beforeEach(() => {823 return modules.accounts.getAccount.callsArgWith(1, null, 'sender1');824 });825 describe('when library.logic.transaction.apply fails', () => {826 beforeEach(() => {827 return modules.transactions.applyConfirmed.callsArgWith(828 3,829 'apply-ERR',830 null831 );832 });833 it('should return rejected promise with error', done => {834 __private835 .applyConfirmedStep(blockWithTransactions, dbStub.tx)836 .catch(err => {837 expect(err).instanceOf(Error);838 expect(err.message).to.equal(839 'Failed to apply transaction: 6 to confirmed state of account - apply-ERR'840 );841 expect(modules.accounts.getAccount.callCount).to.equal(1);842 expect(modules.transactions.applyConfirmed.callCount).to.equal(843 1844 );845 expect(loggerStub.error.args[0][0]).to.equal(846 'Failed to apply transaction: 6 to confirmed state of account - apply-ERR'847 );848 expect(loggerStub.error.args[1][0]).to.equal('Transaction');849 expect(loggerStub.error.args[1][1]).to.deep.equal(850 blockWithTransactions.transactions[0]851 );852 done();853 });854 });855 });856 describe('when library.logic.transaction.applyConfirmed succeeds', () => {857 beforeEach(() => {858 return modules.transactions.applyConfirmed.callsArgWith(859 3,860 null,861 true862 );863 });864 it('should return resolved promise with no error', done => {865 __private866 .applyConfirmedStep(blockWithTransactions, dbStub.tx)867 .then(resolve => {868 expect(resolve).to.be.deep.equal([869 undefined,870 undefined,871 undefined,872 ]);873 done();874 });875 });876 });877 });878 });879 });880 describe('__private.saveBlockStep', () => {881 let saveBlockTemp;882 beforeEach(done => {883 saveBlockTemp = blocksChainModule.saveBlock;884 blocksChainModule.saveBlock = sinonSandbox885 .stub()886 .callsArgWith(1, null, true);887 modules.rounds.tick.callsArgWith(1, null, true);888 process.emit = sinonSandbox.stub();889 library.db.tx = (desc, tx) => {890 return tx();891 };892 done();893 });894 afterEach(done => {895 blocksChainModule.saveBlock = saveBlockTemp;896 done();897 });898 describe('when saveBlock is true', () => {899 describe('when self.saveBlock fails', () => {900 beforeEach(() => {901 return blocksChainModule.saveBlock.callsArgWith(902 1,903 'saveBlock-ERR',904 null905 );906 });907 it('should call a callback with error', done => {908 __private909 .saveBlockStep(blockWithTransactions, true, dbStub.tx)910 .catch(err => {911 expect(err).instanceOf(Error);912 expect(err.message).to.equal('Failed to save block');913 expect(loggerStub.error.args[0][0]).to.contains(914 'Failed to save block'915 );916 expect(loggerStub.error.args[0][1]).to.contains('saveBlock-ERR');917 expect(loggerStub.error.args[1][0]).to.equal('Block');918 expect(loggerStub.error.args[1][1]).to.deep.equal(919 blockWithTransactions920 );921 expect(blocksChainModule.saveBlock.args[0][0]).to.deep.equal(922 blockWithTransactions923 );924 expect(modules.blocks.lastBlock.set.calledOnce).to.be.false;925 done();926 });927 });928 });929 describe('when self.saveBlock succeeds', () => {930 beforeEach(() => {931 return blocksChainModule.saveBlock.callsArgWith(1, null, true);932 });933 afterEach(() => {934 expect(loggerStub.debug.args[0][0]).to.contains(935 'Block applied correctly with 3 transactions'936 );937 return expect(blocksChainModule.saveBlock.args[0][0]).to.deep.equal(938 blockWithTransactions939 );940 });941 describe('when modules.rounds.tick fails', () => {942 beforeEach(() => {943 return modules.rounds.tick.callsArgWith(1, 'tick-ERR', null);944 });945 it('should call a callback with error', done => {946 __private947 .saveBlockStep(blockWithTransactions, true, dbStub.tx)948 .catch(err => {949 expect(err).to.equal('tick-ERR');950 expect(library.bus.message.calledOnce).to.be.false;951 done();952 });953 });954 });955 describe('when modules.rounds.tick succeeds', () => {956 beforeEach(() => {957 return modules.rounds.tick.callsArgWith(1, null, true);958 });959 it('should call a callback with no error', done => {960 __private961 .saveBlockStep(blockWithTransactions, true, dbStub.tx)962 .then(resolve => {963 expect(resolve).to.be.undefined;964 expect(library.bus.message.calledOnce).to.be.true;965 expect(library.bus.message.args[0][0]).to.deep.equal(966 'newBlock'967 );968 expect(library.bus.message.args[0][1]).to.deep.equal(969 blockWithTransactions970 );971 done();972 });973 });974 });975 });976 });977 describe('when saveBlock is false', () => {978 describe('when modules.rounds.tick fails', () => {979 beforeEach(() => {980 return modules.rounds.tick.callsArgWith(1, 'tick-ERR', null);981 });982 it('should call a callback with error', done => {983 __private984 .saveBlockStep(blockWithTransactions, true, dbStub.tx)985 .catch(err => {986 expect(err).to.equal('tick-ERR');987 expect(library.bus.message.calledOnce).to.be.false;988 done();989 });990 });991 });992 describe('when modules.rounds.tick succeeds', () => {993 beforeEach(() => {994 return modules.rounds.tick.callsArgWith(1, null, true);995 });996 it('should call a callback with no error', done => {997 __private998 .saveBlockStep(blockWithTransactions, true, dbStub.tx)999 .then(resolve => {1000 expect(resolve).to.be.undefined;1001 expect(library.bus.message.calledOnce).to.be.true;1002 expect(library.bus.message.args[0][0]).to.deep.equal('newBlock');1003 expect(library.bus.message.args[0][1]).to.deep.equal(1004 blockWithTransactions1005 );1006 done();1007 });1008 });1009 });1010 });1011 });1012 describe('applyBlock', () => {1013 let privateTemp;1014 let txTemp;1015 beforeEach(done => {1016 txTemp = library.db.tx;1017 privateTemp = __private;1018 process.emit = sinonSandbox.stub();1019 modules.transactions.undoUnconfirmedList.callsArgWith(0, null, true);1020 __private.applyUnconfirmedStep = sinonSandbox1021 .stub()1022 .resolves(blockWithTransactions);1023 __private.applyConfirmedStep = sinonSandbox1024 .stub()1025 .resolves(blockWithTransactions);1026 __private.saveBlockStep = sinonSandbox1027 .stub()1028 .resolves(blockWithTransactions);1029 done();1030 });1031 afterEach(done => {1032 expect(__private.applyUnconfirmedStep).calledWith(1033 blockWithTransactions,1034 txTemp1035 );1036 expect(__private.applyConfirmedStep).calledWith(1037 blockWithTransactions,1038 txTemp1039 );1040 expect(__private.saveBlockStep).calledWith(1041 blockWithTransactions,1042 true,1043 txTemp1044 );1045 expect(modules.blocks.isActive.set.calledTwice).to.be.true;1046 __private = privateTemp;1047 library.db.tx = txTemp;1048 done();1049 });1050 describe('when library.db.tx fails', () => {1051 afterEach(() => {1052 expect(modules.blocks.isActive.set.args[0][0]).to.be.true;1053 return expect(modules.blocks.isActive.set.args[1][0]).to.be.false;1054 });1055 describe('when reason === Snapshot finished', () => {1056 beforeEach(done => {1057 library.db.tx = (desc, tx) => {1058 return tx(txTemp.rejects());1059 };1060 __private.saveBlockStep.rejects('Snapshot finished');1061 done();1062 });1063 it('should call a callback with error', done => {1064 blocksChainModule.applyBlock(blockWithTransactions, true, err => {1065 expect(err.name).to.equal('Snapshot finished');1066 expect(loggerStub.info.args[0][0].name).to.equal(1067 'Snapshot finished'1068 );1069 expect(process.emit).to.have.been.calledWith('SIGTERM');1070 done();1071 });1072 });1073 });1074 describe('when reason !== Snapshot finished', () => {1075 beforeEach(done => {1076 library.db.tx = (desc, tx) => {1077 return tx(txTemp.rejects());1078 };1079 __private.saveBlockStep.rejects('Chain:applyBlock-ERR');1080 done();1081 });1082 it('should call a callback with error', done => {1083 blocksChainModule.applyBlock(blockWithTransactions, true, err => {1084 expect(err.name).to.equal('Chain:applyBlock-ERR');1085 expect(process.emit.callCount).to.equal(0);1086 done();1087 });1088 });1089 });1090 });1091 describe('when library.db.tx succeeds', () => {1092 beforeEach(done => {1093 library.db.tx = (desc, tx) => {1094 return tx(txTemp.resolves());1095 };1096 modules.transactions.removeUnconfirmedTransaction.returns(true);1097 done();1098 });1099 it('should call a callback with no error', done => {1100 blocksChainModule.applyBlock(blockWithTransactions, true, err => {1101 expect(err).to.be.null;1102 expect(1103 modules.transactions.removeUnconfirmedTransaction.callCount1104 ).to.equal(3);1105 expect(modules.blocks.isActive.set.callCount).to.equal(2);1106 done();1107 });1108 });1109 });1110 });1111 describe('broadcastReducedBlock', () => {1112 it('should call library.bus.message with reducedBlock and broadcast', () => {1113 blocksChainModule.broadcastReducedBlock(blockReduced, true);1114 expect(library.bus.message.calledOnce).to.be.true;1115 expect(library.bus.message.args[0][0]).to.equal('broadcastBlock');1116 expect(library.bus.message.args[0][1]).to.deep.equal(blockReduced);1117 return expect(library.bus.message.args[0][2]).to.be.true;1118 });1119 });1120 describe('__private.loadSecondLastBlockStep', () => {1121 let tx;1122 beforeEach(() => {1123 tx = sinonSandbox.stub();1124 return modules.blocks.utils.loadBlocksPart.callsArgWith(1125 1,1126 'loadBlocksPart-ERR',1127 null1128 );1129 });1130 describe('when modules.blocks.utils.loadBlocksPart fails', () => {1131 describe('if returns error', () => {1132 it('should call a callback with returned error', done => {1133 __private.loadSecondLastBlockStep(blockReduced.id, tx).catch(err => {1134 expect(err).to.equal('loadBlocksPart-ERR');1135 done();1136 });1137 });1138 });1139 describe('if returns empty', () => {1140 beforeEach(() => {1141 return modules.blocks.utils.loadBlocksPart.callsArgWith(1, null, []);1142 });1143 it('should call a callback with error "previousBlock is null"', done => {1144 __private.loadSecondLastBlockStep(blockReduced.id, tx).catch(err => {1145 expect(err).to.equal('previousBlock is null');1146 done();1147 });1148 });1149 });1150 });1151 describe('when modules.blocks.utils.loadBlocksPart succeeds', () => {1152 beforeEach(() => {1153 return modules.blocks.utils.loadBlocksPart.callsArgWith(1, null, [1154 { id: 2, height: 2 },1155 ]);1156 });1157 });1158 });1159 describe('__private.undoConfirmedStep', () => {1160 let tx;1161 describe('when oldLastBlock.transactions is not empty', () => {1162 describe('when modules.accounts.getAccount fails', () => {1163 beforeEach(() => {1164 return modules.accounts.getAccount.callsArgWith(1165 1,1166 'getAccount-ERR',1167 null1168 );1169 });1170 it('should reject promise with "getAccount-ERR"', done => {1171 __private1172 .undoConfirmedStep(1173 blockWithTransactions.transactions[0],1174 blockWithTransactions,1175 tx1176 )1177 .catch(err => {1178 expect(err).to.equal('getAccount-ERR');1179 done();1180 });1181 });1182 });1183 describe('when modules.accounts.getAccount succeeds', () => {1184 beforeEach(done => {1185 modules.accounts.getAccount.callsArgWith(1, null, '12ab');1186 modules.transactions.undoConfirmed.callsArgWith(3, null, true);1187 done();1188 });1189 it('should call modules.accounts.getAccount', done => {1190 __private1191 .undoConfirmedStep(1192 blockWithTransactions.transactions[0],1193 blockWithTransactions,1194 tx1195 )1196 .then(() => {1197 expect(modules.accounts.getAccount.callCount).to.equal(1);1198 done();1199 });1200 });1201 it('should call modules.transactions.undoConfirmed', done => {1202 __private1203 .undoConfirmedStep(1204 blockWithTransactions.transactions[0],1205 blockWithTransactions,1206 tx1207 )1208 .then(() => {1209 expect(modules.transactions.undoConfirmed.callCount).to.equal(1);1210 done();1211 });1212 });1213 it('should resolve the promise', done => {1214 __private1215 .undoConfirmedStep(1216 blockWithTransactions.transactions[0],1217 blockWithTransactions,1218 tx1219 )1220 .then(res => {1221 expect(res).to.not.exist;1222 done();1223 });1224 });1225 });1226 });1227 });1228 describe('__private.undoUnconfirmStep', () => {1229 let tx;1230 describe('when oldLastBlock.transactions is not empty', () => {1231 describe('when modules.transactions.undoUnconfirmed fails', () => {1232 beforeEach(done => {1233 modules.transactions.undoUnconfirmed.callsArgWith(1234 1,1235 'undoUnconfirmed-ERR',1236 null1237 );1238 done();1239 });1240 it('should reject promise with "undoUnconfirmed-ERR"', done => {1241 __private1242 .undoUnconfirmStep(1243 blockWithTransactions.transactions[0],1244 blockWithTransactions,1245 tx1246 )1247 .catch(err => {1248 expect(err).to.equal('undoUnconfirmed-ERR');1249 done();1250 });1251 });1252 });1253 describe('when modules.transactions.undoUnconfirmed succeeds', () => {1254 beforeEach(done => {1255 modules.transactions.undoUnconfirmed.callsArgWith(1, null, true);1256 done();1257 });1258 it('should call modules.transactions.undoUnconfirmed', done => {1259 __private1260 .undoUnconfirmStep(1261 blockWithTransactions.transactions[0],1262 blockWithTransactions,1263 tx1264 )1265 .then(() => {1266 expect(modules.transactions.undoUnconfirmed.callCount).to.equal(1267 11268 );1269 done();1270 });1271 });1272 it('should resolve the promise', done => {1273 __private1274 .undoUnconfirmStep(1275 blockWithTransactions.transactions[0],1276 blockWithTransactions,1277 tx1278 )1279 .then(res => {1280 expect(res).to.not.exist;1281 done();1282 });1283 });1284 });1285 });1286 });1287 describe('__private.backwardTickStep', () => {1288 let tx;1289 describe('when modules.rounds.backwardTick fails', () => {1290 beforeEach(() => {1291 return modules.rounds.backwardTick.callsArgWith(1292 2,1293 'backwardTick-ERR',1294 null1295 );1296 });1297 it('should reject the promise with "backwardTick-ERR"', done => {1298 __private1299 .backwardTickStep(1300 blockWithEmptyTransactions,1301 blockWithTransactions,1302 tx1303 )1304 .catch(err => {1305 expect(err).to.equal('backwardTick-ERR');1306 done();1307 });1308 });1309 });1310 describe('when modules.rounds.backwardTick succeeds', () => {1311 beforeEach(done => {1312 modules.rounds.backwardTick.callsArgWith(2, null);1313 done();1314 });1315 it('should resolve the promise', () => {1316 return __private.backwardTickStep(1317 blockWithTransactions,1318 blockWithTransactions,1319 tx1320 );1321 });1322 });1323 });1324 describe('__private.deleteBlockStep', () => {1325 let deleteBlockTemp;1326 let tx;1327 beforeEach(done => {1328 deleteBlockTemp = blocksChainModule.deleteBlock;1329 blocksChainModule.deleteBlock = sinonSandbox.stub();1330 done();1331 });1332 afterEach(done => {1333 blocksChainModule.deleteBlock = deleteBlockTemp;1334 done();1335 });1336 describe('when self.deleteBlock fails', () => {1337 beforeEach(() => {1338 return blocksChainModule.deleteBlock.callsArgWith(1339 1,1340 'deleteBlock-ERR',1341 null1342 );1343 });1344 it('should reject promise with "deleteBlock-ERR"', done => {1345 __private.deleteBlockStep(blockWithEmptyTransactions, tx).catch(err => {1346 expect(err).to.equal('deleteBlock-ERR');1347 done();1348 });1349 });1350 });1351 describe('when self.deleteBlock succeeds', () => {1352 beforeEach(() => {1353 return blocksChainModule.deleteBlock.callsArgWith(1, null, true);1354 });1355 it('should resolve promise', done => {1356 __private.deleteBlockStep(blockWithEmptyTransactions, tx).then(done);1357 });1358 });1359 });1360 describe('__private.popLastBlock', () => {1361 describe('when library.db.tx fails', () => {1362 beforeEach(done => {1363 library.db.tx.rejects('db-tx_ERR');1364 done();1365 });1366 it('should call a callback with proper error message', done => {1367 __private.popLastBlock(blockWithTransactions, err => {1368 expect(err.name).to.eql('db-tx_ERR');1369 done();1370 });1371 });1372 });1373 describe('when library.db.tx passes', () => {1374 beforeEach(done => {1375 library.db.tx.resolves('savedBlock');1376 done();1377 });1378 it('should call a callback', done => {1379 __private.popLastBlock(blockWithTransactions, err => {1380 expect(err).to.be.null;1381 done();1382 });1383 });1384 });1385 });1386 describe('deleteLastBlock', () => {1387 let popLastBlockTemp;1388 beforeEach(done => {1389 popLastBlockTemp = __private.popLastBlock;1390 __private.popLastBlock = sinonSandbox.stub();1391 modules.system.update.callsArgWith(0, null, true);1392 modules.transport.broadcastHeaders.callsArgWith(0, null, true);1393 done();1394 });1395 afterEach(done => {1396 __private.popLastBlock = popLastBlockTemp;1397 expect(modules.blocks.lastBlock.get.calledOnce).to.be.true;1398 expect(loggerStub.warn.args[0][0]).to.equal('Deleting last block');1399 done();1400 });1401 describe('when lastBlock.height = 1', () => {1402 beforeEach(() => {1403 return modules.blocks.lastBlock.get.returns(1404 genesisBlockWithTransactions1405 );1406 });1407 it('should call a callback with error "Cannot delete genesis block', done => {1408 blocksChainModule.deleteLastBlock(err => {1409 expect(err).to.equal('Cannot delete genesis block');1410 expect(loggerStub.warn.args[0][1]).to.deep.equal(1411 genesisBlockWithTransactions1412 );1413 done();1414 });1415 });1416 });1417 describe('when lastBlock.height != 1', () => {1418 beforeEach(() => {1419 modules.blocks.lastBlock.set.returns(blockWithTransactions);1420 return modules.blocks.lastBlock.get.returns(blockWithTransactions);1421 });1422 describe('when __private.popLastBlock fails', () => {1423 beforeEach(() => {1424 return __private.popLastBlock.callsArgWith(1425 1,1426 'popLastBlock-ERR',1427 true1428 );1429 });1430 it('should call a callback with error', done => {1431 blocksChainModule.deleteLastBlock(err => {1432 expect(err).to.equal('popLastBlock-ERR');1433 expect(loggerStub.error.args[0][0]).to.equal(1434 'Error deleting last block'1435 );1436 expect(loggerStub.error.args[0][1]).to.deep.equal(1437 blockWithTransactions1438 );1439 done();1440 });1441 });1442 });1443 describe('when __private.popLastBlock succeeds', () => {1444 beforeEach(() => {1445 return __private.popLastBlock.callsArgWith(1446 1,1447 null,1448 blockWithTransactions1449 );1450 });1451 describe('when modules.transactions.receiveTransactions fails', () => {1452 beforeEach(() => {1453 return modules.transactions.receiveTransactions.callsArgWith(1454 2,1455 'receiveTransactions-ERR',1456 true1457 );1458 });1459 it('should call a callback with no error', done => {1460 blocksChainModule.deleteLastBlock((err, newLastBlock) => {1461 expect(err).to.be.null;1462 expect(newLastBlock).to.deep.equal(blockWithTransactions);1463 expect(loggerStub.error.args[0][0]).to.equal(1464 'Error adding transactions'1465 );1466 expect(loggerStub.error.args[0][1]).to.deep.equal(1467 'receiveTransactions-ERR'1468 );1469 expect(modules.blocks.lastBlock.set.calledOnce).to.be.true;1470 expect(modules.system.update.calledOnce).to.be.true;1471 expect(modules.transport.broadcastHeaders.calledOnce).to.be.true;1472 done();1473 });1474 });1475 });1476 describe('when modules.transactions.receiveTransactions succeeds', () => {1477 beforeEach(() => {1478 return modules.transactions.receiveTransactions.callsArgWith(1479 2,1480 null,1481 true1482 );1483 });1484 it('should call a callback with no error', done => {1485 blocksChainModule.deleteLastBlock((err, newLastBlock) => {1486 expect(err).to.be.null;1487 expect(newLastBlock).to.deep.equal(blockWithTransactions);1488 expect(modules.blocks.lastBlock.set.calledOnce).to.be.true;1489 expect(modules.system.update.calledOnce).to.be.true;1490 expect(modules.transport.broadcastHeaders.calledOnce).to.be.true;1491 done();1492 });1493 });1494 });1495 });1496 });1497 });1498 describe('recoverChain', () => {1499 let deleteLastBlockTemp;1500 beforeEach(done => {1501 deleteLastBlockTemp = blocksChainModule.deleteLastBlock;1502 done();1503 });1504 afterEach(done => {1505 expect(loggerStub.warn.args[0][0]).to.equal(1506 'Chain comparison failed, starting recovery'1507 );1508 blocksChainModule.deleteLastBlock = deleteLastBlockTemp;1509 done();1510 });1511 describe('when self.deleteLastBlock fails', () => {1512 beforeEach(done => {1513 blocksChainModule.deleteLastBlock = sinonSandbox1514 .stub()1515 .callsArgWith(0, 'deleteLastBlock-ERR', null);1516 done();1517 });1518 it('should call a callback with error', done => {1519 blocksChainModule.recoverChain(err => {1520 expect(err).to.equal('deleteLastBlock-ERR');1521 expect(loggerStub.error.args[0][0]).to.equal('Recovery failed');1522 done();1523 });1524 });1525 });1526 describe('when self.deleteLastBlock succeeds', () => {1527 beforeEach(done => {1528 blocksChainModule.deleteLastBlock = sinonSandbox1529 .stub()1530 .callsArgWith(0, null, { id: 1 });1531 done();1532 });1533 it('should call a callback with error = null', done => {1534 blocksChainModule.recoverChain(err => {1535 expect(err).to.be.null;1536 expect(loggerStub.info.args[0][0]).to.equal(1537 'Recovery complete, new last block'1538 );1539 expect(loggerStub.info.args[0][1]).to.equal(1);1540 done();1541 });1542 });1543 });1544 });1545 describe('onBind', () => {1546 beforeEach(done => {1547 loggerStub.trace.reset();1548 __private.loaded = false;1549 blocksChainModule.onBind(modulesStub);1550 done();1551 });1552 it('should call library.logger.trace with "Blocks->Chain: Shared modules bind."', () => {1553 return expect(loggerStub.trace.args[0][0]).to.equal(1554 'Blocks->Chain: Shared modules bind.'1555 );1556 });1557 it('should assign params to modules', () => {1558 expect(modules.accounts).to.equal(modulesStub.accounts);1559 expect(modules.blocks).to.equal(modulesStub.blocks);1560 expect(modules.rounds).to.equal(modulesStub.rounds);1561 expect(modules.system).to.equal(modulesStub.system);1562 expect(modules.transport).to.equal(modulesStub.transport);1563 return expect(modules.transactions).to.equal(modulesStub.transactions);1564 });1565 it('should set __private.loaded to true', () => {1566 return expect(__private.loaded).to.be.true;1567 });1568 });...

Full Screen

Full Screen

transport.js

Source:transport.js Github

copy

Full Screen

1/*2 * Copyright © 2018 Lisk Foundation3 *4 * See the LICENSE file at the top-level directory of this distribution5 * for licensing information.6 *7 * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation,8 * no part of this software, including this file, may be copied, modified,9 * propagated, or distributed except according to the terms contained in the10 * LICENSE file.11 *12 * Removal or modification of this copyright notice is prohibited.13 */14'use strict';15var rewire = require('rewire');16var chai = require('chai');17var expect = chai.expect;18var swaggerHelper = require('../../../helpers/swagger');19var TransportModule = rewire('../../../modules/transport.js');20// TODO: Sometimes the callback error is null, other times it's undefined. It should be consistent.21describe('transport', () => {22 var dbStub;23 var loggerStub;24 var busStub;25 var schemaStub;26 var networkStub;27 var balancesSequenceStub;28 var transactionStub;29 var blockStub;30 var peersStub;31 var broadcasterStubRef;32 var transportInstance;33 var library;34 var __private;35 var modules;36 var defaultScope;37 var restoreRewiredTopDeps;38 var peerStub;39 var definitions;40 const SAMPLE_SIGNATURE_1 =41 '32636139613731343366633732316664633534306665663839336232376538643634386432323838656661363165353632363465646630316132633233303739';42 const SAMPLE_SIGNATURE_2 =43 '61383939393932343233383933613237653864363438643232383865666136316535363236346564663031613263323330373784192003750382840553137595';44 beforeEach(done => {45 // Recreate all the stubs and default structures before each test case to make46 // sure that they are fresh every time; that way each test case can modify47 // stubs without affecting other test cases.48 dbStub = {49 query: sinonSandbox.spy(),50 };51 loggerStub = {52 debug: sinonSandbox.spy(),53 error: sinonSandbox.spy(),54 };55 busStub = {};56 schemaStub = {};57 networkStub = {};58 balancesSequenceStub = {59 add: () => {},60 };61 transactionStub = {62 attachAssetType: sinonSandbox.stub(),63 };64 blockStub = {};65 peersStub = {};66 restoreRewiredTopDeps = TransportModule.__set__({67 Broadcaster: function() {68 this.bind = () => {};69 broadcasterStubRef = this;70 },71 });72 defaultScope = {73 logic: {74 block: blockStub,75 transaction: transactionStub,76 peers: peersStub,77 },78 db: dbStub,79 logger: loggerStub,80 bus: busStub,81 schema: schemaStub,82 network: networkStub,83 balancesSequence: balancesSequenceStub,84 config: {85 peers: {86 options: {87 timeout: 1234,88 },89 },90 forging: {},91 broadcasts: {92 broadcastInterval: 10000,93 releaseLimit: 10,94 },95 },96 };97 peerStub = {98 nonce: 'sYHEDBKcScaAAAYg',99 };100 swaggerHelper.getResolvedSwaggerSpec().then(resolvedSpec => {101 defaultScope.swagger = {102 definitions: resolvedSpec.definitions,103 };104 done();105 });106 });107 afterEach(done => {108 restoreRewiredTopDeps();109 done();110 });111 describe('constructor', () => {112 describe('library', () => {113 var localTransportInstance;114 var error;115 var transportSelf;116 beforeEach(done => {117 localTransportInstance = new TransportModule((err, transport) => {118 error = err;119 transportSelf = transport;120 library = TransportModule.__get__('library');121 __private = TransportModule.__get__('__private');122 transportSelf.onBind(defaultScope);123 done();124 }, defaultScope);125 });126 it('should assign scope variables when instantiating', () => {127 expect(library)128 .to.have.property('db')129 .which.is.equal(dbStub);130 expect(library)131 .to.have.property('logger')132 .which.is.equal(loggerStub);133 expect(library)134 .to.have.property('bus')135 .which.is.equal(busStub);136 expect(library)137 .to.have.property('schema')138 .which.is.equal(schemaStub);139 expect(library)140 .to.have.property('network')141 .which.is.equal(networkStub);142 expect(library)143 .to.have.property('balancesSequence')144 .which.is.equal(balancesSequenceStub);145 expect(library)146 .to.have.nested.property('logic.block')147 .which.is.equal(blockStub);148 expect(library)149 .to.have.nested.property('logic.transaction')150 .which.is.equal(transactionStub);151 expect(library)152 .to.have.nested.property('logic.peers')153 .which.is.equal(peersStub);154 expect(library)155 .to.have.nested.property('config.peers.options.timeout')156 .which.is.equal(1234);157 expect(__private)158 .to.have.property('broadcaster')159 .which.is.equal(broadcasterStubRef);160 expect(error).to.equal(null);161 expect(transportSelf).to.equal(localTransportInstance);162 });163 });164 });165 describe('__private', () => {166 var __privateOriginal;167 var restoreRewiredDeps;168 beforeEach(done => {169 __privateOriginal = {};170 transportInstance = new TransportModule((err, transportSelf) => {171 // Backup the __private variable so that properties can be overridden172 // by individual test cases and then we will restore them after each test case has run.173 // This is neccessary because different test cases may want to stub out different parts of the174 // __private modules while testing other parts.175 __private = TransportModule.__get__('__private');176 Object.keys(__private).forEach(field => {177 __privateOriginal[field] = __private[field];178 });179 transportSelf.onBind(defaultScope);180 library = {181 schema: {182 validate: sinonSandbox.stub().callsArg(2),183 },184 logger: {185 debug: sinonSandbox.spy(),186 },187 };188 modules = {189 peers: {190 remove: sinonSandbox.stub().returns(true),191 },192 transactions: {193 processUnconfirmedTransaction: sinonSandbox.stub().callsArg(2),194 },195 };196 definitions = {};197 restoreRewiredDeps = TransportModule.__set__({198 library: library,199 modules: modules,200 definitions: definitions,201 });202 done();203 }, defaultScope);204 });205 afterEach(done => {206 Object.keys(__private).forEach(field => {207 delete __private[field];208 });209 Object.keys(__privateOriginal).forEach(field => {210 __private[field] = __privateOriginal[field];211 });212 restoreRewiredDeps();213 done();214 });215 describe('removePeer', () => {216 describe('when options.peer is undefined', () => {217 var result;218 beforeEach(done => {219 result = __private.removePeer({}, 'Custom peer remove message');220 done();221 });222 it('should call library.logger.debug with "Cannot remove empty peer"', () => {223 expect(library.logger.debug.called).to.be.true;224 expect(library.logger.debug.calledWith('Cannot remove empty peer')).to225 .be.true;226 });227 it('should return false', () => {228 expect(result).to.be.false;229 });230 });231 describe('when options.peer is defined', () => {232 var removeSpy;233 var peerData;234 beforeEach(done => {235 removeSpy = sinonSandbox.spy();236 modules.peers = {237 remove: removeSpy,238 };239 peerData = {240 ip: '127.0.0.1',241 wsPort: 8000,242 };243 __private.removePeer(244 {245 peer: peerData,246 },247 'Custom peer remove message'248 );249 done();250 });251 it('should call library.logger.debug', () => {252 expect(library.logger.debug.called).to.be.true;253 });254 it('should call modules.peers.remove with options.peer', () => {255 expect(removeSpy.calledWith(peerData)).to.be.true;256 });257 });258 });259 describe('receiveSignatures', () => {260 describe('when signatures array is empty', () => {261 beforeEach(done => {262 __private.receiveSignature = sinonSandbox.stub().callsArg(1);263 __private.receiveSignatures(264 {265 signatures: [],266 },267 () => {268 done();269 }270 );271 });272 it('should call library.schema.validate with empty query.signatures', () => {273 expect(library.schema.validate.called).to.be.true;274 });275 });276 describe('when signatures array contains multiple signatures', () => {277 beforeEach(done => {278 definitions.Signature = {279 id: 'transport.signatures',280 type: 'object',281 properties: {282 signatures: {283 type: 'array',284 minItems: 1,285 maxItems: 40,286 },287 },288 required: ['signatures'],289 };290 __private.receiveSignature = sinonSandbox.stub().callsArg(1);291 __private.receiveSignatures(292 {293 signatures: [SAMPLE_SIGNATURE_1, SAMPLE_SIGNATURE_2],294 },295 () => {296 done();297 }298 );299 });300 it('should call library.schema.validate with custom schema.signatures', () => {301 expect(library.schema.validate.called).to.be.true;302 });303 });304 describe('when library.schema.validate fails', () => {305 var error;306 var validateErr;307 beforeEach(done => {308 validateErr = new Error('Transaction did not match schema');309 validateErr.code = 'INVALID_FORMAT';310 library.schema.validate = sinonSandbox311 .stub()312 .callsArgWith(2, [validateErr]);313 __private.receiveSignatures(314 {315 signatures: [SAMPLE_SIGNATURE_1, SAMPLE_SIGNATURE_2],316 },317 err => {318 error = err;319 done();320 }321 );322 });323 it('should call series callback with error = "Invalid signatures body"', () => {324 expect(library.schema.validate.called).to.be.true;325 expect(error).to.equal('Invalid signatures body');326 });327 });328 describe('when library.schema.validate succeeds', () => {329 describe('for every signature in signatures', () => {330 describe('when __private.receiveSignature succeeds', () => {331 var error;332 beforeEach(done => {333 __private.receiveSignature = sinonSandbox.stub().callsArg(1);334 __private.receiveSignatures(335 {336 signatures: [SAMPLE_SIGNATURE_1, SAMPLE_SIGNATURE_2],337 },338 err => {339 error = err;340 done();341 }342 );343 });344 it('should call __private.receiveSignature with signature', () => {345 expect(library.schema.validate.called).to.be.true;346 expect(__private.receiveSignature.calledTwice).to.be.true;347 expect(__private.receiveSignature.calledWith(SAMPLE_SIGNATURE_1))348 .to.be.true;349 expect(__private.receiveSignature.calledWith(SAMPLE_SIGNATURE_2))350 .to.be.true;351 });352 it('should call callback with error null', () => {353 expect(error).to.equal(null);354 });355 });356 describe('when __private.receiveSignature fails', () => {357 var error;358 var receiveSignatureError;359 beforeEach(done => {360 receiveSignatureError =361 'Error processing signature: Error message';362 __private.receiveSignature = sinonSandbox363 .stub()364 .callsArgWith(1, receiveSignatureError);365 __private.receiveSignatures(366 {367 signatures: [SAMPLE_SIGNATURE_1, SAMPLE_SIGNATURE_2],368 },369 err => {370 error = err;371 done();372 }373 );374 });375 it('should call library.logger.debug with err and signature', () => {376 expect(library.schema.validate.called).to.be.true;377 // If any of the __private.receiveSignature calls fail, the whole378 // receiveSignatures operation should fail immediately.379 expect(__private.receiveSignature.calledOnce).to.be.true;380 expect(library.logger.debug.calledWith(error, SAMPLE_SIGNATURE_1))381 .to.be.true;382 });383 it('should call callback with error', () => {384 expect(error).to.equal(receiveSignatureError);385 });386 });387 });388 });389 });390 describe('receiveSignature', () => {391 beforeEach(done => {392 library.schema = {393 validate: sinonSandbox.stub().callsArg(2),394 };395 modules.multisignatures = {396 processSignature: sinonSandbox.stub().callsArg(1),397 };398 done();399 });400 describe('when library.schema.validate succeeds', () => {401 describe('when modules.multisignatures.processSignature succeeds', () => {402 var error;403 beforeEach(done => {404 modules.multisignatures.processSignature = sinonSandbox405 .stub()406 .callsArg(1);407 __private.receiveSignature(SAMPLE_SIGNATURE_1, err => {408 error = err;409 done();410 });411 });412 it('should call library.schema.validate with signature', () => {413 expect(error).to.equal(undefined);414 expect(library.schema.validate.calledOnce).to.be.true;415 expect(library.schema.validate.calledWith(SAMPLE_SIGNATURE_1)).to.be416 .true;417 });418 it('should call modules.multisignatures.processSignature with signature', () => {419 expect(error).to.equal(undefined);420 expect(421 modules.multisignatures.processSignature.calledWith(422 SAMPLE_SIGNATURE_1423 )424 ).to.be.true;425 });426 it('should call callback with error = undefined', () => {427 expect(error).to.equal(undefined);428 });429 });430 describe('when modules.multisignatures.processSignature fails', () => {431 var error;432 var processSignatureError;433 beforeEach(done => {434 processSignatureError = 'Transaction not found';435 modules.multisignatures.processSignature = sinonSandbox436 .stub()437 .callsArgWith(1, processSignatureError);438 __private.receiveSignature(SAMPLE_SIGNATURE_1, err => {439 error = err;440 done();441 });442 });443 it('should call callback with error', () => {444 expect(error).to.equal(445 `Error processing signature: ${processSignatureError}`446 );447 });448 });449 });450 describe('when library.schema.validate fails', () => {451 var error;452 var validateErr;453 beforeEach(done => {454 validateErr = new Error('Transaction did not match schema');455 validateErr.code = 'INVALID_FORMAT';456 library.schema.validate = sinonSandbox457 .stub()458 .callsArgWith(2, [validateErr]);459 __private.receiveSignature(SAMPLE_SIGNATURE_1, err => {460 error = err;461 done();462 });463 });464 it('should call callback with error = "Invalid signature body"', () => {465 expect(error).to.equal(466 `Invalid signature body ${validateErr.message}`467 );468 });469 });470 });471 describe('receiveTransactions', () => {472 var query;473 beforeEach(done => {474 library.schema = {475 validate: sinonSandbox.stub().callsArg(2),476 };477 library.logger = {478 debug: sinonSandbox.spy(),479 };480 modules.peers = {481 remove: sinonSandbox.stub().returns(true),482 };483 query = {484 transactions: [485 {486 id: '222675625422353767',487 type: 0,488 amount: '100',489 fee: '10',490 senderPublicKey:491 '2ca9a7143fc721fdc540fef893b27e8d648d2288efa61e56264edf01a2c23079',492 recipientId: '12668885769632475474L',493 timestamp: 28227090,494 asset: {},495 signature:496 '2821d93a742c4edf5fd960efad41a4def7bf0fd0f7c09869aed524f6f52bf9c97a617095e2c712bd28b4279078a29509b339ac55187854006591aa759784c205',497 },498 ],499 };500 __private.receiveTransaction = sinonSandbox.stub().callsArg(3);501 done();502 });503 // TODO: It doesn't seem that library.schema.validate currently gets called by the __private.receiveTransaction logic.504 describe.skip('when library.schema.validate fails', () => {505 var validateErr;506 beforeEach(done => {507 validateErr = new Error('Transaction did not match schema');508 validateErr.code = 'INVALID_FORMAT';509 library.schema.validate = sinonSandbox510 .stub()511 .callsArgWith(2, [validateErr]);512 __private.receiveTransactions(query, peerStub, '', () => {513 done();514 });515 });516 it('should call callback with error = "Invalid transactions body"', () => {517 // TODO: Check that error is what we expect it to be.518 expect(library.schema.validate.called).to.be.true;519 });520 });521 describe('when library.schema.validate succeeds', () => {522 describe.skip('when called', () => {523 var error;524 beforeEach(done => {525 __private.receiveTransactions(query, peerStub, '', err => {526 error = err;527 done();528 });529 });530 // TODO: It doesn't seem that library.schema.validate currently gets called by the __private.receiveTransaction logic.531 it.skip('should call library.schema.validate with query and definitions.Transaction', () => {532 expect(error).to.equal(null);533 expect(534 library.schema.validate.calledWith(535 query,536 defaultScope.swagger.definitions.Transaction537 )538 ).to.be.true;539 });540 });541 describe('for every transaction in transactions', () => {542 describe('when transaction is undefined', () => {543 var error;544 beforeEach(done => {545 query.transactions[0] = undefined;546 __private.receiveTransactions(query, peerStub, '', err => {547 error = err;548 done();549 });550 });551 it('should call callback with error = "Unable to process transaction. Transaction is undefined."', () => {552 expect(error).to.equal(553 'Unable to process transaction. Transaction is undefined.'554 );555 });556 });557 describe('when transaction is defined', () => {558 describe('when call __private.receiveTransaction succeeds', () => {559 var error;560 beforeEach(done => {561 __private.receiveTransactions(562 query,563 peerStub,564 'This is a log message',565 err => {566 error = err;567 done();568 }569 );570 });571 it('should set transaction.bundled = true', () => {572 expect(query.transactions[0])573 .to.have.property('bundled')574 .which.equals(true);575 });576 it('should call __private.receiveTransaction with transaction with transaction, peer and extraLogMessage arguments', () => {577 expect(578 __private.receiveTransaction.calledWith(579 query.transactions[0],580 peerStub,581 'This is a log message'582 )583 ).to.be.true;584 });585 it('should call callback with error = null', () => {586 expect(error).to.equal(null);587 });588 });589 describe('when call __private.receiveTransaction fails', () => {590 var error;591 var receiveTransactionError;592 beforeEach(done => {593 receiveTransactionError = 'Invalid transaction body - ...';594 __private.receiveTransaction = sinonSandbox595 .stub()596 .callsArgWith(3, receiveTransactionError);597 __private.receiveTransactions(598 query,599 peerStub,600 'This is a log message',601 err => {602 error = err;603 done();604 }605 );606 });607 it('should call library.logger.debug with error and transaction', () => {608 expect(609 library.logger.debug.calledWith(610 receiveTransactionError,611 query.transactions[0]612 )613 ).to.be.true;614 });615 it('should call callback with error', () => {616 expect(error).to.equal(receiveTransactionError);617 });618 });619 });620 });621 });622 });623 describe('receiveTransaction', () => {624 var transaction;625 var peerAddressString;626 beforeEach(() => {627 transaction = {628 id: '222675625422353767',629 type: 0,630 amount: '100',631 fee: '10',632 senderPublicKey:633 '2ca9a7143fc721fdc540fef893b27e8d648d2288efa61e56264edf01a2c23079',634 recipientId: '12668885769632475474L',635 timestamp: 28227090,636 asset: {},637 signature:638 '2821d93a742c4edf5fd960efad41a4def7bf0fd0f7c09869aed524f6f52bf9c97a617095e2c712bd28b4279078a29509b339ac55187854006591aa759784c205',639 };640 sinonSandbox641 .stub(balancesSequenceStub, 'add')642 .callsFake((callback, doneCallback) => {643 callback(doneCallback);644 });645 peerAddressString = '40.40.40.40:5000';646 library.logic = {647 transaction: {648 objectNormalize: sinonSandbox.stub().returns(transaction),649 },650 peers: {651 peersManager: {652 getAddress: sinonSandbox.stub().returns(peerAddressString),653 },654 },655 };656 library.schema = {657 validate: sinonSandbox.stub().callsArg(2),658 };659 library.logger = {660 debug: sinonSandbox.spy(),661 };662 library.balancesSequence = balancesSequenceStub;663 modules.peers.remove = sinonSandbox.stub().returns(true);664 modules.transactions.processUnconfirmedTransaction = sinonSandbox665 .stub()666 .callsArg(2);667 });668 describe('when transaction and peer are defined', () => {669 beforeEach(done => {670 __private.receiveTransaction(671 transaction,672 peerStub,673 'This is a log message',674 () => {675 done();676 }677 );678 });679 it('should call library.logic.transaction.objectNormalize with transaction', () => {680 expect(681 library.logic.transaction.objectNormalize.calledWith(transaction)682 ).to.be.true;683 });684 it('should call library.balancesSequence.add', () => {685 expect(library.balancesSequence.add.called).to.be.true;686 });687 it('should call modules.transactions.processUnconfirmedTransaction with transaction and true as arguments', () => {688 expect(689 modules.transactions.processUnconfirmedTransaction.calledWith(690 transaction,691 true692 )693 ).to.be.true;694 });695 });696 describe('when library.logic.transaction.objectNormalize throws', () => {697 var error;698 var extraLogMessage;699 var objectNormalizeError;700 beforeEach(done => {701 extraLogMessage = 'This is a log message';702 objectNormalizeError = 'Unknown transaction type 0';703 library.logic.transaction.objectNormalize = sinonSandbox704 .stub()705 .throws(objectNormalizeError);706 __private.removePeer = sinonSandbox.spy();707 __private.receiveTransaction(708 transaction,709 peerStub,710 extraLogMessage,711 err => {712 error = err;713 done();714 }715 );716 });717 it('should call library.logger.debug with "Transaction normalization failed" error message and error details object', () => {718 var errorDetails = {719 id: transaction.id,720 err: 'Unknown transaction type 0',721 module: 'transport',722 transaction: transaction,723 };724 expect(725 library.logger.debug.calledWith(726 'Transaction normalization failed',727 errorDetails728 )729 ).to.be.true;730 });731 it('should call __private.removePeer with peer details object', () => {732 var peerDetails = { peer: peerStub, code: 'ETRANSACTION' };733 expect(__private.removePeer.calledWith(peerDetails, extraLogMessage))734 .to.be.true;735 });736 it('should call callback with error = "Invalid transaction body"', () => {737 expect(error).to.equal(738 `Invalid transaction body - ${objectNormalizeError}`739 );740 });741 });742 describe('when peer is undefined', () => {743 beforeEach(done => {744 __private.receiveTransaction(745 transaction,746 undefined,747 'This is a log message',748 () => {749 done();750 }751 );752 });753 it('should call library.logger.debug with "Received transaction " + transaction.id + " from public client"', () => {754 expect(755 library.logger.debug.calledWith(756 `Received transaction ${transaction.id} from public client`757 )758 ).to.be.true;759 });760 });761 describe('when peer is defined', () => {762 beforeEach(done => {763 __private.receiveTransaction(764 transaction,765 peerStub,766 'This is a log message',767 () => {768 done();769 }770 );771 });772 it('should call library.logger.debug with "Received transaction " + transaction.id + " from peer ..."', () => {773 expect(774 library.logger.debug.calledWith(775 `Received transaction ${776 transaction.id777 } from peer ${peerAddressString}`778 )779 ).to.be.true;780 });781 it('should call library.logic.peers.peersManager.getAddress with peer.nonce', () => {782 expect(783 library.logic.peers.peersManager.getAddress.calledWith(784 peerStub.nonce785 )786 ).to.be.true;787 });788 });789 describe('when modules.transactions.processUnconfirmedTransaction fails', () => {790 var error;791 var processUnconfirmedTransactionError;792 beforeEach(done => {793 processUnconfirmedTransactionError = `Transaction is already processed: ${794 transaction.id795 }`;796 modules.transactions.processUnconfirmedTransaction = sinonSandbox797 .stub()798 .callsArgWith(2, processUnconfirmedTransactionError);799 __private.receiveTransaction(800 transaction,801 peerStub,802 'This is a log message',803 err => {804 error = err;805 done();806 }807 );808 });809 it('should call library.logger.debug with "Transaction ${transaction.id}" and error string', () => {810 expect(811 library.logger.debug.calledWith(812 `Transaction ${transaction.id}`,813 processUnconfirmedTransactionError814 )815 ).to.be.true;816 });817 describe('when transaction is defined', () => {818 it('should call library.logger.debug with "Transaction" and transaction as arguments', () => {819 expect(library.logger.debug.calledWith('Transaction', transaction))820 .to.be.true;821 });822 });823 it('should call callback with err.toString()', () => {824 expect(error).to.equal(processUnconfirmedTransactionError);825 });826 });827 describe('when modules.transactions.processUnconfirmedTransaction succeeds', () => {828 var error;829 var result;830 beforeEach(done => {831 __private.receiveTransaction(832 transaction,833 peerStub,834 'This is a log message',835 (err, res) => {836 error = err;837 result = res;838 done();839 }840 );841 });842 it('should call callback with error = null', () => {843 expect(error).to.equal(null);844 });845 it('should call callback with result = transaction.id', () => {846 expect(result).to.equal(transaction.id);847 });848 });849 });850 });851 describe('Transport', () => {852 var restoreRewiredTransportDeps;853 beforeEach(done => {854 transportInstance = new TransportModule((err, transportSelf) => {855 transportSelf.onBind(defaultScope);856 library = {857 schema: {858 validate: sinonSandbox.stub().callsArg(2),859 },860 logger: {861 debug: sinonSandbox.spy(),862 },863 config: {864 forging: {865 force: false,866 },867 },868 };869 modules = {870 peers: {871 calculateConsensus: sinonSandbox.stub().returns(100),872 },873 };874 restoreRewiredTransportDeps = TransportModule.__set__({875 library: library,876 modules: modules,877 });878 done();879 }, defaultScope);880 });881 afterEach(done => {882 restoreRewiredTransportDeps();883 done();884 });885 describe('poorConsensus', () => {886 var isPoorConsensusResult;887 describe('when library.config.forging.force is true', () => {888 beforeEach(done => {889 library.config.forging.force = true;890 isPoorConsensusResult = transportInstance.poorConsensus();891 done();892 });893 it('should return false', () => {894 expect(isPoorConsensusResult).to.be.false;895 });896 });897 describe('when library.config.forging.force is false', () => {898 beforeEach(done => {899 library.config.forging.force = false;900 done();901 });902 describe('when modules.peers.calculateConsensus() < constants.minBroadhashConsensus', () => {903 beforeEach(done => {904 modules.peers.calculateConsensus = sinonSandbox.stub().returns(50);905 isPoorConsensusResult = transportInstance.poorConsensus();906 done();907 });908 it('should return true', () => {909 expect(isPoorConsensusResult).to.be.true;910 });911 });912 describe('when modules.peers.calculateConsensus() >= constants.minBroadhashConsensus', () => {913 beforeEach(done => {914 modules.peers.calculateConsensus = sinonSandbox.stub().returns(51);915 isPoorConsensusResult = transportInstance.poorConsensus();916 done();917 });918 it('should return false', () => {919 expect(isPoorConsensusResult).to.be.false;920 });921 });922 });923 });924 describe('getPeers', () => {925 var paramsArg = {};926 var callbackArg = {};927 beforeEach(done => {928 __private.broadcaster = {929 getPeers: sinonSandbox.stub().callsArgWith(1, null, []),930 };931 paramsArg = {};932 callbackArg = () => {};933 transportInstance.getPeers(paramsArg, callbackArg);934 done();935 });936 it('should call __private.broadcaster.getPeers with paramsArg and callbackArg as arguments', () => {937 expect(938 __private.broadcaster.getPeers.calledWith(paramsArg, callbackArg)939 ).to.be.true;940 });941 });942 describe('onBind', () => {943 describe('modules', () => {944 it('should assign blocks');945 it('should assign dapps');946 it('should assign loader');947 it('should assign multisignatures');948 it('should assign peers');949 it('should assign system');950 it('should assign transaction');951 });952 it('should call System.getHeaders');953 it('should call __private.broadcaster.bind');954 it('should call __private.broadcaster.bind with scope.peers');955 it('should call __private.broadcaster.bind with scope.transport');956 it('should call __private.broadcaster.bind with scope.transactions');957 });958 describe('onSignature', () => {959 describe('when broadcast is defined', () => {960 it('should call __private.broadcaster.maxRelays');961 it('should call __private.broadcaster.maxRelays with signature');962 describe('when result of __private.broadcaster.maxRelays is false', () => {963 it('should call __private.broadcaster.enqueue');964 it('should call __private.broadcaster.enqueue with {}');965 it(966 'should call __private.broadcaster.enqueue with {api: "postSignatures", data: {signature: signature}}'967 );968 it('should call library.network.io.sockets.emit');969 it(970 'should call library.network.io.sockets.emit with "signature/change"'971 );972 it('should call library.network.io.sockets.emit with signature');973 });974 });975 });976 describe('onUnconfirmedTransaction', () => {977 describe('when broadcast is defined', () => {978 it('should call __private.broadcaster.maxRelays');979 it('should call __private.broadcaster.maxRelays with transaction');980 describe('when result of __private.broadcaster.maxRelays is false', () => {981 it('should call __private.broadcaster.enqueue');982 it('should call __private.broadcaster.enqueue with {}');983 it(984 'should call __private.broadcaster.enqueue with {api: "postTransactions", data: {transaction: transaction}}'985 );986 it('should call library.network.io.sockets.emit');987 it(988 'should call library.network.io.sockets.emit with "transactions/change"'989 );990 it('should call library.network.io.sockets.emit with transaction');991 });992 });993 });994 describe('onNewBlock', () => {995 describe('when broadcast is defined', () => {996 it('should call modules.system.update');997 describe('when modules.system.update succeeds', () => {998 it('should call __private.broadcaster.maxRelays');999 it('should call __private.broadcaster.maxRelays with blocks');1000 describe('when __private.broadcaster.maxRelays with blocks = true', () => {1001 it(1002 'should call library.logger.debug with "Broadcasting block aborted - max block relays exceeded"'1003 );1004 });1005 describe('when modules.loader.syncing = true', () => {1006 it(1007 'should call library.logger.debug with "Broadcasting block aborted - blockchain synchronization in progress"'1008 );1009 });1010 it('should call modules.peers.list');1011 it('should call modules.peers.list with {normalized: false}');1012 describe('when peers = undefined', () => {1013 it(1014 'should call library.logger.debug with "Broadcasting block aborted - active peer list empty"'1015 );1016 });1017 describe('when peers.length = 0', () => {1018 it(1019 'should call library.logger.debug with "Broadcasting block aborted - active peer list empty"'1020 );1021 });1022 it('should call peers.filter');1023 it(1024 'should call peers.filter with peer.state === Peer.STATE.CONNECTED'1025 );1026 describe('for every filtered peer in peers', () => {1027 it('should call peer.rpc.updateMyself');1028 it('should call peer.rpc.updateMyself with library.logic.peers.me');1029 describe('when peer.rpc.updateMyself fails', () => {1030 it('should call __private.removePeer');1031 it(1032 'should call __private.removePeer with {peer: peer, code: "ECOMMUNICATION"}'1033 );1034 });1035 describe('when peer.rpc.updateMyself succeeds', () => {1036 it('should call library.logger.debug');1037 it(1038 'should call __private.removePeer with "Peer notified correctly after update:" + peer.string'1039 );1040 });1041 });1042 describe('when async.each succeeds', () => {1043 it('should call __private.broadcaster.broadcast');1044 it(1045 'should call __private.broadcaster.broadcast with {limit: constants.maxPeers, broadhash: modules.system.getBroadhash()}'1046 );1047 it(1048 'should call __private.broadcaster.broadcast with {api: "postBlock", data: {block: block}, immediate: true}'1049 );1050 });1051 });1052 });1053 it('should call library.network.io.sockets.emit');1054 it('should call library.network.io.sockets.emit with "blocks/change"');1055 it('should call library.network.io.sockets.emit with block');1056 });1057 describe('shared', () => {1058 describe('blocksCommon', () => {1059 describe('when query is undefined', () => {1060 it('should set query = {}');1061 });1062 it('should call library.schema.validate');1063 it('should call library.schema.validate with query');1064 it('should call library.schema.validate with schema.commonBlock');1065 describe('when library.schema.validate fails', () => {1066 it('should set err = err[0].message + ": " + err[0].path');1067 it('should call library.logger.debug');1068 it(1069 'should call library.logger.debug with "Common block request validation failed"'1070 );1071 it(1072 'should call library.logger.debug with {err: err.toString(), req: query}'1073 );1074 it('should call callback with error');1075 });1076 describe('when library.schema.validate succeeds', () => {1077 describe('escapedIds', () => {1078 it('should remove quotes from query.ids');1079 it('should separate ids from query.ids by comma');1080 it('should remove any non-numeric values from query.ids');1081 });1082 describe('when escapedIds.length = 0', () => {1083 it('should call library.logger.debug');1084 it(1085 'should call library.logger.debug with "Common block request validation failed"'1086 );1087 it(1088 'should call library.logger.debug with {err: "ESCAPE", req: query.ids}'1089 );1090 it('should call __private.removePeer');1091 it(1092 'should call __private.removePeer with {peer: query.peer, code: "ECOMMON"}'1093 );1094 it('should call callback with error = "Invalid block id sequence"');1095 });1096 it('should call library.db.query');1097 it('should call library.db.query with sql.getCommonBlock');1098 it('should call library.db.query with escapedIds');1099 describe('when library.db.query fails', () => {1100 it('should call library.logger.error with error stack');1101 it(1102 'should call callback with error = "Failed to get common block"'1103 );1104 });1105 describe('when library.db.query succeeds', () => {1106 it('should call callback with error = null');1107 it(1108 'should call callback with result = { success: true, common: rows[0] || null }'1109 );1110 });1111 });1112 });1113 describe('blocks', () => {1114 describe('when query is undefined', () => {1115 it('should set query = {}');1116 });1117 it('should call modules.blocks.utils.loadBlocksData');1118 it(1119 'should call modules.blocks.utils.loadBlocksData with { limit: 34,lastId: query.lastBlockId }'1120 );1121 describe('when modules.blocks.utils.loadBlocksData fails', () => {1122 it('should call callback with error = null');1123 it('should call callback with result = { blocks: [] }');1124 });1125 describe('when modules.blocks.utils.loadBlocksData fails', () => {1126 it('should call callback with error = null');1127 it('should call callback with result = { blocks: data }');1128 });1129 });1130 describe('postBlock', () => {1131 describe('when query is undefined', () => {1132 it('should set query = {}');1133 });1134 describe('when it throws', () => {1135 it('should call library.logger.debug');1136 it(1137 'should call library.logger.debug with "Block normalization failed"'1138 );1139 it(1140 'should call library.logger.debug with {err: e.toString(), module: "transport", block: query.block }'1141 );1142 it('should call __private.removePeer');1143 it(1144 'should call __private.removePeer with {peer: query.peer, code: "EBLOCK"}'1145 );1146 it('should call callback with error = e.toString()');1147 });1148 describe('when it does not throw', () => {1149 describe('when query.block is defined', () => {1150 it('should call bson.deserialize');1151 it('should call bson.deserialize with Buffer.from(query.block)');1152 describe('block', () => {1153 it('should call modules.blocks.verify.addBlockProperties');1154 it(1155 'should call modules.blocks.verify.addBlockProperties with query.block'1156 );1157 });1158 });1159 it('should call library.logic.block.objectNormalize');1160 });1161 it('should call library.bus.message');1162 it('should call library.bus.message with "receiveBlock"');1163 it('should call library.bus.message with block');1164 it('should call callback with error = null');1165 it(1166 'should call callback with result = {success: true, blockId: block.id}'1167 );1168 });1169 describe('list', () => {1170 describe('when req is undefined', () => {1171 it('should set req = {}');1172 });1173 describe('peersFinder', () => {1174 describe('when req.query is undefined', () => {1175 it('should set peerFinder = modules.peers.list');1176 });1177 describe('when req.query is defined', () => {1178 it('should set peerFinder = modules.peers.shared.getPeers');1179 });1180 });1181 it('should call peersFinder');1182 it(1183 'should call peersFinder with Object.assign({}, {limit: constants.maxPeers}, req.query)'1184 );1185 describe('when peersFinder fails', () => {1186 it('should set peers to []');1187 });1188 it('should return callback with error = null');1189 it(1190 'should return callback with result = {success: !err, peers: peers}'1191 );1192 });1193 describe('height', () => {1194 it('should call callback with error = null');1195 it(1196 'should call callback with result = {success: true, height: modules.system.getHeight()}'1197 );1198 });1199 describe('status', () => {1200 it('should call callback with error = null');1201 it(1202 'should call callback with result = {success: true, height: modules.system.getHeight(), broadhash: modules.system.getBroadhash(), nonce: modules.system.getNonce()}'1203 );1204 });1205 describe('postSignatures', () => {1206 describe('when query.signatures is defined', () => {1207 it('should call __private.receiveSignatures');1208 it('should call __private.receiveSignatures with query');1209 describe('when __private.receiveSignatures fails', () => {1210 it('should call callback with error = null');1211 it(1212 'should call callback with result = {success: false, message: err}'1213 );1214 });1215 describe('when __private.receiveSignatures succeeds', () => {1216 it('should call callback with error = null');1217 it('should call callback with result = {success: true}');1218 });1219 });1220 describe('when query.signatures is undefined', () => {1221 it('should call __private.receiveSignature');1222 it('should call __private.receiveSignature with query.signature');1223 describe('when __private.receiveSignature fails', () => {1224 it('should call callback with error = null');1225 it(1226 'should call callback with result = {success: false, message: err}'1227 );1228 });1229 describe('when __private.receiveSignature succeeds', () => {1230 it('should call callback with error = null');1231 it('should call callback with result = {success: true}');1232 });1233 });1234 });1235 describe('getSignatures', () => {1236 it('should call modules.transactions.getMultisignatureTransactionList');1237 it(1238 'should call modules.transactions.getMultisignatureTransactionList with true'1239 );1240 it(1241 'should call modules.transactions.getMultisignatureTransactionList with constants.maxSharedTxs'1242 );1243 describe('for every transaction', () => {1244 describe('when trs.signatures are defined', () => {1245 describe('and trs.signatures.length is defined', () => {1246 describe('signature', () => {1247 it('should assign transaction: trs.id');1248 it('should assign signatures: trs.signatures');1249 });1250 });1251 });1252 });1253 it('should call callback with error = null');1254 it(1255 'should call callback with result = {success: true, signatures: signatures}'1256 );1257 });1258 describe('getTransactions', () => {1259 it('should call modules.transactions.getMergedTransactionList');1260 it(1261 'should call modules.transactions.getMergedTransactionList with true'1262 );1263 it(1264 'should call modules.transactions.getMergedTransactionList with constants.maxSharedTxs'1265 );1266 it('should call callback with error = null');1267 it(1268 'should call callback with result = {success: true, transactions: transactions}'1269 );1270 });1271 describe('postTransactions', () => {1272 describe('when query.transactions is defined', () => {1273 it('should call __private.receiveTransactions');1274 it('should call __private.receiveTransactions with query');1275 it('should call __private.receiveTransactions with query.peer');1276 it(1277 'should call __private.receiveTransactions with query.extraLogMessage'1278 );1279 describe('when __private.receiveTransactions fails', () => {1280 it('should call callback with error = null');1281 it(1282 'should call callback with result = {success: false, message: err}'1283 );1284 });1285 describe('when __private.receiveTransactions succeeds', () => {1286 it('should call callback with error = null');1287 it('should call callback with result = {success: true}');1288 });1289 });1290 describe('when query.transactions is undefined', () => {1291 it('should call __private.receiveTransaction');1292 it('should call __private.receiveTransaction with query.transaction');1293 it('should call __private.receiveTransaction with query.peer');1294 it(1295 'should call __private.receiveTransaction with query.extraLogMessage'1296 );1297 describe('when __private.receiveTransaction fails', () => {1298 it('should call callback with error = null');1299 it(1300 'should call callback with result = {success: false, message: err}'1301 );1302 });1303 describe('when __private.receiveTransaction succeeds', () => {1304 it('should call callback with error = null');1305 it(1306 'should call callback with result = {success: true, transactionId: id}'1307 );1308 });1309 });1310 });1311 });1312 });1313 describe('__private.checkInternalAccess', () => {1314 it('should call library.schema.validate');1315 it('should call library.schema.validate with query');1316 it('should call library.schema.validate with schema.internalAccess');1317 describe('when library.schema.validate fails', () => {1318 it('should call callback with error = err[0].message');1319 });1320 describe('when library.schema.validate succeeds', () => {1321 describe('when query.authKey != wsRPC.getServerAuthKey()', () => {1322 it(1323 'should call callback with error = "Unable to access internal function - Incorrect authKey"'1324 );1325 });1326 it('should call callback with error = null');1327 it('should call callback with result = undefined');1328 });1329 });1330 describe('Transport.prototype.internal', () => {1331 describe('updatePeer', () => {1332 it('should call __private.checkInternalAccess');1333 it('should call __private.checkInternalAccess with query');1334 describe('when __private.checkInternalAccess fails', () => {1335 it('should call callback wit error = err');1336 });1337 describe('when __private.checkInternalAccess succeeds', () => {1338 describe('updateResult', () => {1339 describe('when query.updateType = 0 (insert)', () => {1340 it('should call modules.peers.update');1341 it('should call modules.peers.update with query.peer');1342 });1343 describe('when query.updateType = 1 (remove)', () => {1344 it('should call modules.peers.remove');1345 it('should call modules.peers.remove with query.peer');1346 });1347 });1348 describe('when updateResult = false', () => {1349 it(1350 'should call callback with error = new PeerUpdateError(updateResult, failureCodes.errorMessages[updateResult])'1351 );1352 });1353 describe('when updateResult = true', () => {1354 it('should call callback with error = null');1355 });1356 });1357 });1358 });...

Full Screen

Full Screen

events_spec.js

Source:events_spec.js Github

copy

Full Screen

...538 return assert.sendErrCalledWith(err)539 })540 })541 it('sends \'focus:tests\' onFocusTests', function () {542 const bus = busStub()543 return this.handleEvent('open:project', '/_test-output/path/to/project-e2e', bus)544 .then(() => {545 return this.handleEvent('on:focus:tests', '', bus)546 }).then(() => {547 expect(bus.on).to.have.been.calledWith('focus:tests')548 })549 })550 it('sends \'config:changed\' onSettingsChanged', function () {551 const bus = busStub()552 return this.handleEvent('open:project', '/_test-output/path/to/project-e2e', bus)553 .then(() => {554 return this.handleEvent('on:config:changed', '', bus)555 }).then(() => {556 expect(bus.on).to.have.been.calledWith('config:changed')557 })558 })559 it('sends \'spec:changed\' onSpecChanged', function () {560 const bus = busStub()561 return this.handleEvent('open:project', '/_test-output/path/to/project-e2e')562 .then(() => {563 return this.handleEvent('on:spec:changed', '', bus)564 }).then((assert) => {565 expect(bus.on).to.have.been.calledWith('spec:changed')566 })567 })568 it('sends \'project:warning\' onWarning', function () {569 const bus = busStub()570 return this.handleEvent('open:project', '/_test-output/path/to/project-e2e')571 .then(() => {572 return this.handleEvent('on:project:warning', '', bus)573 }).then(() => {574 expect(bus.on).to.have.been.calledWith('project:warning')575 })576 })577 it('sends \'project:error\' onError', function () {578 const bus = busStub()579 return this.handleEvent('open:project', '/_test-output/path/to/project-e2e')580 .then(() => {581 return this.handleEvent('on:project:error', '', bus)582 }).then((assert) => {583 expect(bus.on).to.have.been.calledWith('project:error')584 })585 })586 it('calls browsers.getAllBrowsersWith with no args when no browser specified', function () {587 return this.handleEvent('open:project', '/_test-output/path/to/project-e2e').then(() => {588 expect(browsers.getAllBrowsersWith).to.be.calledWith()589 })590 })591 it('calls browsers.getAllBrowsersWith with browser when browser specified', function () {592 sinon.stub(openProject, 'create').resolves()...

Full Screen

Full Screen

engines.test.js

Source:engines.test.js Github

copy

Full Screen

1const proxyquire = require("proxyquire");2const { rainbow, client } = require("./data");3const definitionsStub = {4 definition() {5 return Promise.resolve(rainbow);6 },7 form() {8 return Promise.resolve(client);9 },10};11const states = [];12const statesStub = {13 findOne() {14 return Promise.resolve({15 id: "1",16 definitionSrc: "rainbow",17 state: "running",18 stopped: false,19 engineVersion: "8.6.0",20 environment: { settings: {}, variables: {}, output: {} },21 definitions: [22 {23 id: "Definitions_1twtxb7",24 type: "bpmn:Definitions",25 executionId: "Definitions_1twtxb7_2ef63b82",26 status: "executing",27 counters: { completed: 0, discarded: 0 },28 environment: {29 settings: {},30 variables: {31 fields: {32 routingKey: "run.execute",33 exchange: "run",34 consumerTag: "_process-run",35 },36 content: {37 id: "rainbow",38 type: "bpmn:Process",39 name: "Rainbow",40 parent: { id: "Definitions_1twtxb7", type: "bpmn:Definitions" },41 executionId: "rainbow_26f27f43",42 },43 properties: {44 messageId: "smq.mid-33972f",45 timestamp: 1588926580358,46 },47 },48 output: {},49 },50 execution: {51 executionId: "Definitions_1twtxb7_2ef63b82",52 stopped: false,53 completed: false,54 status: "executing",55 processes: [56 {57 id: "rainbow",58 type: "bpmn:Process",59 name: "Rainbow",60 parent: { id: "Definitions_1twtxb7", type: "bpmn:Definitions" },61 executionId: "rainbow_26f27f43",62 status: "executing",63 counters: { completed: 0, discarded: 0, terminated: 0 },64 broker: {65 exchanges: [66 {67 name: "run",68 type: "topic",69 options: { durable: true, autoDelete: false },70 deliveryQueue: {71 name: "delivery-q",72 options: { autoDelete: true },73 messages: [],74 messageCount: 0,75 },76 bindings: [77 {78 id: "run-q/run.#",79 options: { priority: 0 },80 pattern: "run.#",81 queueName: "run-q",82 },83 ],84 },85 {86 name: "format",87 type: "topic",88 options: { durable: true, autoDelete: false },89 deliveryQueue: {90 name: "delivery-q",91 options: { autoDelete: true },92 messages: [],93 messageCount: 0,94 },95 bindings: [96 {97 id: "format-run-q/run.#",98 options: { priority: 0 },99 pattern: "run.#",100 queueName: "format-run-q",101 },102 ],103 },104 {105 name: "execution",106 type: "topic",107 options: { durable: true, autoDelete: false },108 deliveryQueue: {109 name: "delivery-q",110 options: { autoDelete: true },111 messages: [],112 messageCount: 0,113 },114 bindings: [115 {116 id: "execution-q/execution.#",117 options: { priority: 0 },118 pattern: "execution.#",119 queueName: "execution-q",120 },121 ],122 },123 {124 name: "message",125 type: "topic",126 options: { durable: true, autoDelete: true },127 deliveryQueue: {128 name: "delivery-q",129 options: { autoDelete: true },130 messages: [],131 messageCount: 0,132 },133 },134 ],135 queues: [136 {137 name: "run-q",138 options: { autoDelete: false, durable: true },139 messages: [140 {141 fields: {142 routingKey: "run.execute",143 exchange: "run",144 consumerTag: "_process-run",145 },146 content: {147 id: "rainbow",148 type: "bpmn:Process",149 name: "Rainbow",150 parent: {151 id: "Definitions_1twtxb7",152 type: "bpmn:Definitions",153 },154 executionId: "rainbow_26f27f43",155 },156 properties: {157 messageId: "smq.mid-33972f",158 timestamp: 1588926580358,159 },160 },161 ],162 messageCount: 1,163 },164 {165 name: "format-run-q",166 options: { autoDelete: false, durable: true },167 messages: [],168 messageCount: 0,169 },170 {171 name: "execution-q",172 options: { autoDelete: false, durable: true },173 messages: [],174 messageCount: 0,175 },176 {177 name: "execute-rainbow_26f27f43-q",178 options: { autoDelete: false, durable: true },179 messages: [180 {181 fields: {182 routingKey: "activity.wait",183 exchange: "event",184 consumerTag: "_process-activity-rainbow_26f27f43",185 },186 content: {187 executionId: "StartEvent_1_2f390886",188 id: "StartEvent_1",189 type: "bpmn:StartEvent",190 parent: {191 id: "rainbow",192 type: "bpmn:Process",193 executionId: "rainbow_26f27f43",194 },195 isStart: true,196 form:197 '{\n "name": "client",\n "title": "Client Form",\n "components": [\n {\n "label": "Client",\n "spellcheck": true,\n "tableView": true,\n "calculateServer": false,\n "validate": {\n "required": true\n },\n "key": "client",\n "type": "textfield",\n "input": true\n }\n ]\n }\n ',198 state: "wait",199 isRootScope: true,200 },201 properties: {202 persistent: true,203 messageId: "smq.mid-86bb1b",204 timestamp: 1588926580395,205 },206 },207 ],208 messageCount: 1,209 },210 ],211 },212 execution: {213 executionId: "rainbow_26f27f43",214 stopped: false,215 completed: false,216 status: "executing",217 children: [218 {219 id: "StartEvent_1",220 type: "bpmn:StartEvent",221 parent: { id: "rainbow", type: "bpmn:Process" },222 isStart: true,223 status: "executing",224 executionId: "StartEvent_1_2f390886",225 stopped: false,226 behaviour: {227 $type: "bpmn:StartEvent",228 id: "StartEvent_1",229 formKey: "client",230 },231 counters: { taken: 0, discarded: 0 },232 broker: {233 exchanges: [234 {235 name: "run",236 type: "topic",237 options: { durable: true, autoDelete: false },238 deliveryQueue: {239 name: "delivery-q",240 options: { autoDelete: true },241 messages: [],242 messageCount: 0,243 },244 bindings: [245 {246 id: "run-q/run.#",247 options: { priority: 0 },248 pattern: "run.#",249 queueName: "run-q",250 },251 ],252 },253 {254 name: "format",255 type: "topic",256 options: { durable: true, autoDelete: false },257 deliveryQueue: {258 name: "delivery-q",259 options: { autoDelete: true },260 messages: [],261 messageCount: 0,262 },263 bindings: [264 {265 id: "format-run-q/run.#",266 options: { priority: 0 },267 pattern: "run.#",268 queueName: "format-run-q",269 },270 ],271 },272 {273 name: "execution",274 type: "topic",275 options: { durable: true, autoDelete: false },276 deliveryQueue: {277 name: "delivery-q",278 options: { autoDelete: true },279 messages: [],280 messageCount: 0,281 },282 bindings: [283 {284 id: "execute-q/execute.#",285 options: { priority: 100 },286 pattern: "execute.#",287 queueName: "execute-q",288 },289 {290 id: "execution-q/execution.#",291 options: { priority: 0 },292 pattern: "execution.#",293 queueName: "execution-q",294 },295 ],296 },297 ],298 queues: [299 {300 name: "run-q",301 options: { autoDelete: false, durable: true },302 messages: [303 {304 fields: {305 routingKey: "run.execute",306 exchange: "run",307 consumerTag: "_activity-run",308 },309 content: {310 executionId: "StartEvent_1_2f390886",311 id: "StartEvent_1",312 type: "bpmn:StartEvent",313 parent: {314 id: "rainbow",315 type: "bpmn:Process",316 },317 isStart: true,318 form:319 '{\n "name": "client",\n "title": "Client Form",\n "components": [\n {\n"label": "Client",\n "spellcheck": true,\n "tableView": true,\n "calculateServer": false,\n "validate": {\n "required": true\n },\n "key": "client",\n "type": "textfield",\n "input": true\n }\n ]\n }\n ',320 },321 properties: {322 messageId: "smq.mid-4a43b",323 timestamp: 1588926580393,324 },325 },326 ],327 messageCount: 1,328 },329 {330 name: "format-run-q",331 options: { autoDelete: false, durable: true },332 messages: [],333 messageCount: 0,334 },335 {336 name: "execution-q",337 options: { autoDelete: false, durable: true },338 messages: [],339 messageCount: 0,340 },341 {342 name: "inbound-q",343 options: { autoDelete: false, durable: true },344 messages: [],345 messageCount: 0,346 },347 {348 name: "execute-q",349 options: { autoDelete: false, durable: true },350 messages: [351 {352 fields: {353 routingKey: "execute.start",354 exchange: "execution",355 consumerTag: "_activity-execute",356 },357 content: {358 executionId: "StartEvent_1_2f390886",359 id: "StartEvent_1",360 type: "bpmn:StartEvent",361 parent: {362 id: "rainbow",363 type: "bpmn:Process",364 },365 isStart: true,366 form:367 '{\n "name": "client",\n "title": "Client Form",\n "components": [\n {\n "label": "Client",\n "spellcheck": true,\n "tableView": true,\n "calculateServer": false,\n "validate": {\n "required": true\n },\n "key": "client",\n "type": "textfield",\n "input": true\n }\n ]\n }\n ',368 state: "start",369 isRootScope: true,370 },371 properties: {372 messageId: "smq.mid-653323",373 timestamp: 1588926580395,374 },375 },376 ],377 messageCount: 1,378 },379 ],380 },381 execution: { completed: false },382 },383 {384 id: "bidOnePager",385 type: "bpmn:UserTask",386 name: "Bid One-Pager",387 parent: { id: "rainbow", type: "bpmn:Process" },388 stopped: false,389 behaviour: {390 $type: "bpmn:UserTask",391 id: "bidOnePager",392 name: "Bid One-Pager",393 formKey: "bidOnePager",394 },395 counters: { taken: 0, discarded: 0 },396 broker: {397 exchanges: [398 {399 name: "run",400 type: "topic",401 options: { durable: true, autoDelete: false },402 deliveryQueue: {403 name: "delivery-q",404 options: { autoDelete: true },405 messages: [],406 messageCount: 0,407 },408 bindings: [409 {410 id: "run-q/run.#",411 options: { priority: 0 },412 pattern: "run.#",413 queueName: "run-q",414 },415 ],416 },417 {418 name: "format",419 type: "topic",420 options: { durable: true, autoDelete: false },421 deliveryQueue: {422 name: "delivery-q",423 options: { autoDelete: true },424 messages: [],425 messageCount: 0,426 },427 bindings: [428 {429 id: "format-run-q/run.#",430 options: { priority: 0 },431 pattern: "run.#",432 queueName: "format-run-q",433 },434 ],435 },436 {437 name: "execution",438 type: "topic",439 options: { durable: true, autoDelete: false },440 deliveryQueue: {441 name: "delivery-q",442 options: { autoDelete: true },443 messages: [],444 messageCount: 0,445 },446 bindings: [447 {448 id: "execution-q/execution.#",449 options: { priority: 0 },450 pattern: "execution.#",451 queueName: "execution-q",452 },453 ],454 },455 ],456 queues: [457 {458 name: "run-q",459 options: { autoDelete: false, durable: true },460 messages: [],461 messageCount: 0,462 },463 {464 name: "format-run-q",465 options: { autoDelete: false, durable: true },466 messages: [],467 messageCount: 0,468 },469 {470 name: "execution-q",471 options: { autoDelete: false, durable: true },472 messages: [],473 messageCount: 0,474 },475 {476 name: "inbound-q",477 options: { autoDelete: false, durable: true },478 messages: [],479 messageCount: 0,480 },481 ],482 },483 },484 {485 id: "Event_1h50wpr",486 type: "bpmn:EndEvent",487 parent: { id: "rainbow", type: "bpmn:Process" },488 isEnd: true,489 stopped: false,490 behaviour: {491 $type: "bpmn:EndEvent",492 id: "Event_1h50wpr",493 },494 counters: { taken: 0, discarded: 0 },495 broker: {496 exchanges: [497 {498 name: "run",499 type: "topic",500 options: { durable: true, autoDelete: false },501 deliveryQueue: {502 name: "delivery-q",503 options: { autoDelete: true },504 messages: [],505 messageCount: 0,506 },507 bindings: [508 {509 id: "run-q/run.#",510 options: { priority: 0 },511 pattern: "run.#",512 queueName: "run-q",513 },514 ],515 },516 {517 name: "format",518 type: "topic",519 options: { durable: true, autoDelete: false },520 deliveryQueue: {521 name: "delivery-q",522 options: { autoDelete: true },523 messages: [],524 messageCount: 0,525 },526 bindings: [527 {528 id: "format-run-q/run.#",529 options: { priority: 0 },530 pattern: "run.#",531 queueName: "format-run-q",532 },533 ],534 },535 {536 name: "execution",537 type: "topic",538 options: { durable: true, autoDelete: false },539 deliveryQueue: {540 name: "delivery-q",541 options: { autoDelete: true },542 messages: [],543 messageCount: 0,544 },545 bindings: [546 {547 id: "execution-q/execution.#",548 options: { priority: 0 },549 pattern: "execution.#",550 queueName: "execution-q",551 },552 ],553 },554 ],555 queues: [556 {557 name: "run-q",558 options: { autoDelete: false, durable: true },559 messages: [],560 messageCount: 0,561 },562 {563 name: "format-run-q",564 options: { autoDelete: false, durable: true },565 messages: [],566 messageCount: 0,567 },568 {569 name: "execution-q",570 options: { autoDelete: false, durable: true },571 messages: [],572 messageCount: 0,573 },574 {575 name: "inbound-q",576 options: { autoDelete: false, durable: true },577 messages: [],578 messageCount: 0,579 },580 ],581 },582 },583 ],584 flows: [585 {586 id: "Flow_0soqtbe",587 type: "bpmn:SequenceFlow",588 sourceId: "StartEvent_1",589 targetId: "bidOnePager",590 counters: { looped: 0, take: 0, discard: 0 },591 broker: {592 exchanges: [593 {594 name: "event",595 type: "topic",596 options: {597 durable: true,598 autoDelete: false,599 prefix: "flow",600 },601 deliveryQueue: {602 name: "delivery-q",603 options: { autoDelete: true },604 messages: [],605 messageCount: 0,606 },607 },608 ],609 },610 },611 {612 id: "Flow_1var5sp",613 type: "bpmn:SequenceFlow",614 sourceId: "bidOnePager",615 targetId: "Event_1h50wpr",616 counters: { looped: 0, take: 0, discard: 0 },617 broker: {618 exchanges: [619 {620 name: "event",621 type: "topic",622 options: {623 durable: true,624 autoDelete: false,625 prefix: "flow",626 },627 deliveryQueue: {628 name: "delivery-q",629 options: { autoDelete: true },630 messages: [],631 messageCount: 0,632 },633 },634 ],635 },636 },637 ],638 messageFlows: [],639 associations: [],640 },641 },642 ],643 },644 broker: {645 exchanges: [646 {647 name: "run",648 type: "topic",649 options: { durable: true, autoDelete: false },650 deliveryQueue: {651 name: "delivery-q",652 options: { autoDelete: true },653 messages: [],654 messageCount: 0,655 },656 bindings: [657 {658 id: "run-q/run.#",659 options: { priority: 0 },660 pattern: "run.#",661 queueName: "run-q",662 },663 ],664 },665 {666 name: "format",667 type: "topic",668 options: { durable: true, autoDelete: false },669 deliveryQueue: {670 name: "delivery-q",671 options: { autoDelete: true },672 messages: [],673 messageCount: 0,674 },675 bindings: [676 {677 id: "format-run-q/run.#",678 options: { priority: 0 },679 pattern: "run.#",680 queueName: "format-run-q",681 },682 ],683 },684 {685 name: "execution",686 type: "topic",687 options: { durable: true, autoDelete: false },688 deliveryQueue: {689 name: "delivery-q",690 options: { autoDelete: true },691 messages: [],692 messageCount: 0,693 },694 bindings: [695 {696 id: "execution-q/execution.#",697 options: { priority: 0 },698 pattern: "execution.#",699 queueName: "execution-q",700 },701 ],702 },703 ],704 queues: [705 {706 name: "run-q",707 options: { autoDelete: false, durable: true },708 messages: [709 {710 fields: {711 routingKey: "run.execute",712 exchange: "run",713 consumerTag: "_definition-run",714 },715 content: {716 id: "Definitions_1twtxb7",717 type: "bpmn:Definitions",718 executionId: "Definitions_1twtxb7_2ef63b82",719 },720 properties: {721 messageId: "smq.mid-877eb2",722 timestamp: 1588926580347,723 },724 },725 ],726 messageCount: 1,727 },728 {729 name: "format-run-q",730 options: { autoDelete: false, durable: true },731 messages: [],732 messageCount: 0,733 },734 {735 name: "execution-q",736 options: { autoDelete: false, durable: true },737 messages: [],738 messageCount: 0,739 },740 {741 name: "execute-Definitions_1twtxb7_2ef63b82-q",742 options: { autoDelete: false, durable: true },743 messages: [744 {745 fields: {746 routingKey: "process.start",747 exchange: "event",748 consumerTag:749 "_definition-activity-Definitions_1twtxb7_2ef63b82",750 },751 content: {752 id: "rainbow",753 type: "bpmn:Process",754 name: "Rainbow",755 parent: {756 id: "Definitions_1twtxb7",757 type: "bpmn:Definitions",758 executionId: "Definitions_1twtxb7_2ef63b82",759 },760 executionId: "rainbow_26f27f43",761 state: "start",762 },763 properties: {764 type: "start",765 mandatory: false,766 messageId: "smq.mid-3a126e",767 timestamp: 1588926580359,768 },769 },770 ],771 messageCount: 1,772 },773 ],774 },775 source:776 '{"id":"Definitions_1twtxb7","type":"bpmn:Definitions","activities":[{"id":"StartEvent_1","type":"bpmn:StartEvent","parent":{"id":"rainbow","type":"bpmn:Process"},"behaviour":{"$type":"bpmn:StartEvent","id":"StartEvent_1","formKey":"client"}},{"id":"bidOnePager","type":"bpmn:UserTask","name":"Bid One-Pager","parent":{"id":"rainbow","type":"bpmn:Process"},"behaviour":{"$type":"bpmn:UserTask","id":"bidOnePager","name":"Bid One-Pager","formKey":"bidOnePager"}},{"id":"Event_1h50wpr","type":"bpmn:EndEvent","parent":{"id":"rainbow","type":"bpmn:Process"},"behaviour":{"$type":"bpmn:EndEvent","id":"Event_1h50wpr"}}],"associations":[],"dataObjects":[],"definition":{"id":"Definitions_1twtxb7","type":"bpmn:Definitions","targetNamespace":"http://bpmn.io/schema/bpmn","exporter":"Camunda Modeler","exporterVersion":"3.7.1"},"messageFlows":[],"processes":[{"id":"rainbow","type":"bpmn:Process","name":"Rainbow","parent":{"id":"Definitions_1twtxb7","type":"bpmn:Definitions"},"behaviour":{"$type":"bpmn:Process","id":"rainbow","name":"Rainbow","isExecutable":true,"flowElements":[{"$type":"bpmn:StartEvent","id":"StartEvent_1","formKey":"client"},{"$type":"bpmn:UserTask","id":"bidOnePager","name":"Bid One-Pager","formKey":"bidOnePager"},{"$type":"bpmn:SequenceFlow","id":"Flow_0soqtbe"},{"$type":"bpmn:EndEvent","id":"Event_1h50wpr"},{"$type":"bpmn:SequenceFlow","id":"Flow_1var5sp"}]}}],"sequenceFlows":[{"id":"Flow_0soqtbe","type":"bpmn:SequenceFlow","parent":{"id":"rainbow","type":"bpmn:Process"},"targetId":"bidOnePager","sourceId":"StartEvent_1","behaviour":{"$type":"bpmn:SequenceFlow","id":"Flow_0soqtbe"}},{"id":"Flow_1var5sp","type":"bpmn:SequenceFlow","parent":{"id":"rainbow","type":"bpmn:Process"},"targetId":"Event_1h50wpr","sourceId":"bidOnePager","behaviour":{"$type":"bpmn:SequenceFlow","id":"Flow_1var5sp"}}]}',777 },778 ],779 });780 },781 save(state) {782 states.push(state);783 return state;784 },785};786const busStub = {787 publish() {},788};789describe("engines", function () {790 let engines;791 beforeEach(() => {792 engines = proxyquire("../lib/engines", {793 "./definitions": definitionsStub,794 "./states": statesStub,795 });796 });797 it("should be able to execute a process", async () => {798 await engines.execute("rainbow", "1", busStub);799 const execution = await engines.get("1");800 expect(states.length).to.be.equal(4);801 expect(execution).to.not.be.undefined;802 expect(execution.getPostponed().length).to.be.equal(1);803 });804 it("should be able to recover a engine", async () => {805 const execution = await engines.get("1", busStub);806 expect(execution.getPostponed().length).to.be.equal(1);807 });...

Full Screen

Full Screen

blocks.js

Source:blocks.js Github

copy

Full Screen

1/* eslint-disable mocha/no-pending-tests */2/*3 * Copyright © 2018 Lisk Foundation4 *5 * See the LICENSE file at the top-level directory of this distribution6 * for licensing information.7 *8 * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation,9 * no part of this software, including this file, may be copied, modified,10 * propagated, or distributed except according to the terms contained in the11 * LICENSE file.12 *13 * Removal or modification of this copyright notice is prohibited.14 */15'use strict';16const rewire = require('rewire');17const { EPOCH_TIME } = global.constants;18const Blocks = rewire('../../../modules/blocks.js');19describe('blocks', () => {20 let blocksInstance;21 let self;22 let library;23 let __private;24 let dbStub;25 let loggerStub;26 let logicBlockStub;27 let logicTransactionStub;28 let schemaStub;29 let dbSequenceStub;30 let sequenceStub;31 let peersStub;32 let dummyGenesisblock;33 let accountStub;34 let busStub;35 let balancesSequenceStub;36 let scope;37 beforeEach(done => {38 dummyGenesisblock = {39 block: {40 id: '6524861224470851795',41 height: 1,42 },43 };44 loggerStub = {45 trace: sinonSandbox.spy(),46 info: sinonSandbox.spy(),47 error: sinonSandbox.spy(),48 warn: sinonSandbox.spy(),49 debug: sinonSandbox.spy(),50 };51 dbStub = {52 blocks: {53 getGenesisBlockId: sinonSandbox54 .stub()55 .resolves([{ id: '6524861224470851795' }]),56 deleteBlock: sinonSandbox.stub(),57 deleteAfterBlock: sinonSandbox.stub(),58 },59 tx: sinonSandbox.stub(),60 };61 logicBlockStub = sinonSandbox.stub();62 logicTransactionStub = sinonSandbox.stub();63 schemaStub = sinonSandbox.stub();64 dbSequenceStub = sinonSandbox.stub();65 sequenceStub = sinonSandbox.stub();66 accountStub = sinonSandbox.stub();67 busStub = sinonSandbox.stub();68 balancesSequenceStub = sinonSandbox.stub();69 scope = {70 logger: loggerStub,71 db: dbStub,72 logic: {73 account: accountStub,74 block: logicBlockStub,75 transaction: logicTransactionStub,76 peers: peersStub,77 },78 schema: schemaStub,79 dbSequence: dbSequenceStub,80 sequence: sequenceStub,81 genesisBlock: dummyGenesisblock,82 bus: busStub,83 balancesSequence: balancesSequenceStub,84 config: { loading: {} },85 };86 blocksInstance = new Blocks((err, cbSelf) => {87 self = cbSelf;88 library = Blocks.__get__('library');89 __private = Blocks.__get__('__private');90 expect(err).to.be.undefined;91 done();92 }, scope);93 });94 afterEach(done => {95 sinonSandbox.restore();96 done();97 });98 describe('constructor', () => {99 it('should assign params to library', () => {100 return expect(library.logger).to.eql(loggerStub);101 });102 it('should instantiate submodules', () => {103 expect(self.submodules.api).to.be.an('object');104 expect(self.submodules.chain).to.be.an('object');105 expect(self.submodules.process).to.be.an('object');106 expect(self.submodules.utils).to.be.an('object');107 return expect(self.submodules.verify).to.be.an('object');108 });109 it('should assign submodules to this', () => {110 expect(self.submodules.api).to.deep.equal(self.shared);111 expect(self.submodules.chain).to.deep.equal(self.chain);112 expect(self.submodules.process).to.deep.equal(self.process);113 expect(self.submodules.utils).to.deep.equal(self.utils);114 return expect(self.submodules.verify).to.deep.equal(self.verify);115 });116 it('should call callback with result = self', () => {117 return expect(self).to.be.deep.equal(blocksInstance);118 });119 describe('when this.submodules.chain.saveGenesisBlock fails', () => {120 it('should call callback with error', done => {121 dbStub.blocks.getGenesisBlockId.resolves([]);122 blocksInstance = new Blocks((err, cbSelf) => {123 self = cbSelf;124 library = Blocks.__get__('library');125 __private = Blocks.__get__('__private');126 expect(err).to.equal('Blocks#saveGenesisBlock error');127 expect(self.submodules.api).to.be.an('object');128 expect(self.submodules.chain).to.be.an('object');129 expect(self.submodules.process).to.be.an('object');130 expect(self.submodules.utils).to.be.an('object');131 expect(self.submodules.verify).to.be.an('object');132 done();133 }, scope);134 });135 });136 });137 describe('lastBlock', () => {138 beforeEach(done => {139 __private.lastBlock = dummyGenesisblock;140 done();141 });142 describe('get', () => {143 it('should return __private.lastBlock', () => {144 return expect(blocksInstance.lastBlock.get()).to.deep.equal(145 dummyGenesisblock146 );147 });148 });149 describe('set', () => {150 it('should assign input parameter block to __private.lastBlock and return input parameter', () => {151 expect(blocksInstance.lastBlock.set({ id: 2 })).to.deep.equal({152 id: 2,153 });154 return expect(__private.lastBlock).to.deep.equal({ id: 2 });155 });156 });157 describe('isFresh', () => {158 describe('when __private.lastBlock = undefined', () => {159 beforeEach(done => {160 __private.lastBlock = undefined;161 done();162 });163 it('should return false', () => {164 return expect(blocksInstance.lastBlock.isFresh()).to.be.false;165 });166 });167 describe('when __private.lastBlock exists', () => {168 describe('when secondsAgo < BLOCK_RECEIPT_TIMEOUT', () => {169 beforeEach(done => {170 const timestamp =171 10000 +172 Math.floor(Date.now() / 1000) -173 Math.floor(EPOCH_TIME / 1000);174 __private.lastBlock = { timestamp };175 done();176 });177 it('should return true', () => {178 return expect(blocksInstance.lastBlock.isFresh()).to.be.true;179 });180 });181 describe('when secondsAgo >= BLOCK_RECEIPT_TIMEOUT', () => {182 beforeEach(done => {183 __private.lastBlock = { timestamp: 555555 };184 done();185 });186 it('should return false', () => {187 return expect(blocksInstance.lastBlock.isFresh()).to.be.false;188 });189 });190 });191 });192 });193 describe('lastReceipt', () => {194 const dummyLastReceipt = 1520593240;195 beforeEach(done => {196 __private.lastReceipt = dummyLastReceipt;197 done();198 });199 describe('get', () => {200 it('should return __private.lastReceipt', () => {201 return expect(blocksInstance.lastReceipt.get()).to.equal(202 dummyLastReceipt203 );204 });205 });206 describe('update', () => {207 it('should assign update __private.lastReceipt with latest time and return new value', () => {208 expect(blocksInstance.lastReceipt.update()).to.be.above(209 dummyLastReceipt210 );211 return expect(__private.lastReceipt).to.be.above(dummyLastReceipt);212 });213 });214 describe('isStale', () => {215 describe('when __private.lastReceipt is null', () => {216 beforeEach(done => {217 __private.lastBlock = null;218 done();219 });220 it('should return false', () => {221 return expect(blocksInstance.lastReceipt.isStale()).to.be.true;222 });223 });224 describe('when __private.lastReceipt is set', () => {225 describe('when secondsAgo > BLOCK_RECEIPT_TIMEOUT', () => {226 beforeEach(done => {227 __private.lastReceipt = dummyLastReceipt;228 done();229 });230 it('should return true', () => {231 return expect(blocksInstance.lastReceipt.isStale()).to.be.true;232 });233 });234 describe('when secondsAgo <= BLOCK_RECEIPT_TIMEOUT', () => {235 beforeEach(done => {236 __private.lastReceipt = Math.floor(Date.now() / 1000) + 10000;237 done();238 });239 it('should return false', () => {240 return expect(blocksInstance.lastReceipt.isStale()).to.be.false;241 });242 });243 });244 });245 });246 describe('isActive', () => {247 beforeEach(done => {248 __private.isActive = false;249 done();250 });251 describe('get', () => {252 it('should return __private.isActive', () => {253 return expect(blocksInstance.isActive.get()).to.be.false;254 });255 });256 describe('set', () => {257 it('should assign input parameter block to __private.isActive and return input parameter', () => {258 expect(blocksInstance.isActive.set(true)).to.be.true;259 return expect(__private.isActive).to.be.true;260 });261 });262 });263 describe('isCleaning', () => {264 beforeEach(done => {265 __private.cleanup = false;266 done();267 });268 describe('get', () => {269 it('should return __private.cleanup', () => {270 return expect(blocksInstance.isCleaning.get()).to.be.false;271 });272 });273 });274 describe('onBind', () => {275 it('should set __private.loaded = true', () => {276 blocksInstance.onBind();277 return expect(__private.loaded).to.be.true;278 });279 });280 describe('cleanup', () => {281 afterEach(() => {282 expect(__private.loaded).to.be.false;283 return expect(__private.cleanup).to.be.true;284 });285 describe('when __private.isActive = false', () => {286 beforeEach(done => {287 __private.isActive = false;288 done();289 });290 it('should call callback', done => {291 blocksInstance.cleanup(cb => {292 expect(cb).to.be.undefined;293 done();294 });295 });296 });297 describe('when __private.isActive = true', () => {298 beforeEach(done => {299 __private.isActive = true;300 done();301 });302 describe('after 10 seconds', () => {303 afterEach(() => {304 expect(loggerStub.info.callCount).to.equal(1);305 return expect(loggerStub.info.args[0][0]).to.equal(306 'Waiting for block processing to finish...'307 );308 });309 it('should log info "Waiting for block processing to finish..."', done => {310 setTimeout(() => {311 __private.isActive = false;312 }, 5000);313 blocksInstance.cleanup(cb => {314 expect(cb).to.be.undefined;315 done();316 });317 });318 });319 describe('after 20 seconds', () => {320 afterEach(() => {321 expect(loggerStub.info.callCount).to.equal(2);322 expect(loggerStub.info.args[0][0]).to.equal(323 'Waiting for block processing to finish...'324 );325 return expect(loggerStub.info.args[1][0]).to.equal(326 'Waiting for block processing to finish...'327 );328 });329 it('should log info "Waiting for block processing to finish..." 2 times', done => {330 setTimeout(() => {331 __private.isActive = false;332 }, 15000);333 blocksInstance.cleanup(cb => {334 expect(cb).to.be.undefined;335 done();336 });337 });338 });339 });340 });341 describe('isLoaded', () => {342 beforeEach(done => {343 __private.loaded = true;344 done();345 });346 it('should return __private.loaded', () => {347 blocksInstance.onBind();348 return expect(__private.loaded).to.be.true;349 });350 });...

Full Screen

Full Screen

Handler.spec.js

Source:Handler.spec.js Github

copy

Full Screen

1import Handler from '../../../../src/Utils/EzACD/Response/Handler'2import OPS from '../../../../src/Utils/EzACD/OPs'3import sinon from 'sinon'4let _ = require('lodash')5let assert = require('assert')6/**7 * Handler 處理的項目8 * 9 * @type {Array}10 */11const handableOps = [12 OPS.CONNECT_TO_ACD_RESPONSE,13 OPS.AGENT_LOGIN_RESPONSE,14 OPS.AGENT_LOGOUT_RESPONSE,15 OPS.CURRENT_AGENT_STATE_RESPONSE,16 OPS.MAKE_2ND_CALL_RESPONSE,17 OPS.MERGE_CALL_ACTION_RESPONSE,18 OPS.QUERY_ACD_QUEUED_RESPONSE,19 OPS.SET_CURRNET_AGENT_STATE_RESPONSE,20 OPS.MAKE_CALL_RESPONSE,21 OPS.DIAL_DTMF_RESPONSE,22 OPS.CALL_ACTION_RESPONSE,23 OPS.GET_AGENT_GROUP_LIST_RESPONSE,24 OPS.GET_DN_STATE_RESPONSE,25 OPS.GET_DN_PERFORMANCE_RESPONSE,26 OPS.GET_AGENT_PERFORMANCE_RESPONSE,27 OPS.GET_AGENT_GROUP_PERFORMANCE_RESPONSE,28 OPS.AGENT_STATE_CHANGE_EVENT,29 OPS.MESSAGE_RECEIVE_EVENT,30 OPS.CALL_STATE_CHANGE_EVENT,31 OPS.INCOMING_CALL_EVENT,32 OPS.SUPERVISOR_COACH_RESPONSE,33 OPS.SUPERVISOR_MONITOR_RESPONSE,34 OPS.SUPERVISOR_CONFERENCE_RESPONSE,35 OPS.SUPERVISOR_TRANSFER_RESPONSE,36 OPS.SUPERVISOR_TALK_TO_AGENT_RESPONSE,37]38describe('Handler 單元測試', () => {39 let busStub = {40 '$emit': function() {}41 }42 let busSpy = sinon.spy(busStub, '$emit')43 let handlerInstance = new Handler({}, busStub)44 describe('檢查 handler 是否存在', () => {45 handableOps.forEach(op => {46 it(`${op} 確認存在對應 handler function`, () => {47 let methodName = _.find(handlerInstance.cbs, { op: Number(op) }).method48 assert.equal(_.isFunction(handlerInstance[methodName]), true) 49 })50 })51 })52 describe('檢查 handler function 內部動作', () => {53 handlerInstance.cbs.forEach(cb => {54 it(`檢查 ${cb.method} 是否有呼叫 bus.$emit()`, () => {55 let testString = "atype=98\n"56 handlerInstance[cb.method](testString)57 assert.ok(busStub.$emit.calledOnce)58 busSpy.resetHistory()59 })60 })61 it(`檢查 unknownHandler 是否有呼叫 bus.$emit()`, () => {62 let testString = 'string'63 handlerInstance.unknownHandler(testString)64 assert.ok(busStub.$emit.calledOnce)65 busSpy.resetHistory()66 })67 })...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1Cypress.Commands.add('busStub', (method, url, response, options = {}) => {2 const { delay = 0, statusCode = 200 } = options;3 cy.server();4 cy.route({5 }).as('busStub');6});7Cypress.Commands.add('busWait', (method, url, options = {}) => {8 const { delay = 0, statusCode = 200 } = options;9 cy.server();10 cy.route({11 }).as('busWait');12});13Cypress.Commands.add('busWait', (method, url, options = {}) => {14 const { delay = 0, statusCode = 200 } = options;15 cy.server();16 cy.route({17 }).as('busWait');18});19Cypress.Commands.add('busWait', (method, url, options = {}) => {20 const { delay = 0, statusCode = 200 } = options;21 cy.server();22 cy.route({23 }).as('busWait');24});25Cypress.Commands.add('busWait', (method, url, options = {}) => {26 const { delay = 0, statusCode = 200 } = options;27 cy.server();28 cy.route({29 }).as('busWait');30});31Cypress.Commands.add('busWait', (method, url, options = {}) => {32 const { delay = 0, statusCode = 200 } = options;33 cy.server();34 cy.route({35 }).as('busWait');36});37Cypress.Commands.add('busWait', (method, url, options

Full Screen

Using AI Code Generation

copy

Full Screen

1cy.busStub('myEvent', 'myEventStub');2cy.busPublish('myEvent', 'myEventData');3cy.busSubscribe('myEventStub', 'myEventData');4describe('Bus Plugin', () => {5 beforeEach(() => {6 });7 it('cy.busSubscribe() - subscribe to a bus event', () => {8 cy.busSubscribe('myEventStub', 'myEventData');9 cy.busPublish('myEvent', 'myEventData');10 cy.get('#data').should('contain', 'myEventData');11 });12});13[MIT](LICENSE)

Full Screen

Using AI Code Generation

copy

Full Screen

1import { busStub } from 'cypress-vue-unit-test'2describe('MyComponent', () => {3 it('emits event', () => {4 cy.mount(MyComponent)5 busStub('event-name')6 cy.get('button').click()7 cy.get('@event-name').should('have.been.calledOnce')8 })9})10import { mount } from '@vue/test-utils'11import MyComponent from './MyComponent.vue'12describe('MyComponent', () => {13 it('emits event', () => {14 const wrapper = mount(MyComponent)15 const eventStub = cy.stub()16 wrapper.vm.$bus.$on('event-name', eventStub)17 wrapper.find('button').trigger('click')18 expect(eventStub).to.have.been.calledOnce19 })20})21import { mount } from '@vue/test-utils'22import MyComponent from './MyComponent.vue'23describe('MyComponent', () => {24 it('emits event', () => {25 const wrapper = mount(MyComponent)26 const eventStub = jest.fn()27 wrapper.vm.$bus.$on('event-name', eventStub)28 wrapper.find('button').trigger('click')29 expect(eventStub).toHaveBeenCalled()30 })31})32import { mount } from '@vue/test-utils'33import MyComponent from './MyComponent.vue'34describe('MyComponent', () => {35 it('emits event', () => {36 const wrapper = mount(MyComponent)37 const eventStub = sinon.stub()38 wrapper.vm.$bus.$on('event-name', eventStub)39 wrapper.find('button').trigger('click')

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('Bus Stub', () => {2 it('should stub a bus', () => {3 cy.busStub('myBus', 'myEvent', { data: 'some data' });4 cy.window().then((win) => {5 win.postMessage({ bus: 'myBus', event: 'myEvent' }, '*');6 });7 cy.get('h1').should('have.text', 'some data');8 });9});10[MIT](LICENSE)

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('Cypress busStub', function() {2 it('should stub bus', function() {3 cy.window().then(win => {4 win.Cypress.busStub('on', 'app:window:before:load', () => {5 console.log('app:window:before:load')6 })7 win.Cypress.busStub('on', 'app:window:load', () => {8 console.log('app:window:load')9 })10 })11 })12})13describe('Cypress busSpy', function() {14 it('should spy bus', function() {15 cy.window().then(win => {16 win.Cypress.busSpy('on', 'app:window:before:load', () => {17 console.log('app:window:before:load')18 })19 win.Cypress.busSpy('on', 'app:window:load', () => {20 console.log('app:window:load')21 })22 })23 })24})25describe('Cypress busRestore', function() {26 it('should restore bus', function() {27 cy.window().then(win => {28 win.Cypress.busRestore('on', 'app:window:before:load')29 win.Cypress.busRestore('on', 'app:window:load')30 })31 })32})33describe('Cypress busReset', function() {34 it('should reset bus', function() {35 cy.window().then(win => {36 win.Cypress.busReset()37 })38 })39})40describe('Cypress bus', function() {41 it('should get bus', function() {42 cy.window().then(win => {43 var bus = win.Cypress.bus()44 bus.emit('app:

Full Screen

Using AI Code Generation

copy

Full Screen

1const busStub = require('cypress-bus-stub')2busStub(Cypress)3it('test', () => {4 cy.stubBus('my-event', 'my-response')5 cy.stubBus('my-event-2', 'my-response-2')6})7### stubBus(eventName, response)8- eventName (string) - The name of the event to stub9- response (string) - The response to send back to the event10- (object) - Returns the stubbed event11cy.stubBus('my-event', 'my-response')12### stubBus(eventName, response, options)13- eventName (string) - The name of the event to stub14- response (string) - The response to send back to the event15- options (object) - The options to pass to the stub16 - delay (number) - The delay in milliseconds to wait before sending the response17- (object) - Returns the stubbed event18cy.stubBus('my-event', 'my-response', { delay: 500 })19### stubBus(eventName, response, fn)20- eventName (string) - The name of the event to stub21- response (string) - The response to send back to the event22- fn (function) - The function to be called when the event is triggered23- (object) - Returns the stubbed event24cy.stubBus('my-event', 'my-response', (data) => {25 console.log(data)26})27### stubBus(eventName, response, options, fn)28- eventName (string) - The name of the event to stub29- response (string) - The response to send back to the event30- options (object) - The options to pass to the stub31 - delay (number) - The delay in milliseconds to wait before sending the response32- fn (function) - The function to be called when the event is triggered33- (object) - Returns the stubbed event34cy.stubBus('my-event', 'my-response', { delay: 500 }, (data) => {35 console.log(data

Full Screen

Using AI Code Generation

copy

Full Screen

1import busStub from 'cypress-bus-stub';2describe('Bus stub test', () => {3 it('should stub the bus', () => {4 busStub();5 cy.bus().emit('event', 'data');6 cy.bus().should('have.been.calledWith', 'event', 'data');7 });8});9import busStub from 'cypress-bus-stub';10busStub();11cy.bus().emit('event', 'data');12cy.bus().should('have.been.calledWith', 'event', 'data');

Full Screen

Using AI Code Generation

copy

Full Screen

1const bus = require('./bus');2describe('stubbing the bus object', () => {3 it('should call the bus', () => {4 cy.stub(bus, 'busStub').as('bus');5 cy.visit('index.html');6 cy.get('#button').click();7 cy.get('@bus').should('have.been.calledWith', 'hello');8 });9});10cy.get('#button').click();11cy.get('#button').click();12cy.get('#button').click();13cy.get('#button').click();14cy.get('#button').click();15cy.get('#button').click();

Full Screen

Cypress Tutorial

Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.

Chapters:

  1. What is Cypress? -
  2. Why Cypress? - Learn why Cypress might be a good choice for testing your web applications.
  3. Features of Cypress Testing - Learn about features that make Cypress a powerful and flexible tool for testing web applications.
  4. Cypress Drawbacks - Although Cypress has many strengths, it has a few limitations that you should be aware of.
  5. Cypress Architecture - Learn more about Cypress architecture and how it is designed to be run directly in the browser, i.e., it does not have any additional servers.
  6. Browsers Supported by Cypress - Cypress is built on top of the Electron browser, supporting all modern web browsers. Learn browsers that support Cypress.
  7. Selenium vs Cypress: A Detailed Comparison - Compare and explore some key differences in terms of their design and features.
  8. Cypress Learning: Best Practices - Take a deep dive into some of the best practices you should use to avoid anti-patterns in your automation tests.
  9. How To Run Cypress Tests on LambdaTest? - Set up a LambdaTest account, and now you are all set to learn how to run Cypress tests.

Certification

You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.

YouTube

Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful