From dfb15aeeec52b5db72d57e8b171cb6752ecb7c3c Mon Sep 17 00:00:00 2001 From: Usman Khan Date: Fri, 1 Sep 2017 17:48:49 +0200 Subject: [PATCH 1/9] Added skeleton for intransfer unit tests --- test/unit/logic/intransfer.js | 553 ++++++++++++++++++++++++++++++++++ 1 file changed, 553 insertions(+) create mode 100644 test/unit/logic/intransfer.js diff --git a/test/unit/logic/intransfer.js b/test/unit/logic/intransfer.js new file mode 100644 index 00000000000..fcfc59d9ffd --- /dev/null +++ b/test/unit/logic/intransfer.js @@ -0,0 +1,553 @@ +'use strict';/*eslint*/ + +var crypto = require('crypto'); +var _ = require('lodash'); + +var expect = require('chai').expect; +var rewire = require('rewire'); +var sinon = require('sinon'); + +var node = require('./../../node.js'); +var ed = require('../../../helpers/ed'); +var modulesLoader = require('../../common/initModule').modulesLoader; + +var InTransfer = rewire('../../../logic/inTransfer.js'); +var sql = require('../../../sql/dapps.js'); + +var validPassword = 'robust weapon course unknown head trial pencil latin acid'; +var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); + +var validSender = { + password: 'yjyhgnu32jmwuii442t9', + secondPassword: 'kub8gm2w330pvptx1or', + username: 'mix8', + publicKey: '5ff3c8f4be105953301e505d23a6e1920da9f72dc8dfd7babe1481b662f2b081', + address: '4835566122337813671L', + secondPublicKey: 'ebfb1157f9f9ad223b1c7468b0d643663ec5a34ac7a6d557243834ae604d72b7' +}; + +var senderHash = crypto.createHash('sha256').update(validSender.password, 'utf8').digest(); +var senderKeypair = ed.makeKeypair(senderHash); + +var validTransaction = { + id: '1907088915785679339', + height: 371, + blockId: '17233974955873751907', + type: 5, + timestamp: 40081792, + senderPublicKey: '644485a01cb11e06a1f4ffef90a7ba251e56d54eb06a0cb2ecb5693a8cc163a2', + senderId: '5519106118231224961L', + recipientId: null, + recipientPublicKey: null, + amount: 0, + fee: 2500000000, + signature: 'b024f90f73e53c9fee943f3c3ef7a9e3da99bab2f9fa3cbfd5ad05ed79cdbbe21130eb7b27698692bf491a1cf573a518dfa63607dc88bc0c01925fda18304905', + signatures: [], + confirmations: 717, + asset: { + dapp: { + name: 'AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi', + description: null, + tags: null, + type: 1, + link: 'http://www.lisk.io/AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi.zip', + category: 2, + icon: null + } + } +}; + +var rawValidTransaction = { + t_id: '1907088915785679339', + b_height: 371, + t_blockId: '17233974955873751907', + t_type: 5, + t_timestamp: 40081792, + t_senderPublicKey: '644485a01cb11e06a1f4ffef90a7ba251e56d54eb06a0cb2ecb5693a8cc163a2', + m_recipientPublicKey: null, + t_senderId: '5519106118231224961L', + t_recipientId: null, + t_amount: '0', + t_fee: '2500000000', + t_signature: 'b024f90f73e53c9fee943f3c3ef7a9e3da99bab2f9fa3cbfd5ad05ed79cdbbe21130eb7b27698692bf491a1cf573a518dfa63607dc88bc0c01925fda18304905', + t_SignSignature: null, + t_signatures: null, + confirmations: 717, + dapp_name: 'AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi', + dapp_description: null, + dapp_tags: null, + dapp_link: 'http://www.lisk.io/AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi.zip', + dapp_type: 1, + dapp_category: 2, + dapp_icon: null +}; + +describe('inTransfer', function () { + + var inTransfer; + var dbStub; + + var trs; + var rawTrs; + var sender; + + before(function () { + dbStub = { + query: sinon.stub() + }; + inTransfer = new InTransfer(dbStub, modulesLoader.scope.logger, modulesLoader.scope.schema, modulesLoader.scope.network); + }); + + beforeEach(function () { + dbStub.query.reset(); + }); + + beforeEach(function () { + trs = _.cloneDeep(validTransaction); + rawTrs = _.cloneDeep(rawValidTransaction); + sender = _.cloneDeep(validSender); + }); + + describe('constructor', function () { + + it('should be attach schema and logger to library variable', function () { + new InTransfer(dbStub, modulesLoader.scope.logger, modulesLoader.scope.schema, modulesLoader.scope.network); + var library = InTransfer.__get__('library'); + + expect(library).to.eql({ + db: dbStub, + logger: modulesLoader.scope.logger, + schema: modulesLoader.scope.schema, + network: modulesLoader.scope.network + }); + }); + }); + + describe('bind', function () { + + it('should be okay with empty params', function () { + inTransfer.bind(); + }); + }); + + describe('calculateFee', function () { + + it('should return the correct fee for second signature transaction', function () { + expect(inTransfer.calculateFee(trs)).to.equal(node.constants.fees.dapp); + }); + }); + + describe('verify', function () { + + it('should return error if receipient exists', function (done) { + trs.recipientId = '4835566122337813671L'; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid recipient'); + done(); + }); + }); + + it('should return error if amount is not equal to 0', function (done) { + trs.amount = 1; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid transaction amount'); + done(); + }); + }); + + it('should return error if dapp cateogry is undefined', function (done) { + trs.asset.inTransfer.category = undefined; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid application category'); + done(); + }); + }); + + it('should return error if dapp cateogry not found', function (done) { + trs.asset.dapp.category = 9; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Application category not found'); + done(); + }); + }); + + it('should return error if dapp icon is not link', function (done) { + trs.asset.dapp.icon = 'random string'; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid application icon link'); + done(); + }); + }); + + it('should return error if dapp icon link is invalid', function (done) { + trs.asset.dapp.icon = 'https://www.youtube.com/watch?v=de1-igivvda'; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid application icon file type'); + done(); + }); + }); + + it('should return error if dapp type is invalid', function (done) { + trs.asset.dapp.type = -1; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid application type'); + done(); + }); + }); + + it('should not return error for valid type', function (done) { + trs.asset.dapp.type = 2; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid application type'); + done(); + }); + }); + + it('should return error if dapp link is not actually a link', function (done) { + trs.asset.inTransfer.link = 'random string'; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid application link'); + done(); + }); + }); + + it('should return error if dapp link is invalid', function (done) { + trs.asset.dapp.link = 'https://www.youtube.com/watch?v=de1-igivvda'; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid application file type'); + done(); + }); + }); + + it('should return error if dapp name is blank', function (done) { + trs.asset.dapp.name = ' '; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Application name must not be blank'); + done(); + }); + }); + + it('should return error if dapp name starts and ends with spac', function (done) { + trs.asset.dapp.name = ' randomname '; + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Application name must not be blank'); + done(); + }); + }); + + it('should return error if dapp name is longer than 32 characters', function (done) { + trs.asset.dapp.name = new Array(33).fill('a').join(''); + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Application name is too long. Maximum is 32 characters'); + done(); + }); + }); + + it('should return error if dapp description is longer than 160 characters', function (done) { + trs.asset.dapp.description = new Array(161).fill('a').join(''); + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Application description is too long. Maximum is 160 characters'); + done(); + }); + }); + + it('should return error if dapp tags are longer than 160 characters', function (done) { + trs.asset.dapp.tags = new Array(161).fill('a').join(''); + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Application tags is too long. Maximum is 160 characters'); + done(); + }); + }); + + it('should return error if dapp tags duplicate', function (done) { + trs.asset.dapp.tags = new Array(2).fill('a').join(','); + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Encountered duplicate tag: a in application'); + done(); + }); + }); + + it('should return error if application name already exists', function (done) { + dbStub.query.withArgs(sql.getExisting, { + name: trs.asset.dapp.name, + link: trs.asset.dapp.link || null, + transactionId: trs.id + }).resolves([{ + name: trs.asset.dapp.name + }]); + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Application name already exists: ' + trs.asset.dapp.name); + done(); + }); + }); + + it('should return error if application link already exists', function (done) { + dbStub.query.withArgs(sql.getExisting, { + name: trs.asset.dapp.name, + link: trs.asset.dapp.link || null, + transactionId: trs.id + }).resolves([{}]); + + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Application already exists'); + done(); + }); + }); + + it('should return error if application link already exists', function (done) { + dbStub.query.withArgs(sql.getExisting, { + name: trs.asset.dapp.name, + link: trs.asset.dapp.link || null, + transactionId: trs.id + }).resolves([]); + + inTransfer.verify(trs, sender, function (err, res) { + expect(err).to.not.exist; + expect(res).to.eql(trs); + done(); + }); + }); + }); + + describe('process', function () { + + it('should call the callback', function (done) { + inTransfer.process(trs, sender, done); + }); + }); + + describe('getBytes', function () { + + it('should get bytes of valid transaction', function () { + expect(inTransfer.getBytes(trs).toString('hex')).to.equal('414f37657a42313143674364555a69356f38597a784341746f524c41364669687474703a2f2f7777772e6c69736b2e696f2f414f37657a42313143674364555a69356f38597a784341746f524c413646692e7a69700100000002000000'); + }); + + // Docs say trs size should vary b/w 150 - 200 bytes, while here it's just 93. + it('should get bytes of valid transaction', function () { + expect(inTransfer.getBytes(trs).length).to.equal(136); + }); + }); + + describe('apply', function () { + + var dummyBlock = { + id: '9314232245035524467', + height: 1 + }; + + it('should update unconfirmed name and links private variables', function (done) { + inTransfer.apply(trs, dummyBlock, sender, function () { + var unconfirmedNames = InTransfer.__get__('__private.unconfirmedNames'); + var unconfirmedLinks = InTransfer.__get__('__private.unconfirmedLinks'); + expect(unconfirmedNames[trs.asset.dapp.name]).to.not.exist; + expect(unconfirmedLinks[trs.asset.dapp.link]).to.not.exist; + done(); + }); + }); + }); + + describe('undo', function () { + + var dummyBlock = { + id: '9314232245035524467', + height: 1 + }; + + it('should call the callback function', function (done) { + inTransfer.undo(trs, dummyBlock, sender, function () { + done(); + }); + }); + }); + + describe('applyUnconfirmed', function () { + + it('should return error if unconfirmed names already exists', function (done) { + var dappNames = {}; + var dappLinks = {}; + dappNames[trs.asset.dapp.name] = true; + dappLinks[trs.asset.dapp.link] = false; + + InTransfer.__set__('__private.unconfirmedNames', dappNames); + InTransfer.__set__('__private.unconfirmedLinks', dappLinks); + + inTransfer.applyUnconfirmed(trs, sender, function (err) { + expect(err).to.equal('Application name already exists'); + done(); + }); + }); + + it('should return error if unconfirmed link already exists', function (done) { + var dappNames = {}; + var dappLinks = {}; + dappNames[trs.asset.dapp.name] = false; + dappLinks[trs.asset.dapp.link] = true; + + InTransfer.__set__('__private.unconfirmedNames', dappNames); + InTransfer.__set__('__private.unconfirmedLinks', dappLinks); + + inTransfer.applyUnconfirmed(trs, sender, function (err) { + expect(err).to.equal('Application link already exists'); + done(); + }); + }); + + it('should update unconfirmed name and links private variable', function (done) { + var dappNames = {}; + var dappLinks = {}; + dappNames[trs.asset.dapp.name] = false; + dappLinks[trs.asset.dapp.link] = false; + + InTransfer.__set__('__private.unconfirmedNames', dappNames); + InTransfer.__set__('__private.unconfirmedLinks', dappLinks); + + inTransfer.applyUnconfirmed(trs, sender, function () { + var unconfirmedNames = InTransfer.__get__('__private.unconfirmedNames'); + var unconfirmedLinks = InTransfer.__get__('__private.unconfirmedLinks'); + expect(unconfirmedNames[trs.asset.dapp.name]).to.equal(true); + expect(unconfirmedLinks[trs.asset.dapp.link]).to.equal(true); + done(); + }); + }); + }); + + describe('undoUnconfirmed', function () { + + it('should update unconfirmed name and links private variables', function (done) { + + var dappNames = {}; + var dappLinks = {}; + dappNames[trs.asset.dapp.name] = true; + dappLinks[trs.asset.dapp.link] = true; + + InTransfer.__set__('__private.unconfirmedNames', dappNames); + InTransfer.__set__('__private.unconfirmedLinks', dappLinks); + + inTransfer.undoUnconfirmed(trs, sender, function () { + var unconfirmedNames = InTransfer.__get__('__private.unconfirmedNames'); + var unconfirmedLinks = InTransfer.__get__('__private.unconfirmedLinks'); + expect(unconfirmedNames[trs.asset.dapp.name]).to.not.exist; + expect(unconfirmedLinks[trs.asset.dapp.link]).to.not.exist; + done(); + }); + }); + }); + + describe('objectNormalize', function () { + + it('should use the correct format to validate against', function () { + var library = InTransfer.__get__('library'); + var schemaSpy = sinon.spy(library.schema, 'validate'); + inTransfer.objectNormalize(trs); + expect(schemaSpy.calledOnce).to.equal(true); + expect(schemaSpy.calledWithExactly(trs.asset.dapp, InTransfer.prototype.schema)).to.equal(true); + schemaSpy.restore(); + }); + + it('should return error asset schema is invalid', function () { + trs.asset.dapp.tags = 2; + + expect(function () { + inTransfer.objectNormalize(trs); + }).to.throw('Failed to validate dapp schema: Expected type string but found type integer'); + }); + + it('should return transaction when asset is valid', function () { + expect(inTransfer.objectNormalize(trs)).to.eql(trs); + }); + }); + + describe('dbRead', function () { + + it('should return null publicKey is not set ', function () { + delete rawTrs.dapp_name; + + expect(inTransfer.dbRead(rawTrs)).to.eql(null); + }); + + it('should be okay for valid input', function () { + expect(inTransfer.dbRead(rawTrs)).to.eql({ + dapp: { + category: 2, + description: null, + icon: null, + link: 'http://www.lisk.io/AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi.zip', + name: 'AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi', + tags: null, + type: 1 + } + }); + }); + }); + + describe('dbSave', function () { + + it('should be okay for valid input', function () { + expect(inTransfer.dbSave(trs)).to.eql({ + table: 'dapps', + fields: [ + 'type', + 'name', + 'description', + 'tags', + 'link', + 'category', + 'icon', + 'transactionId' + ], + values: { + type: trs.asset.dapp.type, + name: trs.asset.dapp.name, + description: trs.asset.dapp.description || null, + tags: trs.asset.dapp.tags || null, + link: trs.asset.dapp.link || null, + icon: trs.asset.dapp.icon || null, + category: trs.asset.dapp.category, + transactionId: trs.id + } + }); + }); + }); + + describe('ready', function () { + + it('should return true for single signature trs', function () { + expect(inTransfer.ready(trs, sender)).to.equal(true); + }); + + it('should return false for multi signature transaction with less signatures', function () { + sender.multisignatures = [validKeypair.publicKey.toString('hex')]; + + expect(inTransfer.ready(trs, sender)).to.equal(false); + }); + + it('should return true for multi signature transaction with alteast min signatures', function () { + sender.multisignatures = [validKeypair.publicKey.toString('hex')]; + sender.multimin = 1; + + delete trs.signature; + // Not really correct signature, but we are not testing that over here + trs.signature = crypto.randomBytes(64).toString('hex');; + trs.signatures = [crypto.randomBytes(64).toString('hex')]; + + expect(inTransfer.ready(trs, sender)).to.equal(true); + }); + }); +}); From 93d105d7367134fec600dc5cedf6f8d27b4bfac7 Mon Sep 17 00:00:00 2001 From: Usman Khan Date: Tue, 5 Sep 2017 15:09:39 +0200 Subject: [PATCH 2/9] Updated tests for intransfer transaction --- logic/inTransfer.js | 2 +- test/unit/logic/intransfer.js | 448 +++++++++++++--------------------- 2 files changed, 173 insertions(+), 277 deletions(-) diff --git a/logic/inTransfer.js b/logic/inTransfer.js index ee6b219db58..d28564702fb 100644 --- a/logic/inTransfer.js +++ b/logic/inTransfer.js @@ -217,7 +217,7 @@ InTransfer.prototype.objectNormalize = function (trs) { var report = library.schema.validate(trs.asset.inTransfer, InTransfer.prototype.schema); if (!report) { - throw 'Failed to validate inTransfer schema: ' + this.scope.schema.getLastErrors().map(function (err) { + throw 'Failed to validate inTransfer schema: ' + library.schema.getLastErrors().map(function (err) { return err.message; }).join(', '); } diff --git a/test/unit/logic/intransfer.js b/test/unit/logic/intransfer.js index fcfc59d9ffd..b4fb15fe5c8 100644 --- a/test/unit/logic/intransfer.js +++ b/test/unit/logic/intransfer.js @@ -9,6 +9,7 @@ var sinon = require('sinon'); var node = require('./../../node.js'); var ed = require('../../../helpers/ed'); +var slots = require('../../../helpers/slots.js'); var modulesLoader = require('../../common/initModule').modulesLoader; var InTransfer = rewire('../../../logic/inTransfer.js'); @@ -18,74 +19,67 @@ var validPassword = 'robust weapon course unknown head trial pencil latin acid'; var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); var validSender = { - password: 'yjyhgnu32jmwuii442t9', - secondPassword: 'kub8gm2w330pvptx1or', - username: 'mix8', - publicKey: '5ff3c8f4be105953301e505d23a6e1920da9f72dc8dfd7babe1481b662f2b081', - address: '4835566122337813671L', - secondPublicKey: 'ebfb1157f9f9ad223b1c7468b0d643663ec5a34ac7a6d557243834ae604d72b7' + balance: '0', + password: 'zdv72jrts9y8613e4s4i', + secondPassword: '33ibzztls7xlrocpzxgvi', + username: '9bzuu', + publicKey: '967e00fbf215b6227a6521226decfdc14c92cb88d35268787a47ff0e6b92f94a', + address: '17603529232728446942L', + secondPublicKey: 'b9aa5c8d1e1cbcf97eb6393cda8315b7d35cecbc8e2eb0629fa3cf80df4cdda7' }; var senderHash = crypto.createHash('sha256').update(validSender.password, 'utf8').digest(); var senderKeypair = ed.makeKeypair(senderHash); -var validTransaction = { - id: '1907088915785679339', - height: 371, - blockId: '17233974955873751907', - type: 5, - timestamp: 40081792, - senderPublicKey: '644485a01cb11e06a1f4ffef90a7ba251e56d54eb06a0cb2ecb5693a8cc163a2', - senderId: '5519106118231224961L', +var validTransaction = { + id: '2273003018673898961', + height: 843, + blockId: '11870363750006389009', + type: 6, + timestamp: 40420761, + senderPublicKey: '6dc3f3f8bcf9fb689a1ec6703ed08c649cdc98619ac4689794bf72b579d6cf25', + requesterPublicKey: undefined, + senderId: '2623857243537009424L', recipientId: null, recipientPublicKey: null, - amount: 0, - fee: 2500000000, - signature: 'b024f90f73e53c9fee943f3c3ef7a9e3da99bab2f9fa3cbfd5ad05ed79cdbbe21130eb7b27698692bf491a1cf573a518dfa63607dc88bc0c01925fda18304905', + amount: 999, + fee: 10000000, + signature: '46b57a56f3a61c815224e4396c9c39316ca62568951f84c2e7404225cf67c489f517db6a848a0a5fd4f311b98102c36098543cecb277c7d039a07ed069d90b0b', + signSignature: undefined, signatures: [], - confirmations: 717, + confirmations: 113, asset: { - dapp: { - name: 'AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi', - description: null, - tags: null, - type: 1, - link: 'http://www.lisk.io/AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi.zip', - category: 2, - icon: null + inTransfer:{ + dappId: '7400202127695414450' } } }; var rawValidTransaction = { - t_id: '1907088915785679339', - b_height: 371, - t_blockId: '17233974955873751907', - t_type: 5, - t_timestamp: 40081792, - t_senderPublicKey: '644485a01cb11e06a1f4ffef90a7ba251e56d54eb06a0cb2ecb5693a8cc163a2', + t_id: '2273003018673898961', + b_height: 843, + t_blockId: '11870363750006389009', + t_type: 6, + t_timestamp: 40420761, + t_senderPublicKey: '6dc3f3f8bcf9fb689a1ec6703ed08c649cdc98619ac4689794bf72b579d6cf25', m_recipientPublicKey: null, - t_senderId: '5519106118231224961L', + t_senderId: '2623857243537009424L', t_recipientId: null, - t_amount: '0', - t_fee: '2500000000', - t_signature: 'b024f90f73e53c9fee943f3c3ef7a9e3da99bab2f9fa3cbfd5ad05ed79cdbbe21130eb7b27698692bf491a1cf573a518dfa63607dc88bc0c01925fda18304905', + t_amount: '999', + t_fee: '10000000', + t_signature: '46b57a56f3a61c815224e4396c9c39316ca62568951f84c2e7404225cf67c489f517db6a848a0a5fd4f311b98102c36098543cecb277c7d039a07ed069d90b0b', t_SignSignature: null, t_signatures: null, - confirmations: 717, - dapp_name: 'AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi', - dapp_description: null, - dapp_tags: null, - dapp_link: 'http://www.lisk.io/AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi.zip', - dapp_type: 1, - dapp_category: 2, - dapp_icon: null + confirmations: 113, + in_dappId: '7400202127695414450' }; describe('inTransfer', function () { var inTransfer; var dbStub; + var sharedStub; + var accountsStub; var trs; var rawTrs; @@ -93,13 +87,28 @@ describe('inTransfer', function () { before(function () { dbStub = { - query: sinon.stub() + query: sinon.stub(), + one: sinon.stub() }; - inTransfer = new InTransfer(dbStub, modulesLoader.scope.logger, modulesLoader.scope.schema, modulesLoader.scope.network); + + sharedStub = { + getGenesis: sinon.stub() + }; + + accountsStub = { + mergeAccountAndGet: sinon.stub(), + getAccount: sinon.stub() + }; + inTransfer = new InTransfer(dbStub, modulesLoader.scope.schema); + inTransfer.bind(accountsStub, sharedStub); }); beforeEach(function () { + dbStub.one.reset(); dbStub.query.reset(); + sharedStub.getGenesis.reset(); + accountsStub.mergeAccountAndGet.reset(); + accountsStub.getAccount.reset(); }); beforeEach(function () { @@ -111,14 +120,13 @@ describe('inTransfer', function () { describe('constructor', function () { it('should be attach schema and logger to library variable', function () { - new InTransfer(dbStub, modulesLoader.scope.logger, modulesLoader.scope.schema, modulesLoader.scope.network); + new InTransfer(dbStub, modulesLoader.scope.schema); var library = InTransfer.__get__('library'); + expect(library).to.eql({ db: dbStub, - logger: modulesLoader.scope.logger, schema: modulesLoader.scope.schema, - network: modulesLoader.scope.network }); }); }); @@ -128,12 +136,22 @@ describe('inTransfer', function () { it('should be okay with empty params', function () { inTransfer.bind(); }); + + it('should bind dependent module mocks', function () { + inTransfer.bind(accountsStub, sharedStub); + var privateShared = InTransfer.__get__('shared'); + var privateModules = InTransfer.__get__('modules'); + expect(privateShared).to.eql(sharedStub); + expect(privateModules).to.eql({ + accounts: accountsStub + }); + }); }); describe('calculateFee', function () { it('should return the correct fee for second signature transaction', function () { - expect(inTransfer.calculateFee(trs)).to.equal(node.constants.fees.dapp); + expect(inTransfer.calculateFee(trs)).to.equal(node.constants.fees.send); }); }); @@ -148,8 +166,8 @@ describe('inTransfer', function () { }); }); - it('should return error if amount is not equal to 0', function (done) { - trs.amount = 1; + it('should return error if amount is undefined', function (done) { + trs.amount = undefined; inTransfer.verify(trs, sender, function (err) { expect(err).to.equal('Invalid transaction amount'); @@ -157,170 +175,70 @@ describe('inTransfer', function () { }); }); - it('should return error if dapp cateogry is undefined', function (done) { - trs.asset.inTransfer.category = undefined; - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid application category'); - done(); - }); - }); - - it('should return error if dapp cateogry not found', function (done) { - trs.asset.dapp.category = 9; - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Application category not found'); - done(); - }); - }); - - it('should return error if dapp icon is not link', function (done) { - trs.asset.dapp.icon = 'random string'; - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid application icon link'); - done(); - }); - }); - - it('should return error if dapp icon link is invalid', function (done) { - trs.asset.dapp.icon = 'https://www.youtube.com/watch?v=de1-igivvda'; - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid application icon file type'); - done(); - }); - }); - - it('should return error if dapp type is invalid', function (done) { - trs.asset.dapp.type = -1; - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid application type'); - done(); - }); - }); - - it('should not return error for valid type', function (done) { - trs.asset.dapp.type = 2; - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid application type'); - done(); - }); - }); - - it('should return error if dapp link is not actually a link', function (done) { - trs.asset.inTransfer.link = 'random string'; - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid application link'); - done(); - }); - }); - - it('should return error if dapp link is invalid', function (done) { - trs.asset.dapp.link = 'https://www.youtube.com/watch?v=de1-igivvda'; - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid application file type'); - done(); - }); - }); - - it('should return error if dapp name is blank', function (done) { - trs.asset.dapp.name = ' '; + it('should return error if amount is equal to 0', function (done) { + trs.amount = 0; inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Application name must not be blank'); + expect(err).to.equal('Invalid transaction amount'); done(); }); }); - it('should return error if dapp name starts and ends with spac', function (done) { - trs.asset.dapp.name = ' randomname '; + it('should return error if asset is undefined', function (done) { + trs.asset.inTransfer = undefined; inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Application name must not be blank'); + expect(err).to.equal('Invalid transaction asset'); done(); }); }); - it('should return error if dapp name is longer than 32 characters', function (done) { - trs.asset.dapp.name = new Array(33).fill('a').join(''); + it('should return error if intransfer property is undefined', function (done) { + trs.asset.inTransfer = undefined; inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Application name is too long. Maximum is 32 characters'); + expect(err).to.equal('Invalid transaction asset'); done(); }); }); - it('should return error if dapp description is longer than 160 characters', function (done) { - trs.asset.dapp.description = new Array(161).fill('a').join(''); + it('should return error if intransfer property is equal to 0', function (done) { + trs.asset.inTransfer = 0; inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Application description is too long. Maximum is 160 characters'); + expect(err).to.equal('Invalid transaction asset'); done(); }); }); - it('should return error if dapp tags are longer than 160 characters', function (done) { - trs.asset.dapp.tags = new Array(161).fill('a').join(''); + it('should return error if dapp does not exist', function (done) { + trs.asset.inTransfer.dappId = '10223892440757987952'; + console.log(' sql.countByTransactionId'); + console.log( sql.countByTransactionId); + console.log('{ id: trs.asset.inTransfer.dappId } '); + console.log({ id: trs.asset.inTransfer.dappId } ); - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Application tags is too long. Maximum is 160 characters'); - done(); + dbStub.one.withArgs(sql.countByTransactionId, { + id: trs.asset.inTransfer.dappId + }).resolves({ + count: 0 }); - }); - - it('should return error if dapp tags duplicate', function (done) { - trs.asset.dapp.tags = new Array(2).fill('a').join(','); inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Encountered duplicate tag: a in application'); + expect(err).to.equal('Application not found: ' + trs.asset.inTransfer.dappId); done(); }); }); - it('should return error if application name already exists', function (done) { - dbStub.query.withArgs(sql.getExisting, { - name: trs.asset.dapp.name, - link: trs.asset.dapp.link || null, - transactionId: trs.id - }).resolves([{ - name: trs.asset.dapp.name - }]); - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Application name already exists: ' + trs.asset.dapp.name); - done(); + it('should be okay with valid transaction', function (done) { + dbStub.one.withArgs(sql.countByTransactionId, { + id: trs.asset.inTransfer.dappId + }).resolves({ + count: 1 }); - }); - - it('should return error if application link already exists', function (done) { - dbStub.query.withArgs(sql.getExisting, { - name: trs.asset.dapp.name, - link: trs.asset.dapp.link || null, - transactionId: trs.id - }).resolves([{}]); inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Application already exists'); - done(); - }); - }); - - it('should return error if application link already exists', function (done) { - dbStub.query.withArgs(sql.getExisting, { - name: trs.asset.dapp.name, - link: trs.asset.dapp.link || null, - transactionId: trs.id - }).resolves([]); - - inTransfer.verify(trs, sender, function (err, res) { expect(err).to.not.exist; - expect(res).to.eql(trs); done(); }); }); @@ -336,12 +254,11 @@ describe('inTransfer', function () { describe('getBytes', function () { it('should get bytes of valid transaction', function () { - expect(inTransfer.getBytes(trs).toString('hex')).to.equal('414f37657a42313143674364555a69356f38597a784341746f524c41364669687474703a2f2f7777772e6c69736b2e696f2f414f37657a42313143674364555a69356f38597a784341746f524c413646692e7a69700100000002000000'); + expect(inTransfer.getBytes(trs).toString('hex')).to.equal('37343030323032313237363935343134343530'); }); - // Docs say trs size should vary b/w 150 - 200 bytes, while here it's just 93. it('should get bytes of valid transaction', function () { - expect(inTransfer.getBytes(trs).length).to.equal(136); + expect(inTransfer.getBytes(trs).length).to.be.lte(20); }); }); @@ -352,101 +269,98 @@ describe('inTransfer', function () { height: 1 }; - it('should update unconfirmed name and links private variables', function (done) { - inTransfer.apply(trs, dummyBlock, sender, function () { - var unconfirmedNames = InTransfer.__get__('__private.unconfirmedNames'); - var unconfirmedLinks = InTransfer.__get__('__private.unconfirmedLinks'); - expect(unconfirmedNames[trs.asset.dapp.name]).to.not.exist; - expect(unconfirmedLinks[trs.asset.dapp.link]).to.not.exist; + it('should return error if dapp does not exist', function (done) { + var error = 'Application genesis block not found'; + sharedStub.getGenesis.withArgs({ + dappid: trs.asset.inTransfer.dappId + }, sinon.match.any).yields(error); + + inTransfer.apply(trs, dummyBlock, sender, function (err) { + expect(err).to.equal(error); done(); }); }); - }); - describe('undo', function () { + it('should update account with correct params', function (done) { + sharedStub.getGenesis.withArgs({ + dappid: trs.asset.inTransfer.dappId + }, sinon.match.any).yields(null, { + authorId: validSender.address + }); - var dummyBlock = { - id: '9314232245035524467', - height: 1 - }; + accountsStub.mergeAccountAndGet.withArgs({ + address: validSender.address, + balance: trs.amount, + u_balance: trs.amount, + blockId: dummyBlock.id, + round: slots.calcRound(dummyBlock.height) + }).yields(null); - it('should call the callback function', function (done) { - inTransfer.undo(trs, dummyBlock, sender, function () { + inTransfer.apply(trs, dummyBlock, sender, function (err) { + expect(err).to.not.exist; + expect(accountsStub.mergeAccountAndGet.calledOnce).to.equal(true); done(); }); }); }); - describe('applyUnconfirmed', function () { + describe('undo', function () { - it('should return error if unconfirmed names already exists', function (done) { - var dappNames = {}; - var dappLinks = {}; - dappNames[trs.asset.dapp.name] = true; - dappLinks[trs.asset.dapp.link] = false; + var dummyBlock = { + id: '9314232245035524467', + height: 1 + }; - InTransfer.__set__('__private.unconfirmedNames', dappNames); - InTransfer.__set__('__private.unconfirmedLinks', dappLinks); + it('should return error if dapp does not exist', function (done) { + var error = 'Application genesis block not found'; + sharedStub.getGenesis.withArgs({ + dappid: trs.asset.inTransfer.dappId + }, sinon.match.any).yields(error); - inTransfer.applyUnconfirmed(trs, sender, function (err) { - expect(err).to.equal('Application name already exists'); + inTransfer.undo(trs, dummyBlock, sender, function (err) { + expect(err).to.equal(error); done(); }); }); - it('should return error if unconfirmed link already exists', function (done) { - var dappNames = {}; - var dappLinks = {}; - dappNames[trs.asset.dapp.name] = false; - dappLinks[trs.asset.dapp.link] = true; - - InTransfer.__set__('__private.unconfirmedNames', dappNames); - InTransfer.__set__('__private.unconfirmedLinks', dappLinks); - - inTransfer.applyUnconfirmed(trs, sender, function (err) { - expect(err).to.equal('Application link already exists'); - done(); + it('should update account with correct params', function (done) { + sharedStub.getGenesis.withArgs({ + dappid: trs.asset.inTransfer.dappId + }, sinon.match.any).yields(null, { + authorId: validSender.address }); - }); - it('should update unconfirmed name and links private variable', function (done) { - var dappNames = {}; - var dappLinks = {}; - dappNames[trs.asset.dapp.name] = false; - dappLinks[trs.asset.dapp.link] = false; + accountsStub.getAccount.withArgs({ + address: sender.address + }, sinon.match.any).yields(); - InTransfer.__set__('__private.unconfirmedNames', dappNames); - InTransfer.__set__('__private.unconfirmedLinks', dappLinks); + accountsStub.mergeAccountAndGet.withArgs({ + address: validSender.address, + balance: trs.amount, + u_balance: trs.amount, + blockId: dummyBlock.id, + round: slots.calcRound(dummyBlock.height) + }).yields(null); - inTransfer.applyUnconfirmed(trs, sender, function () { - var unconfirmedNames = InTransfer.__get__('__private.unconfirmedNames'); - var unconfirmedLinks = InTransfer.__get__('__private.unconfirmedLinks'); - expect(unconfirmedNames[trs.asset.dapp.name]).to.equal(true); - expect(unconfirmedLinks[trs.asset.dapp.link]).to.equal(true); + inTransfer.apply(trs, dummyBlock, sender, function (err) { + expect(err).to.not.exist; + expect(accountsStub.mergeAccountAndGet.calledOnce).to.equal(true); done(); }); }); }); - describe('undoUnconfirmed', function () { - - it('should update unconfirmed name and links private variables', function (done) { + describe('applyUnconfirmed', function () { - var dappNames = {}; - var dappLinks = {}; - dappNames[trs.asset.dapp.name] = true; - dappLinks[trs.asset.dapp.link] = true; + it('should call the callback function', function (done) { + inTransfer.applyUnconfirmed(trs, sender, done); + }); + }); - InTransfer.__set__('__private.unconfirmedNames', dappNames); - InTransfer.__set__('__private.unconfirmedLinks', dappLinks); + describe('undoUnconfirmed', function () { - inTransfer.undoUnconfirmed(trs, sender, function () { - var unconfirmedNames = InTransfer.__get__('__private.unconfirmedNames'); - var unconfirmedLinks = InTransfer.__get__('__private.unconfirmedLinks'); - expect(unconfirmedNames[trs.asset.dapp.name]).to.not.exist; - expect(unconfirmedLinks[trs.asset.dapp.link]).to.not.exist; - done(); - }); + it('should call the callback function', function (done) { + inTransfer.undoUnconfirmed(trs, sender, done); }); }); @@ -457,16 +371,16 @@ describe('inTransfer', function () { var schemaSpy = sinon.spy(library.schema, 'validate'); inTransfer.objectNormalize(trs); expect(schemaSpy.calledOnce).to.equal(true); - expect(schemaSpy.calledWithExactly(trs.asset.dapp, InTransfer.prototype.schema)).to.equal(true); + expect(schemaSpy.calledWithExactly(trs.asset.inTransfer, InTransfer.prototype.schema)).to.equal(true); schemaSpy.restore(); }); it('should return error asset schema is invalid', function () { - trs.asset.dapp.tags = 2; + trs.asset.inTransfer.dappId = 2; expect(function () { inTransfer.objectNormalize(trs); - }).to.throw('Failed to validate dapp schema: Expected type string but found type integer'); + }).to.throw('Failed to validate inTransfer schema: Expected type string but found type integer'); }); it('should return transaction when asset is valid', function () { @@ -476,22 +390,16 @@ describe('inTransfer', function () { describe('dbRead', function () { - it('should return null publicKey is not set ', function () { - delete rawTrs.dapp_name; + it('should return null dappId does not exist', function () { + delete rawTrs.in_dappId; expect(inTransfer.dbRead(rawTrs)).to.eql(null); }); it('should be okay for valid input', function () { expect(inTransfer.dbRead(rawTrs)).to.eql({ - dapp: { - category: 2, - description: null, - icon: null, - link: 'http://www.lisk.io/AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi.zip', - name: 'AO7ezB11CgCdUZi5o8YzxCAtoRLA6Fi', - tags: null, - type: 1 + inTransfer: { + dappId: trs.asset.inTransfer.dappId } }); }); @@ -501,25 +409,13 @@ describe('inTransfer', function () { it('should be okay for valid input', function () { expect(inTransfer.dbSave(trs)).to.eql({ - table: 'dapps', + table: 'intransfer', fields: [ - 'type', - 'name', - 'description', - 'tags', - 'link', - 'category', - 'icon', + 'dappId', 'transactionId' ], values: { - type: trs.asset.dapp.type, - name: trs.asset.dapp.name, - description: trs.asset.dapp.description || null, - tags: trs.asset.dapp.tags || null, - link: trs.asset.dapp.link || null, - icon: trs.asset.dapp.icon || null, - category: trs.asset.dapp.category, + dappId: trs.asset.inTransfer.dappId, transactionId: trs.id } }); From bcce9302a5375bf61726cc53414646cdbe080499 Mon Sep 17 00:00:00 2001 From: Usman Khan Date: Thu, 14 Sep 2017 16:33:41 +0200 Subject: [PATCH 3/9] Fixed typo in test --- test/unit/logic/intransfer.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/unit/logic/intransfer.js b/test/unit/logic/intransfer.js index b4fb15fe5c8..8a437f1f992 100644 --- a/test/unit/logic/intransfer.js +++ b/test/unit/logic/intransfer.js @@ -185,7 +185,7 @@ describe('inTransfer', function () { }); it('should return error if asset is undefined', function (done) { - trs.asset.inTransfer = undefined; + trs.asset = undefined; inTransfer.verify(trs, sender, function (err) { expect(err).to.equal('Invalid transaction asset'); @@ -213,10 +213,6 @@ describe('inTransfer', function () { it('should return error if dapp does not exist', function (done) { trs.asset.inTransfer.dappId = '10223892440757987952'; - console.log(' sql.countByTransactionId'); - console.log( sql.countByTransactionId); - console.log('{ id: trs.asset.inTransfer.dappId } '); - console.log({ id: trs.asset.inTransfer.dappId } ); dbStub.one.withArgs(sql.countByTransactionId, { id: trs.asset.inTransfer.dappId From 09e816677a0c0648ba0c0803a5e81b61d1de3f77 Mon Sep 17 00:00:00 2001 From: Maciej Baj Date: Fri, 6 Oct 2017 11:34:34 +0200 Subject: [PATCH 4/9] Add empty unit test skeletons --- .../logic/{intransfer.js => inTransfer.js} | 290 ++++++++++++++++-- 1 file changed, 263 insertions(+), 27 deletions(-) rename test/unit/logic/{intransfer.js => inTransfer.js} (59%) diff --git a/test/unit/logic/intransfer.js b/test/unit/logic/inTransfer.js similarity index 59% rename from test/unit/logic/intransfer.js rename to test/unit/logic/inTransfer.js index 8a437f1f992..269d309280d 100644 --- a/test/unit/logic/intransfer.js +++ b/test/unit/logic/inTransfer.js @@ -84,6 +84,7 @@ describe('inTransfer', function () { var trs; var rawTrs; var sender; + var dummyBlock; before(function () { dbStub = { @@ -115,10 +116,21 @@ describe('inTransfer', function () { trs = _.cloneDeep(validTransaction); rawTrs = _.cloneDeep(rawValidTransaction); sender = _.cloneDeep(validSender); + dummyBlock = { + id: '9314232245035524467', + height: 1 + }; }); describe('constructor', function () { + describe('library', function () { + + it('should assign db'); + + it('should assign schema'); + }); + it('should be attach schema and logger to library variable', function () { new InTransfer(dbStub, modulesLoader.scope.schema); var library = InTransfer.__get__('library'); @@ -133,6 +145,13 @@ describe('inTransfer', function () { describe('bind', function () { + describe('modules', function () { + + it('should assign accounts'); + }); + + it('should assign shared'); + it('should be okay with empty params', function () { inTransfer.bind(); }); @@ -150,6 +169,8 @@ describe('inTransfer', function () { describe('calculateFee', function () { + it('should return constants.fees.send'); + it('should return the correct fee for second signature transaction', function () { expect(inTransfer.calculateFee(trs)).to.equal(node.constants.fees.send); }); @@ -157,6 +178,62 @@ describe('inTransfer', function () { describe('verify', function () { + describe('when trs.recipientId exists', function () { + + it('should call callback with error = "Invalid recipient"'); + }); + + describe('when trs.amount does not exist', function () { + + it('should call callback with error = "Invalid transaction amount"'); + }); + + describe('when trs.amount = 0', function () { + + it('should call callback with error = "Invalid transaction amount"'); + }); + + describe('when trs.asset does not exist', function () { + + it('should call callback with error = "Invalid transaction asset"'); + }); + + describe('when trs.asset.inTransfer does not exist', function () { + + it('should call callback with error = "Invalid transaction asset"'); + }); + + describe('when trs.asset.inTransfer = 0', function () { + + it('should call callback with error = "Invalid transaction asset"'); + }); + + it('should call library.db.one'); + + it('should call library.db.one with sql.countByTransactionId'); + + it('should call library.db.one with {id: trs.asset.inTransfer.dappId}'); + + describe('when library.db.one fails', function () { + + it('should call callback with error'); + }); + + describe('when library.db.one succeeds', function () { + + describe('when dapp exists', function () { + + it('should call callback with error = undefined'); + + it('should call callback with result = undefined'); + }); + + describe('when dapp does not exist', function () { + + it('should call callback with error'); + }); + }); + it('should return error if receipient exists', function (done) { trs.recipientId = '4835566122337813671L'; @@ -242,31 +319,92 @@ describe('inTransfer', function () { describe('process', function () { - it('should call the callback', function (done) { - inTransfer.process(trs, sender, done); + it('should call callback with error = null', function (done) { + inTransfer.process(trs, sender, function (err) { + expect(err).to.be.null; + done(); + }); + }); + + it('should call callback with result = transaction', function (done) { + inTransfer.process(trs, sender, function (err, result) { + expect(result).to.eql(trs); + done(); + }); }); }); describe('getBytes', function () { - it('should get bytes of valid transaction', function () { - expect(inTransfer.getBytes(trs).toString('hex')).to.equal('37343030323032313237363935343134343530'); + describe('when trs.asset.inTransfer.dappId = undefined', function () { + + beforeEach(function () { + trs.asset.inTransfer.dappId = undefined; + }); + + it('should throw', function () { + expect(inTransfer.getBytes.bind(null, trs)).to.throw; + }); }); - it('should get bytes of valid transaction', function () { - expect(inTransfer.getBytes(trs).length).to.be.lte(20); + describe('when trs.asset.inTransfer.dappId is a valid dapp id', function () { + + it('should not throw', function () { + expect(inTransfer.getBytes.bind(null, trs)).not.to.throw; + }); + + it('should get bytes of valid transaction', function () { + expect(inTransfer.getBytes(trs).toString('utf8')).to.equal(validTransaction.asset.inTransfer.dappId); + }); + + it('should return result as a Buffer type', function () { + expect(inTransfer.getBytes(trs)).to.be.instanceOf(Buffer); + }); }); }); describe('apply', function () { - var dummyBlock = { - id: '9314232245035524467', - height: 1 - }; + it('should call shared.getGenesis'); + + it('should call shared.getGenesis with {dappid: trs.asset.inTransfer.dappId}'); + + describe('when shared.getGenesis fails', function () { + + it('should call callback with error'); + }); + + describe('when shared.getGenesis succeeds', function () { + + it('should call modules.accounts.mergeAccountAndGet'); + + it('should call modules.accounts.mergeAccountAndGet with address = dapp.authorId'); + + it('should call modules.accounts.mergeAccountAndGet with balance = trs.amount'); + + it('should call modules.accounts.mergeAccountAndGet with u_balance = trs.amount'); + + it('should call modules.accounts.mergeAccountAndGet with blockId = block.id'); + + it('should call modules.accounts.mergeAccountAndGet with round = slots.calcRound result'); + + describe('when modules.accounts.mergeAccountAndGet fails', function () { + + it('should call callback with error'); + }); + + describe('when modules.accounts.mergeAccountAndGet succeeds', function () { + + it('should call callback with error = undefined'); + + it('should call callback with result = undefined'); + }); + }); it('should return error if dapp does not exist', function (done) { + var error = 'Application genesis block not found'; + sharedStub.getGenesis.withArgs({ dappid: trs.asset.inTransfer.dappId }, sinon.match.any).yields(error); @@ -302,10 +440,41 @@ describe('inTransfer', function () { describe('undo', function () { - var dummyBlock = { - id: '9314232245035524467', - height: 1 - }; + it('should call shared.getGenesis'); + + it('should call shared.getGenesis with {dappid: trs.asset.inTransfer.dappId}'); + + describe('when shared.getGenesis fails', function () { + + it('should call callback with error'); + }); + + describe('when shared.getGenesis succeeds', function () { + + it('should call modules.accounts.mergeAccountAndGet'); + + it('should call modules.accounts.mergeAccountAndGet with address = dapp.authorId'); + + it('should call modules.accounts.mergeAccountAndGet with balance = trs.amount'); + + it('should call modules.accounts.mergeAccountAndGet with u_balance = trs.amount'); + + it('should call modules.accounts.mergeAccountAndGet with blockId = block.id'); + + it('should call modules.accounts.mergeAccountAndGet with round = slots.calcRound result'); + + describe('when modules.accounts.mergeAccountAndGet fails', function () { + + it('should call callback with error'); + }); + + describe('when modules.accounts.mergeAccountAndGet succeeds', function () { + + it('should call callback with error = undefined'); + + it('should call callback with result = undefined'); + }); + }); it('should return error if dapp does not exist', function (done) { var error = 'Application genesis block not found'; @@ -348,20 +517,58 @@ describe('inTransfer', function () { describe('applyUnconfirmed', function () { - it('should call the callback function', function (done) { - inTransfer.applyUnconfirmed(trs, sender, done); + it('should call callback with error = undefined', function (done) { + inTransfer.applyUnconfirmed(trs, sender, function (err) { + expect(err).to.be.undefined; + done(); + }); + }); + + it('should call callback with result = undefined', function (done) { + inTransfer.applyUnconfirmed(trs, sender, function (err, result) { + expect(result).to.be.undefined; + done(); + }); }); }); describe('undoUnconfirmed', function () { - it('should call the callback function', function (done) { - inTransfer.undoUnconfirmed(trs, sender, done); + it('should call callback with error = undefined', function (done) { + inTransfer.undoUnconfirmed(trs, sender, function (err) { + expect(err).to.be.undefined; + done(); + }); + }); + + it('should call callback with result = undefined', function (done) { + inTransfer.undoUnconfirmed(trs, sender, function (err, result) { + expect(result).to.be.undefined; + done(); + }); }); }); describe('objectNormalize', function () { + it('should call library.schema.validate'); + + it('should call library.schema.validate with trs.asset.inTransfer'); + + it('should call library.schema.validate InTransfer.prototype.schema'); + + describe('when transaction is invalid', function () { + + it('should throw', function () { + + }); + }); + + describe('when transaction is valid', function () { + + it('should return transaction'); + }); + it('should use the correct format to validate against', function () { var library = InTransfer.__get__('library'); var schemaSpy = sinon.spy(library.schema, 'validate'); @@ -386,23 +593,41 @@ describe('inTransfer', function () { describe('dbRead', function () { - it('should return null dappId does not exist', function () { - delete rawTrs.in_dappId; + describe('when raw.in_dappId does not exist', function () { + + beforeEach(function () { + delete rawTrs.in_dappId; + }); - expect(inTransfer.dbRead(rawTrs)).to.eql(null); + it('should return null', function () { + expect(inTransfer.dbRead(rawTrs)).to.eql(null); + }); }); - it('should be okay for valid input', function () { - expect(inTransfer.dbRead(rawTrs)).to.eql({ - inTransfer: { - dappId: trs.asset.inTransfer.dappId - } + describe('when raw.in_dappId exists', function () { + + it('should return result containing inTransfer', function () { + expect(inTransfer.dbRead(rawTrs)).to.have.property('inTransfer'); + }); + + it('should return result containing inTransfer.dappId = raw.dapp_id', function () { + expect(inTransfer.dbRead(rawTrs)).to.have.nested.property('inTransfer.dappId').equal(rawTrs.in_dappId); }); }); }); describe('dbSave', function () { + it('should return result containing table = "intransfer"'); + + it('should return result containing fields = ["dappId", "transactionId"]'); + + it('should return result containing values'); + + it('should return result containing values.dappId = trs.asset.inTransfer.dappId'); + + it('should return result containing values.transactionId = trs.id'); + it('should be okay for valid input', function () { expect(inTransfer.dbSave(trs)).to.eql({ table: 'intransfer', @@ -418,6 +643,17 @@ describe('inTransfer', function () { }); }); + describe('afterSave', function () { + + it('should call callback with error = undefined', function () { + + }); + + it('should call callback with result = undefined', function () { + + }); + }); + describe('ready', function () { it('should return true for single signature trs', function () { @@ -436,7 +672,7 @@ describe('inTransfer', function () { delete trs.signature; // Not really correct signature, but we are not testing that over here - trs.signature = crypto.randomBytes(64).toString('hex');; + trs.signature = crypto.randomBytes(64).toString('hex'); trs.signatures = [crypto.randomBytes(64).toString('hex')]; expect(inTransfer.ready(trs, sender)).to.equal(true); From c8b489acc3266a54bdce8a3d64b832ddb37aa5ed Mon Sep 17 00:00:00 2001 From: Maciej Baj Date: Fri, 6 Oct 2017 15:45:22 +0200 Subject: [PATCH 5/9] Implement inTransfer tests skeletons (except apply/undo) --- test/common/typesRepresentatives.js | 20 +- test/unit/logic/inTransfer.js | 342 ++++++++++++++-------------- 2 files changed, 194 insertions(+), 168 deletions(-) diff --git a/test/common/typesRepresentatives.js b/test/common/typesRepresentatives.js index 0f363944e37..6b4ba8a68c3 100644 --- a/test/common/typesRepresentatives.js +++ b/test/common/typesRepresentatives.js @@ -1,5 +1,7 @@ 'use strict'; +var difference = require('lodash').difference; + var arrays = [ { input: [], @@ -101,6 +103,11 @@ var others = [ input: null, description: 'null', expectation: 'null' + }, + { + input: undefined, + description: 'undefined', + expectation: 'undefined' } ]; @@ -165,14 +172,25 @@ var allTypes = arrays module.exports = { allTypes: allTypes, arrays: arrays, + nonArrays: difference(allTypes, arrays), booleans: booleans, + nonBooleans: difference(allTypes, booleans), positiveIntegers: positiveIntegers, + nonPositiveIntegers: difference(allTypes, positiveIntegers), negativeIntegers: negativeIntegers, + nonNegativeIntegers: difference(allTypes, negativeIntegers), positiveNumbers: positiveNumbers, + nonPositiveNumbers: difference(allTypes, positiveNumbers), negativeNumbers: negativeNumbers, + nonNegativeNumbers: difference(allTypes, negativeNumbers), objects: objects, + nonObjects: difference(allTypes, objects), others: others, + nonOthers: difference(allTypes, others), strings: strings, + nonStrings: difference(allTypes, strings), nonEmptyStrings: nonEmptyStrings, - emptyString: emptyString + nonNonEmptyStrings: difference(allTypes, nonEmptyStrings), + emptyString: emptyString, + nonEmptyString: difference(allTypes, emptyString) }; diff --git a/test/unit/logic/inTransfer.js b/test/unit/logic/inTransfer.js index 269d309280d..71dcd5eb5e6 100644 --- a/test/unit/logic/inTransfer.js +++ b/test/unit/logic/inTransfer.js @@ -11,6 +11,7 @@ var node = require('./../../node.js'); var ed = require('../../../helpers/ed'); var slots = require('../../../helpers/slots.js'); var modulesLoader = require('../../common/initModule').modulesLoader; +var typesRepresentatives = require('../../common/typesRepresentatives'); var InTransfer = rewire('../../../logic/inTransfer.js'); var sql = require('../../../sql/dapps.js'); @@ -86,16 +87,14 @@ describe('inTransfer', function () { var sender; var dummyBlock; - before(function () { + beforeEach(function () { dbStub = { - query: sinon.stub(), - one: sinon.stub() + query: sinon.stub().resolves(), + one: sinon.stub().resolves() }; - sharedStub = { getGenesis: sinon.stub() }; - accountsStub = { mergeAccountAndGet: sinon.stub(), getAccount: sinon.stub() @@ -104,14 +103,6 @@ describe('inTransfer', function () { inTransfer.bind(accountsStub, sharedStub); }); - beforeEach(function () { - dbStub.one.reset(); - dbStub.query.reset(); - sharedStub.getGenesis.reset(); - accountsStub.mergeAccountAndGet.reset(); - accountsStub.getAccount.reset(); - }); - beforeEach(function () { trs = _.cloneDeep(validTransaction); rawTrs = _.cloneDeep(rawValidTransaction); @@ -126,52 +117,49 @@ describe('inTransfer', function () { describe('library', function () { - it('should assign db'); + var library; - it('should assign schema'); - }); - - it('should be attach schema and logger to library variable', function () { - new InTransfer(dbStub, modulesLoader.scope.schema); - var library = InTransfer.__get__('library'); + beforeEach(function () { + new InTransfer(dbStub, modulesLoader.scope.schema); + library = InTransfer.__get__('library'); + }); + it('should assign db', function () { + expect(library).to.have.property('db').eql(dbStub); + }); - expect(library).to.eql({ - db: dbStub, - schema: modulesLoader.scope.schema, + it('should assign schema', function () { + expect(library).to.have.property('schema').eql(modulesLoader.scope.schema); }); }); }); describe('bind', function () { - describe('modules', function () { + var modules; + var shared; - it('should assign accounts'); + beforeEach(function () { + inTransfer.bind(accountsStub, sharedStub); + modules = InTransfer.__get__('modules'); + shared = InTransfer.__get__('shared'); }); - it('should assign shared'); + describe('modules', function () { - it('should be okay with empty params', function () { - inTransfer.bind(); + it('should assign accounts', function () { + expect(modules).to.have.property('accounts').eql(accountsStub); + }); }); - it('should bind dependent module mocks', function () { - inTransfer.bind(accountsStub, sharedStub); - var privateShared = InTransfer.__get__('shared'); - var privateModules = InTransfer.__get__('modules'); - expect(privateShared).to.eql(sharedStub); - expect(privateModules).to.eql({ - accounts: accountsStub - }); + it('should assign shared', function () { + expect(shared).to.eql(sharedStub); }); }); describe('calculateFee', function () { - it('should return constants.fees.send'); - - it('should return the correct fee for second signature transaction', function () { + it('should return constants.fees.send', function () { expect(inTransfer.calculateFee(trs)).to.equal(node.constants.fees.send); }); }); @@ -180,139 +168,140 @@ describe('inTransfer', function () { describe('when trs.recipientId exists', function () { - it('should call callback with error = "Invalid recipient"'); + it('should call callback with error = "Invalid recipient"', function (done) { + trs.recipientId = '4835566122337813671L'; + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid recipient'); + done(); + }); + }); }); describe('when trs.amount does not exist', function () { - it('should call callback with error = "Invalid transaction amount"'); + it('should call callback with error = "Invalid transaction amount"', function (done) { + trs.amount = undefined; + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid transaction amount'); + done(); + }); + }); }); describe('when trs.amount = 0', function () { - it('should call callback with error = "Invalid transaction amount"'); + it('should call callback with error = "Invalid transaction amount"', function (done) { + trs.amount = 0; + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid transaction amount'); + done(); + }); + }); }); describe('when trs.asset does not exist', function () { - it('should call callback with error = "Invalid transaction asset"'); + it('should call callback with error = "Invalid transaction asset"', function (done) { + trs.asset = undefined; + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid transaction asset'); + done(); + }); + }); }); describe('when trs.asset.inTransfer does not exist', function () { - it('should call callback with error = "Invalid transaction asset"'); + it('should call callback with error = "Invalid transaction asset"', function (done) { + trs.asset.inTransfer = undefined; + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid transaction asset'); + done(); + }); + }); }); describe('when trs.asset.inTransfer = 0', function () { - it('should call callback with error = "Invalid transaction asset"'); - }); - - it('should call library.db.one'); - - it('should call library.db.one with sql.countByTransactionId'); - - it('should call library.db.one with {id: trs.asset.inTransfer.dappId}'); - - describe('when library.db.one fails', function () { - - it('should call callback with error'); - }); - - describe('when library.db.one succeeds', function () { - - describe('when dapp exists', function () { - - it('should call callback with error = undefined'); - - it('should call callback with result = undefined'); - }); - - describe('when dapp does not exist', function () { - - it('should call callback with error'); + it('should call callback with error = "Invalid transaction asset"', function (done) { + trs.asset.inTransfer = 0; + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Invalid transaction asset'); + done(); + }); }); }); - it('should return error if receipient exists', function (done) { - trs.recipientId = '4835566122337813671L'; - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid recipient'); + it('should call library.db.one', function (done) { + inTransfer.verify(trs, sender, function () { + expect(dbStub.one.calledOnce).to.be.true; done(); }); }); - it('should return error if amount is undefined', function (done) { - trs.amount = undefined; - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid transaction amount'); + it('should call library.db.one with sql.countByTransactionId', function (done) { + inTransfer.verify(trs, sender, function () { + expect(dbStub.one.calledWith(sql.countByTransactionId)).to.be.true; done(); }); }); - it('should return error if amount is equal to 0', function (done) { - trs.amount = 0; - - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid transaction amount'); + it('should call library.db.one with {id: trs.asset.inTransfer.dappId}', function (done) { + inTransfer.verify(trs, sender, function () { + expect(dbStub.one.args[0][1]).to.eql({id: trs.asset.inTransfer.dappId}); done(); }); }); - it('should return error if asset is undefined', function (done) { - trs.asset = undefined; + describe('when library.db.one fails', function () { - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid transaction asset'); - done(); + beforeEach(function () { + dbStub.one = sinon.stub().rejects('Rejection error'); }); - }); - - it('should return error if intransfer property is undefined', function (done) { - trs.asset.inTransfer = undefined; - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid transaction asset'); - done(); + it('should call callback with error', function (done) { + inTransfer.verify(trs, sender, function (err) { + expect(err).not.to.be.empty; + done(); + }); }); }); - it('should return error if intransfer property is equal to 0', function (done) { - trs.asset.inTransfer = 0; + describe('when library.db.one succeeds', function () { - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Invalid transaction asset'); - done(); - }); - }); + describe('when dapp does not exist', function () { - it('should return error if dapp does not exist', function (done) { - trs.asset.inTransfer.dappId = '10223892440757987952'; + beforeEach(function () { + dbStub.one = sinon.stub().resolves({count: 0}); + }); - dbStub.one.withArgs(sql.countByTransactionId, { - id: trs.asset.inTransfer.dappId - }).resolves({ - count: 0 + it('should call callback with error', function (done) { + inTransfer.verify(trs, sender, function (err) { + expect(err).to.equal('Application not found: ' + trs.asset.inTransfer.dappId); + done(); + }); + }); }); - inTransfer.verify(trs, sender, function (err) { - expect(err).to.equal('Application not found: ' + trs.asset.inTransfer.dappId); - done(); - }); - }); + describe('when dapp exists', function () { - it('should be okay with valid transaction', function (done) { - dbStub.one.withArgs(sql.countByTransactionId, { - id: trs.asset.inTransfer.dappId - }).resolves({ - count: 1 - }); + beforeEach(function () { + dbStub.one = sinon.stub().resolves({count: 1}); + }); - inTransfer.verify(trs, sender, function (err) { - expect(err).to.not.exist; - done(); + it('should call callback with error = undefined', function (done) { + inTransfer.verify(trs, sender, function (err) { + expect(err).to.be.undefined; + done(); + }); + }); + + it('should call callback with result = undefined', function (done) { + inTransfer.verify(trs, sender, function (err, res) { + expect(res).to.be.undefined; + done(); + }); + }); }); }); }); @@ -551,43 +540,56 @@ describe('inTransfer', function () { describe('objectNormalize', function () { - it('should call library.schema.validate'); + var library; + var schemaSpy; - it('should call library.schema.validate with trs.asset.inTransfer'); - - it('should call library.schema.validate InTransfer.prototype.schema'); - - describe('when transaction is invalid', function () { - - it('should throw', function () { + beforeEach(function () { + library = InTransfer.__get__('library'); + schemaSpy = sinon.spy(library.schema, 'validate'); + }); - }); + afterEach(function () { + schemaSpy.restore(); }); - describe('when transaction is valid', function () { + it('should call library.schema.validate', function () { + inTransfer.objectNormalize(trs); + expect(schemaSpy.calledOnce).to.be.true; + }); - it('should return transaction'); + it('should call library.schema.validate with trs.asset.inTransfer', function () { + inTransfer.objectNormalize(trs); + expect(schemaSpy.calledWith(trs.asset.inTransfer)).to.be.true; }); - it('should use the correct format to validate against', function () { - var library = InTransfer.__get__('library'); - var schemaSpy = sinon.spy(library.schema, 'validate'); + it('should call library.schema.validate InTransfer.prototype.schema', function () { inTransfer.objectNormalize(trs); - expect(schemaSpy.calledOnce).to.equal(true); - expect(schemaSpy.calledWithExactly(trs.asset.inTransfer, InTransfer.prototype.schema)).to.equal(true); - schemaSpy.restore(); + expect(schemaSpy.calledWith(InTransfer.prototype.schema)).to.be.true; + }); + + describe('when transaction.asset.inTransfer is invalid object argument', function () { + + typesRepresentatives.nonObjects.forEach(function (nonObject) { + it('should throw for transaction.asset.inTransfer = ' + nonObject.description, function () { + expect(inTransfer.objectNormalize.bind(null, nonObject.input)).to.throw(); + }); + }); }); - it('should return error asset schema is invalid', function () { - trs.asset.inTransfer.dappId = 2; + describe('when transaction.asset.inTransfer.dappId is invalid string argument', function () { - expect(function () { - inTransfer.objectNormalize(trs); - }).to.throw('Failed to validate inTransfer schema: Expected type string but found type integer'); + typesRepresentatives.nonStrings.forEach(function (nonString) { + it('should throw for transaction.asset.inTransfer.dappId = ' + nonString.description, function () { + expect(inTransfer.objectNormalize.bind(null, nonString.input)).to.throw(); + }); + }); }); - it('should return transaction when asset is valid', function () { - expect(inTransfer.objectNormalize(trs)).to.eql(trs); + describe('when when transaction.asset.inTransfer is valid', function () { + + it('should return transaction', function () { + expect(inTransfer.objectNormalize(trs)).to.eql(trs); + }); }); }); @@ -618,39 +620,45 @@ describe('inTransfer', function () { describe('dbSave', function () { - it('should return result containing table = "intransfer"'); + var dbSaveResult; - it('should return result containing fields = ["dappId", "transactionId"]'); + beforeEach(function () { + dbSaveResult = inTransfer.dbSave(trs); + }); - it('should return result containing values'); + it('should return result containing table = "intransfer"', function () { + expect(dbSaveResult).to.have.property('table').equal('intransfer'); + }); - it('should return result containing values.dappId = trs.asset.inTransfer.dappId'); + it('should return result containing fields = ["dappId", "transactionId"]', function () { + expect(dbSaveResult).to.have.property('fields').eql(['dappId', 'transactionId']); + }); - it('should return result containing values.transactionId = trs.id'); + it('should return result containing values', function () { + expect(dbSaveResult).to.have.property('values'); + }); - it('should be okay for valid input', function () { - expect(inTransfer.dbSave(trs)).to.eql({ - table: 'intransfer', - fields: [ - 'dappId', - 'transactionId' - ], - values: { - dappId: trs.asset.inTransfer.dappId, - transactionId: trs.id - } - }); + it('should return result containing values.dappId = trs.asset.inTransfer.dappId', function () { + expect(dbSaveResult).to.have.nested.property('values.dappId').equal(trs.asset.inTransfer.dappId); + }); + + it('should return result containing values.transactionId = trs.id', function () { + expect(dbSaveResult).to.have.nested.property('values.transactionId').equal(trs.id); }); }); describe('afterSave', function () { it('should call callback with error = undefined', function () { - + inTransfer.afterSave(trs, function (err) { + expect(err).to.be.undefined; + }); }); it('should call callback with result = undefined', function () { - + inTransfer.afterSave(trs, function (err, res) { + expect(res).to.be.undefined; + }); }); }); From 091551cb1526b73572881f49c02b4e0dc8df54af Mon Sep 17 00:00:00 2001 From: Maciej Baj Date: Mon, 9 Oct 2017 11:59:49 +0200 Subject: [PATCH 6/9] Refactor apply and undo inTransfer unit tests --- test/unit/logic/inTransfer.js | 223 +++++++++++++++++++--------------- 1 file changed, 125 insertions(+), 98 deletions(-) diff --git a/test/unit/logic/inTransfer.js b/test/unit/logic/inTransfer.js index 71dcd5eb5e6..9f8a42d9075 100644 --- a/test/unit/logic/inTransfer.js +++ b/test/unit/logic/inTransfer.js @@ -11,6 +11,7 @@ var node = require('./../../node.js'); var ed = require('../../../helpers/ed'); var slots = require('../../../helpers/slots.js'); var modulesLoader = require('../../common/initModule').modulesLoader; +var slots = require('../../../helpers/slots'); var typesRepresentatives = require('../../common/typesRepresentatives'); var InTransfer = rewire('../../../logic/inTransfer.js'); @@ -75,6 +76,10 @@ var rawValidTransaction = { in_dappId: '7400202127695414450' }; +var validGetGensisResult = { + authorId: 'validAuthorId' +}; + describe('inTransfer', function () { var inTransfer; @@ -93,10 +98,10 @@ describe('inTransfer', function () { one: sinon.stub().resolves() }; sharedStub = { - getGenesis: sinon.stub() + getGenesis: sinon.stub().callsArgWith(1, null, validGetGensisResult) }; accountsStub = { - mergeAccountAndGet: sinon.stub(), + mergeAccountAndGet: sinon.stub().callsArg(1), getAccount: sinon.stub() }; inTransfer = new InTransfer(dbStub, modulesLoader.scope.schema); @@ -354,152 +359,174 @@ describe('inTransfer', function () { describe('apply', function () { - it('should call shared.getGenesis'); - - it('should call shared.getGenesis with {dappid: trs.asset.inTransfer.dappId}'); - - describe('when shared.getGenesis fails', function () { - - it('should call callback with error'); + beforeEach(function (done) { + inTransfer.apply(trs, dummyBlock, sender, done); }); - describe('when shared.getGenesis succeeds', function () { - - it('should call modules.accounts.mergeAccountAndGet'); + it('should call shared.getGenesis', function () { + expect(sharedStub.getGenesis.calledOnce).to.be.true; + }); - it('should call modules.accounts.mergeAccountAndGet with address = dapp.authorId'); + it('should call shared.getGenesis with {dappid: trs.asset.inTransfer.dappId}', function () { + expect(sharedStub.getGenesis.calledWith({dappid: trs.asset.inTransfer.dappId})).to.be.true; + }); - it('should call modules.accounts.mergeAccountAndGet with balance = trs.amount'); + describe('when shared.getGenesis fails', function () { - it('should call modules.accounts.mergeAccountAndGet with u_balance = trs.amount'); + beforeEach(function () { + sharedStub.getGenesis = sinon.stub.callsArgWith(1, 'getGenesis error'); + }); - it('should call modules.accounts.mergeAccountAndGet with blockId = block.id'); + it('should call callback with error', function () { + inTransfer.apply(trs, dummyBlock, sender, function (err) { + expect(err).not.to.be.empty; + }); + }); + }); - it('should call modules.accounts.mergeAccountAndGet with round = slots.calcRound result'); + describe('when shared.getGenesis succeeds', function () { - describe('when modules.accounts.mergeAccountAndGet fails', function () { + beforeEach(function () { + sharedStub.getGenesis = sinon.stub.callsArg(1); + }); - it('should call callback with error'); + it('should call modules.accounts.mergeAccountAndGet', function () { + expect(accountsStub.mergeAccountAndGet.calledOnce).to.be.true; }); - describe('when modules.accounts.mergeAccountAndGet succeeds', function () { + it('should call modules.accounts.mergeAccountAndGet with address = dapp.authorId', function () { + expect(accountsStub.mergeAccountAndGet.calledWith(sinon.match({address: validGetGensisResult.authorId}))).to.be.true; + }); - it('should call callback with error = undefined'); + it('should call modules.accounts.mergeAccountAndGet with balance = trs.amount', function () { + expect(accountsStub.mergeAccountAndGet.calledWith(sinon.match({balance: trs.amount}))).to.be.true; + }); - it('should call callback with result = undefined'); + it('should call modules.accounts.mergeAccountAndGet with u_balance = trs.amount', function () { + expect(accountsStub.mergeAccountAndGet.calledWith(sinon.match({u_balance: trs.amount}))).to.be.true; }); - }); - it('should return error if dapp does not exist', function (done) { + it('should call modules.accounts.mergeAccountAndGet with blockId = block.id', function () { + expect(accountsStub.mergeAccountAndGet.calledWith(sinon.match({blockId: dummyBlock.id}))).to.be.true; + }); - var error = 'Application genesis block not found'; + it('should call modules.accounts.mergeAccountAndGet with round = slots.calcRound result', function () { + expect(accountsStub.mergeAccountAndGet.calledWith(sinon.match({round: slots.calcRound(dummyBlock.height)}))).to.be.true; + }); - sharedStub.getGenesis.withArgs({ - dappid: trs.asset.inTransfer.dappId - }, sinon.match.any).yields(error); + describe('when modules.accounts.mergeAccountAndGet fails', function () { - inTransfer.apply(trs, dummyBlock, sender, function (err) { - expect(err).to.equal(error); - done(); + beforeEach(function () { + accountsStub.mergeAccountAndGet = sinon.stub().callsArgWith(1, 'mergeAccountAndGet error'); + }); + + it('should call callback with error', function () { + inTransfer.apply(trs, dummyBlock, sender, function (err) { + expect(err).not.to.be.empty; + }); + }); }); - }); - it('should update account with correct params', function (done) { - sharedStub.getGenesis.withArgs({ - dappid: trs.asset.inTransfer.dappId - }, sinon.match.any).yields(null, { - authorId: validSender.address - }); + describe('when modules.accounts.mergeAccountAndGet succeeds', function () { - accountsStub.mergeAccountAndGet.withArgs({ - address: validSender.address, - balance: trs.amount, - u_balance: trs.amount, - blockId: dummyBlock.id, - round: slots.calcRound(dummyBlock.height) - }).yields(null); + it('should call callback with error = undefined', function () { + inTransfer.apply(trs, dummyBlock, sender, function (err) { + expect(err).to.be.undefined; + }); + }); - inTransfer.apply(trs, dummyBlock, sender, function (err) { - expect(err).to.not.exist; - expect(accountsStub.mergeAccountAndGet.calledOnce).to.equal(true); - done(); + it('should call callback with result = undefined', function () { + inTransfer.apply(trs, dummyBlock, sender, function (err, res) { + expect(res).to.be.undefined; + }); + }); }); }); }); describe('undo', function () { - it('should call shared.getGenesis'); - - it('should call shared.getGenesis with {dappid: trs.asset.inTransfer.dappId}'); - - describe('when shared.getGenesis fails', function () { + beforeEach(function (done) { + inTransfer.undo(trs, dummyBlock, sender, done); + }); - it('should call callback with error'); + it('should call shared.getGenesis', function () { + expect(sharedStub.getGenesis.calledOnce).to.be.true; }); - describe('when shared.getGenesis succeeds', function () { + it('should call shared.getGenesis with {dappid: trs.asset.inTransfer.dappId}', function () { + expect(sharedStub.getGenesis.calledWith({dappid: trs.asset.inTransfer.dappId})).to.be.true; + }); - it('should call modules.accounts.mergeAccountAndGet'); + describe('when shared.getGenesis fails', function () { - it('should call modules.accounts.mergeAccountAndGet with address = dapp.authorId'); + beforeEach(function () { + sharedStub.getGenesis = sinon.stub.callsArgWith(1, 'getGenesis error'); + }); - it('should call modules.accounts.mergeAccountAndGet with balance = trs.amount'); + it('should call callback with error', function () { + inTransfer.undo(trs, dummyBlock, sender, function (err) { + expect(err).not.to.be.empty; + }); + }); + }); - it('should call modules.accounts.mergeAccountAndGet with u_balance = trs.amount'); + describe('when shared.getGenesis succeeds', function () { - it('should call modules.accounts.mergeAccountAndGet with blockId = block.id'); + beforeEach(function () { + sharedStub.getGenesis = sinon.stub.callsArg(1); + }); - it('should call modules.accounts.mergeAccountAndGet with round = slots.calcRound result'); + it('should call modules.accounts.mergeAccountAndGet', function () { + expect(accountsStub.mergeAccountAndGet.calledOnce).to.be.true; + }); - describe('when modules.accounts.mergeAccountAndGet fails', function () { + it('should call modules.accounts.mergeAccountAndGet with address = dapp.authorId', function () { + expect(accountsStub.mergeAccountAndGet.calledWith(sinon.match({address: validGetGensisResult.authorId}))).to.be.true; + }); - it('should call callback with error'); + it('should call modules.accounts.mergeAccountAndGet with balance = -trs.amount', function () { + expect(accountsStub.mergeAccountAndGet.calledWith(sinon.match({balance: -trs.amount}))).to.be.true; }); - describe('when modules.accounts.mergeAccountAndGet succeeds', function () { + it('should call modules.accounts.mergeAccountAndGet with u_balance = -trs.amount', function () { + expect(accountsStub.mergeAccountAndGet.calledWith(sinon.match({u_balance: -trs.amount}))).to.be.true; + }); - it('should call callback with error = undefined'); + it('should call modules.accounts.mergeAccountAndGet with blockId = block.id', function () { + expect(accountsStub.mergeAccountAndGet.calledWith(sinon.match({blockId: dummyBlock.id}))).to.be.true; + }); - it('should call callback with result = undefined'); + it('should call modules.accounts.mergeAccountAndGet with round = slots.calcRound result', function () { + expect(accountsStub.mergeAccountAndGet.calledWith(sinon.match({round: slots.calcRound(dummyBlock.height)}))).to.be.true; }); - }); - it('should return error if dapp does not exist', function (done) { - var error = 'Application genesis block not found'; - sharedStub.getGenesis.withArgs({ - dappid: trs.asset.inTransfer.dappId - }, sinon.match.any).yields(error); + describe('when modules.accounts.mergeAccountAndGet fails', function () { - inTransfer.undo(trs, dummyBlock, sender, function (err) { - expect(err).to.equal(error); - done(); - }); - }); + beforeEach(function () { + accountsStub.mergeAccountAndGet = sinon.stub().callsArgWith(1, 'mergeAccountAndGet error'); + }); - it('should update account with correct params', function (done) { - sharedStub.getGenesis.withArgs({ - dappid: trs.asset.inTransfer.dappId - }, sinon.match.any).yields(null, { - authorId: validSender.address + it('should call callback with error', function () { + inTransfer.undo(trs, dummyBlock, sender, function (err) { + expect(err).not.to.be.empty; + }); + }); }); - accountsStub.getAccount.withArgs({ - address: sender.address - }, sinon.match.any).yields(); + describe('when modules.accounts.mergeAccountAndGet succeeds', function () { - accountsStub.mergeAccountAndGet.withArgs({ - address: validSender.address, - balance: trs.amount, - u_balance: trs.amount, - blockId: dummyBlock.id, - round: slots.calcRound(dummyBlock.height) - }).yields(null); + it('should call callback with error = undefined', function () { + inTransfer.undo(trs, dummyBlock, sender, function (err) { + expect(err).to.be.undefined; + }); + }); - inTransfer.apply(trs, dummyBlock, sender, function (err) { - expect(err).to.not.exist; - expect(accountsStub.mergeAccountAndGet.calledOnce).to.equal(true); - done(); + it('should call callback with result = undefined', function () { + inTransfer.undo(trs, dummyBlock, sender, function (err, res) { + expect(res).to.be.undefined; + }); + }); }); }); }); @@ -564,7 +591,7 @@ describe('inTransfer', function () { it('should call library.schema.validate InTransfer.prototype.schema', function () { inTransfer.objectNormalize(trs); - expect(schemaSpy.calledWith(InTransfer.prototype.schema)).to.be.true; + expect(schemaSpy.args[0][1]).to.eql(InTransfer.prototype.schema); }); describe('when transaction.asset.inTransfer is invalid object argument', function () { From f265e547941d46a6f711f0fdbcf03911007e357a Mon Sep 17 00:00:00 2001 From: Maciej Baj Date: Mon, 9 Oct 2017 16:13:37 +0200 Subject: [PATCH 7/9] Fix invalid dappId schema test --- test/unit/logic/inTransfer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/logic/inTransfer.js b/test/unit/logic/inTransfer.js index 9f8a42d9075..da26f38cc7a 100644 --- a/test/unit/logic/inTransfer.js +++ b/test/unit/logic/inTransfer.js @@ -9,7 +9,6 @@ var sinon = require('sinon'); var node = require('./../../node.js'); var ed = require('../../../helpers/ed'); -var slots = require('../../../helpers/slots.js'); var modulesLoader = require('../../common/initModule').modulesLoader; var slots = require('../../../helpers/slots'); var typesRepresentatives = require('../../common/typesRepresentatives'); @@ -607,7 +606,8 @@ describe('inTransfer', function () { typesRepresentatives.nonStrings.forEach(function (nonString) { it('should throw for transaction.asset.inTransfer.dappId = ' + nonString.description, function () { - expect(inTransfer.objectNormalize.bind(null, nonString.input)).to.throw(); + trs.asset.inTransfer.dappId = nonString.input; + expect(inTransfer.objectNormalize.bind(null, trs)).to.throw(); }); }); }); From c774a9d7a2311af6d72f74b9309ec3ab0e750712 Mon Sep 17 00:00:00 2001 From: Usman Khan Date: Fri, 13 Oct 2017 14:03:31 +0200 Subject: [PATCH 8/9] Removed undefined property from othertypes --- test/common/typesRepresentatives.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/common/typesRepresentatives.js b/test/common/typesRepresentatives.js index 6b4ba8a68c3..3f6bce83e40 100644 --- a/test/common/typesRepresentatives.js +++ b/test/common/typesRepresentatives.js @@ -103,11 +103,6 @@ var others = [ input: null, description: 'null', expectation: 'null' - }, - { - input: undefined, - description: 'undefined', - expectation: 'undefined' } ]; From 100ccd8f24f2f1dcd7e476056d185e84c586ef02 Mon Sep 17 00:00:00 2001 From: Usman Khan Date: Fri, 13 Oct 2017 14:28:10 +0200 Subject: [PATCH 9/9] Added intransfer tests to run with npm run test-unit --- test/unit/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/index.js b/test/unit/index.js index de7417e6afc..928d4c7e862 100644 --- a/test/unit/index.js +++ b/test/unit/index.js @@ -23,6 +23,7 @@ require('./logic/transactionPool'); require('./logic/transfer'); require('./logic/signature.js'); require('./logic/vote'); +require('./logic/multisignature.js'); require('./modules/blocks/process'); require('./modules/blocks/verify');