add tests
This commit is contained in:
parent
4a0a3f1bad
commit
fa9a8cd38c
|
@ -69,7 +69,7 @@ EmailService.prototype._getRecipientsList = function(notification, emailType, cb
|
||||||
|
|
||||||
self.storage.fetchPreferences(notification.walletId, null, function(err, preferences) {
|
self.storage.fetchPreferences(notification.walletId, null, function(err, preferences) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (_.isEmpty(preferences)) return cb(null, {});
|
if (_.isEmpty(preferences)) return cb(null, []);
|
||||||
|
|
||||||
var recipients = _.compact(_.map(preferences, function(p) {
|
var recipients = _.compact(_.map(preferences, function(p) {
|
||||||
if (!p.email) return;
|
if (!p.email) return;
|
||||||
|
@ -138,7 +138,7 @@ EmailService.prototype.sendEmail = function(notification, cb) {
|
||||||
self._getRecipientsList(notification, emailType, function(err, list) {
|
self._getRecipientsList(notification, emailType, function(err, list) {
|
||||||
if (_.isEmpty(list)) return cb();
|
if (_.isEmpty(list)) return cb();
|
||||||
recipientsList = list;
|
recipientsList = list;
|
||||||
return next();
|
next();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(next) {
|
function(next) {
|
||||||
|
@ -150,13 +150,15 @@ EmailService.prototype.sendEmail = function(notification, cb) {
|
||||||
function(next) {
|
function(next) {
|
||||||
self._getDataForTemplate(notification, next);
|
self._getDataForTemplate(notification, next);
|
||||||
},
|
},
|
||||||
], next);
|
], function(err, res) {
|
||||||
|
next(err, res[0], res[1]);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(template, data, next) {
|
function(template, data, next) {
|
||||||
self._applyTemplate(template, data, next);
|
self._applyTemplate(template, data, next);
|
||||||
},
|
},
|
||||||
function(content, next) {
|
function(content, next) {
|
||||||
_.each(recipientsList, function(recipient) {
|
async.map(recipientsList, function(recipient, next) {
|
||||||
var email = Model.Email.create({
|
var email = Model.Email.create({
|
||||||
walletId: notification.walletId,
|
walletId: notification.walletId,
|
||||||
copayerId: recipient.copayerId,
|
copayerId: recipient.copayerId,
|
||||||
|
@ -167,14 +169,14 @@ EmailService.prototype.sendEmail = function(notification, cb) {
|
||||||
self.storage.storeEmail(email, function(err) {
|
self.storage.storeEmail(email, function(err) {
|
||||||
return next(err, email);
|
return next(err, email);
|
||||||
});
|
});
|
||||||
});
|
}, next);
|
||||||
},
|
},
|
||||||
function(email, next) {
|
function(emails, next) {
|
||||||
self._send(email, next);
|
async.each(emails, function(email, next) {
|
||||||
|
self._send(email, next);
|
||||||
|
}, next);
|
||||||
},
|
},
|
||||||
], cb);
|
], cb);
|
||||||
|
|
||||||
return cb();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = EmailService;
|
module.exports = EmailService;
|
||||||
|
|
|
@ -85,6 +85,8 @@ WalletService.initialize = function(opts, cb) {
|
||||||
emailService = new EmailService({
|
emailService = new EmailService({
|
||||||
lock: lock,
|
lock: lock,
|
||||||
storage: storage,
|
storage: storage,
|
||||||
|
mailer: opts.mailer,
|
||||||
|
email: opts.email,
|
||||||
});
|
});
|
||||||
return cb();
|
return cb();
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,15 +27,15 @@ var TestData = require('../testdata');
|
||||||
|
|
||||||
var helpers = {};
|
var helpers = {};
|
||||||
helpers.getAuthServer = function(copayerId, cb) {
|
helpers.getAuthServer = function(copayerId, cb) {
|
||||||
var signatureStub = sinon.stub(WalletService.prototype, '_verifySignature');
|
var verifyStub = sinon.stub(WalletService.prototype, '_verifySignature');
|
||||||
signatureStub.returns(true);
|
verifyStub.returns(true);
|
||||||
WalletService.getInstanceWithAuth({
|
WalletService.getInstanceWithAuth({
|
||||||
copayerId: copayerId,
|
copayerId: copayerId,
|
||||||
message: 'dummy',
|
message: 'dummy',
|
||||||
signature: 'dummy',
|
signature: 'dummy',
|
||||||
}, function(err, server) {
|
}, function(err, server) {
|
||||||
|
verifyStub.restore();
|
||||||
if (err || !server) throw new Error('Could not login as copayerId ' + copayerId);
|
if (err || !server) throw new Error('Could not login as copayerId ' + copayerId);
|
||||||
signatureStub.restore();
|
|
||||||
return cb(server);
|
return cb(server);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -132,7 +132,6 @@ helpers.toSatoshi = function(btc) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Amounts in satoshis
|
|
||||||
helpers.stubUtxos = function(server, wallet, amounts, cb) {
|
helpers.stubUtxos = function(server, wallet, amounts, cb) {
|
||||||
var amounts = [].concat(amounts);
|
var amounts = [].concat(amounts);
|
||||||
|
|
||||||
|
@ -211,16 +210,22 @@ helpers.createAddresses = function(server, wallet, main, change, cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var db, storage, blockchainExplorer;
|
var db, storage, blockchainExplorer, mailer;
|
||||||
|
|
||||||
function openDb(cb) {
|
function openDb(cb) {
|
||||||
db = new tingodb.Db('./db/test', {});
|
db = new tingodb.Db('./db/test', {});
|
||||||
|
// HACK: There appears to be a bug in TingoDB's close function where the callback is not being executed
|
||||||
|
db.__close = db.close;
|
||||||
|
db.close = function(force, cb) {
|
||||||
|
this.__close(force, cb);
|
||||||
|
return cb();
|
||||||
|
};
|
||||||
return cb();
|
return cb();
|
||||||
};
|
};
|
||||||
|
|
||||||
function resetDb(cb) {
|
function resetDb(cb) {
|
||||||
if (!db) return cb();
|
if (!storage.db) return cb();
|
||||||
db.dropDatabase(function(err) {
|
storage.db.dropDatabase(function(err) {
|
||||||
return cb();
|
return cb();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -228,19 +233,27 @@ function resetDb(cb) {
|
||||||
|
|
||||||
describe('Wallet service', function() {
|
describe('Wallet service', function() {
|
||||||
before(function(done) {
|
before(function(done) {
|
||||||
openDb(function() {
|
// openDb(function() {
|
||||||
storage = new Storage({
|
// storage = new Storage({
|
||||||
db: db
|
// db: db
|
||||||
});
|
// });
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
|
storage = new Storage();
|
||||||
|
storage.connect({
|
||||||
|
mongoDb: {
|
||||||
|
uri: 'mongodb://localhost:27017/bws_test'
|
||||||
|
}
|
||||||
|
}, done);
|
||||||
});
|
});
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
resetDb(function() {
|
resetDb(function() {
|
||||||
blockchainExplorer = sinon.stub();
|
blockchainExplorer = sinon.stub();
|
||||||
|
mailer = sinon.stub();
|
||||||
WalletService.initialize({
|
WalletService.initialize({
|
||||||
storage: storage,
|
storage: storage,
|
||||||
blockchainExplorer: blockchainExplorer,
|
blockchainExplorer: blockchainExplorer,
|
||||||
|
mailer: mailer,
|
||||||
}, done);
|
}, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -3066,4 +3079,44 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('Email notifications', function() {
|
||||||
|
var server, wallet;
|
||||||
|
beforeEach(function(done) {
|
||||||
|
mailer.sendMail = sinon.stub().yields();
|
||||||
|
helpers.createAndJoinWallet(2, 3, function(s, w) {
|
||||||
|
server = s;
|
||||||
|
wallet = w;
|
||||||
|
var i = 0;
|
||||||
|
async.eachSeries(w.copayers, function(copayer, next) {
|
||||||
|
helpers.getAuthServer(copayer.id, function(server) {
|
||||||
|
server.savePreferences({
|
||||||
|
email: 'copayer' + (i++) + '@domain.com',
|
||||||
|
}, next);
|
||||||
|
});
|
||||||
|
}, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
afterEach(function() {
|
||||||
|
NotificationBroadcaster.removeAllListeners();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should notify copayers a new tx proposal has been created', function(done) {
|
||||||
|
WalletService.onNotification(function(n) {
|
||||||
|
if (n.type != 'NewTxProposal') return;
|
||||||
|
var calls = mailer.sendMail.getCalls();
|
||||||
|
calls.length.should.equal(2);
|
||||||
|
var recipients = _.pluck(_.map(calls, function(c) {
|
||||||
|
return c.args[0];
|
||||||
|
}), 'to');
|
||||||
|
_.difference(['copayer1@domain.com', 'copayer2@domain.com'], recipients).should.be.empty;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
helpers.stubUtxos(server, wallet, [1, 1], function() {
|
||||||
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.8, 'some message', TestData.copayers[0].privKey_1H_0);
|
||||||
|
server.createTx(txOpts, function(err, tx) {
|
||||||
|
should.not.exist(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,9 +16,16 @@ var db, storage;
|
||||||
|
|
||||||
function openDb(cb) {
|
function openDb(cb) {
|
||||||
db = new tingodb.Db('./db/test', {});
|
db = new tingodb.Db('./db/test', {});
|
||||||
|
// HACK: There appears to be a bug in TingoDB's close function where the callback is not being executed
|
||||||
|
db.__close = db.close;
|
||||||
|
db.close = function(force, cb) {
|
||||||
|
this.__close(force, cb);
|
||||||
|
return cb();
|
||||||
|
};
|
||||||
return cb();
|
return cb();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function resetDb(cb) {
|
function resetDb(cb) {
|
||||||
if (!db) return cb();
|
if (!db) return cb();
|
||||||
db.dropDatabase(function(err) {
|
db.dropDatabase(function(err) {
|
||||||
|
|
Loading…
Reference in New Issue