From 90136f1c3080dcf1dad9fb64a6d18ab9abc932e9 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Mon, 1 Dec 2014 12:13:11 -0300 Subject: [PATCH 1/4] added controls to ux --- js/controllers/profile.js | 4 ++++ views/profile.html | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/js/controllers/profile.js b/js/controllers/profile.js index 92238910c..5eaea7953 100644 --- a/js/controllers/profile.js +++ b/js/controllers/profile.js @@ -4,6 +4,7 @@ angular.module('copayApp.controllers').controller('ProfileController', function( $scope.isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; $rootScope.title = 'Profile'; + $scope.hideAdv = true; $scope.downloadProfileBackup = function() { backupService.profileDownload($rootScope.iden); @@ -53,4 +54,7 @@ angular.module('copayApp.controllers').controller('ProfileController', function( }); }; + $scope.deleteProfile = function () { + + }; }); diff --git a/views/profile.html b/views/profile.html index a0d0a6160..85e07270a 100644 --- a/views/profile.html +++ b/views/profile.html @@ -37,6 +37,7 @@ +
@@ -94,4 +95,35 @@
+ +
+ +
+ +
+ +
+
+
+
+

+ Delete Profile +

+

Permanently delete this profile and all its wallets. WARNING: this action cannot be reversed.

+ Delete Profile + +
+
+
+
From 14cb0449905de9e82cb52bf0ca90cfb8d6a2601d Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Mon, 1 Dec 2014 14:44:36 -0300 Subject: [PATCH 2/4] remove profile --- js/controllers/profile.js | 12 +++++++++++- js/models/Identity.js | 25 +++++++++++++++++++++++++ js/services/identityService.js | 4 ++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/js/controllers/profile.js b/js/controllers/profile.js index 5eaea7953..ff08185ee 100644 --- a/js/controllers/profile.js +++ b/js/controllers/profile.js @@ -55,6 +55,16 @@ angular.module('copayApp.controllers').controller('ProfileController', function( }; $scope.deleteProfile = function () { - + identityService.deleteProfile(function (err, res) { + if (err) { + log.warn(err); + notification.error('Error', 'Could not delete profile'); + return; + } + $location.path('/'); + setTimeout(function () { + notification.error('Success', 'Profile successfully deleted'); + }, 1); + }); }; }); diff --git a/js/models/Identity.js b/js/models/Identity.js index 23329ca77..0f9fcdad7 100644 --- a/js/models/Identity.js +++ b/js/models/Identity.js @@ -307,6 +307,31 @@ Identity.prototype.store = function(opts, cb) { }); }; +/** + * @param {Object} opts + * @param {Function} cb + */ +Identity.prototype.remove = function(opts, cb) { + log.debug('Deleting profile'); + + var self = this; + opts = opts || {}; + + // HACK (isocolsky): remove notifications while deleting wallets + self.removeAllListeners('deletedWallet'); + + async.each(_.values(self.wallets), function(w, cb) { + self.deleteWallet(w.getId(), cb); + }, function (err) { + if (err) return cb(err); + self.storage.removeItem(self.getId(), function(err) { + if (err) return cb(err); + self.emitAndKeepAlive('closed'); + return cb(); + }); + }); +}; + Identity.prototype._cleanUp = function() { // NOP }; diff --git a/js/services/identityService.js b/js/services/identityService.js index 6fb1cd0aa..94e6f1653 100644 --- a/js/services/identityService.js +++ b/js/services/identityService.js @@ -87,6 +87,10 @@ angular.module('copayApp.services') }); }; + root.deleteProfile = function (cb) { + $rootScope.iden.remove(null, cb); + }; + root.deleteWallet = function(w, cb) { $rootScope.iden.deleteWallet(w.id, cb); }; From e308fd6f924ea2f2801cfd076156dbacfd00732a Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Mon, 1 Dec 2014 15:37:28 -0300 Subject: [PATCH 3/4] tests --- js/models/Identity.js | 10 +++--- test/Identity.js | 71 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/js/models/Identity.js b/js/models/Identity.js index 0f9fcdad7..5c2c9a2a1 100644 --- a/js/models/Identity.js +++ b/js/models/Identity.js @@ -317,13 +317,15 @@ Identity.prototype.remove = function(opts, cb) { var self = this; opts = opts || {}; - // HACK (isocolsky): remove notifications while deleting wallets - self.removeAllListeners('deletedWallet'); - async.each(_.values(self.wallets), function(w, cb) { - self.deleteWallet(w.getId(), cb); + w.close(); + self.storage.removeItem(Wallet.getStorageKey(w.getId()), function(err) { + if (err) return cb(err); + cb(); + }); }, function (err) { if (err) return cb(err); + self.storage.removeItem(self.getId(), function(err) { if (err) return cb(err); self.emitAndKeepAlive('closed'); diff --git a/test/Identity.js b/test/Identity.js index 0e939f916..f3fa2dfd3 100644 --- a/test/Identity.js +++ b/test/Identity.js @@ -158,6 +158,77 @@ describe('Identity model', function() { }); }); + describe('#remove', function(done) { + it('should remove empty profile', function (done) { + var storage = sinon.stub(); + storage.setCredentials = sinon.stub(); + storage.removeItem = sinon.stub().yields(null); + + 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); + iden.remove(null, function (err, res) { + should.not.exist(err); + storage.removeItem.calledOnce.should.be.true; + storage.removeItem.getCall(0).args[0].should.equal(iden.getId()); + done(); + }); + }); + + it('should remove profile and wallets', function(done) { + var storage = sinon.stub(); + storage.setCredentials = sinon.stub(); + storage.removeItem = sinon.stub().yields(null); + + 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); + + _.each(_.range(3), function(i) { + var w = { + on: sinon.stub().yields(null), + getId: sinon.stub().returns('wallet' + i), + getName: sinon.stub().returns('wallet' + i), + close: sinon.stub(), + }; + iden.bindWallet(w); + }); + + iden.remove(null, function(err, res) { + should.not.exist(err); + storage.removeItem.callCount.should.equal(4); + storage.removeItem.getCall(0).args[0].should.equal(Wallet.getStorageKey('wallet0')); + storage.removeItem.getCall(3).args[0].should.equal(iden.getId()); + done(); + }); + + }); + }); + describe.skip('#storeWallet', function() { // TODO test storeWallet }); From 2840fd7813e8633164ae50544c92e08cb2cba888 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Mon, 1 Dec 2014 15:48:26 -0300 Subject: [PATCH 4/4] avoiding Identity#bindWallet from tests --- test/Identity.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/Identity.js b/test/Identity.js index f3fa2dfd3..f46c72f0e 100644 --- a/test/Identity.js +++ b/test/Identity.js @@ -215,7 +215,7 @@ describe('Identity model', function() { getName: sinon.stub().returns('wallet' + i), close: sinon.stub(), }; - iden.bindWallet(w); + iden.wallets[w.getId()] = w; }); iden.remove(null, function(err, res) { @@ -225,7 +225,6 @@ describe('Identity model', function() { storage.removeItem.getCall(3).args[0].should.equal(iden.getId()); done(); }); - }); });