diff --git a/js/models/Identity.js b/js/models/Identity.js index b26ac959c..88942672d 100644 --- a/js/models/Identity.js +++ b/js/models/Identity.js @@ -395,10 +395,10 @@ Identity.prototype.createWallet = function(opts, cb) { this.storage.setPassphrase(opts.passphrase); + var self = this; var w = this._getWallet(opts); this.profile.addWallet(w.id, function(err) { if (err) return cb(err); - var self = this; w.store(function(err) { if (err) return cb(err); self.storage.setLastOpened(w.id, function(err) { @@ -453,6 +453,10 @@ Identity.prototype.openWallet = function(walletId, passphrase, cb) { }); }; + +TODO +from profile +implement lastOpen Identity.prototype.listWallets = function(cb) { var self = this; this.storage.getWallets(function(wallets) { diff --git a/js/models/Profile.js b/js/models/Profile.js index c29a3595a..581749f39 100644 --- a/js/models/Profile.js +++ b/js/models/Profile.js @@ -12,7 +12,7 @@ function Profile(info, password, storage) { this.email = info.email; this.extra = info.extra; - this.walletIds = {}; + this.walletInfos = {}; this.hash = Profile.hash(this.email, password); this.storage = storage; }; @@ -45,12 +45,47 @@ Profile.open = function(storage, cb) { }); }; +Profile.prototype.getWallet = function(walletId, cb) { + return this.walletInfos[walletId]; +}; -Profile.prototype.addWallet = function(walletId, cb) { - if (this.walletIds[walletId]) +Profile.prototype.listWallets = function(opts, cb) { + return _.sortBy(this.walletInfos,function(winfo){ + return winfo.lastOpenedTs || winfo.createdTs; + }); +}; + + +Profile.prototype.deleteWallet = function(walletId, cb) { + if (!this.walletInfos[walletId]) + return cb(new Error('WNOEXIST: Wallet not on profile')); + + delete this.walletInfos[walletId]; + + this.store({ + overwrite: true + }, cb); +}; + +Profile.prototype.addToWallet = function(walletId, info, cb) { + if (!this.walletInfos[walletId]) + return cb(new Error('WNOEXIST: Wallet not on profile')); + + this.walletInfos[walletId] = _.extend(this.walletInfos[walletId], info); + + this.store({ + overwrite: true + }, cb); +}; + + + +Profile.prototype.addWallet = function(walletId, info, cb) { + if (this.walletInfos[walletId]) return cb(new Error('WEXIST: Wallet already on profile')); - this.walletIds[walletId] = Date.now(); + this.walletInfos[walletId] = _.extend(info, {createdTs: Date.now(), id: walletId} ); + this.store({ overwrite: true }, cb); diff --git a/test/test.Identity.js b/test/test.Identity.js index 65e266db7..9b714f332 100644 --- a/test/test.Identity.js +++ b/test/test.Identity.js @@ -45,7 +45,7 @@ describe('Identity model', function() { Identity._newWallet = sinon.stub().returns(wallet); profile = sinon.stub(); - profile.test = sinon.stub(); + profile.addWallet = sinon.stub().yields(null);; profile.store = sinon.stub().yields(null);; Identity._newProfile = sinon.stub().returns(profile); @@ -105,7 +105,7 @@ describe('Identity model', function() { should.exist(iden); iden.walletDefaults.should.deep.equal(config.wallet); iden.version.should.equal('0.0.1'); - should.exist(iden.profile.test); + should.exist(iden.profile.addWallet); Identity._newProfile.getCall(0).args[0].should.deep.equal({ email: email @@ -119,7 +119,7 @@ describe('Identity model', function() { it('should call .store', function(done) { Identity.create(email, password, config, function(err, iden) { should.not.exist(err); - should.exist(iden.profile.test); + should.exist(iden.profile.addWallet); iden.profile.store.getCall(0).args[0].should.deep.equal({ overwrite: false }); @@ -133,7 +133,7 @@ describe('Identity model', function() { Identity.prototype.read = sinon.stub().yields(null); Identity.open(email, password, config, function(err, iden) { should.not.exist(err); - should.exist(iden.profile.test); + should.exist(iden.profile.addWallet); iden.read.calledOnce.should.equal(true); done(); }); @@ -202,6 +202,14 @@ describe('Identity model', function() { }); }); + it('should add wallet to profile', function(done) { + iden.createWallet(null, function(err, w) { + profile.addWallet.getCall(0).args[0].should.contain('spy#'); + done(); + }); + }); + + it('should be able to create wallets with given pk', function(done) { var priv = 'tprv8ZgxMBicQKsPdEqHcA7RjJTayxA3gSSqeRTttS1JjVbgmNDZdSk9EHZK5pc52GY5xFmwcakmUeKWUDzGoMLGAhrfr5b3MovMUZUTPqisL2m'; iden.createWallet({ diff --git a/test/test.Profile.js b/test/test.Profile.js index 7eb4adfad..b4801aee2 100644 --- a/test/test.Profile.js +++ b/test/test.Profile.js @@ -1,5 +1,5 @@ 'use strict'; - +var _ = require('underscore'); var chai = chai || require('chai'); var should = chai.should(); var bitcore = bitcore || require('bitcore'); @@ -44,27 +44,104 @@ describe('Profile model', function() { p2.should.deep.equal(p); }); - describe.only('#addWallet', function() { + describe('#addWallet', function() { it('should add a wallet id', function(done) { var p = new Profile(opts, password, storage); - p.addWallet('123', function(err) { - p.walletIds['123'].should.be.above(123456789); + 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 value', function(done) { + it('should keep old ts value', function(done) { var p = new Profile(opts, password, storage); - p.walletIds['123']=1; - p.addWallet('123', function(err) { - p.walletIds['123'].should.equal(1); + 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, password, 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, password, 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, password, 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, password, storage); + p.addWallet('123', {}, function(err) { + p.addWallet('234', {}, function(err) { + _.pluck(p.listWallets(), 'id').should.deep.equal(['123', '234']); + done(); + }) + }); + }); + }); + + describe('#deleteWallet', function() { + it('should delete a wallet', function(done) { + var p = new Profile(opts, password, storage); + p.addWallet('123', {}, function(err) { + p.addWallet('234', {}, function(err) { + p.addWallet('345', {}, function(err) { + _.pluck(p.listWallets(), 'id').should.deep.equal(['123', '234', '345']); + p.deleteWallet('234', function(err) { + _.pluck(p.listWallets(), 'id').should.deep.equal(['123', '345']); + done(); + }); + }) + }); + }); + }); + it('should warn if wallet does not exist', function(done) { + var p = new Profile(opts, password, 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, password, storage);