{"action":"created","comment":{"url":"https://api.github.com/repos/RiseVision/rise-node/pulls/comments/146808664","pull_request_review_id":71804012,"id":146808664,"diff_hunk":"@@ -0,0 +1,1012 @@\n+var chai = require('chai')\n+var assertArrays = require('chai-arrays')\n+chai.use(assertArrays)\n+var expect = chai.expect\n+var sinon = require('sinon')\n+var rewire = require('rewire')\n+var Vote = rewire('../../../logic/vote')\n+var zSchema = require('../../../helpers/z_schema')\n+var constants = require('../../../helpers/constants.js')\n+var crypto = require('crypto')\n+\n+describe('logic/vote', function () {\n+\tdescribe('when is imported', function () {\n+\t\tit('should be a function', function () {\n+\t\t\texpect(Vote).to.be.a('function')\n+\t\t})\n+\t})\n+\n+\tdescribe('when Vote is instantiated...', function () {\n+\n+\t\tvar logger, schema, vote\n+\n+\t\tbeforeEach(function () {\n+\t\t\tlogger = 1\n+\t\t\tschema = 2\n+\t\t\tvote = new Vote(logger, schema)\n+\t\t})\n+\n+\t\tdescribe('logger and schema should be setted properly into library', function () {\n+\t\t\tit('should be an object', function () {\n+\t\t\t\texpect(Vote.__get__('library').logger).to.equals(logger)\n+\t\t\t\texpect(Vote.__get__('library').schema).to.equals(schema)\n+\t\t\t})\n+\t\t})\n+\t})\n+\n+\tdescribe('when we call to...', function () {\n+\n+\t\tvar logger, schema, vote\n+\n+\t\tbeforeEach(function () {\n+\t\t\tlogger = 1\n+\t\t\tschema = 2\n+\t\t\tvote = new Vote(logger, schema)\n+\t\t})\n+\n+\t\tdescribe('bind()', function () {\n+\n+\t\t\tvar delegates, rounds, system\n+\n+\t\t\tbeforeEach(function () {\n+\t\t\t\tdelegates = 'a'\n+\t\t\t\trounds = 'b'\n+\t\t\t\tsystem = 'c'\n+\t\t\t})\n+\n+\t\t\tit('delegates, rounds and system should be setted properly into modules variable', function () {\n+\t\t\t\tvote.bind(delegates, rounds, system)\n+\t\t\t\texpect(Vote.__get__('modules').delegates).to.equals(delegates)\n+\t\t\t\texpect(Vote.__get__('modules').rounds).to.equals(rounds)\n+\t\t\t\texpect(Vote.__get__('modules').system).to.equals(system)\n+\t\t\t})\n+\t\t})\n+\n+\t\tdescribe('create()', function () {\n+\n+\t\t\tvar data, trs\n+\n+\t\t\tbeforeEach(function () {\n+\t\t\t\tdata = {sender: {address: 10}, votes: 20}\n+\t\t\t\ttrs = {recipientId: 0, asset: {votes: 0}}\n+\t\t\t})\n+\n+\t\t\tit('transaction should be setted properly with data parameter', function () {\n+\t\t\t\tvar transaction = vote.create(data, trs)\n+\t\t\t\texpect(transaction.recipientId).to.equals(data.sender.address)\n+\t\t\t\texpect(transaction.asset.votes).to.equals(data.votes)\n+\t\t\t})\n+\t\t})\n+\n+\t\tdescribe('calculateFee()', function () {\n+\n+\t\t\tvar trs, sender, height, delegates, rounds, system\n+\n+\t\t\tbeforeEach(function () {\n+\t\t\t\theight = 50\n+\t\t\t\tsystem = {getFees: function (height) {\n+\t\t\t\t\treturn {fees: {vote: 100}}\n+\t\t\t\t}}\n+\t\t\t})\n+\n+\t\t\tit('should return vote\\'s fee', function () {\n+\t\t\t\tvote.bind(delegates, rounds, system)\n+\t\t\t\tvar fee = vote.calculateFee(trs, sender, height)\n+\t\t\t\texpect(fee).to.equals(100)\n+\t\t\t})\n+\t\t})\n+\n+\t\tdescribe('verify()', function () {\n+\n+\t\t\tvar clock, trs, sender, callback\n+\n+\t\t\tcontext('if trs.recipientId and trs.senderId are not equals', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t\ttrs = {recipientId: 1, senderId: 2}\n+\t\t\t\t\tvote.verify(trs, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Invalid recipient\\' error', function () {\n+\t\t\t\t\tclock.tick()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.equals('Invalid recipient')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset is not true', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t\ttrs = {asset: {}}\n+\t\t\t\t\tvote.verify(trs, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Invalid transaction asset\\' error', function () {\n+\t\t\t\t\tclock.tick()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.equals('Invalid transaction asset')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes is not true', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t\ttrs = {asset: {votes: undefined}}\n+\t\t\t\t\tvote.verify(trs, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Invalid transaction asset\\' error', function () {\n+\t\t\t\t\tclock.tick()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.equals('Invalid transaction asset')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes is not an Array', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t\ttrs = {asset: {votes: 'foo'}}\n+\t\t\t\t\tvote.verify(trs, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Invalid votes. Must be an array\\' error', function () {\n+\t\t\t\t\tclock.tick()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.equals('Invalid votes. Must be an array')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes.length is not true', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t\ttrs = {asset: {votes: []}}\n+\t\t\t\t\tvote.verify(trs, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Invalid votes. Must not be empty\\' error', function () {\n+\t\t\t\t\tclock.tick()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.equals('Invalid votes. Must not be empty')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes.length is not true', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t\ttrs = {asset: {votes: []}}\n+\t\t\t\t\tvote.verify(trs, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Invalid votes. Must not be empty\\' error', function () {\n+\t\t\t\t\tclock.tick()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.equals('Invalid votes. Must not be empty')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes is greater than maxVotesPerTransaction', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t\ttrs = {asset: {votes: [1,2,3,4,5,6,7,8,9,10]}}\n+\t\t\t\t\tvote.verify(trs, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Voting limit exceeded. Maximum is\\' error', function () {\n+\t\t\t\t\tclock.tick()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.include('Voting limit exceeded')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if vote has not a valid format', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t\ttrs = {asset: {votes: [123]}}\n+\t\t\t\t\tvote.verify(trs, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Invalid vote at index\\' error', function () {\n+\n+\t\t\t\t\tclock.runAll()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.include('Invalid vote at index')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if there are duplicate votes', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t\ttrs = {asset: {votes: ['+b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9', '+b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9']}}\n+\t\t\t\t\tvote.verify(trs, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Multiple votes for same delegate are not allowed\\' error', function () {\n+\n+\t\t\t\t\tclock.runAll()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.include('Multiple votes for same delegate are not allowed')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if everything is ok', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tVote.__set__('self.checkConfirmedDelegates', function (trs, cb) {\n+\t\t\t\t\t\treturn setImmediate(cb)\n+\t\t\t\t\t})\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t\ttrs = {asset: {votes: ['+b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9', '+37b6d3fc89fb418fa5e3799e760cc2b1733a567daebb08a531d3d7e8b24f2d22']}}\n+\t\t\t\t\tvote.verify(trs, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should call to callback without errors', function () {\n+\n+\t\t\t\t\tclock.runAll()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.equals(undefined)\n+\t\t\t\t})\n+\t\t\t})\n+\t\t})\n+\n+\t\tdescribe('verifyVote()', function () {\n+\n+\t\t\tvar clock, callback\n+\n+\t\t\tcontext('if vote is not a string', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Invalid vote type\\' error', function () {\n+\t\t\t\t\tvote.verifyVote(123, callback)\n+\t\t\t\t\tclock.tick()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.equals('Invalid vote type')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if vote has not a valid format', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Invalid vote format\\' error', function () {\n+\t\t\t\t\tvote.verifyVote('+b94d27b993-d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9', callback)\n+\t\t\t\t\tclock.tick()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.equals('Invalid vote format')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if vote length is not 65', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return an \\'Invalid vote length\\' error', function () {\n+\t\t\t\t\tvote.verifyVote('+b94d27b993d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9zz', callback)\n+\t\t\t\t\tclock.tick()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.equals('Invalid vote length')\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if vote is valid', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\t\tcallback = sinon.spy()\n+\t\t\t\t})\n+\n+\t\t\t\tafterEach(function () {\n+\t\t\t\t\tclock.restore()\n+\t\t\t\t})\n+\n+\t\t\t\tit('should call to callback without errors', function () {\n+\t\t\t\t\tvote.verifyVote('+b94d27b993d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9z', callback)\n+\t\t\t\t\tclock.tick()\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t\texpect(callback.args[0][0]).to.equals(undefined)\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t})\n+\n+\t\tdescribe('checkConfirmedDelegates()', function () {\n+\n+\t\t\tvar clock, trs, callback, delegates, rounds, system\n+\n+\t\t\tbeforeEach(function () {\n+\t\t\t\tcallback = sinon.spy()\n+\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\ttrs = {senderPublicKey: 'foo', asset: {votes: []}}\n+\t\t\t\tdelegates = {}\n+\t\t\t\trounds = {}\n+\t\t\t\tsystem = {}\n+\t\t\t\tvote.bind(delegates, rounds, system)\n+\t\t\t\tVote.__set__({ modules: {\n+\t\t\t\t\tdelegates: {\n+\t\t\t\t\t\tcheckConfirmedDelegates: function (trs, votes, cb) {\n+\t\t\t\t\t\t\treturn setImmediate(cb)\n+\t\t\t\t\t\t}\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\t})\n+\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\tvote.checkConfirmedDelegates(trs, callback)\n+\t\t\t})\n+\n+\t\t\tafterEach(function () {\n+\t\t\t\tclock.restore()\n+\t\t\t})\n+\n+\t\t\tit('should call to callback without errors', function () {\n+\t\t\t\tclock.runAll()\n+\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\texpect(callback.args[0][0]).to.equals(undefined)\n+\t\t\t})\n+\t\t})\n+\n+\t\tdescribe('checkUnconfirmedDelegates()', function () {\n+\t\t\tvar clock, trs, callback, delegates, rounds, system\n+\n+\t\t\tbeforeEach(function () {\n+\t\t\t\tcallback = sinon.spy()\n+\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\ttrs = {senderPublicKey: 'foo', asset: {votes: []}}\n+\t\t\t\tdelegates = {}\n+\t\t\t\trounds = {}\n+\t\t\t\tsystem = {}\n+\t\t\t\tvote.bind(delegates, rounds, system)\n+\t\t\t\tVote.__set__({ modules: {\n+\t\t\t\t\tdelegates: {\n+\t\t\t\t\t\tcheckUnconfirmedDelegates: function (trs, votes, cb) {\n+\t\t\t\t\t\t\treturn setImmediate(cb)\n+\t\t\t\t\t\t}\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\t})\n+\t\t\t\tvote.checkUnconfirmedDelegates(trs, callback)\n+\t\t\t})\n+\n+\t\t\tafterEach(function () {\n+\t\t\t\tclock.restore()\n+\t\t\t})\n+\n+\t\t\tit('should call to callback without errors', function () {\n+\t\t\t\tclock.runAll()\n+\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\texpect(callback.args[0][0]).to.equals(undefined)\n+\t\t\t})\n+\t\t})\n+\n+\t\tdescribe('process()', function () {\n+\n+\t\t\tvar clock, trs, callback\n+\n+\t\t\tbeforeEach(function () {\n+\t\t\t\ttrs = 1\n+\t\t\t\tcallback = sinon.spy()\n+\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\tvote.process(trs, null, callback)\n+\t\t\t})\n+\n+\t\t\tit('should call to callback passing the same transaction parameter received', function () {\n+\t\t\t\tclock.runAll()\n+\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\texpect(callback.args[0][1]).to.equals(trs)\n+\t\t\t})\n+\n+\t\t})\n+\n+\t\tdescribe('getBytes()', function () {\n+\n+\t\t\tvar trs, result, getBytes\n+\n+\t\t\tcontext('if the input data is wrong', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\ttrs = {asset: {votes: 123}}\n+\t\t\t\t\tgetBytes = function () {\n+\t\t\t\t\t\tvote.getBytes(trs)\n+\t\t\t\t\t}\n+\t\t\t\t})\n+\n+\t\t\t\tit('should throws an error', function () {\n+\t\t\t\t\texpect(getBytes).to.throw()\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes is undefined', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\ttrs = {asset: {votes: undefined}}\n+\t\t\t\t\tresult = vote.getBytes(trs)\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return null', function () {\n+\t\t\t\t\texpect(result).to.equals(null)\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if everything is ok', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\ttrs = {asset: {votes: ['+37b6d3fc89fb418fa5e3799e760cc2b1733a567daebb08a531d3d7e8b24f2d22','+9f59d4260dcd848f71d17824f53df31f3dfb87542042590554419ff40542c55e']}}\n+\t\t\t\t\tresult = vote.getBytes(trs)\n+\t\t\t\t})\n+\n+\t\t\t\tit('should return a Buffer object', function () {\n+\t\t\t\t\texpect(result).to.be.an.instanceof(Buffer)\n+\t\t\t\t})\n+\t\t\t})\n+\t\t})\n+\n+\t\tdescribe('apply()', function () {\n+\t\t\tvar clock, trs, block, sender, callback, scope, delegates, rounds, system\n+\n+\t\t\tbeforeEach(function () {\n+\t\t\t\tcallback = sinon.spy()\n+\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\tscope = { account: { merge: function (address, data, cb) { cb() } } }\n+\t\t\t\trounds = {calc: function (height) { return height }}\n+\t\t\t\ttrs = {asset: {votes: []}}\n+\t\t\t\tsender = {address: 123}\n+\t\t\t\tblock = {id: 123, height: 123}\n+\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\tVote.__set__('self.checkConfirmedDelegates', function (trs, cb) {\n+\t\t\t\t\treturn setImmediate(cb)\n+\t\t\t\t})\n+\t\t\t\tVote.__set__('self.scope', scope)\n+\t\t\t\tvote.bind(delegates, rounds, system)\n+\t\t\t\tvote.apply(trs, block, sender, callback)\n+\t\t\t})\n+\n+\t\t\tafterEach(function () {\n+\t\t\t\tclock.restore()\n+\t\t\t})\n+\n+\t\t\tit('should call to callback', function () {\n+\n+\t\t\t\tclock.runAll()\n+\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t})\n+\t\t})\n+\n+\t\tdescribe('undo()', function () {\n+\t\t\tvar clock, trs, block, sender, callback, delegates, rounds, system, account, schema, logger\n+\n+\t\t\tbeforeEach(function () {\n+\t\t\t\tcallback = sinon.spy()\n+\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\tschema = new zSchema()\n+\t\t\t\tvote = new Vote(logger, schema)\n+\t\t\t\taccount = { merge: function () {} }\n+\t\t\t\tsinon.stub(account, 'merge').callsFake(function (address, data, cb) {\n+\t\t\t\t\tcb()\n+\t\t\t\t})\n+\t\t\t\tVote.__set__('self.scope', {account: account})\n+\t\t\t\trounds = {calc: function (height) { return height }}\n+\t\t\t\tsender = {address: 123}\n+\t\t\t\tblock = {id: 123, height: 123}\n+\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\n+\t\t\t\tvote.bind(delegates, rounds, system)\n+\t\t\t})\n+\n+\t\t\tafterEach(function () {\n+\t\t\t\tclock.restore()\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes is null', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\ttrs = {asset: {votes: null}}\n+\t\t\t\t\tvote.undo(trs, block, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tit('should not call to scope.account.merge()', function () {\n+\t\t\t\t\tclock.runAll()\n+\t\t\t\t\tvar result = Vote.__get__('self.scope')\n+\t\t\t\t\texpect(result.account.merge.called).to.be.false\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes is empty', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\ttrs = {asset: {votes: []}}\n+\t\t\t\t\tvote.undo(trs, block, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tit('should not call to scope.account.merge()', function () {\n+\t\t\t\t\tclock.runAll()\n+\t\t\t\t\tvar result = Vote.__get__('self.scope')\n+\t\t\t\t\texpect(result.account.merge.called).to.be.false\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes is undefined', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\ttrs = {asset: {votes: undefined}}\n+\t\t\t\t\tvote.undo(trs, block, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tit('should not call to scope.account.merge()', function () {\n+\t\t\t\t\tclock.runAll()\n+\t\t\t\t\tvar result = Vote.__get__('self.scope')\n+\t\t\t\t\texpect(result.account.merge.called).to.be.false\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes has not a valid format', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\ttrs = {asset: {votes: [1,2]}}\n+\t\t\t\t\tvote.undo(trs, block, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tit('should not call to scope.account.merge()', function () {\n+\t\t\t\t\tclock.runAll()\n+\t\t\t\t\tvar result = Vote.__get__('self.scope')\n+\t\t\t\t\texpect(result.account.merge.called).to.be.false\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t})\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes is an Array and have items', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\ttrs = {asset: {votes: ['+37b6d3fc89fb418fa5e3799e760cc2b1733a567daebb08a531d3d7e8b24f2d22', '+b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9']}}\n+\t\t\t\t\tvote.undo(trs, block, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tit('should call to scope.account.merge() and callback()', function () {\n+\t\t\t\t\tclock.runAll()\n+\t\t\t\t\tvar result = Vote.__get__('self.scope')\n+\t\t\t\t\texpect(result.account.merge.called).to.be.true\n+\t\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t\t})\n+\t\t\t})\n+\t\t})\n+\n+\t\tdescribe('applyUnconfirmed', function () {\n+\t\t\tvar clock, trs, sender, callback, scope\n+\n+\t\t\tbeforeEach(function () {\n+\t\t\t\tcallback = sinon.spy()\n+\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\tsender = {address: 123}\n+\t\t\t\tscope = { account: { merge: function (address, data, cb) { cb() } } }\n+\t\t\t\ttrs = {asset: {votes: []}}\n+\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\t\t\t\tVote.__set__('self.checkUnconfirmedDelegates', function (trs, cb) {\n+\t\t\t\t\treturn setImmediate(cb)\n+\t\t\t\t})\n+\t\t\t\tVote.__set__('self.scope', scope)\n+\t\t\t\tvote.applyUnconfirmed(trs, sender, callback)\n+\t\t\t})\n+\n+\t\t\tafterEach(function () {\n+\t\t\t\tclock.restore()\n+\t\t\t})\n+\n+\t\t\tit('should call to callback', function () {\n+\n+\t\t\t\tclock.runAll()\n+\t\t\t\texpect(callback.called).to.be.true\n+\t\t\t})\n+\t\t})\n+\n+\t\tdescribe('undoUnconfirmed()', function () {\n+\t\t\tvar clock, trs, sender, callback, delegates, rounds, system, account, schema, logger\n+\n+\t\t\tbeforeEach(function () {\n+\t\t\t\tcallback = sinon.spy()\n+\t\t\t\tclock = sinon.useFakeTimers()\n+\t\t\t\tschema = new zSchema()\n+\t\t\t\tvote = new Vote(logger, schema)\n+\t\t\t\taccount = { merge: function () {} }\n+\t\t\t\tsinon.stub(account, 'merge').callsFake(function (address, data, cb) {\n+\t\t\t\t\tcb()\n+\t\t\t\t})\n+\t\t\t\tVote.__set__('self.scope', {account: account})\n+\t\t\t\trounds = {calc: function (height) { return height }}\n+\t\t\t\tsender = {address: 123}\n+\t\t\t\tVote.__set__('setImmediate', setImmediate)\n+\n+\t\t\t\tvote.bind(delegates, rounds, system)\n+\t\t\t})\n+\n+\t\t\tafterEach(function () {\n+\t\t\t\tclock.restore()\n+\t\t\t})\n+\n+\t\t\tcontext('if trs.asset.votes is null', function () {\n+\n+\t\t\t\tbeforeEach(function () {\n+\t\t\t\t\ttrs = {asset: {votes: null}}\n+\t\t\t\t\tvote.undoUnconfirmed(trs, sender, callback)\n+\t\t\t\t})\n+\n+\t\t\t\tit('should not call to scope.account.merge()', function () {\n+\t\t\t\t\tclock.runAll()\n+\t\t\t\t\tvar result = Vote.__get__('self.scope')\n+\t\t\t\t\texpect(result.account.merge.called).to.be.false\n+\t\t\t\t\texpect(callback.called).to.be.true","path":"tests/unit/logic/vote.spec.js","position":605,"original_position":733,"commit_id":"428921e16878c2009573522d3e5a322f2ee8ebb0","original_commit_id":"428921e16878c2009573522d3e5a322f2ee8ebb0","user":{"login":"jarenal","id":696774,"avatar_url":"https://avatars2.githubusercontent.com/u/696774?v=4","gravatar_id":"","url":"https://api.github.com/users/jarenal","html_url":"https://github.com/jarenal","followers_url":"https://api.github.com/users/jarenal/followers","following_url":"https://api.github.com/users/jarenal/following{/other_user}","gists_url":"https://api.github.com/users/jarenal/gists{/gist_id}","starred_url":"https://api.github.com/users/jarenal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jarenal/subscriptions","organizations_url":"https://api.github.com/users/jarenal/orgs","repos_url":"https://api.github.com/users/jarenal/repos","events_url":"https://api.github.com/users/jarenal/events{/privacy}","received_events_url":"https://api.github.com/users/jarenal/received_events","type":"User","site_admin":false},"body":"Done!","created_at":"2017-10-25T10:04:27Z","updated_at":"2017-10-25T10:04:27Z","html_url":"https://github.com/RiseVision/rise-node/pull/26#discussion_r146808664","pull_request_url":"https://api.github.com/repos/RiseVision/rise-node/pulls/26","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/RiseVision/rise-node/pulls/comments/146808664"},"html":{"href":"https://github.com/RiseVision/rise-node/pull/26#discussion_r146808664"},"pull_request":{"href":"https://api.github.com/repos/RiseVision/rise-node/pulls/26"}},"in_reply_to_id":145697837},"pull_request":{"url":"https://api.github.com/repos/RiseVision/rise-node/pulls/26","id":146471824,"html_url":"https://github.com/RiseVision/rise-node/pull/26","diff_url":"https://github.com/RiseVision/rise-node/pull/26.diff","patch_url":"https://github.com/RiseVision/rise-node/pull/26.patch","issue_url":"https://api.github.com/repos/RiseVision/rise-node/issues/26","number":26,"state":"open","locked":false,"title":"Unit tests for logic/vote","user":{"login":"jarenal","id":696774,"avatar_url":"https://avatars2.githubusercontent.com/u/696774?v=4","gravatar_id":"","url":"https://api.github.com/users/jarenal","html_url":"https://github.com/jarenal","followers_url":"https://api.github.com/users/jarenal/followers","following_url":"https://api.github.com/users/jarenal/following{/other_user}","gists_url":"https://api.github.com/users/jarenal/gists{/gist_id}","starred_url":"https://api.github.com/users/jarenal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jarenal/subscriptions","organizations_url":"https://api.github.com/users/jarenal/orgs","repos_url":"https://api.github.com/users/jarenal/repos","events_url":"https://api.github.com/users/jarenal/events{/privacy}","received_events_url":"https://api.github.com/users/jarenal/received_events","type":"User","site_admin":false},"body":"Test ready for review! Some test will fail until I fix some little issues that I found in logic/vote","created_at":"2017-10-13T14:28:40Z","updated_at":"2017-10-25T10:04:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a4ad90da14489f3d89221432f6ea451ad1abab3c","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/RiseVision/rise-node/pulls/26/commits","review_comments_url":"https://api.github.com/repos/RiseVision/rise-node/pulls/26/comments","review_comment_url":"https://api.github.com/repos/RiseVision/rise-node/pulls/comments{/number}","comments_url":"https://api.github.com/repos/RiseVision/rise-node/issues/26/comments","statuses_url":"https://api.github.com/repos/RiseVision/rise-node/statuses/428921e16878c2009573522d3e5a322f2ee8ebb0","head":{"label":"RiseVision:unit-test-logic-vote","ref":"unit-test-logic-vote","sha":"428921e16878c2009573522d3e5a322f2ee8ebb0","user":{"login":"RiseVision","id":18466003,"avatar_url":"https://avatars1.githubusercontent.com/u/18466003?v=4","gravatar_id":"","url":"https://api.github.com/users/RiseVision","html_url":"https://github.com/RiseVision","followers_url":"https://api.github.com/users/RiseVision/followers","following_url":"https://api.github.com/users/RiseVision/following{/other_user}","gists_url":"https://api.github.com/users/RiseVision/gists{/gist_id}","starred_url":"https://api.github.com/users/RiseVision/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RiseVision/subscriptions","organizations_url":"https://api.github.com/users/RiseVision/orgs","repos_url":"https://api.github.com/users/RiseVision/repos","events_url":"https://api.github.com/users/RiseVision/events{/privacy}","received_events_url":"https://api.github.com/users/RiseVision/received_events","type":"Organization","site_admin":false},"repo":{"id":97703767,"name":"rise-node","full_name":"RiseVision/rise-node","owner":{"login":"RiseVision","id":18466003,"avatar_url":"https://avatars1.githubusercontent.com/u/18466003?v=4","gravatar_id":"","url":"https://api.github.com/users/RiseVision","html_url":"https://github.com/RiseVision","followers_url":"https://api.github.com/users/RiseVision/followers","following_url":"https://api.github.com/users/RiseVision/following{/other_user}","gists_url":"https://api.github.com/users/RiseVision/gists{/gist_id}","starred_url":"https://api.github.com/users/RiseVision/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RiseVision/subscriptions","organizations_url":"https://api.github.com/users/RiseVision/orgs","repos_url":"https://api.github.com/users/RiseVision/repos","events_url":"https://api.github.com/users/RiseVision/events{/privacy}","received_events_url":"https://api.github.com/users/RiseVision/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/RiseVision/rise-node","description":null,"fork":false,"url":"https://api.github.com/repos/RiseVision/rise-node","forks_url":"https://api.github.com/repos/RiseVision/rise-node/forks","keys_url":"https://api.github.com/repos/RiseVision/rise-node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/RiseVision/rise-node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/RiseVision/rise-node/teams","hooks_url":"https://api.github.com/repos/RiseVision/rise-node/hooks","issue_events_url":"https://api.github.com/repos/RiseVision/rise-node/issues/events{/number}","events_url":"https://api.github.com/repos/RiseVision/rise-node/events","assignees_url":"https://api.github.com/repos/RiseVision/rise-node/assignees{/user}","branches_url":"https://api.github.com/repos/RiseVision/rise-node/branches{/branch}","tags_url":"https://api.github.com/repos/RiseVision/rise-node/tags","blobs_url":"https://api.github.com/repos/RiseVision/rise-node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/RiseVision/rise-node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/RiseVision/rise-node/git/refs{/sha}","trees_url":"https://api.github.com/repos/RiseVision/rise-node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/RiseVision/rise-node/statuses/{sha}","languages_url":"https://api.github.com/repos/RiseVision/rise-node/languages","stargazers_url":"https://api.github.com/repos/RiseVision/rise-node/stargazers","contributors_url":"https://api.github.com/repos/RiseVision/rise-node/contributors","subscribers_url":"https://api.github.com/repos/RiseVision/rise-node/subscribers","subscription_url":"https://api.github.com/repos/RiseVision/rise-node/subscription","commits_url":"https://api.github.com/repos/RiseVision/rise-node/commits{/sha}","git_commits_url":"https://api.github.com/repos/RiseVision/rise-node/git/commits{/sha}","comments_url":"https://api.github.com/repos/RiseVision/rise-node/comments{/number}","issue_comment_url":"https://api.github.com/repos/RiseVision/rise-node/issues/comments{/number}","contents_url":"https://api.github.com/repos/RiseVision/rise-node/contents/{+path}","compare_url":"https://api.github.com/repos/RiseVision/rise-node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/RiseVision/rise-node/merges","archive_url":"https://api.github.com/repos/RiseVision/rise-node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/RiseVision/rise-node/downloads","issues_url":"https://api.github.com/repos/RiseVision/rise-node/issues{/number}","pulls_url":"https://api.github.com/repos/RiseVision/rise-node/pulls{/number}","milestones_url":"https://api.github.com/repos/RiseVision/rise-node/milestones{/number}","notifications_url":"https://api.github.com/repos/RiseVision/rise-node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/RiseVision/rise-node/labels{/name}","releases_url":"https://api.github.com/repos/RiseVision/rise-node/releases{/id}","deployments_url":"https://api.github.com/repos/RiseVision/rise-node/deployments","created_at":"2017-07-19T10:24:21Z","updated_at":"2017-09-20T22:44:56Z","pushed_at":"2017-10-25T07:55:13Z","git_url":"git://github.com/RiseVision/rise-node.git","ssh_url":"git@github.com:RiseVision/rise-node.git","clone_url":"https://github.com/RiseVision/rise-node.git","svn_url":"https://github.com/RiseVision/rise-node","homepage":null,"size":10764,"stargazers_count":6,"watchers_count":6,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"archived":false,"open_issues_count":9,"forks":5,"open_issues":9,"watchers":6,"default_branch":"development"}},"base":{"label":"RiseVision:development","ref":"development","sha":"14117c08addedad9378f8a990a64dcf40ae17ee2","user":{"login":"RiseVision","id":18466003,"avatar_url":"https://avatars1.githubusercontent.com/u/18466003?v=4","gravatar_id":"","url":"https://api.github.com/users/RiseVision","html_url":"https://github.com/RiseVision","followers_url":"https://api.github.com/users/RiseVision/followers","following_url":"https://api.github.com/users/RiseVision/following{/other_user}","gists_url":"https://api.github.com/users/RiseVision/gists{/gist_id}","starred_url":"https://api.github.com/users/RiseVision/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RiseVision/subscriptions","organizations_url":"https://api.github.com/users/RiseVision/orgs","repos_url":"https://api.github.com/users/RiseVision/repos","events_url":"https://api.github.com/users/RiseVision/events{/privacy}","received_events_url":"https://api.github.com/users/RiseVision/received_events","type":"Organization","site_admin":false},"repo":{"id":97703767,"name":"rise-node","full_name":"RiseVision/rise-node","owner":{"login":"RiseVision","id":18466003,"avatar_url":"https://avatars1.githubusercontent.com/u/18466003?v=4","gravatar_id":"","url":"https://api.github.com/users/RiseVision","html_url":"https://github.com/RiseVision","followers_url":"https://api.github.com/users/RiseVision/followers","following_url":"https://api.github.com/users/RiseVision/following{/other_user}","gists_url":"https://api.github.com/users/RiseVision/gists{/gist_id}","starred_url":"https://api.github.com/users/RiseVision/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RiseVision/subscriptions","organizations_url":"https://api.github.com/users/RiseVision/orgs","repos_url":"https://api.github.com/users/RiseVision/repos","events_url":"https://api.github.com/users/RiseVision/events{/privacy}","received_events_url":"https://api.github.com/users/RiseVision/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/RiseVision/rise-node","description":null,"fork":false,"url":"https://api.github.com/repos/RiseVision/rise-node","forks_url":"https://api.github.com/repos/RiseVision/rise-node/forks","keys_url":"https://api.github.com/repos/RiseVision/rise-node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/RiseVision/rise-node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/RiseVision/rise-node/teams","hooks_url":"https://api.github.com/repos/RiseVision/rise-node/hooks","issue_events_url":"https://api.github.com/repos/RiseVision/rise-node/issues/events{/number}","events_url":"https://api.github.com/repos/RiseVision/rise-node/events","assignees_url":"https://api.github.com/repos/RiseVision/rise-node/assignees{/user}","branches_url":"https://api.github.com/repos/RiseVision/rise-node/branches{/branch}","tags_url":"https://api.github.com/repos/RiseVision/rise-node/tags","blobs_url":"https://api.github.com/repos/RiseVision/rise-node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/RiseVision/rise-node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/RiseVision/rise-node/git/refs{/sha}","trees_url":"https://api.github.com/repos/RiseVision/rise-node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/RiseVision/rise-node/statuses/{sha}","languages_url":"https://api.github.com/repos/RiseVision/rise-node/languages","stargazers_url":"https://api.github.com/repos/RiseVision/rise-node/stargazers","contributors_url":"https://api.github.com/repos/RiseVision/rise-node/contributors","subscribers_url":"https://api.github.com/repos/RiseVision/rise-node/subscribers","subscription_url":"https://api.github.com/repos/RiseVision/rise-node/subscription","commits_url":"https://api.github.com/repos/RiseVision/rise-node/commits{/sha}","git_commits_url":"https://api.github.com/repos/RiseVision/rise-node/git/commits{/sha}","comments_url":"https://api.github.com/repos/RiseVision/rise-node/comments{/number}","issue_comment_url":"https://api.github.com/repos/RiseVision/rise-node/issues/comments{/number}","contents_url":"https://api.github.com/repos/RiseVision/rise-node/contents/{+path}","compare_url":"https://api.github.com/repos/RiseVision/rise-node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/RiseVision/rise-node/merges","archive_url":"https://api.github.com/repos/RiseVision/rise-node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/RiseVision/rise-node/downloads","issues_url":"https://api.github.com/repos/RiseVision/rise-node/issues{/number}","pulls_url":"https://api.github.com/repos/RiseVision/rise-node/pulls{/number}","milestones_url":"https://api.github.com/repos/RiseVision/rise-node/milestones{/number}","notifications_url":"https://api.github.com/repos/RiseVision/rise-node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/RiseVision/rise-node/labels{/name}","releases_url":"https://api.github.com/repos/RiseVision/rise-node/releases{/id}","deployments_url":"https://api.github.com/repos/RiseVision/rise-node/deployments","created_at":"2017-07-19T10:24:21Z","updated_at":"2017-09-20T22:44:56Z","pushed_at":"2017-10-25T07:55:13Z","git_url":"git://github.com/RiseVision/rise-node.git","ssh_url":"git@github.com:RiseVision/rise-node.git","clone_url":"https://github.com/RiseVision/rise-node.git","svn_url":"https://github.com/RiseVision/rise-node","homepage":null,"size":10764,"stargazers_count":6,"watchers_count":6,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"archived":false,"open_issues_count":9,"forks":5,"open_issues":9,"watchers":6,"default_branch":"development"}},"_links":{"self":{"href":"https://api.github.com/repos/RiseVision/rise-node/pulls/26"},"html":{"href":"https://github.com/RiseVision/rise-node/pull/26"},"issue":{"href":"https://api.github.com/repos/RiseVision/rise-node/issues/26"},"comments":{"href":"https://api.github.com/repos/RiseVision/rise-node/issues/26/comments"},"review_comments":{"href":"https://api.github.com/repos/RiseVision/rise-node/pulls/26/comments"},"review_comment":{"href":"https://api.github.com/repos/RiseVision/rise-node/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/RiseVision/rise-node/pulls/26/commits"},"statuses":{"href":"https://api.github.com/repos/RiseVision/rise-node/statuses/428921e16878c2009573522d3e5a322f2ee8ebb0"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"jarenal"}}