2013-11-28 05:36:14 -05:00
|
|
|
define(function(require) {
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var EmailDAO = require('js/dao/email-dao-2'),
|
|
|
|
KeychainDAO = require('js/dao/keychain-dao'),
|
|
|
|
ImapClient = require('imap-client'),
|
|
|
|
SmtpClient = require('smtp-client'),
|
|
|
|
PGP = require('js/crypto/pgp'),
|
|
|
|
DeviceStorageDAO = require('js/dao/devicestorage-dao'),
|
|
|
|
expect = chai.expect;
|
|
|
|
|
|
|
|
|
|
|
|
describe('Email DAO 2 unit tests', function() {
|
|
|
|
var dao, keychainStub, imapClientStub, smtpClientStub, pgpStub, devicestorageStub;
|
|
|
|
|
|
|
|
var emailAddress = 'asdf@asdf.com',
|
|
|
|
passphrase = 'asdf',
|
|
|
|
asymKeySize = 2048,
|
|
|
|
mockkeyId = 1234,
|
|
|
|
mockKeyPair = {
|
|
|
|
publicKey: {
|
|
|
|
_id: mockkeyId,
|
|
|
|
userId: emailAddress,
|
|
|
|
publicKey: 'publicpublicpublicpublic'
|
|
|
|
},
|
|
|
|
privateKey: {
|
|
|
|
_id: mockkeyId,
|
|
|
|
userId: emailAddress,
|
|
|
|
encryptedKey: 'privateprivateprivateprivate'
|
|
|
|
}
|
|
|
|
}, account = {
|
|
|
|
emailAddress: emailAddress,
|
|
|
|
asymKeySize: asymKeySize,
|
|
|
|
};
|
|
|
|
|
|
|
|
beforeEach(function() {
|
|
|
|
keychainStub = sinon.createStubInstance(KeychainDAO);
|
|
|
|
imapClientStub = sinon.createStubInstance(ImapClient);
|
|
|
|
smtpClientStub = sinon.createStubInstance(SmtpClient);
|
|
|
|
pgpStub = sinon.createStubInstance(PGP);
|
|
|
|
devicestorageStub = sinon.createStubInstance(DeviceStorageDAO);
|
|
|
|
|
|
|
|
dao = new EmailDAO(keychainStub, imapClientStub, smtpClientStub, pgpStub, devicestorageStub);
|
|
|
|
dao._account = account;
|
|
|
|
|
|
|
|
expect(dao._keychain).to.equal(keychainStub);
|
|
|
|
expect(dao._imapClient).to.equal(imapClientStub);
|
|
|
|
expect(dao._smtpClient).to.equal(smtpClientStub);
|
|
|
|
expect(dao._crypto).to.equal(pgpStub);
|
|
|
|
expect(dao._devicestorage).to.equal(devicestorageStub);
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(function() {});
|
|
|
|
|
|
|
|
describe('init', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
delete dao._account;
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should init', function(done) {
|
2013-11-29 10:13:18 -05:00
|
|
|
var loginStub, listFolderStub, folders;
|
|
|
|
|
|
|
|
folders = [];
|
2013-11-28 09:05:29 -05:00
|
|
|
|
|
|
|
// initKeychain
|
2013-11-28 05:36:14 -05:00
|
|
|
devicestorageStub.init.withArgs(emailAddress).yields();
|
|
|
|
keychainStub.getUserKeyPair.yields(null, mockKeyPair);
|
|
|
|
|
2013-11-28 09:05:29 -05:00
|
|
|
// initFolders
|
|
|
|
loginStub = sinon.stub(dao, '_imapLogin');
|
|
|
|
listFolderStub = sinon.stub(dao, '_imapListFolders');
|
|
|
|
loginStub.yields();
|
2013-11-29 10:13:18 -05:00
|
|
|
listFolderStub.yields(null, folders);
|
2013-11-28 09:05:29 -05:00
|
|
|
|
2013-11-28 05:36:14 -05:00
|
|
|
dao.init({
|
|
|
|
account: account
|
|
|
|
}, function(err, keyPair) {
|
|
|
|
expect(err).to.not.exist;
|
|
|
|
expect(keyPair).to.equal(mockKeyPair);
|
|
|
|
|
|
|
|
expect(dao._account).to.equal(account);
|
2013-11-29 10:13:18 -05:00
|
|
|
expect(dao._account.folders).to.equal(folders);
|
2013-11-28 05:36:14 -05:00
|
|
|
expect(devicestorageStub.init.calledOnce).to.be.true;
|
|
|
|
expect(keychainStub.getUserKeyPair.calledOnce).to.be.true;
|
|
|
|
|
2013-11-28 09:05:29 -05:00
|
|
|
expect(loginStub.calledOnce).to.be.true;
|
|
|
|
expect(listFolderStub.calledOnce).to.be.true;
|
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should fail due to error while listing folders', function(done) {
|
|
|
|
var loginStub, listFolderStub;
|
|
|
|
|
|
|
|
// initKeychain
|
|
|
|
devicestorageStub.init.withArgs(emailAddress).yields();
|
|
|
|
keychainStub.getUserKeyPair.yields(null, mockKeyPair);
|
|
|
|
|
|
|
|
// initFolders
|
|
|
|
loginStub = sinon.stub(dao, '_imapLogin');
|
|
|
|
listFolderStub = sinon.stub(dao, '_imapListFolders');
|
|
|
|
loginStub.yields();
|
|
|
|
listFolderStub.yields({});
|
|
|
|
|
|
|
|
dao.init({
|
|
|
|
account: account
|
|
|
|
}, function(err, keyPair) {
|
|
|
|
expect(err).to.exist;
|
|
|
|
expect(keyPair).to.not.exist;
|
|
|
|
|
|
|
|
expect(dao._account).to.equal(account);
|
|
|
|
expect(devicestorageStub.init.calledOnce).to.be.true;
|
|
|
|
expect(keychainStub.getUserKeyPair.calledOnce).to.be.true;
|
|
|
|
|
|
|
|
expect(loginStub.calledOnce).to.be.true;
|
|
|
|
expect(listFolderStub.calledOnce).to.be.true;
|
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should fail due to error during imap login', function(done) {
|
|
|
|
var loginStub = sinon.stub(dao, '_imapLogin');
|
|
|
|
|
|
|
|
// initKeychain
|
|
|
|
devicestorageStub.init.withArgs(emailAddress).yields();
|
|
|
|
keychainStub.getUserKeyPair.yields(null, mockKeyPair);
|
|
|
|
|
|
|
|
// initFolders
|
|
|
|
loginStub.yields({});
|
|
|
|
|
|
|
|
dao.init({
|
|
|
|
account: account
|
|
|
|
}, function(err, keyPair) {
|
|
|
|
expect(err).to.exist;
|
|
|
|
expect(keyPair).to.not.exist;
|
|
|
|
|
|
|
|
expect(dao._account).to.equal(account);
|
|
|
|
expect(devicestorageStub.init.calledOnce).to.be.true;
|
|
|
|
expect(keychainStub.getUserKeyPair.calledOnce).to.be.true;
|
|
|
|
|
|
|
|
expect(loginStub.calledOnce).to.be.true;
|
|
|
|
|
2013-11-28 05:36:14 -05:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should fail due to error in getUserKeyPair', function(done) {
|
|
|
|
devicestorageStub.init.yields();
|
|
|
|
keychainStub.getUserKeyPair.yields({});
|
|
|
|
|
|
|
|
dao.init({
|
|
|
|
account: account
|
|
|
|
}, function(err, keyPair) {
|
|
|
|
expect(err).to.exist;
|
|
|
|
expect(keyPair).to.not.exist;
|
|
|
|
|
|
|
|
expect(devicestorageStub.init.calledOnce).to.be.true;
|
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('unlock', function() {
|
|
|
|
it('should unlock', function(done) {
|
|
|
|
var importMatcher = sinon.match(function(o) {
|
|
|
|
expect(o.passphrase).to.equal(passphrase);
|
|
|
|
expect(o.privateKeyArmored).to.equal(mockKeyPair.privateKey.encryptedKey);
|
|
|
|
expect(o.publicKeyArmored).to.equal(mockKeyPair.publicKey.publicKey);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
pgpStub.importKeys.withArgs(importMatcher).yields();
|
|
|
|
|
|
|
|
dao.unlock({
|
|
|
|
passphrase: passphrase,
|
|
|
|
keypair: mockKeyPair
|
|
|
|
}, function(err) {
|
|
|
|
expect(err).to.not.exist;
|
|
|
|
|
|
|
|
expect(pgpStub.importKeys.calledOnce).to.be.true;
|
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should generate a keypair and unlock', function(done) {
|
|
|
|
var genKeysMatcher, persistKeysMatcher, importMatcher, keypair;
|
|
|
|
|
|
|
|
keypair = {
|
|
|
|
keyId: 123,
|
|
|
|
publicKeyArmored: mockKeyPair.publicKey.publicKey,
|
|
|
|
privateKeyArmored: mockKeyPair.privateKey.encryptedKey
|
|
|
|
};
|
|
|
|
genKeysMatcher = sinon.match(function(o) {
|
|
|
|
expect(o.emailAddress).to.equal(emailAddress);
|
|
|
|
expect(o.keySize).to.equal(asymKeySize);
|
|
|
|
expect(o.passphrase).to.equal(passphrase);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
importMatcher = sinon.match(function(o) {
|
|
|
|
expect(o.passphrase).to.equal(passphrase);
|
|
|
|
expect(o.privateKeyArmored).to.equal(mockKeyPair.privateKey.encryptedKey);
|
|
|
|
expect(o.publicKeyArmored).to.equal(mockKeyPair.publicKey.publicKey);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
persistKeysMatcher = sinon.match(function(o) {
|
|
|
|
expect(o).to.deep.equal(mockKeyPair);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
pgpStub.generateKeys.withArgs(genKeysMatcher).yields(null, keypair);
|
|
|
|
pgpStub.importKeys.withArgs(importMatcher).yields();
|
|
|
|
keychainStub.putUserKeyPair.withArgs().yields();
|
|
|
|
|
|
|
|
dao.unlock({
|
|
|
|
passphrase: passphrase
|
|
|
|
}, function(err) {
|
|
|
|
expect(err).to.not.exist;
|
|
|
|
|
|
|
|
expect(pgpStub.generateKeys.calledOnce).to.be.true;
|
|
|
|
expect(pgpStub.importKeys.calledOnce).to.be.true;
|
|
|
|
expect(keychainStub.putUserKeyPair.calledOnce).to.be.true;
|
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should fail when persisting fails', function(done) {
|
|
|
|
var keypair = {
|
|
|
|
keyId: 123,
|
|
|
|
publicKeyArmored: 'qwerty',
|
|
|
|
privateKeyArmored: 'asdfgh'
|
|
|
|
};
|
|
|
|
pgpStub.generateKeys.yields(null, keypair);
|
|
|
|
pgpStub.importKeys.withArgs().yields();
|
|
|
|
keychainStub.putUserKeyPair.yields({});
|
|
|
|
|
|
|
|
dao.unlock({
|
|
|
|
passphrase: passphrase
|
|
|
|
}, function(err) {
|
|
|
|
expect(err).to.exist;
|
|
|
|
|
|
|
|
expect(pgpStub.generateKeys.calledOnce).to.be.true;
|
|
|
|
expect(pgpStub.importKeys.calledOnce).to.be.true;
|
|
|
|
expect(keychainStub.putUserKeyPair.calledOnce).to.be.true;
|
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should fail when import fails', function(done) {
|
|
|
|
var keypair = {
|
|
|
|
keyId: 123,
|
|
|
|
publicKeyArmored: 'qwerty',
|
|
|
|
privateKeyArmored: 'asdfgh'
|
|
|
|
};
|
|
|
|
|
|
|
|
pgpStub.generateKeys.withArgs().yields(null, keypair);
|
|
|
|
pgpStub.importKeys.withArgs().yields({});
|
|
|
|
|
|
|
|
dao.unlock({
|
|
|
|
passphrase: passphrase
|
|
|
|
}, function(err) {
|
|
|
|
expect(err).to.exist;
|
|
|
|
|
|
|
|
expect(pgpStub.generateKeys.calledOnce).to.be.true;
|
|
|
|
expect(pgpStub.importKeys.calledOnce).to.be.true;
|
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should fail when generation fails', function(done) {
|
|
|
|
pgpStub.generateKeys.yields({});
|
|
|
|
|
|
|
|
dao.unlock({
|
|
|
|
passphrase: passphrase
|
|
|
|
}, function(err) {
|
|
|
|
expect(err).to.exist;
|
|
|
|
|
|
|
|
expect(pgpStub.generateKeys.calledOnce).to.be.true;
|
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2013-11-28 05:46:08 -05:00
|
|
|
|
2013-11-28 09:05:29 -05:00
|
|
|
describe('_imapLogin', function() {
|
2013-11-28 05:46:08 -05:00
|
|
|
it('should work', function(done) {
|
|
|
|
imapClientStub.login.yields();
|
|
|
|
|
2013-11-28 09:05:29 -05:00
|
|
|
dao._imapLogin(function(err) {
|
2013-11-28 05:46:08 -05:00
|
|
|
expect(err).to.not.exist;
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should fail due to error in imap login', function(done) {
|
|
|
|
imapClientStub.login.yields({});
|
|
|
|
|
2013-11-28 09:05:29 -05:00
|
|
|
dao._imapLogin(function(err) {
|
2013-11-28 05:46:08 -05:00
|
|
|
expect(err).to.exist;
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2013-11-28 09:05:29 -05:00
|
|
|
describe('_imapLogout', function() {
|
2013-11-28 05:46:08 -05:00
|
|
|
it('should work', function(done) {
|
|
|
|
imapClientStub.logout.yields();
|
|
|
|
|
2013-11-28 09:05:29 -05:00
|
|
|
dao._imapLogout(function(err) {
|
2013-11-28 05:46:08 -05:00
|
|
|
expect(err).to.not.exist;
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should fail due to error in imap login', function(done) {
|
|
|
|
imapClientStub.logout.yields({});
|
|
|
|
|
2013-11-28 09:05:29 -05:00
|
|
|
dao._imapLogout(function(err) {
|
|
|
|
expect(err).to.exist;
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('_imapListFolders', function() {
|
|
|
|
var dummyFolders = [{
|
|
|
|
type: 'Inbox',
|
|
|
|
path: 'INBOX'
|
|
|
|
}, {
|
|
|
|
type: 'Outbox',
|
|
|
|
path: 'OUTBOX'
|
|
|
|
}];
|
|
|
|
|
|
|
|
it('should list from storage', function(done) {
|
|
|
|
devicestorageStub.listItems.withArgs('folders').yields(null, [dummyFolders]);
|
|
|
|
|
|
|
|
dao._imapListFolders(function(err, folders) {
|
|
|
|
expect(err).to.not.exist;
|
|
|
|
expect(devicestorageStub.listItems.calledOnce).to.be.true;
|
|
|
|
expect(folders[0].type).to.equal('Inbox');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should not list from storage due to error', function(done) {
|
|
|
|
devicestorageStub.listItems.yields({});
|
|
|
|
|
|
|
|
dao._imapListFolders(function(err, folders) {
|
|
|
|
expect(err).to.exist;
|
|
|
|
expect(folders).to.not.exist;
|
|
|
|
expect(devicestorageStub.listItems.calledOnce).to.be.true;
|
|
|
|
expect(imapClientStub.listWellKnownFolders.called).to.be.false;
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should list from imap', function(done) {
|
|
|
|
devicestorageStub.listItems.yields(null, []);
|
|
|
|
imapClientStub.listWellKnownFolders.yields(null, {
|
|
|
|
inbox: dummyFolders[0]
|
|
|
|
});
|
|
|
|
devicestorageStub.storeList.yields();
|
|
|
|
|
|
|
|
dao._imapListFolders(function(err, folders) {
|
|
|
|
expect(err).to.not.exist;
|
|
|
|
expect(devicestorageStub.listItems.calledOnce).to.be.true;
|
|
|
|
expect(imapClientStub.listWellKnownFolders.calledOnce).to.be.true;
|
|
|
|
expect(devicestorageStub.storeList.calledOnce).to.be.true;
|
|
|
|
expect(folders[0].type).to.equal('Inbox');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should not list from imap due to store error', function(done) {
|
|
|
|
devicestorageStub.listItems.yields(null, []);
|
|
|
|
imapClientStub.listWellKnownFolders.yields(null, {
|
|
|
|
inbox: dummyFolders[0]
|
|
|
|
});
|
|
|
|
devicestorageStub.storeList.yields({});
|
|
|
|
|
|
|
|
dao._imapListFolders(function(err, folders) {
|
|
|
|
expect(err).to.exist;
|
|
|
|
expect(folders).to.not.exist;
|
|
|
|
expect(devicestorageStub.listItems.calledOnce).to.be.true;
|
|
|
|
expect(imapClientStub.listWellKnownFolders.calledOnce).to.be.true;
|
|
|
|
expect(devicestorageStub.storeList.calledOnce).to.be.true;
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should not list from imap due to imap error', function(done) {
|
|
|
|
devicestorageStub.listItems.yields(null, []);
|
|
|
|
imapClientStub.listWellKnownFolders.yields({});
|
|
|
|
|
|
|
|
dao._imapListFolders(function(err, folders) {
|
2013-11-28 05:46:08 -05:00
|
|
|
expect(err).to.exist;
|
2013-11-28 09:05:29 -05:00
|
|
|
expect(folders).to.not.exist;
|
|
|
|
expect(devicestorageStub.listItems.calledOnce).to.be.true;
|
|
|
|
expect(imapClientStub.listWellKnownFolders.calledOnce).to.be.true;
|
|
|
|
expect(devicestorageStub.storeList.called).to.be.false;
|
2013-11-28 05:46:08 -05:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2013-11-28 05:36:14 -05:00
|
|
|
});
|
|
|
|
});
|