From 24c927a93a0ce2bf3f6167994228949da89c1041 Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Sat, 25 Oct 2014 17:14:04 -0300 Subject: [PATCH] Remove WalletLock and Storage tests --- copay.js | 1 - js/models/Wallet.js | 1 - js/models/WalletLock.js | 101 -------- test/Identity.js | 229 ++++++++-------- test/PayPro.js | 10 +- test/Profile.js | 185 ------------- test/Storage.js | 461 --------------------------------- test/Wallet.js | 30 +-- test/WalletLock.js | 99 ------- test/mocks/FakeBlockchain.js | 3 + test/mocks/FakeLocalStorage.js | 43 --- 11 files changed, 114 insertions(+), 1049 deletions(-) delete mode 100644 js/models/WalletLock.js delete mode 100644 test/Profile.js delete mode 100644 test/Storage.js delete mode 100644 test/WalletLock.js delete mode 100644 test/mocks/FakeLocalStorage.js diff --git a/copay.js b/copay.js index 0bf381bf8..d56f9f25a 100644 --- a/copay.js +++ b/copay.js @@ -14,7 +14,6 @@ var Insight = module.exports.Insight = require('./js/models/Insight'); module.exports.Identity = require('./js/models/Identity'); module.exports.Wallet = require('./js/models/Wallet'); -module.exports.WalletLock = require('./js/models/WalletLock'); module.exports.PluginManager = require('./js/models/PluginManager'); module.exports.version = require('./version').version; module.exports.commitHash = require('./version').commitHash; diff --git a/js/models/Wallet.js b/js/models/Wallet.js index 68e664dd0..dd5b7d147 100644 --- a/js/models/Wallet.js +++ b/js/models/Wallet.js @@ -24,7 +24,6 @@ var PublicKeyRing = require('./PublicKeyRing'); var TxProposal = require('./TxProposal'); var TxProposals = require('./TxProposals'); var PrivateKey = require('./PrivateKey'); -var WalletLock = require('./WalletLock'); var Async = require('./Async'); var Insight = module.exports.Insight = require('./Insight'); var copayConfig = require('../../config'); diff --git a/js/models/WalletLock.js b/js/models/WalletLock.js deleted file mode 100644 index 0b1fe503d..000000000 --- a/js/models/WalletLock.js +++ /dev/null @@ -1,101 +0,0 @@ -'use strict'; - -var preconditions = require('preconditions').singleton(); - -function WalletLock(storage, walletId, timeoutMin) { - preconditions.checkArgument(storage); - preconditions.checkArgument(walletId); - - this.storage = storage; - this.timeoutMin = timeoutMin || 5; - this.key = WalletLock._keyFor(walletId); -} - - -WalletLock.prototype.init = function(cb) { - preconditions.checkArgument(cb); - var self = this; - - self.storage.getSessionId(function(sid) { - preconditions.checkState(sid); - - self.sessionId = sid; - cb(); - }); -}; - -WalletLock._keyFor = function(walletId) { - return 'lock' + '::' + walletId; -}; - -WalletLock.prototype._isLockedByOther = function(cb) { - var self = this; - - this.storage.getGlobal(this.key, function(json) { - var wl = json ? JSON.parse(json) : null; - if (!wl || !wl.expireTs) - return cb(false); - - var expiredSince = Date.now() - wl.expireTs; - if (expiredSince >= 0) - return cb(false); - - var isMyself = wl.sessionId === self.sessionId; - - if (isMyself) - return cb(false); - - // Seconds remainding - return cb(parseInt(-expiredSince / 1000)); - }); -}; - - -WalletLock.prototype._setLock = function(cb) { - preconditions.checkArgument(cb); - preconditions.checkState(this.sessionId); - var self = this; - - this.storage.setGlobal(this.key, { - sessionId: this.sessionId, - expireTs: Date.now() + this.timeoutMin * 60 * 1000, - }, function() { - - cb(null); - }); -}; - - -WalletLock.prototype._doKeepAlive = function(cb) { - preconditions.checkArgument(cb); - preconditions.checkState(this.sessionId); - - var self = this; - - this._isLockedByOther(function(t) { - if (t) - return cb(new Error('LOCKED: Wallet is locked for ' + t + ' srcs')); - - self._setLock(cb); - }); -}; - - - -WalletLock.prototype.keepAlive = function(cb) { - var self = this; - - if (!self.sessionId) { - return self.init(self._doKeepAlive.bind(self, cb)); - }; - - return this._doKeepAlive(cb); -}; - - -WalletLock.prototype.release = function(cb) { - this.storage.removeGlobal(this.key, cb); -}; - - -module.exports = WalletLock; diff --git a/test/Identity.js b/test/Identity.js index 87c5aa1c2..91fe4c4c0 100644 --- a/test/Identity.js +++ b/test/Identity.js @@ -8,15 +8,11 @@ var should = chai.should(); var PluginManager = require('../js/models/PluginManager'); var Insight = require('../js/models/Insight'); - -var FakeBlockchain = requireMock('FakeBlockchain'); -var FakeStorage = function FakeStorage() {}; var Identity = copay.Identity; +var Wallet = copay.Wallet; var Passphrase = copay.Passphrase; -var mockLocalStorage = requireMock('FakeLocalStorage'); -var mockSessionStorage = requireMock('FakeLocalStorage'); - +var FakeBlockchain = require('./mocks/FakeBlockchain'); var PERSISTED_PROPERTIES = (copay.Wallet || require('../js/models/Wallet')).PERSISTED_PROPERTIES; @@ -29,56 +25,11 @@ function assertObjectEqual(a, b) { } -describe('Identity model', function() { - var iden, storage, wallet, profile; - - beforeEach(function(done) { - storage = sinon.stub(); - storage.getItem = sinon.stub(); - storage.set = sinon.stub().yields(null); - storage.savePassphrase = sinon.spy(); - storage.restorePassphrase = sinon.spy(); - storage.setPassword = sinon.spy(); - storage.hasPassphrase = sinon.stub().returns(true); - storage.getSessionId = sinon.spy(); - storage.setFromObj = sinon.spy(); - storage.deletePrefix = sinon.stub().yields(null); - Identity._newStorage = sinon.stub().returns(storage); - - - wallet = sinon.stub(); - wallet.on = sinon.stub().yields(null); - wallet.netStart = sinon.stub(); - wallet.toObj = sinon.stub(); - wallet.getName = sinon.stub().returns('walletname'); - wallet.getId = sinon.stub().returns('wid:123'); - Identity._newWallet = sinon.stub().returns(wallet); - - profile = sinon.stub(); - profile.addWallet = sinon.stub().yields(null);; - profile.deleteWallet = sinon.stub().yields(null);; - profile.listWallets = sinon.stub().returns([]); - profile.setLastOpenedTs = sinon.stub().yields(null);; - profile.store = sinon.stub().yields(null);; - profile.getName = sinon.stub().returns('profile name');; - Identity._createProfile = sinon.stub().callsArgWith(3, null, profile); - - - - Identity.create(email, password, config, function(err, i) { - iden = i; - done(); - }); - }); - - - afterEach(function() { - iden = storage = wallet = profile = undefined; - }); - - +describe.only('Identity model', function() { + var params, wallet; var email = 'hola@hola.com'; var password = 'password'; + var blockchain; var config = { walletDefaults: { @@ -108,80 +59,115 @@ describe('Identity model', function() { url: 'https://insight.bitpay.com:443' }, }, - version: '0.0.1', + version: '0.0.1' + }; + + function getDefaultParams() { + var params = _.clone(config); + _.extend(params, { + email: email, + password: password + }); + params.storage = sinon.stub(); + params.storage.setCredentials = sinon.stub(); + params.storage.getItem = sinon.stub(); + params.storage.setItem = sinon.stub(); + params.storage.setItem.onFirstCall().callsArgWith(2, null); + params.storage.setItem.onSecondCall().callsArgWith(2, null); + return params; + } + + function createIdentity(done) { + console.error("Reseting"); + + // TODO (eordano): Change this to proper dependency injection + blockchain = new FakeBlockchain(config.blockchain); + blockchain.on = sinon.stub(); + Wallet._newInsight = sinon.stub().returns(blockchain); + + wallet = sinon.stub(); + wallet.on = sinon.stub().yields(null); + wallet.netStart = sinon.stub(); + wallet.toObj = sinon.stub(); + wallet.getName = sinon.stub().returns('walletname'); + wallet.getId = sinon.stub().returns('wid:123'); + Identity._newWallet = sinon.stub().returns(wallet); + + params = getDefaultParams(); + + Identity.create(params, done); }; - describe('#constructors', function() { - describe('#new', function() { - it('should create an identity', function() { - var iden = new Identity(password, config); - should.exist(iden); - iden.walletDefaults.should.deep.equal(config.walletDefaults); - }); + describe('new Identity()', function() { + it('returns an identity', function() { + var iden = new Identity(getDefaultParams()); + should.exist(iden); + iden.walletDefaults.should.deep.equal(config.walletDefaults); }); + }); - describe('#create', function(done) { - it('should call .store', function(done) { - Identity.create(email, password, config, function(err, iden) { + describe('Identity.create()', function() { + it('should call .store', function(done) { + Identity.create(params, function(err, iden) { - should.not.exist(err); - should.exist(iden.profile.addWallet); + should.not.exist(err); + should.exist(iden.profile.addWallet); - Identity._createProfile.getCall(0).args[0].should.deep.equal(email); - Identity._createProfile.getCall(0).args[1].should.deep.equal(password); - done(); - }); - }); - }); - - describe('#open', function(done) { - beforeEach(function() { - storage.getFirst = sinon.stub().yields(null, 'wallet1234'); - profile.listWallets = sinon.stub().returns([{ - id: 'walletid' - }]); - profile.getLastFocusedWallet = sinon.stub().returns(null); - Identity._openProfile = sinon.stub().callsArgWith(3, null, profile); - Identity._walletRead = sinon.stub().callsArgWith(2, null, wallet); - }); - - it('should call ._openProfile', function(done) { - Identity.open(email, password, config, function(err, iden, w) { - Identity._openProfile.calledOnce.should.equal(true); - should.not.exist(err); - iden.profile.should.equal(profile); - done(); - }); - }); - - it('should return last focused wallet', function(done) { - var wallets = [{ - id: 'wallet1', - store: sinon.stub().yields(null), - netStart: sinon.stub(), - }, { - id: 'wallet2', - store: sinon.stub().yields(null), - netStart: sinon.stub(), - }, { - id: 'wallet3', - store: sinon.stub().yields(null), - netStart: sinon.stub(), - }]; - profile.listWallets = sinon.stub().returns(wallets); - profile.getLastFocusedWallet = sinon.stub().returns(wallets[1]); - Identity._walletRead = sinon.stub(); - Identity._walletRead.onCall(0).callsArgWith(2, null, wallets[0]); - Identity._walletRead.onCall(1).callsArgWith(2, null, wallets[1]); - Identity._walletRead.onCall(2).callsArgWith(2, null, wallets[2]); - - Identity.open(email, password, config, function(err, iden, w) { - w.id.should.equal('wallet2'); - done(); - }); + Identity._createProfile.getCall(0).args[0].should.deep.equal(email); + Identity._createProfile.getCall(0).args[1].should.deep.equal(password); + done(); }); }); }); + + describe('#open', function(done) { + beforeEach(function() { + storage.getFirst = sinon.stub().yields(null, 'wallet1234'); + profile.listWallets = sinon.stub().returns([{ + id: 'walletid' + }]); + profile.getLastFocusedWallet = sinon.stub().returns(null); + Identity._openProfile = sinon.stub().callsArgWith(3, null, profile); + Identity._walletRead = sinon.stub().callsArgWith(2, null, wallet); + }); + + it('should call ._openProfile', function(done) { + Identity.open(email, password, config, function(err, iden, w) { + Identity._openProfile.calledOnce.should.equal(true); + should.not.exist(err); + iden.profile.should.equal(profile); + done(); + }); + }); + + it('should return last focused wallet', function(done) { + var wallets = [{ + id: 'wallet1', + store: sinon.stub().yields(null), + netStart: sinon.stub(), + }, { + id: 'wallet2', + store: sinon.stub().yields(null), + netStart: sinon.stub(), + }, { + id: 'wallet3', + store: sinon.stub().yields(null), + netStart: sinon.stub(), + }]; + profile.listWallets = sinon.stub().returns(wallets); + profile.getLastFocusedWallet = sinon.stub().returns(wallets[1]); + Identity._walletRead = sinon.stub(); + Identity._walletRead.onCall(0).callsArgWith(2, null, wallets[0]); + Identity._walletRead.onCall(1).callsArgWith(2, null, wallets[1]); + Identity._walletRead.onCall(2).callsArgWith(2, null, wallets[2]); + + Identity.open(email, password, config, function(err, iden, w) { + w.id.should.equal('wallet2'); + done(); + }); + }); + }); + describe('#store', function() { it('should call .store from profile and no wallets', function(done) { @@ -417,7 +403,9 @@ describe('Identity model', function() { }); }); - + /** + * TODO (eordano): Move this to a different test file + * describe('#pluginManager', function() { it('should create a new PluginManager object', function() { var pm = new PluginManager({plugins: { FakeLocalStorage: true }, pluginsPath: '../../test/mocks/'}); @@ -431,6 +419,7 @@ describe('Identity model', function() { should.exist(uri); }); }); + */ describe('#joinWallet', function() { var opts = { diff --git a/test/PayPro.js b/test/PayPro.js index b2c6f42bc..969c64dcf 100644 --- a/test/PayPro.js +++ b/test/PayPro.js @@ -10,9 +10,6 @@ var Address = bitcore.Address; var PayPro = bitcore.PayPro; var bignum = bitcore.Bignum; var startServer = copay.FakePayProServer; // TODO should be require('./mocks/FakePayProServer'); -var localMock = requireMock('FakeLocalStorage'); -var sessionMock = requireMock('FakeLocalStorage'); -var Storage = copay.Storage; var server; @@ -21,8 +18,7 @@ var walletConfig = { totalCopayers: 1, spendUnconfirmed: true, reconnectDelay: 100, - networkName: 'testnet', - storage: requireMock('FakeLocalStorage').storageParams, + networkName: 'testnet' }; var getNewEpk = function() { @@ -57,11 +53,8 @@ describe('PayPro (in Wallet) model', function() { networkName: c.networkName, }); - var storage = new Storage(walletConfig.storage); - storage._setPassphrase('xxx'); var network = new Network(walletConfig.network); var blockchain = new Blockchain(walletConfig.blockchain); - c.storage = storage; c.network = network; c.blockchain = blockchain; @@ -135,7 +128,6 @@ describe('PayPro (in Wallet) model', function() { Wallet._newInsight = sinon.stub().returns(new Blockchain(walletConfig.blockchain)); var w = Wallet.fromObj(cachedW2obj, { - storage: cachedW2.storage, blockchainOpts: {}, networkOpts: {}, }); diff --git a/test/Profile.js b/test/Profile.js deleted file mode 100644 index fe09f1773..000000000 --- a/test/Profile.js +++ /dev/null @@ -1,185 +0,0 @@ -'use strict'; -var _ = require('underscore'); -var chai = chai || require('chai'); -var should = chai.should(); -var bitcore = bitcore || require('bitcore'); -var buffertools = bitcore.buffertools; -var Profile = require('../js/models/Profile') -var sinon = require('sinon'); -var FakeStorage = function() {}; - -describe('Profile model', function() { - var email = 'email@pepe.com'; - var password = 'iamnotsatoshi'; - var hash = '1234'; - var storage = new FakeStorage(); - var opts = { - email: email, - hash: hash, - }; - - beforeEach(function() { - storage.setPassword = sinon.stub(); - storage.set = sinon.stub(); - storage.set.yields(null); - storage.get = sinon.stub().yields(null); - }); - - it('should fail create an instance', function() { - (function() { - new Profile({ - email: email, - }, storage) - }).should.throw('Illegal Arg'); - }); - - it('should create an instance', function() { - var p = new Profile({ - email: email, - hash: hash, - }, storage); - should.exist(p); - }); - - it('#fromObj #toObj round trip', function() { - var p = new Profile(opts, storage); - var p2 = new Profile(p.toObj(), storage); - p2.should.deep.equal(p); - }); - - describe('#addWallet', function() { - it('should add a wallet id', function(done) { - var p = new Profile(opts, storage); - p.addWallet('123', {}, function(err) { - p.getWallet('123').createdTs.should.be.above(123456789); - storage.set.getCall(0).args[1].should.deep.equal(p.toObj()); - done(); - }) - }); - it('should keep old ts value', function(done) { - var p = new Profile(opts, storage); - p.walletInfos['123'] = { - createdTs: 1 - }; - p.addWallet('123', {}, function(err) { - err.toString().should.contain('WEXIST'); - p.walletInfos['123'].createdTs.should.equal(1); - should.not.exist(storage.set.getCall(0)); - done(); - }) - }); - it('should add a wallet info', function(done) { - var p = new Profile(opts, storage); - p.addWallet('123', { - a: 1, - b: 2 - }, function(err) { - var w = p.getWallet('123'); - w.createdTs.should.be.above(123456789); - w.a.should.equal(1); - w.b.should.equal(2); - storage.set.getCall(0).args[1].should.deep.equal(p.toObj()); - done(); - }) - }); - }); - - describe('#addToWallet', function() { - it('should warn if wallet does not exist', function(done) { - var p = new Profile(opts, storage); - p.addToWallet('234', { - 1: 1 - }, function(err) { - err.toString().should.contain('WNOEXIST'); - done(); - }); - }); - it('should add info to a wallet', function(done) { - var p = new Profile(opts, storage); - p.addWallet('234', {}, function(err) { - p.addToWallet('234', { - 'hola': 1 - }, function(err) { - var w = p.getWallet('234'); - should.exist(w); - w.hola.should.equal(1); - w.createdTs.should.be.above(123456789); - done(); - }) - }) - }); - }); - - - - describe('#listWallets', function() { - it('should list wallets in order', function(done) { - var p = new Profile(opts, storage); - p.addWallet('123', {}, function(err) { - setTimeout(function() { - p.addWallet('234', {}, function(err) { - _.pluck(p.listWallets(), 'id').should.deep.equal(['123', '234']); - done(); - }) - }, 10); - }); - }); - }); - - describe('#deleteWallet', function() { - it('should delete a wallet', function(done) { - var p = new Profile(opts, storage); - p.addWallet('123', {}, function(err) { - p.addWallet('234', {}, function(err) { - p.addWallet('345', {}, function(err) { - _.pluck(p.listWallets(), 'id').sort().should.deep.equal(['123', '234', '345']); - p.deleteWallet('234', function(err) { - _.pluck(p.listWallets(), 'id').sort().should.deep.equal(['123', '345']); - done(); - }); - }) - }); - }); - }); - it('should warn if wallet does not exist', function(done) { - var p = new Profile(opts, storage); - p.deleteWallet('234', function(err) { - err.toString().should.contain('WNOEXIST'); - done(); - }); - }); - }); - - - describe('#store', function() { - it('should call storage set', function(done) { - var p = new Profile(opts, storage); - p.store({}, function(err) { - storage.set.getCall(0).args[1].should.deep.equal(p.toObj()); - should.not.exist(err); - done(); - }) - }); - it('should use fail to overwrite', function(done) { - storage.get = sinon.stub().yields(123); - var p = new Profile(opts, storage); - p.store({}, function(err) { - err.toString().should.contain('PEXISTS'); - should.not.exist(storage.set.getCall(0)); - done(); - }) - }); - - it('should use overwrite param', function(done) { - storage.get = sinon.stub().yields(123); - var p = new Profile(opts, storage); - p.store({ - overwrite: true - }, function(err) { - storage.set.getCall(0).args[1].should.deep.equal(p.toObj()); - should.not.exist(err); - done(); - }) - }); - }); -}); diff --git a/test/Storage.js b/test/Storage.js deleted file mode 100644 index 458035441..000000000 --- a/test/Storage.js +++ /dev/null @@ -1,461 +0,0 @@ -'use strict'; -var Storage = copay.Storage; - -var fakeWallet = 'fake-wallet-id'; -var timeStamp = Date.now(); - -describe('Storage model', function() { - - var s; - beforeEach(function(done) { - s = new Storage(requireMock('FakeLocalStorage').storageParams); - s.setPassword('mysupercoolpassword'); - s.clearAll(done); - }); - - - it('should create an instance', function() { - var s2 = new Storage(requireMock('FakeLocalStorage').storageParams); - should.exist(s2); - }); - it('should fail when encrypting without a password', function() { - var s2 = new Storage(requireMock('FakeLocalStorage').storageParams); - (function() { - var params = _.clone(requireMock('FakeLocalStorage').storageParams); - params.passphrase = '1234'; - new Storage(params); - }).should.throw('Illegal Argument'); - }); - it('should be able to encrypt and decrypt', function(done) { - s._write(fakeWallet + timeStamp, 'value', function() { - s._read(fakeWallet + timeStamp, function(v) { - v.should.equal('value'); - done(); - }); - }); - }); - it('should be able to set a value', function(done) { - s._write(fakeWallet + timeStamp, 1, function() { - done(); - }); - }); - var getSetData = [ - 1, 1000, -15, -1000, - 0.1, -0.5, -0.5e-10, Math.PI, - 'hi', 'auydoaiusyodaisudyoa', '0b5b8556a0c2ce828c9ccfa58b3dd0a1ae879b9b', - '1CjPR7Z5ZSyWk6WtXvSFgkptmpoi4UM9BC', 'OP_DUP OP_HASH160 80ad90d4035', [1, 2, 3, 4, 5, 6], { - x: 1, - y: 2 - }, { - x: 'hi', - y: null - }, { - a: {}, - b: [], - c: [1, 2, 'hi'] - }, - null - ]; - getSetData.forEach(function(obj) { - it('should be able to set a value and get it for ' + JSON.stringify(obj), function(done) { - s._write(fakeWallet + timeStamp, obj, function() { - s._read(fakeWallet + timeStamp, function(obj2) { - JSON.stringify(obj2).should.equal(JSON.stringify(obj)); - done(); - }); - }); - }); - }); - - describe('#encrypt', function() { - it('should encrypt the encrypted wallet', function(done) { - s._write(fakeWallet + timeStamp, 'testval', function() { - var obj = { - test: 'testval' - }; - var encrypted = s.encrypt(obj); - encrypted.length.should.be.greaterThan(10); - done(); - }); - }); - }); - - describe('#_getWalletIds_Old', function() { - it('should get wallet ids', function(done) { - s._write('1::hola', 'juan', function() { - s._write('2::hola', 'juan', function() { - s._getWalletIds_Old(function(v) { - v.should.deep.equal(['1', '2']); - done(); - }); - }); - }); - }); - }); - - if (is_browser) { - describe('#getSessionId', function() { - it('should get SessionId', function(done) { - s.getSessionId(function(sid) { - should.exist(sid); - s.getSessionId(function(sid2) { - sid2.should.equal(sid); - done(); - }); - }); - }); - }); - } - - describe('#getWallets1_Old', function() { - it('should retrieve wallets from storage', function(done) { - s._write('1::hola', 'juan', function() { - s._write('2::hola', 'juan', function() { - s.setGlobal('nameFor::1', 'hola', function() { - - s.getWallets1_Old(function(ws) { - ws[0].should.deep.equal({ - id: '1', - name: 'hola', - }); - ws[1].should.deep.equal({ - id: '2', - name: undefined - }); - done(); - }); - }); - }); - }); - }); - it('should retrieve wallets from storage (with delay)', function(done) { - s._write('1::hola', 'juan', function() { - s._write('2::hola', 'juan', function() { - s.setGlobal('nameFor::1', 'hola', function() { - - var orig = s.getGlobal.bind(s); - s.getGlobal = function(k, cb) { - setTimeout(function() { - orig(k, cb); - }, 1); - }; - - s.getWallets1_Old(function(ws) { - ws[0].should.deep.equal({ - id: '1', - name: 'hola', - }); - ws[1].should.deep.equal({ - id: '2', - name: undefined - }); - done(); - }); - }); - }); - }); - }); - }); - - describe.skip('#getWallets2_Old', function() { - it('should retrieve wallets from storage', function(done) { - var w1 = { - name: 'juan', - opts: { - name: 'wallet1' - } - }; - var w2 = { - name: 'pepe' - }; - s.set('wallet::1_wallet1', w1, function() { - s.set('wallet::2', w2, function() { - s.getWallets2_Old(function(ws) { - ws[0].should.deep.equal({ - id: '1', - name: 'wallet1', - }); - ws[1].should.deep.equal({ - id: '2', - name: undefined - }); - done(); - }); - }); - }); - }); - }); - - - describe.skip('#getWallets', function() { - it('should retrieve wallets from storage both new and old format', function(done) { - var w1 = { - name: 'juan', - opts: { - name: 'wallet1' - } - }; - var w2 = { - name: 'pepe' - }; - - s.set('wallet::1_wallet1', w1, function() { - s.set('wallet::2', w2, function() { - s._write('3::name', 'matias', function() { - s._write('1::name', 'juan', function() { - s.setGlobal('nameFor::3', 'wallet3', function() { - s.getWallets_Old(function(ws) { - ws.length.should.equal(3); - ws[0].should.deep.equal({ - id: '1', - name: 'wallet1', - }); - ws[1].should.deep.equal({ - id: '2', - name: undefined - }); - ws[2].should.deep.equal({ - id: '3', - name: 'wallet3', - }); - done(); - }); - }); - }); - }) - }); - }); - }); - }); - - describe.skip('#deleteWallet_Old', function() { - it('should fail to delete a unexisting wallet', function(done) { - s._write('1::hola', 'juan', function() { - s._write('2::hola', 'juan', function() { - s.deleteWallet_Old('3', function(err) { - err.toString().should.include('WNOTFOUND'); - done(); - }); - }); - }); - }); - - it('should delete a wallet', function(done) { - s._write('1::hola', 'juan', function() { - s._write('2::hola', 'juan', function() { - s.deleteWallet_Old('1', function(err) { - should.not.exist(err); - s.getWallets_Old(function(ws) { - ws.length.should.equal(1); - ws[0].should.deep.equal({ - id: '2', - name: undefined - }); - done(); - }); - }); - }); - }); - }); - }); - - describe.skip('#deleteWallet', function() { - it('should fail to delete a unexisting wallet', function(done) { - var w1 = { - name: 'juan', - opts: { - name: 'wallet1' - } - }; - var w2 = { - name: 'pepe' - }; - - s.set('wallet::1', w1, function() { - s.set('wallet::2', w2, function() { - s.deleteWallet('3', function(err) { - err.toString().should.include('WNOTFOUND'); - done(); - }); - }); - }); - }); - - it('should delete a wallet', function(done) { - var w1 = { - name: 'juan', - opts: { - name: 'wallet1' - } - }; - var w2 = { - name: 'pepe' - }; - - s.set('wallet::1', w1, function() { - s.set('wallet::2', w2, function() { - s.deleteWallet('1', function(err) { - should.not.exist(err); - s.getWallets2_Old(function(ws) { - ws.length.should.equal(1); - ws[0].id.should.equal('2'); - done(); - }); - }); - }); - }); - }); - }); - - describe('#readWallet_Old', function() { - it('should read wallet', function(done) { - var data = { - 'id1::a': 'x', - 'id1::b': 'y', - 'id2::c': 'z', - }; - s.db.allKeys = sinon.stub().yields(_.keys(data)); - sinon.stub(s, '_read', function(k, cb) { - return cb(data[k]); - }); - s.readWallet_Old('id1', function(err, w) { - should.not.exist(err); - w.should.exist; - w.hasOwnProperty('a').should.be.true; - w.hasOwnProperty('b').should.be.true; - w.hasOwnProperty('c').should.be.false; - w.a.should.equal('x'); - w.b.should.equal('y'); - s._read.restore(); - done(); - }); - }); - }); - - describe('#getFirst', function() { - it('should read first key', function(done) { - var data = { - 'wallet::id1_wallet1': { - a: 'x', - b: 'y' - }, - 'wallet::id2': { - c: 'z' - }, - }; - s.db.allKeys = sinon.stub().yields(_.keys(data)); - sinon.stub(s, '_read', function(k, cb) { - return cb(data[k]); - }); - s.getFirst('wallet::id1', {}, function(err, w) { - should.not.exist(err); - w.should.exist; - w.hasOwnProperty('a').should.be.true; - w.hasOwnProperty('b').should.be.true; - w.hasOwnProperty('c').should.be.false; - w.a.should.equal('x'); - w.b.should.equal('y'); - s._read.restore(); - done(); - }); - }); - }); - - describe('#set', function() { - it('should store from an object as single key', function(done) { - s.set('wallet::id1_nameid1', { - 'key': 'val', - 'opts': { - 'name': 'nameid1' - }, - }, function() { - s._read('wallet::id1_nameid1', function(r) { - r.should.exist; - r.key.should.exist; - r.key.should.equal('val'); - r.opts.name.should.equal('nameid1'); - done(); - }); - }); - }); - }); - - describe('#globals', function() { - it('should set, get and remove keys', function(done) { - s.setGlobal('a', { - b: 1 - }, function() { - s.getGlobal('a', function(v) { - - JSON.parse(v).should.deep.equal({ - b: 1 - }); - s.removeGlobal('a', function() { - s.getGlobal('a', function(v) { - should.not.exist(v); - done(); - }); - }); - }); - }); - }); - }); - - - describe('session storage', function() { - it('should get a session ID', function(done) { - s.getSessionId(function(s) { - should.exist(s); - s.length.should.equal(16); - (new Buffer(s, 'hex')).length.should.equal(8); - done(); - }); - }); - }); - - describe('#decrypt', function() { - it('should not be able to decrypt with wrong password', function() { - s.setPassword('xxx'); - var wo = s.decrypt(encryptedLegacy1); - should.not.exist(wo); - }); - it('should call save / restorePassphrase', function() { - sinon.spy(s,'savePassphrase'); - sinon.spy(s,'restorePassphrase'); - s.decrypt(encryptedLegacy1, 'xxx'); - s.savePassphrase.calledOnce.should.equal(true); - s.restorePassphrase.calledOnce.should.equal(true); - }); - - - - - it('should be able to decrypt an old backup', function() { - s._setPassphrase(legacyPassword1); - var wo = s.decrypt(encryptedLegacy1); - should.exist(wo); - wo.opts.id.should.equal('48ba2f1ffdfe9708'); - wo.opts.spendUnconfirmed.should.equal(true); - wo.opts.requiredCopayers.should.equal(1); - wo.opts.totalCopayers.should.equal(1); - wo.opts.name.should.equal('pepe wallet'); - wo.opts.version.should.equal('0.4.7'); - wo.publicKeyRing.walletId.should.equal('48ba2f1ffdfe9708'); - wo.publicKeyRing.networkName.should.equal('testnet'); - wo.publicKeyRing.requiredCopayers.should.equal(1); - wo.publicKeyRing.totalCopayers.should.equal(1); - wo.publicKeyRing.indexes.length.should.equal(2); - JSON.stringify(wo.publicKeyRing.indexes[0]).should.equal('{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":1}'); - JSON.stringify(wo.publicKeyRing.indexes[1]).should.equal('{"copayerIndex":0,"changeIndex":0,"receiveIndex":1}'); - wo.publicKeyRing.copayersBackup.length.should.equal(1); - wo.publicKeyRing.copayersBackup[0].should.equal('0298f65b2694c55f9048bc05f10368242727c7f9d2065cbd788c3ecde1ec57f33f'); - wo.publicKeyRing.copayersExtPubKeys.length.should.equal(1); - wo.publicKeyRing.copayersExtPubKeys[0].should.equal('tpubD9SGoP7CXsqSKTiQxCZSCpicDcophqnE4yuqjfw5M9tAR3fSjT9GDGwPEUFCN7SSmRKGDLZgKQePYFaLWyK32akeSan45TNTd8sgef9Ymh6'); - wo.privateKey.extendedPrivateKeyString.should.equal('tprv8ZgxMBicQKsPfQCscb7CtJKzixxcVSyrCVcfr3WCFbtT8kYTzNubhjQ5R7AuYJgPCcSH4R8T34YVxeohKGhAB9wbB4eFBbQFjUpjGCqptHm'); - wo.privateKey.networkName.should.equal('testnet'); - }); - }); -}); - -var legacyPassword1 = '1DUpLRbuVpgLkcEY8gY8iod/SmA7+OheGZJ9PtvmTlvNE0FkEWpCKW9STdzXYJqbn0wiAapE4ojHNYj2hjYYAQ=='; -var encryptedLegacy1 = 'U2FsdGVkX19yGM1uBAIzQa8Po/dvUicmxt1YyRk/S97PcZ6I6rHMp9dMagIrehg4Qd6JHn/ustmFHS7vmBYj0EBpf6rdXiQezaWnVAJS9/xYjAO36EFUbl+NmUanuwujAxgYdSP/sNssRLeInvExmZYW993EEclxkwL6YUyX66kKsxGQo2oWng0NreBJNhFmrbOEWeFje2PiWP57oUjKsurFzwpluAAarUTYSLud+nXeabC7opzOP5yqniWBMJz0Ou8gpNCWCMhG/P9F9ccVPY7juyd0Hf41FVse8nd2++axKB57+paozLdO+HRfV6zkMqC3h8gWY7LkS75j3bvqcTw9LhXmzE0Sz21n9yDnRpA4chiAvtwQvvBGgj1pFMKhNQU6Obac9ZwKYzUTgdDn3Uzg1UlDzgyOh9S89rbRTV84WB+hXwhuVluWzbNNYV3vXe5PFrocVktIrtS3xQh+k/7my4A6/gRRrzNYpKrUASJqDS/9u9WBkG35xD63J/qXjtG2M0YPwbI57BK1IK4K510b8V72lz5U2XQrIC4ldBwni1rpSavwCJV9xF6hUdOmNV8fZsVHP0NeN1PYlLkSb2QgfuoWnkcsJerwuFR7GZC/i6efrswtpO0wMEQr/J0CLbeXlHAru6xxjCBhWoJvZpMGw72zgnDLoyMNsEVglNhx/VlV9ZMYkkdaEYAxPOEIyZdQ5MS+2jEAlXf818n/xzJSVrniCn9be8EPePvkw35pivprvy09vbW4cKsWBKvgIyoT6A3OhUOCCS8E9cg0WAjjav2EymrbKmGWRHaiD+EoJqaDg6s20zhHn1YEa/YwvGGSB5+Hg8baLHD8ZASvxz4cFFAAVZrBUedRFgHzqwaMUlFXLgueivWUj7RXlIw6GuNhLoo1QkhZMacf23hrFxxQYvGBRw1hekBuDmcsGWljA28udBxBd5f9i+3gErttMLJ6IPaud590uvrxRIclu0Sz9R2EQX64YJxqDtLpMY0PjddSMu8vaDRpK9/ZSrnz/xrXsyabaafz4rE/ItFXjwFUFkvtmuauHTz6nmuKjVfxvNLNAiKb/gI7vQyUhnTbKIApe7XyJsjedNDtZqsPoJRIzdDmrZYxGStbAZ7HThqFJlSJ9NPNhH+E2jm3TwL5mwt0fFZ5h+p497lHMtIcKffESo7KNa2juSVNMDREk0NcyxGXGiVB2FWl4sLdvyhcsVq0I7tmW6OGZKRf8W49GCJXq6Ie69DJ9LB1DO67NV1jsYbsLx9uhE2yEmpWZ3jkoCV/Eas4grxt0CGN6EavzQ=='; diff --git a/test/Wallet.js b/test/Wallet.js index 81c32d43a..900f681ad 100644 --- a/test/Wallet.js +++ b/test/Wallet.js @@ -2,7 +2,6 @@ var Wallet = copay.Wallet; var PrivateKey = copay.PrivateKey; -var Storage = copay.Storage; var Network = requireMock('FakeNetwork'); var Blockchain = requireMock('FakeBlockchain'); var Builder = requireMock('FakeBuilder'); @@ -26,7 +25,6 @@ var walletConfig = { spendUnconfirmed: true, reconnectDelay: 100, networkName: 'testnet', - storage: requireMock('FakeLocalStorage').storageParams, // network layer config networkOpts: { testnet: { @@ -94,11 +92,7 @@ describe('Wallet model', function() { networkName: c.networkName, }); - var storage = new Storage(walletConfig.storage); - storage._setPassphrase('xxx'); - c.blockchain = new Blockchain(walletConfig.blockchain); - c.storage = storage; c.network = sinon.stub(); c.network.setHexNonce = sinon.stub(); @@ -143,7 +137,6 @@ describe('Wallet model', function() { Wallet._newInsight = sinon.stub().returns(new Blockchain(walletConfig.blockchain)); var w = Wallet.fromObj(cachedWobj, { - storage: cachedW.storage, blockchainOpts: {}, networkOpts: {}, }); @@ -216,7 +209,6 @@ describe('Wallet model', function() { Wallet._newInsight = sinon.stub().returns(new Blockchain(walletConfig.blockchain)); var w = Wallet.fromObj(cachedW2obj, { - storage: cachedW2.storage, blockchainOpts: {}, networkOpts: {}, }); @@ -378,10 +370,7 @@ describe('Wallet model', function() { // non stored options o.opts.reconnectDelay = 100; - var s = new Storage(walletConfig.storage); - s._setPassphrase('xxx'); var w2 = Wallet.fromObj(o, { - storage: s, blockchainOpts: {}, networkOpts: {}, }); @@ -1879,14 +1868,12 @@ describe('Wallet model', function() { }); describe('#fromObj / #toObj', function() { - var storage = new Storage(walletConfig.storage); var network = new Network(walletConfig.network); var blockchain = new Blockchain(walletConfig.blockchain); it('Import backup using old copayerIndex', function() { var w = Wallet.fromObj(JSON.parse(o), { - storage: storage, blockchainOpts: {}, networkOpts: {}, }); @@ -1901,7 +1888,6 @@ describe('Wallet model', function() { it('#fromObj, skipping fields', function() { var w = Wallet.fromObj(JSON.parse(o), { - storage: storage, networkOpts: {}, blockchainOpts: {}, skipFields: ['publicKeyRing'], @@ -1922,7 +1908,6 @@ describe('Wallet model', function() { var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; var w = Wallet.fromObj(JSON.parse(o), { - storage: storage, networkOpts: {}, blockchainOpts: {}, }); @@ -2179,22 +2164,18 @@ describe('Wallet model', function() { describe('#read', function() { - var storage, network, blockchain; + var network, blockchain; beforeEach(function() { var s = function() {}; - storage = new s(); network = new Network(walletConfig.network); blockchain = new Blockchain(walletConfig.blockchain); - storage.setPassword = sinon.stub(); }); it('should fail to read an unexisting wallet', function(done) { - storage.getFirst = sinon.stub().yields(null); Wallet.read('123', { - storage: storage, networkOpts: {}, blockchainOpts: {}, }, function(err, w) { @@ -2205,10 +2186,7 @@ describe('Wallet model', function() { it('should not read a corrupted wallet', function(done) { - storage.getFirst = sinon.stub().yields(null, '{hola:1}'); - Wallet.read('123', { - storage: storage, networkOpts: {}, blockchainOpts: {}, }, function(err, w) { @@ -2218,9 +2196,7 @@ describe('Wallet model', function() { }); it('should read a wallet', function(done) { - storage.getFirst = sinon.stub().yields(null, JSON.parse(o)); Wallet.read('123', { - storage: storage, networkOpts: {}, blockchainOpts: {}, }, function(err, w) { @@ -2230,9 +2206,7 @@ describe('Wallet model', function() { }); it('should be able to import unencrypted legacy wallet TxProposal: v0', function(done) { - storage.getFirst = sinon.stub().yields(null, JSON.parse(legacyO)); Wallet.read('123', { - storage: storage, networkOpts: {}, blockchainOpts: {}, }, function(err, w) { @@ -2246,10 +2220,8 @@ describe('Wallet model', function() { }); it('should be able to import simple 1-of-1 encrypted legacy testnet wallet', function(done) { - storage.getFirst = sinon.stub().yields(null, JSON.parse(legacy1)); Wallet.read('123', { - storage: storage, networkOpts: {}, blockchainOpts: {}, }, function(err, w) { diff --git a/test/WalletLock.js b/test/WalletLock.js deleted file mode 100644 index ed72bfbc0..000000000 --- a/test/WalletLock.js +++ /dev/null @@ -1,99 +0,0 @@ -'use strict'; - -var WalletLock = copay.WalletLock; -var PrivateKey = copay.PrivateKey; -var Storage = copay.Storage; - - -var storage; -describe('WalletLock model', function() { - - beforeEach(function() { - storage = new Storage(requireMock('FakeLocalStorage').storageParams); - storage._setPassphrase('mysupercoolpassword'); - storage.clearAll(); - }); - - it('should fail with missing args', function() { - (function() { - new WalletLock() - }).should.throw('Argument'); - }); - - - it('should fail with missing args (case 2)', function() { - (function() { - new WalletLock(storage) - }).should.throw('Argument'); - }); - - it('should create an instance', function() { - var w = new WalletLock(storage, 'id'); - should.exist(w); - }); - - - it('should generate a sessionId with init', function(done) { - var w = new WalletLock(storage, 'id'); - var spy = sinon.spy(storage, 'getSessionId'); - w.init(function() { - spy.calledOnce.should.equal(true); - done(); - }); - }); - - it('#keepAlive should call getsessionId if not called before', function(done) { - var w = new WalletLock(storage, 'id'); - var spy = sinon.spy(storage, 'getSessionId'); - w.keepAlive(function() { - spy.calledOnce.should.equal(true); - done(); - }); - }); - - it('should NOT fail if locked already by me', function(done) { - var w = new WalletLock(storage, 'walletId2'); - w.keepAlive(function() { - var w2 = new WalletLock(storage, 'walletId2'); - w2.init(function() { - w2.keepAlive(function() { - w.sessionId.should.equal(w2.sessionId); - should.exist(w2); - done(); - }); - }); - }) - }); - - it('should FAIL if locked by someone else', function(done) { - var w = new WalletLock(storage, 'walletId'); - w.keepAlive(function() { - storage.setSessionId('session2', function() { - var w2 = new WalletLock(storage, 'walletId'); - w2.keepAlive(function(locked) { - should.exist(locked); - locked.message.should.contain('LOCKED'); - done(); - }); - }); - }); - }) - - it('should FAIL if locked by someone else but expired', function(done) { - var w = new WalletLock(storage, 'walletId'); - w.keepAlive(function() { - storage.setSessionId('session2', function() { - - var json = JSON.parse(storage.db.ls['lock::walletId']); - json.expireTs -= 3600 * 1000; - storage.db.ls['lock::walletId'] = JSON.stringify(json); - var w2 = new WalletLock(storage, 'walletId'); - w2.keepAlive(function(locked) { - w2.sessionId.should.equal('session2'); - should.not.exist(locked); - done(); - }); - }); - }); - }) -}); diff --git a/test/mocks/FakeBlockchain.js b/test/mocks/FakeBlockchain.js index b77a5a931..208688d62 100644 --- a/test/mocks/FakeBlockchain.js +++ b/test/mocks/FakeBlockchain.js @@ -60,4 +60,7 @@ FakeBlockchain.prototype.checkSentTx = function (tx, cb) { return cb(null, txid); }; +FakeBlockchain.prototype.removeAllListeners = function() { +}; + module.exports = FakeBlockchain; diff --git a/test/mocks/FakeLocalStorage.js b/test/mocks/FakeLocalStorage.js deleted file mode 100644 index b3714412e..000000000 --- a/test/mocks/FakeLocalStorage.js +++ /dev/null @@ -1,43 +0,0 @@ -//localstorage Mock - -function FakeLocalStorage() { - this.ls = {}; - this.type = 'DB'; -}; - -FakeLocalStorage.prototype.init = function() { -}; - -FakeLocalStorage.prototype.removeItem = function(key, cb) { - delete this.ls[key]; - cb(); -}; - -FakeLocalStorage.prototype.getItem = function(k, cb) { - return cb(this.ls[k]); -}; - - -FakeLocalStorage.prototype.allKeys = function(cb) { - return cb(Object.keys(this.ls)); -}; - -FakeLocalStorage.prototype.setItem = function(k, v, cb) { - this.ls[k] = v; - return cb(); -}; -FakeLocalStorage.prototype.clear = function(cb) { - this.ls = {}; - if (cb) return cb(); -} - -module.exports = FakeLocalStorage; - -module.exports.storageParams = { - password: '123', - db: new FakeLocalStorage(), - sessionStorage: new FakeLocalStorage(), - passphraseConfig: { - iterations: 1, - }, -};