add error handling and tests for corner cases

This commit is contained in:
Felix Hammerl 2013-12-02 19:37:41 +01:00
parent 548ca655c7
commit 4ff88694d4
2 changed files with 504 additions and 41 deletions

View File

@ -32,6 +32,7 @@ define(function(require) {
keypair; keypair;
self._account = options.account; self._account = options.account;
self._account.busy = false;
// validate email address // validate email address
var emailAddress = self._account.emailAddress; var emailAddress = self._account.emailAddress;
@ -162,6 +163,15 @@ define(function(require) {
return; return;
} }
if (self._account.busy) {
callback({
errMsg: 'Sync aborted: Previous sync still in progress'
});
return;
}
self._account.busy = true;
folder = _.findWhere(self._account.folders, { folder = _.findWhere(self._account.folders, {
path: options.folder path: options.folder
}); });
@ -182,6 +192,7 @@ define(function(require) {
folder: folder.path folder: folder.path
}, function(err, messages) { }, function(err, messages) {
if (err) { if (err) {
self._account.busy = false;
callback(err); callback(err);
return; return;
} }
@ -189,6 +200,7 @@ define(function(require) {
if (_.isEmpty(messages)) { if (_.isEmpty(messages)) {
// if there's nothing here, we're good // if there's nothing here, we're good
callback(); callback();
doImapDelta();
return; return;
} }
@ -198,7 +210,13 @@ define(function(require) {
}); });
messages.forEach(function(message) { messages.forEach(function(message) {
handleMessage(message, function(cleartextMessage) { handleMessage(message, function(err, cleartextMessage) {
if (err) {
self._account.busy = false;
callback(err);
return;
}
folder.messages.push(cleartextMessage); folder.messages.push(cleartextMessage);
after(); after();
}); });
@ -210,6 +228,12 @@ define(function(require) {
self._localListMessages({ self._localListMessages({
folder: folder.path folder: folder.path
}, function(err, messages) { }, function(err, messages) {
if (err) {
self._account.busy = false;
callback(err);
return;
}
/* /*
* delta1: storage > memory => we deleted messages, remove from remote * delta1: storage > memory => we deleted messages, remove from remote
* delta2: memory > storage => we added messages, push to remote * delta2: memory > storage => we added messages, push to remote
@ -219,8 +243,8 @@ define(function(require) {
if (_.isEmpty(delta1) /* && _.isEmpty(delta2)*/ ) { if (_.isEmpty(delta1) /* && _.isEmpty(delta2)*/ ) {
// if there is no delta, head directly to imap sync // if there is no delta, head directly to imap sync
doImapDelta();
callback(); callback();
doImapDelta();
return; return;
} }
@ -229,8 +253,8 @@ define(function(require) {
function doDelta1() { function doDelta1() {
var after = _.after(delta1.length, function() { var after = _.after(delta1.length, function() {
// doDelta2(); when it is implemented // doDelta2(); when it is implemented
doImapDelta();
callback(); callback();
doImapDelta();
}); });
delta1.forEach(function(message) { delta1.forEach(function(message) {
@ -241,12 +265,14 @@ define(function(require) {
self._imapDeleteMessage(deleteMe, function(err) { self._imapDeleteMessage(deleteMe, function(err) {
if (err) { if (err) {
self._account.busy = false;
callback(err); callback(err);
return; return;
} }
self._localDeleteMessage(deleteMe, function(err) { self._localDeleteMessage(deleteMe, function(err) {
if (err) { if (err) {
self._account.busy = false;
callback(err); callback(err);
return; return;
} }
@ -264,6 +290,7 @@ define(function(require) {
folder: folder.path folder: folder.path
}, function(err, headers) { }, function(err, headers) {
if (err) { if (err) {
self._account.busy = false;
callback(err); callback(err);
return; return;
} }
@ -282,6 +309,7 @@ define(function(require) {
if (_.isEmpty(delta3) && _.isEmpty(delta4)) { if (_.isEmpty(delta3) && _.isEmpty(delta4)) {
// if there is no delta, we're done // if there is no delta, we're done
self._account.busy = false;
callback(); callback();
return; return;
} }
@ -311,6 +339,7 @@ define(function(require) {
uid: header.uid uid: header.uid
}, function(err) { }, function(err) {
if (err) { if (err) {
self._account.busy = false;
callback(err); callback(err);
return; return;
} }
@ -325,10 +354,12 @@ define(function(require) {
function doDelta4() { function doDelta4() {
// no delta, we're done here // no delta, we're done here
if (_.isEmpty(delta4)) { if (_.isEmpty(delta4)) {
self._account.busy = false;
callback(); callback();
} }
var after = _.after(delta4.length, function() { var after = _.after(delta4.length, function() {
self._account.busy = false;
callback(); callback();
}); });
@ -339,6 +370,7 @@ define(function(require) {
uid: header.uid uid: header.uid
}, function(err, message) { }, function(err, message) {
if (err) { if (err) {
self._account.busy = false;
callback(err); callback(err);
return; return;
} }
@ -349,6 +381,7 @@ define(function(require) {
emails: [message] emails: [message]
}, function(err) { }, function(err) {
if (err) { if (err) {
self._account.busy = false;
callback(err); callback(err);
return; return;
} }
@ -356,6 +389,7 @@ define(function(require) {
// decrypt and add to folder in memory // decrypt and add to folder in memory
handleMessage(message, function(err, cleartextMessage) { handleMessage(message, function(err, cleartextMessage) {
if (err) { if (err) {
self._account.busy = false;
callback(err); callback(err);
return; return;
} }

View File

@ -7,7 +7,6 @@ define(function(require) {
SmtpClient = require('smtp-client'), SmtpClient = require('smtp-client'),
PGP = require('js/crypto/pgp'), PGP = require('js/crypto/pgp'),
DeviceStorageDAO = require('js/dao/devicestorage-dao'), DeviceStorageDAO = require('js/dao/devicestorage-dao'),
_ = require('underscore'),
expect = chai.expect; expect = chai.expect;
@ -59,6 +58,7 @@ define(function(require) {
account = { account = {
emailAddress: emailAddress, emailAddress: emailAddress,
asymKeySize: asymKeySize, asymKeySize: asymKeySize,
busy: false
}; };
publicKey = "-----BEGIN PUBLIC KEY-----\r\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxy+Te5dyeWd7g0P+8LNO7fZDQ\r\n" + "g96xTb1J6pYE/pPTMlqhB6BRItIYjZ1US5q2vk5Zk/5KasBHAc9RbCqvh9v4XFEY\r\n" + "JVmTXC4p8ft1LYuNWIaDk+R3dyYXmRNct/JC4tks2+8fD3aOvpt0WNn3R75/FGBt\r\n" + "h4BgojAXDE+PRQtcVQIDAQAB\r\n" + "-----END PUBLIC KEY-----"; publicKey = "-----BEGIN PUBLIC KEY-----\r\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxy+Te5dyeWd7g0P+8LNO7fZDQ\r\n" + "g96xTb1J6pYE/pPTMlqhB6BRItIYjZ1US5q2vk5Zk/5KasBHAc9RbCqvh9v4XFEY\r\n" + "JVmTXC4p8ft1LYuNWIaDk+R3dyYXmRNct/JC4tks2+8fD3aOvpt0WNn3R75/FGBt\r\n" + "h4BgojAXDE+PRQtcVQIDAQAB\r\n" + "-----END PUBLIC KEY-----";
@ -538,8 +538,9 @@ define(function(require) {
describe('sync', function() { describe('sync', function() {
it('should work initially', function(done) { it('should work initially', function(done) {
var folder, localListStub; var folder, localListStub, invocations, imapListStub;
invocations = 0;
folder = 'FOLDAAAA'; folder = 'FOLDAAAA';
dao._account.folders = [{ dao._account.folders = [{
type: 'Folder', type: 'Folder',
@ -551,10 +552,22 @@ define(function(require) {
}).yields(null, [dummyEncryptedMail]); }).yields(null, [dummyEncryptedMail]);
keychainStub.getReceiverPublicKey.withArgs(dummyEncryptedMail.from[0].address).yields(null, mockKeyPair); keychainStub.getReceiverPublicKey.withArgs(dummyEncryptedMail.from[0].address).yields(null, mockKeyPair);
pgpStub.decrypt.withArgs(dummyEncryptedMail.body, mockKeyPair.publicKey).yields(null, dummyDecryptedMail.body); pgpStub.decrypt.withArgs(dummyEncryptedMail.body, mockKeyPair.publicKey).yields(null, dummyDecryptedMail.body);
imapListStub = sinon.stub(dao, '_imapListMessages').withArgs({
folder: folder
}).yields(null, [dummyEncryptedMail]);
dao.sync({ dao.sync({
folder: folder folder: folder
}, function() { }, function(err) {
expect(err).to.not.exist;
if (invocations === 0) {
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.not.be.empty; expect(dao._account.folders[0].messages).to.not.be.empty;
expect(localListStub.calledOnce).to.be.true; expect(localListStub.calledOnce).to.be.true;
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true; expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
@ -564,9 +577,126 @@ define(function(require) {
}); });
}); });
it('should be up to date', function(done) { it('should initially error on decryption', function(done) {
var after, folder, localListStub, imapListStub; var folder, localListStub, invocations;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder
}];
localListStub = sinon.stub(dao, '_localListMessages').yields(null, [dummyEncryptedMail]);
keychainStub.getReceiverPublicKey.yields({});
dao.sync({
folder: folder
}, function(err) {
expect(err).to.exist;
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
done();
});
});
it('should initially sync downstream when storage is empty', function(done) {
var folder, localListStub, localStoreStub, invocations, imapListStub, imapGetStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder
}];
localListStub = sinon.stub(dao, '_localListMessages').withArgs({
folder: folder
}).yields(null, []);
keychainStub.getReceiverPublicKey.withArgs(dummyEncryptedMail.from[0].address).yields(null, mockKeyPair);
pgpStub.decrypt.withArgs(dummyEncryptedMail.body, mockKeyPair.publicKey).yields(null, dummyDecryptedMail.body);
imapListStub = sinon.stub(dao, '_imapListMessages').withArgs({
folder: folder
}).yields(null, [dummyEncryptedMail]);
imapGetStub = sinon.stub(dao, '_imapGetMessage').withArgs({
folder: folder,
uid: dummyEncryptedMail.uid
}).yields(null, dummyEncryptedMail);
localStoreStub = sinon.stub(dao, '_localStoreMessages').yields();
dao.sync({
folder: folder
}, function(err) {
expect(err).to.not.exist;
if (invocations === 0) {
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.not.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true;
expect(imapGetStub.calledOnce).to.be.true;
expect(localStoreStub.calledOnce).to.be.true;
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
expect(pgpStub.decrypt.calledOnce).to.be.true;
done();
});
});
it('should not work when busy', function(done) {
dao._account.busy = true;
dao.sync({
folder: 'OOGA'
}, function(err) {
expect(err).to.exist;
done();
});
});
it('should fetch messages downstream from the remote', function(done) {
dao.sync({}, function(err) {
expect(err).to.exist;
done();
});
});
it('should not work when initial setup errors', function(done) {
var folder, localListStub;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder
}];
localListStub = sinon.stub(dao, '_localListMessages').yields({});
dao.sync({
folder: folder
}, function(err) {
expect(err).to.exist;
expect(dao._account.busy).to.be.false;
expect(localListStub.calledOnce).to.be.true;
done();
});
});
it('should be up to date', function(done) {
var folder, localListStub, imapListStub, invocations;
invocations = 0;
folder = 'FOLDAAAA'; folder = 'FOLDAAAA';
dao._account.folders = [{ dao._account.folders = [{
type: 'Folder', type: 'Folder',
@ -581,20 +711,154 @@ define(function(require) {
folder: folder folder: folder
}).yields(null, [dummyEncryptedMail]); }).yields(null, [dummyEncryptedMail]);
after = _.after(2, function() {
dao.sync({
folder: folder
}, function(err) {
expect(err).to.not.exist;
if (invocations === 0) {
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0]).to.not.be.empty; expect(dao._account.folders[0]).to.not.be.empty;
expect(localListStub.calledOnce).to.be.true; expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true; expect(imapListStub.calledOnce).to.be.true;
done(); done();
}); });
});
it('should error while listing from imap', function(done) {
var folder, localListStub, imapListStub, invocations;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: [dummyDecryptedMail]
}];
localListStub = sinon.stub(dao, '_localListMessages').yields(null, [dummyEncryptedMail]);
imapListStub = sinon.stub(dao, '_imapListMessages').yields({});
dao.sync({ dao.sync({
folder: folder folder: folder
}, after); }, function(err) {
if (invocations === 0) {
expect(err).to.not.exist;
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(err).to.exist;
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0]).to.not.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true;
done();
});
});
it('should error while listing local messages', function(done) {
var folder, localListStub;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: [dummyDecryptedMail]
}];
localListStub = sinon.stub(dao, '_localListMessages').yields({});
dao.sync({
folder: folder
}, function(err) {
expect(err).to.exist;
expect(dao._account.busy).to.be.false;
expect(localListStub.calledOnce).to.be.true;
done();
});
}); });
it('should remove messages from the remote', function(done) { it('should remove messages from the remote', function(done) {
var after, folder, localListStub, imapListStub, localDeleteStub, imapDeleteStub; var invocations, folder, localListStub, imapListStub, localDeleteStub, imapDeleteStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: []
}];
localListStub = sinon.stub(dao, '_localListMessages').yields(null, [dummyEncryptedMail]);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, []);
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage').yields();
localDeleteStub = sinon.stub(dao, '_localDeleteMessage').yields();
dao.sync({
folder: folder
}, function(err) {
expect(err).to.not.exist;
if (invocations === 0) {
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true;
expect(localDeleteStub.calledOnce).to.be.true;
expect(imapDeleteStub.calledOnce).to.be.true;
done();
});
});
it('should error whilte removing messages from local', function(done) {
var invocations, folder, localListStub, imapListStub, localDeleteStub, imapDeleteStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: []
}];
localListStub = sinon.stub(dao, '_localListMessages').yields(null, [dummyEncryptedMail]);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, []);
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage').yields();
localDeleteStub = sinon.stub(dao, '_localDeleteMessage').yields({});
dao.sync({
folder: folder
}, function(err) {
expect(err).to.exist;
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.called).to.be.false;
expect(localDeleteStub.calledOnce).to.be.true;
expect(imapDeleteStub.calledOnce).to.be.true;
done();
});
});
it('should error while removing messages from the remote', function(done) {
var folder, localListStub, imapListStub, localDeleteStub, imapDeleteStub;
folder = 'FOLDAAAA'; folder = 'FOLDAAAA';
dao._account.folders = [{ dao._account.folders = [{
@ -603,38 +867,30 @@ define(function(require) {
messages: [] messages: []
}]; }];
localListStub = sinon.stub(dao, '_localListMessages').withArgs({ localListStub = sinon.stub(dao, '_localListMessages').yields(null, [dummyEncryptedMail]);
folder: folder imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, []);
}).yields(null, [dummyEncryptedMail]); imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage').yields({});
imapListStub = sinon.stub(dao, '_imapListMessages').withArgs({ localDeleteStub = sinon.stub(dao, '_localDeleteMessage');
folder: folder
}).yields(null, []);
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage').withArgs({
folder: folder,
uid: dummyEncryptedMail.uid
}).yields();
localDeleteStub = sinon.stub(dao, '_localDeleteMessage').withArgs({
folder: folder,
uid: dummyEncryptedMail.uid
}).yields();
after = _.after(2, function() {
expect(dao._account.folders[0].messages).to.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true;
expect(localDeleteStub.calledOnce).to.be.true;
expect(imapDeleteStub.calledOnce).to.be.true;
done();
});
dao.sync({ dao.sync({
folder: folder folder: folder
}, after); }, function(err) {
expect(err).to.exist;
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapDeleteStub.calledOnce).to.be.true;
expect(localDeleteStub.called).to.be.false;
done();
});
}); });
it('should delete messages locally if not present on remote', function(done) { it('should delete messages locally if not present on remote', function(done) {
var after, folder, localListStub, imapListStub, localDeleteStub; var invocations, folder, localListStub, imapListStub, localDeleteStub;
invocations = 0;
folder = 'FOLDAAAA'; folder = 'FOLDAAAA';
dao._account.folders = [{ dao._account.folders = [{
type: 'Folder', type: 'Folder',
@ -642,6 +898,7 @@ define(function(require) {
messages: [dummyDecryptedMail] messages: [dummyDecryptedMail]
}]; }];
localListStub = sinon.stub(dao, '_localListMessages').withArgs({ localListStub = sinon.stub(dao, '_localListMessages').withArgs({
folder: folder folder: folder
}).yields(null, [dummyEncryptedMail]); }).yields(null, [dummyEncryptedMail]);
@ -653,7 +910,18 @@ define(function(require) {
uid: dummyEncryptedMail.uid uid: dummyEncryptedMail.uid
}).yields(); }).yields();
after = _.after(2, function() { dao.sync({
folder: folder
}, function(err) {
expect(err).to.not.exist;
if (invocations === 0) {
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.be.empty; expect(dao._account.folders[0].messages).to.be.empty;
expect(localListStub.calledOnce).to.be.true; expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true; expect(imapListStub.calledOnce).to.be.true;
@ -661,14 +929,49 @@ define(function(require) {
done(); done();
}); });
});
it('should error while deleting locally if not present on remote', function(done) {
var invocations, folder, localListStub, imapListStub, localDeleteStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: [dummyDecryptedMail]
}];
localListStub = sinon.stub(dao, '_localListMessages').yields(null, [dummyEncryptedMail]);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, []);
localDeleteStub = sinon.stub(dao, '_localDeleteMessage').yields({});
dao.sync({ dao.sync({
folder: folder folder: folder
}, after); }, function(err) {
if (invocations === 0) {
expect(err).to.not.exist;
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(err).to.exist;
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true;
expect(localDeleteStub.calledOnce).to.be.true;
done();
});
}); });
it('should fetch messages downstream from the remote', function(done) { it('should fetch messages downstream from the remote', function(done) {
var after, folder, localListStub, imapListStub, imapGetStub, localStoreStub; var invocations, folder, localListStub, imapListStub, imapGetStub, localStoreStub;
invocations = 0;
folder = 'FOLDAAAA'; folder = 'FOLDAAAA';
dao._account.folders = [{ dao._account.folders = [{
type: 'Folder', type: 'Folder',
@ -691,7 +994,18 @@ define(function(require) {
pgpStub.decrypt.withArgs(dummyEncryptedMail.body, mockKeyPair.publicKey).yields(null, dummyDecryptedMail.body); pgpStub.decrypt.withArgs(dummyEncryptedMail.body, mockKeyPair.publicKey).yields(null, dummyDecryptedMail.body);
after = _.after(2, function() { dao.sync({
folder: folder
}, function(err) {
expect(err).to.not.exist;
if (invocations === 0) {
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.not.be.empty; expect(dao._account.folders[0].messages).to.not.be.empty;
expect(localListStub.calledOnce).to.be.true; expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true; expect(imapListStub.calledOnce).to.be.true;
@ -701,10 +1015,125 @@ define(function(require) {
expect(pgpStub.decrypt.calledOnce).to.be.true; expect(pgpStub.decrypt.calledOnce).to.be.true;
done(); done();
}); });
});
it('should error while decrypting fetch messages from the remote', function(done) {
var invocations, folder, localListStub, imapListStub, imapGetStub, localStoreStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: []
}];
localListStub = sinon.stub(dao, '_localListMessages').yields(null, []);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [dummyEncryptedMail]);
imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, dummyEncryptedMail);
localStoreStub = sinon.stub(dao, '_localStoreMessages').yields();
keychainStub.getReceiverPublicKey.yields({});
dao.sync({ dao.sync({
folder: folder folder: folder
}, after); }, function(err) {
if (invocations === 0) {
expect(err).to.not.exist;
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(err).to.exist;
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true;
expect(imapGetStub.calledOnce).to.be.true;
expect(localStoreStub.calledOnce).to.be.true;
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
expect(pgpStub.decrypt.called).to.be.false;
done();
});
});
it('should error while storing messages from the remote locally', function(done) {
var invocations, folder, localListStub, imapListStub, imapGetStub, localStoreStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: []
}];
localListStub = sinon.stub(dao, '_localListMessages').yields(null, []);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [dummyEncryptedMail]);
imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, dummyEncryptedMail);
localStoreStub = sinon.stub(dao, '_localStoreMessages').yields({});
dao.sync({
folder: folder
}, function(err) {
if (invocations === 0) {
expect(err).to.not.exist;
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(err).to.exist;
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true;
expect(imapGetStub.calledOnce).to.be.true;
expect(localStoreStub.calledOnce).to.be.true;
expect(keychainStub.getReceiverPublicKey.called).to.be.false;
expect(pgpStub.decrypt.called).to.be.false;
done();
});
});
it('should error while fetching messages from the remote', function(done) {
var invocations, folder, localListStub, imapListStub, imapGetStub, localStoreStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: []
}];
localListStub = sinon.stub(dao, '_localListMessages').yields(null, []);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [dummyEncryptedMail]);
imapGetStub = sinon.stub(dao, '_imapGetMessage').yields({});
localStoreStub = sinon.stub(dao, '_localStoreMessages');
dao.sync({
folder: folder
}, function(err) {
if (invocations === 0) {
expect(err).to.not.exist;
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(err).to.exist;
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true;
expect(imapGetStub.calledOnce).to.be.true;
expect(localStoreStub.called).to.be.false;
expect(keychainStub.getReceiverPublicKey.called).to.be.false;
expect(pgpStub.decrypt.called).to.be.false;
done();
});
}); });
}); });