From 1f2ac1296e3b9f7376700594bd8b434c1414216d Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Thu, 14 May 2015 11:55:05 -0300 Subject: [PATCH 1/4] add WalletComplete notification --- lib/server.js | 27 ++++++++++++++++++++----- test/integration/server.js | 40 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/lib/server.js b/lib/server.js index 3e191f4..ec64863 100644 --- a/lib/server.js +++ b/lib/server.js @@ -423,11 +423,28 @@ WalletService.prototype.joinWallet = function(opts, cb) { self.storage.storeWalletAndUpdateCopayersLookup(wallet, function(err) { if (err) return cb(err); - self._notify('NewCopayer', { - walletId: opts.walletId, - copayerId: copayer.id, - copayerName: copayer.name, - }, function() { + + async.parallel([ + + function(done) { + self._notify('NewCopayer', { + walletId: opts.walletId, + copayerId: copayer.id, + copayerName: copayer.name, + }, done); + }, + function(done) { + if (wallet.isComplete() && wallet.isShared()) { + self._notify('WalletComplete', { + walletId: opts.walletId, + }, { + isGlobal: true + }, done); + } else { + done(); + } + }, + ], function() { return cb(null, { copayerId: copayer.id, wallet: wallet diff --git a/test/integration/server.js b/test/integration/server.js index 4cf42a4..20d38df 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -478,7 +478,22 @@ describe('Wallet service', function() { var copayer = wallet.copayers[0]; copayer.name.should.equal('me'); copayer.id.should.equal(copayerId); - done(); + server.getNotifications({}, function(err, notifications) { + should.not.exist(err); + var notif = _.find(notifications, { + type: 'NewCopayer' + }); + should.exist(notif); + notif.data.walletId.should.equal(walletId); + notif.data.copayerId.should.equal(copayerId); + notif.data.copayerName.should.equal('me'); + + notif = _.find(notifications, { + type: 'WalletComplete' + }); + should.not.exist(notif); + done(); + }); }); }); }); @@ -548,7 +563,7 @@ describe('Wallet service', function() { }); }); - it('should fail two wallets with same xPubKey', function(done) { + it('should fail to join two wallets with same xPubKey', function(done) { var copayerOpts = helpers.getSignedCopayerOpts({ walletId: walletId, name: 'me', @@ -630,6 +645,27 @@ describe('Wallet service', function() { should.not.exist(err); wallet.status.should.equal('complete'); wallet.publicKeyRing.length.should.equal(3); + server.getNotifications({}, function(err, notifications) { + should.not.exist(err); + var notif = _.find(notifications, { + type: 'WalletComplete' + }); + should.exist(notif); + notif.data.walletId.should.equal(wallet.id); + done(); + }); + }); + }); + }); + + it('should not notify WalletComplete if 1-of-1', function(done) { + helpers.createAndJoinWallet(1, 1, function(server) { + server.getNotifications({}, function(err, notifications) { + should.not.exist(err); + var notif = _.find(notifications, { + type: 'WalletComplete' + }); + should.not.exist(notif); done(); }); }); From 0a0869c4fa7cb05e7069c793e1801a9009479301 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Thu, 14 May 2015 11:57:23 -0300 Subject: [PATCH 2/4] add email notification & template --- lib/emailservice.js | 4 ++++ lib/templates/wallet_complete.plain | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 lib/templates/wallet_complete.plain diff --git a/lib/emailservice.js b/lib/emailservice.js index 595a620..e5f8d43 100644 --- a/lib/emailservice.js +++ b/lib/emailservice.js @@ -15,6 +15,10 @@ var EMAIL_TYPES = { filename: 'new_copayer', notifyDoer: false, }, + 'WalletComplete': { + filename: 'wallet_complete', + notifyDoer: true, + }, 'NewTxProposal': { filename: 'new_tx_proposal', notifyDoer: false, diff --git a/lib/templates/wallet_complete.plain b/lib/templates/wallet_complete.plain new file mode 100644 index 0000000..ba52e3e --- /dev/null +++ b/lib/templates/wallet_complete.plain @@ -0,0 +1,2 @@ +<%= subjectPrefix %>Wallet complete +Your wallet <%= walletName %> is complete. From d66c0502ceeaa46f92dec606eb5277147a70a9f8 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Thu, 14 May 2015 12:06:41 -0300 Subject: [PATCH 3/4] add moment to package.json --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index b5d4bd3..ca38461 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "locker-server": "^0.1.3", "lodash": "^3.3.1", "mocha-lcov-reporter": "0.0.1", + "moment": "^2.10.3", "mongodb": "^2.0.27", "morgan": "*", "nodemailer": "^1.3.4", From 226f18d345d9af3e5adfe32709e9b895395160ca Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Thu, 14 May 2015 12:48:19 -0300 Subject: [PATCH 4/4] preserve order of notifications --- lib/server.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/server.js b/lib/server.js index ec64863..b3d1878 100644 --- a/lib/server.js +++ b/lib/server.js @@ -424,24 +424,24 @@ WalletService.prototype.joinWallet = function(opts, cb) { if (err) return cb(err); - async.parallel([ + async.series([ - function(done) { + function(next) { self._notify('NewCopayer', { walletId: opts.walletId, copayerId: copayer.id, copayerName: copayer.name, - }, done); + }, next); }, - function(done) { + function(next) { if (wallet.isComplete() && wallet.isShared()) { self._notify('WalletComplete', { walletId: opts.walletId, }, { isGlobal: true - }, done); + }, next); } else { - done(); + next(); } }, ], function() { @@ -951,21 +951,21 @@ WalletService.prototype.signTx = function(opts, cb) { self.storage.storeTx(self.walletId, txp, function(err) { if (err) return cb(err); - async.parallel([ + async.series([ - function(done) { + function(next) { self._notify('TxProposalAcceptedBy', { txProposalId: opts.txProposalId, copayerId: self.copayerId, - }, done); + }, next); }, - function(done) { + function(next) { if (txp.isAccepted()) { self._notify('TxProposalFinallyAccepted', { txProposalId: opts.txProposalId, - }, done); + }, next); } else { - done(); + next(); } }, ], function() { @@ -1052,21 +1052,21 @@ WalletService.prototype.rejectTx = function(opts, cb) { self.storage.storeTx(self.walletId, txp, function(err) { if (err) return cb(err); - async.parallel([ + async.series([ - function(done) { + function(next) { self._notify('TxProposalRejectedBy', { txProposalId: opts.txProposalId, copayerId: self.copayerId, - }, done); + }, next); }, - function(done) { + function(next) { if (txp.status == 'rejected') { self._notify('TxProposalFinallyRejected', { txProposalId: opts.txProposalId, - }, done); + }, next); } else { - done(); + next(); } }, ], function() {