diff --git a/js/models/Identity.js b/js/models/Identity.js index 396e78ae5..8cda88980 100644 --- a/js/models/Identity.js +++ b/js/models/Identity.js @@ -379,8 +379,14 @@ Identity.prototype.setBackupNeeded = function(backupNeeded) { self.backupNeeded = !!backupNeeded; self.verifyChecksum(function(err, match) { - if (err) return cb(err); - if (!match) return cb('The profile is out of sync. Please re-login to get the latest changes.'); + if (err) { + log.error(err); + return; + } + if (!match) { + log.error('The profile is out of sync. Please re-login to get the latest changes.'); + return; + } self.store({ noWallets: true diff --git a/js/models/TxProposal.js b/js/models/TxProposal.js index ba3def705..374d40077 100644 --- a/js/models/TxProposal.js +++ b/js/models/TxProposal.js @@ -75,6 +75,8 @@ TxProposal.prototype._checkPayPro = function() { if (!this.merchant.total || !this.merchant.outs[0].amountSatStr || !this.merchant.outs[0].address) throw new Error('PayPro: Missing amount'); + console.log('outs ', this.builder.vanilla.outs); + console.log('size ', _.size(outs)); var outs = JSON.parse(this.builder.vanilla.outs); if (_.size(outs) != 1) throw new Error('PayPro: Wrong outs in Tx'); diff --git a/test/Identity.js b/test/Identity.js index c74572245..a77737139 100644 --- a/test/Identity.js +++ b/test/Identity.js @@ -175,8 +175,122 @@ describe('Identity model', function() { done(); }); }); + + + it('should return an error', function(done) { + var storage = sinon.stub(); + storage.setCredentials = sinon.stub(); + + var opts = { + email: 'test@test.com', + password: '123', + network: { + testnet: { + url: 'https://test-insight.bitpay.com:443' + }, + livenet: { + url: 'https://insight.bitpay.com:443' + }, + }, + storage: storage, + }; + + var iden = new Identity(opts); + + storage.getItem = sinon.stub().yields('error', JSON.stringify(iden)); + + Identity.open(opts, function(err, res) { + should.exist(err); + done(); + }); + }); + + it('should return an error because data has bad format', function(done) { + var storage = sinon.stub(); + storage.setCredentials = sinon.stub(); + + var opts = { + email: 'test@test.com', + password: '123', + network: { + testnet: { + url: 'https://test-insight.bitpay.com:443' + }, + livenet: { + url: 'https://insight.bitpay.com:443' + }, + }, + storage: storage, + }; + + var iden = new Identity(opts); + + storage.getItem = sinon.stub().yields(null, '{badformat'); //bad format of object + + Identity.open(opts, function(err, res) { + should.exist(err); + done(); + }); + }); + }); + + describe('#verifyChecksum', function(done) { + it('should return an error', function(done) { + var storage = sinon.stub(); + storage.setCredentials = sinon.stub(); + + var opts = { + email: 'test@test.com', + password: '123', + network: { + testnet: { + url: 'https://test-insight.bitpay.com:443' + }, + livenet: { + url: 'https://insight.bitpay.com:443' + }, + }, + storage: storage, + }; + + var iden = new Identity(opts); + storage.getItem = sinon.stub().yields('error', null); + iden.verifyChecksum(function(err, res) { + should.exist(err); + done(); + }); + }); + + it('should return an error bad object format', function(done) { + var storage = sinon.stub(); + storage.setCredentials = sinon.stub(); + + var opts = { + email: 'test@test.com', + password: '123', + network: { + testnet: { + url: 'https://test-insight.bitpay.com:443' + }, + livenet: { + url: 'https://insight.bitpay.com:443' + }, + }, + storage: storage, + }; + + var iden = new Identity(opts); + storage.getItem = sinon.stub().yields(null, '{badformat'); + iden.verifyChecksum(function(err, res) { + should.exist(err); + done(); + }); + }); + }); + + describe('#resendVerificationEmail', function(done) { it('should resend verification email', function() { var storage = sinon.stub(); @@ -233,6 +347,20 @@ describe('Identity model', function() { iden.store.calledOnce.should.be.true; iden.store.getCall(0).args[0].noWallets.should.equal(true); }); + it('should not set the flag backupNeeded ', function() { + var iden = new Identity(getDefaultParams()); + iden.verifyChecksum = sinon.stub().yields('error', true); + iden.setBackupNeeded(false); + iden.backupNeeded.should.be.false; + iden.store.calledOnce.should.be.false; + }); + it('should not set the flag backupNeeded match returns false', function() { + var iden = new Identity(getDefaultParams()); + iden.verifyChecksum = sinon.stub().yields(null, false); + iden.setBackupNeeded(false); + iden.backupNeeded.should.be.false; + iden.store.calledOnce.should.be.false; + }); }); describe('#close', function(done) { @@ -481,6 +609,30 @@ describe('Identity model', function() { }); }); + it('should return error', function(done) { + args.storage.getItem = sinon.stub().yields(null, JSON.stringify(iden)); + args.storage.setItem = sinon.stub(); + iden.verifyChecksum = sinon.stub().yields('error'); + iden.createWallet({ + walletClass: walletClass, + }, function(err, w) { + should.exist(err); + done(); + }); + }); + + it('should return error because verifyChecksum returns false', function(done) { + args.storage.getItem = sinon.stub().yields(null, JSON.stringify(iden)); + args.storage.setItem = sinon.stub(); + iden.verifyChecksum = sinon.stub().yields(null, false); + iden.createWallet({ + walletClass: walletClass, + }, function(err, w) { + should.exist(err); + done(); + }); + }); + it('should be able to create wallets with random pk', function(done) { args.storage.getItem = sinon.stub().yields(null, JSON.stringify(iden)); args.storage.setItem = sinon.stub(); @@ -528,6 +680,25 @@ describe('Identity model', function() { }); }); }); + it('should return error', function(done) { + var args = createIdentity(); + args.storage.getItem.onFirstCall().callsArgWith(1, null, '{"walletError'); + var backup = Wallet.fromUntrustedObj; + args.params.noWallets = true; + sinon.stub().returns(args.wallet); + + var opts = { + importWallet: sinon.stub().returns(getNewWallet()), + }; + + Identity.create(args.params, function(err, iden) { + iden.retrieveWalletFromStorage('dummy', opts, function(err, wallet) { + + should.exist(err); + done(); + }); + }); + }); }); @@ -659,6 +830,34 @@ describe('Identity model', function() { done(); }); }); + + it('should return an error ', function(done) { + iden.addWallet(w); + iden.storage.getItem = sinon.stub().yields('error', JSON.stringify(iden)); + iden.deleteWallet('32', function(err) { + should.exist(err); + done(); + }); + }); + + it('should return an checksum error ', function(done) { + iden.addWallet(w); + iden.verifyChecksum = sinon.stub().yields(null, false); + iden.deleteWallet('32', function(err) { + should.exist(err); + done(); + }); + }); + + it('should return an error because of removeItem ', function(done) { + iden.addWallet(w); + iden.storage.getItem = sinon.stub().yields(null, JSON.stringify(iden)); + iden.storage.removeItem = sinon.stub().yields('error', JSON.stringify(iden)); + iden.deleteWallet('32', function(err) { + should.exist(err); + done(); + }); + }); }); @@ -690,6 +889,58 @@ describe('Identity model', function() { }); */ + describe('#bindWallet', function() { + var opts = { + secret: '8WtTuiFTkhP5ao7AF2QErSwV39Cbur6pdMebKzQXFqL59RscXM', + nickname: 'test', + password: 'pass' + }; + var iden = null; + var args = null; + var net = null; + + beforeEach(function() { + args = createIdentity(); + args.params.Async = net = sinon.stub(); + net.cleanUp = sinon.spy(); + net.on = sinon.stub(); + net.start = sinon.spy(); + var old = Identity.prototype.createWallet; + Identity.create(args.params, function(err, res) { + iden = res; + iden.store.restore(); + }); + }); + + it('should bindWallet', function() { + var net = sinon.stub(); + + net.greet = sinon.stub(); + net.cleanUp = sinon.stub(); + net.start = sinon.stub().yields(null); + net.on = sinon.stub(); + net.on.withArgs('data').yields('senderId', { + type: 'walletId', + networkName: 'aWeirdNetworkName', + opts: {}, + }); + + opts.privHex = undefined; + opts.Async = net; + + var w = { + on: sinon.stub(), + getId: sinon.stub().returns('1'), + getName: sinon.stub().returns('wName') + } + iden.getWalletById = sinon.stub().returns(true); + iden.emitAndKeepAlive = sinon.spy(); + iden.bindWallet(w); + iden.emitAndKeepAlive.calledOnce.should.be.true; + }); + }); + + describe('#joinWallet', function() { var opts = { secret: '8WtTuiFTkhP5ao7AF2QErSwV39Cbur6pdMebKzQXFqL59RscXM', @@ -734,6 +985,28 @@ describe('Identity model', function() { }); }); + it('should yield bad secret', function(done) { + var net = sinon.stub(); + + net.greet = sinon.stub(); + net.cleanUp = sinon.stub(); + net.start = sinon.stub().yields(null); + net.on = sinon.stub(); + net.on.withArgs('data').yields('senderId', { + type: 'walletId', + networkName: 'testnet', + opts: {}, + }); + + opts.privHex = undefined; + opts.Async = net; + iden.decodeSecret = sinon.stub().returns(false); + iden.joinWallet(opts, function(err, w) { + err.should.equal('badSecret'); + done(); + }); + }); + it('should callback with a join error in case of a problem', function(done) { opts.privHex = undefined; @@ -1267,6 +1540,47 @@ describe('Identity model', function() { }); + describe('readAndBindWallet', function(done) { + var opts; + var storage = sinon.stub(); + beforeEach(function() { + + storage.setCredentials = sinon.stub(); + storage.getItem = sinon.stub().yields({}); + opts = { + email: 'test@test.com', + password: '123', + network: { + testnet: { + url: 'https://test-insight.bitpay.com:443' + }, + livenet: { + url: 'https://insight.bitpay.com:443' + }, + }, + storage: storage, + }; + }); + it('should throw error', function(done) { + var iden = new Identity(opts); + iden.retrieveWalletFromStorage = sinon.stub().yields('error'); + iden.readAndBindWallet('1', function(err) { + should.exist(err); + done(); + }); + }); + it('should call addWallet', function(done) { + var iden = new Identity(opts); + iden.retrieveWalletFromStorage = sinon.stub().yields(null); + iden.addWallet = sinon.spy(); + iden.bindWallet = sinon.spy(); + iden.readAndBindWallet('1', function(err) { + iden.addWallet.callCount.should.be.equal(1); + iden.bindWallet.callCount.should.be.equal(1); + done(); + }); + }); + }); });