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