diff --git a/package.json b/package.json
index b12c4cf..7285942 100644
--- a/package.json
+++ b/package.json
@@ -62,13 +62,13 @@
"grunt-string-replace": "~1.0.0",
"grunt-svgmin": "~1.0.0",
"grunt-svgstore": "~0.3.4",
- "imap-client": "~0.10.0",
+ "imap-client": "~0.11.0",
"jquery": "~2.1.1",
"mailreader": "~0.4.0",
"mocha": "^1.21.4",
"ng-infinite-scroll": "~1.1.2",
- "pgpbuilder": "~0.5.0",
- "pgpmailer": "~0.8.0",
+ "pgpbuilder": "~0.6.0",
+ "pgpmailer": "~0.9.0",
"sinon": "~1.7.3",
"tcp-socket": "~0.5.0",
"time-grunt": "^1.0.0",
diff --git a/src/js/email/email.js b/src/js/email/email.js
index 709c71d..3c6d477 100644
--- a/src/js/email/email.js
+++ b/src/js/email/email.js
@@ -188,23 +188,16 @@ Email.prototype.unlock = function(options) {
*/
Email.prototype.openFolder = function(options) {
var self = this;
- return new Promise(function(resolve, reject) {
+ return new Promise(function(resolve) {
self.checkOnline();
+ resolve();
- if (options.folder.path === config.outboxMailboxPath) {
- resolve();
- return;
+ }).then(function() {
+ if (options.folder.path !== config.outboxMailboxPath) {
+ return self._imapClient.selectMailbox({
+ path: options.folder.path
+ });
}
-
- self._imapClient.selectMailbox({
- path: options.folder.path
- }, function(err, folder) {
- if (err) {
- reject(err);
- } else {
- resolve(folder);
- }
- });
});
};
/**
@@ -499,6 +492,12 @@ Email.prototype.setFlags = function(options) {
}).then(function(storedMessages) {
// set the flags
var storedMessage = storedMessages[0];
+
+ if (!storedMessage) {
+ // the message has been deleted in the meantime
+ return;
+ }
+
storedMessage.unread = options.message.unread;
storedMessage.flagged = options.message.flagged;
storedMessage.answered = options.message.answered;
@@ -610,12 +609,15 @@ Email.prototype.getBody = function(options) {
folder: folder,
uid: message.uid
}).then(function(localMessages) {
- if (localMessages.length === 0) {
- return;
- }
-
localMessage = localMessages[0];
+ if (!localMessage) {
+ // the message has been deleted in the meantime
+ var error = new Error('Can not get the contents of this message. It has already been deleted!');
+ error.hide = true;
+ throw error;
+ }
+
// treat attachment and non-attachment body parts separately:
// we need to fetch the content for non-attachment body parts (encrypted, signed, text, html, resources referenced from the html)
// but we spare the effort and fetch attachment content later upon explicit user request.
@@ -731,6 +733,10 @@ Email.prototype.getBody = function(options) {
}).catch(function(err) {
self.done();
message.loadingBody = false;
+ if (err.hide) {
+ // ignore errors with err.hide
+ return message;
+ }
throw err;
});
@@ -960,15 +966,7 @@ Email.prototype._sendGeneric = function(options, mailer) {
}).then(function() {
// send the email
- return new Promise(function(resolve, reject) {
- self._pgpMailer.send(options, function(err, rfcText) {
- if (err) {
- reject(err);
- } else {
- resolve(rfcText);
- }
- });
- });
+ return self._pgpMailer.send(options);
}).then(function(rfcText) {
// try to upload to sent, but we don't actually care if the upload failed or not
// this should not negatively impact the process of sending
@@ -990,20 +988,14 @@ Email.prototype._sendGeneric = function(options, mailer) {
* Signs and encrypts a message
*
* @param {Object} options.email The message to be encrypted
- * @param {Function} callback(error, message) Invoked when the message was encrypted, or an error occurred
+ * @param {Function} callback(message) Invoked when the message was encrypted, or an error occurred
*/
Email.prototype.encrypt = function(options) {
var self = this;
self.busy();
- return new Promise(function(resolve, reject) {
- self._pgpbuilder.encrypt(options, function(err, message) {
- self.done();
- if (err) {
- reject(err);
- } else {
- resolve(message);
- }
- });
+ return self._pgpbuilder.encrypt(options).then(function(message) {
+ self.done();
+ return message;
});
};
@@ -1043,15 +1035,7 @@ Email.prototype.onConnect = function(imap) {
}).then(function() {
// imap login
- return new Promise(function(resolve, reject) {
- self._imapClient.login(function(err) {
- if (err) {
- reject(err);
- } else {
- resolve();
- }
- });
- });
+ return self._imapClient.login();
}).then(function() {
self._account.loggingIn = false;
@@ -1185,7 +1169,7 @@ Email.prototype._onSyncUpdate = function(options) {
folder: folder,
firstUid: Math.min.apply(null, options.list),
lastUid: Math.max.apply(null, options.list)
- }, self._dialog.error);
+ }).then(self._dialog.error).catch(self._dialog.error);
} else if (options.type === SYNC_TYPE_DELETED) {
// messages have been deleted, remove from local storage and memory
options.list.forEach(function(uid) {
@@ -1201,7 +1185,7 @@ Email.prototype._onSyncUpdate = function(options) {
folder: folder,
message: message,
localOnly: true
- }, self._dialog.error);
+ }).then(self._dialog.error).catch(self._dialog.error);
});
} else if (options.type === SYNC_TYPE_MSGS) {
// NB! several possible reasons why this could be called.
@@ -1228,7 +1212,7 @@ Email.prototype._onSyncUpdate = function(options) {
folder: folder,
message: message,
localOnly: true
- }, self._dialog.error);
+ }).then(self._dialog.error).catch(self._dialog.error);
});
}
};
@@ -1276,7 +1260,7 @@ Email.prototype._initFoldersFromImap = function() {
self.busy(); // start the spinner
// fetch list from imap server
- return listWellknownFolder().then(function(wellKnownFolders) {
+ return self._imapClient.listWellKnownFolders().then(function(wellKnownFolders) {
var foldersChanged = false, // indicates if we need to persist anything to disk
imapFolders = []; // aggregate all the imap folders
@@ -1409,18 +1393,6 @@ Email.prototype._initFoldersFromImap = function() {
self.done(); // stop the spinner
throw err;
});
-
- function listWellknownFolder() {
- return new Promise(function(resolve, reject) {
- self._imapClient.listWellKnownFolders(function(err, wellKnownFolders) {
- if (err) {
- reject(err);
- } else {
- resolve(wellKnownFolders);
- }
- });
- });
- }
};
/**
@@ -1475,17 +1447,13 @@ Email.prototype.done = function() {
*/
Email.prototype._imapMark = function(options) {
var self = this;
- return new Promise(function(resolve, reject) {
- self.checkOnline();
+ return new Promise(function(resolve) {
+ self.checkOnline();
+ resolve();
+ }).then(function() {
options.path = options.folder.path;
- self._imapClient.updateFlags(options, function(err) {
- if (err) {
- reject(err);
- } else {
- resolve();
- }
- });
+ return self._imapClient.updateFlags(options);
});
};
@@ -1510,7 +1478,10 @@ Email.prototype._imapDeleteMessage = function(options) {
// there's no known trash folder to move the mail to or we're in the trash folder, so we can purge the message
if (!trash || options.folder === trash) {
- return imapDelete();
+ return self._imapClient.deleteMessage({
+ path: options.folder.path,
+ uid: options.uid
+ });
}
return self._imapMoveMessage({
@@ -1519,21 +1490,6 @@ Email.prototype._imapDeleteMessage = function(options) {
uid: options.uid
});
});
-
- function imapDelete() {
- return new Promise(function(resolve, reject) {
- self._imapClient.deleteMessage({
- path: options.folder.path,
- uid: options.uid
- }, function(err) {
- if (err) {
- reject(err);
- } else {
- resolve();
- }
- });
- });
- }
};
/**
@@ -1546,19 +1502,14 @@ Email.prototype._imapDeleteMessage = function(options) {
*/
Email.prototype._imapMoveMessage = function(options) {
var self = this;
- return new Promise(function(resolve, reject) {
+ return new Promise(function(resolve) {
self.checkOnline();
-
- self._imapClient.moveMessage({
+ resolve();
+ }).then(function() {
+ return self._imapClient.moveMessage({
path: options.folder.path,
destination: options.destination.path,
uid: options.uid
- }, function(err) {
- if (err) {
- reject(err);
- } else {
- resolve();
- }
});
});
};
@@ -1575,17 +1526,12 @@ Email.prototype._imapMoveMessage = function(options) {
*/
Email.prototype._imapListMessages = function(options) {
var self = this;
- return new Promise(function(resolve, reject) {
+ return new Promise(function(resolve) {
self.checkOnline();
-
+ resolve();
+ }).then(function() {
options.path = options.folder.path;
- self._imapClient.listMessages(options, function(err, messages) {
- if (err) {
- reject(err);
- } else {
- resolve(messages);
- }
- });
+ return self._imapClient.listMessages(options);
});
};
@@ -1597,17 +1543,10 @@ Email.prototype._imapListMessages = function(options) {
*/
Email.prototype._imapUploadMessage = function(options) {
var self = this;
- return new Promise(function(resolve, reject) {
- self._imapClient.uploadMessage({
- path: options.folder.path,
- message: options.message
- }, function(err) {
- if (err) {
- reject(err);
- } else {
- resolve();
- }
- });
+
+ return self._imapClient.uploadMessage({
+ path: options.folder.path,
+ message: options.message
});
};
@@ -1619,26 +1558,22 @@ Email.prototype._imapUploadMessage = function(options) {
*/
Email.prototype._getBodyParts = function(options) {
var self = this;
- return new Promise(function(resolve, reject) {
+ return new Promise(function(resolve) {
self.checkOnline();
-
+ resolve();
+ }).then(function() {
options.path = options.folder.path;
- self._imapClient.getBodyParts(options, function(err) {
- if (err) {
- reject(err);
- return;
- }
+ return self._imapClient.getBodyParts(options);
+ }).then(function() {
+ if (options.bodyParts.filter(function(bodyPart) {
+ return !(bodyPart.raw || bodyPart.content);
+ }).length) {
+ var error = new Error('Can not get the contents of this message. It has already been deleted!');
+ error.hide = true;
+ throw error;
+ }
- // interpret the raw content of the email
- self._mailreader.parse(options, function(err, message) {
- if (err) {
- reject(err);
- return;
- }
-
- resolve(message);
- });
- });
+ return self._parse(options);
});
};
diff --git a/src/js/util/connection-doctor.js b/src/js/util/connection-doctor.js
index eada553..538b20a 100644
--- a/src/js/util/connection-doctor.js
+++ b/src/js/util/connection-doctor.js
@@ -218,25 +218,21 @@ ConnectionDoctor.prototype._checkImap = function() {
}
};
- self._imap.login(function() {
+ self._imap.login().then(function() {
loggedIn = true;
+ return self._imap.listWellKnownFolders();
+ }).then(function(wellKnownFolders) {
+ if (wellKnownFolders.Inbox.length === 0) {
+ // the client needs at least an inbox folder to work properly
+ reject(createError(NO_INBOX, str.connDocNoInbox.replace('{0}', host)));
+ return;
+ }
- self._imap.listWellKnownFolders(function(error, wellKnownFolders) {
- if (error) {
- reject(createError(GENERIC_ERROR, str.connDocGenericError.replace('{0}', host).replace('{1}', error.message), error));
- return;
- }
-
- if (wellKnownFolders.Inbox.length === 0) {
- // the client needs at least an inbox folder to work properly
- reject(createError(NO_INBOX, str.connDocNoInbox.replace('{0}', host)));
- return;
- }
-
- self._imap.logout(function() {
- resolve();
- });
- });
+ return self._imap.logout();
+ }).then(function(){
+ resolve();
+ }).catch(function(error) {
+ reject(createError(GENERIC_ERROR, str.connDocGenericError.replace('{0}', host).replace('{1}', error.message), error));
});
});
};
diff --git a/src/tpl/mail-list.html b/src/tpl/mail-list.html
index e0c758e..7a230f0 100644
--- a/src/tpl/mail-list.html
+++ b/src/tpl/mail-list.html
@@ -28,7 +28,7 @@
+ ng-repeat="email in displayMessages track by email.uid">
-
diff --git a/test/integration/email-dao-test.js b/test/integration/email-dao-test.js
index 82dc9a3..d2b0d00 100644
--- a/test/integration/email-dao-test.js
+++ b/test/integration/email-dao-test.js
@@ -305,11 +305,11 @@ describe('Email DAO integration tests', function() {
openpgp.initWorker.restore();
mailreader.startWorker.restore();
- imapClient.stopListeningForChanges(function() {
- imapClient.logout(function() {
- userStorage.clear().then(done);
- });
- });
+ imapClient.stopListeningForChanges().then(function() {
+ return imapClient.logout();
+ }).then(function() {
+ return userStorage.clear();
+ }).then(done);
});
describe('IMAP Integration Tests', function() {
diff --git a/test/unit/email/email-dao-test.js b/test/unit/email/email-dao-test.js
index cb9c161..b1c6298 100644
--- a/test/unit/email/email-dao-test.js
+++ b/test/unit/email/email-dao-test.js
@@ -294,7 +294,7 @@ describe('Email DAO unit tests', function() {
it('should open an imap mailbox', function(done) {
imapClientStub.selectMailbox.withArgs({
path: inboxFolder.path
- }).yieldsAsync();
+ }).returns(resolves());
dao.openFolder({
folder: inboxFolder
@@ -534,7 +534,7 @@ describe('Email DAO unit tests', function() {
content: '' + cfg.cloudUrl + cfg.verificationUrl + validUuid
}]));
- keychainStub.verifyPublicKey.withArgs(validUuid).yieldsAsync({});
+ keychainStub.verifyPublicKey.withArgs(validUuid).returns(rejects({}));
localStoreStub.withArgs({
folder: inboxFolder,
@@ -733,6 +733,32 @@ describe('Email DAO unit tests', function() {
});
});
+ it('should not explode when message has been deleted during imap roundtrip', function(done) {
+ imapMark.withArgs({
+ folder: inboxFolder,
+ uid: message.uid,
+ unread: message.unread,
+ answered: message.answered,
+ flagged: message.flagged
+ }).returns(resolves());
+
+ localListStub.withArgs({
+ folder: inboxFolder,
+ uid: message.uid
+ }).returns(resolves([]));
+
+ dao.setFlags({
+ folder: inboxFolder,
+ message: message
+ }).then(function() {
+ expect(imapMark.calledOnce).to.be.true;
+ expect(localListStub.calledOnce).to.be.true;
+ expect(localStoreStub.called).to.be.false;
+
+ done();
+ });
+ });
+
it('should set flags for outbox for disk, memory', function(done) {
localListStub.withArgs({
folder: outboxFolder,
@@ -1224,6 +1250,80 @@ describe('Email DAO unit tests', function() {
expect(message.loadingBody).to.be.true;
});
+ it('should not error when message is deleted from imap', function(done) {
+ var error = new Error('Can not get the contents of this message. It has already been deleted!');
+ error.hide = true;
+
+ var message = {
+ uid: uid,
+ encrypted: true,
+ bodyParts: [{
+ type: 'text'
+ }]
+ };
+
+ localListStub.withArgs({
+ folder: inboxFolder,
+ uid: uid
+ }).returns(resolves([message]));
+
+ localStoreStub.withArgs({
+ folder: inboxFolder,
+ emails: [message]
+ }).returns(resolves());
+
+ imapGetStub.withArgs({
+ folder: inboxFolder,
+ uid: message.uid,
+ bodyParts: message.bodyParts
+ }).returns(rejects(error));
+
+
+ dao.getBody({
+ message: message,
+ folder: inboxFolder
+ }).then(function(msg) {
+ expect(msg).to.equal(message);
+ expect(msg.body).to.not.exist;
+ expect(msg.loadingBody).to.be.false;
+
+ expect(localListStub.calledOnce).to.be.true;
+ expect(imapGetStub.calledOnce).to.be.true;
+ expect(localStoreStub.called).to.be.false;
+
+ done();
+ });
+ expect(message.loadingBody).to.be.true;
+ });
+
+ it('should not error when message has already been removed from memory', function(done) {
+ var message = {
+ uid: uid,
+ encrypted: true,
+ bodyParts: [{
+ type: 'text'
+ }]
+ };
+
+ localListStub.returns(resolves([]));
+
+ dao.getBody({
+ message: message,
+ folder: inboxFolder
+ }).then(function(msg) {
+ expect(msg).to.equal(message);
+ expect(msg.body).to.not.exist;
+ expect(msg.loadingBody).to.be.false;
+
+ expect(localListStub.calledOnce).to.be.true;
+ expect(imapGetStub.called).to.be.false;
+ expect(localStoreStub.called).to.be.false;
+
+ done();
+ });
+ expect(message.loadingBody).to.be.true;
+ });
+
it('fail to stream from imap due to error when persisting', function(done) {
var message = {
uid: uid,
@@ -1641,7 +1741,7 @@ describe('Email DAO unit tests', function() {
imapClientStub.uploadMessage.withArgs({
path: sentFolder.path,
message: msg
- }).yields();
+ }).returns(resolves());
authStub.getCredentials.returns(resolves(credentials));
pgpMailerStub.send.withArgs({
@@ -1649,7 +1749,7 @@ describe('Email DAO unit tests', function() {
mail: dummyMail,
smtpclient: undefined,
publicKeysArmored: publicKeys
- }).yieldsAsync(null, msg);
+ }).returns(resolves(msg));
dao.sendEncrypted({
email: dummyMail
@@ -1672,7 +1772,7 @@ describe('Email DAO unit tests', function() {
mail: dummyMail,
smtpclient: undefined,
publicKeysArmored: publicKeys
- }).yieldsAsync(null, msg);
+ }).returns(resolves(msg));
dao.sendEncrypted({
email: dummyMail
@@ -1687,8 +1787,8 @@ describe('Email DAO unit tests', function() {
});
it('should send encrypted and ignore error on upload', function(done) {
- imapClientStub.uploadMessage.yields(new Error());
- pgpMailerStub.send.yieldsAsync(null, msg);
+ imapClientStub.uploadMessage.returns(rejects(new Error()));
+ pgpMailerStub.send.returns(resolves(msg));
authStub.getCredentials.returns(resolves(credentials));
dao.sendEncrypted({
@@ -1703,7 +1803,7 @@ describe('Email DAO unit tests', function() {
});
it('should not send when pgpmailer fails', function(done) {
- pgpMailerStub.send.yieldsAsync({});
+ pgpMailerStub.send.returns(rejects({}));
authStub.getCredentials.returns(resolves(credentials));
dao.sendEncrypted({
@@ -1754,13 +1854,13 @@ describe('Email DAO unit tests', function() {
pgpMailerStub.send.withArgs({
smtpclient: undefined,
mail: dummyMail
- }).yieldsAsync(null, msg);
+ }).returns(resolves(msg));
authStub.getCredentials.returns(resolves(credentials));
imapClientStub.uploadMessage.withArgs({
path: sentFolder.path,
message: msg
- }).yields();
+ }).returns(resolves());
dao.sendPlaintext({
email: dummyMail
@@ -1779,7 +1879,7 @@ describe('Email DAO unit tests', function() {
pgpMailerStub.send.withArgs({
smtpclient: undefined,
mail: dummyMail
- }).yieldsAsync(null, msg);
+ }).returns(resolves(msg));
authStub.getCredentials.returns(resolves(credentials));
dao.sendPlaintext({
@@ -1793,8 +1893,8 @@ describe('Email DAO unit tests', function() {
});
it('should send and ignore error on upload', function(done) {
- imapClientStub.uploadMessage.yields(new Error());
- pgpMailerStub.send.yieldsAsync(null, msg);
+ imapClientStub.uploadMessage.returns(rejects(new Error()));
+ pgpMailerStub.send.returns(resolves(msg));
authStub.getCredentials.returns(resolves(credentials));
dao.sendPlaintext({
@@ -1809,7 +1909,7 @@ describe('Email DAO unit tests', function() {
});
it('should not send due to error', function(done) {
- pgpMailerStub.send.yieldsAsync({});
+ pgpMailerStub.send.returns(rejects({}));
authStub.getCredentials.returns(resolves(credentials));
dao.sendPlaintext({
@@ -1840,7 +1940,7 @@ describe('Email DAO unit tests', function() {
describe('#encrypt', function() {
it('should encrypt', function(done) {
- pgpBuilderStub.encrypt.yieldsAsync();
+ pgpBuilderStub.encrypt.returns(resolves());
dao.encrypt({}).then(function() {
expect(pgpBuilderStub.encrypt.calledOnce).to.be.true;
@@ -1869,9 +1969,9 @@ describe('Email DAO unit tests', function() {
modseq: '123'
}];
authStub.getCredentials.returns(resolves(credentials));
- imapClientStub.login.yieldsAsync();
- imapClientStub.selectMailbox.yields();
- imapClientStub.listenForChanges.yields();
+ imapClientStub.login.returns(resolves());
+ imapClientStub.selectMailbox.returns(resolves());
+ imapClientStub.listenForChanges.returns(resolves());
initFoldersStub.returns(resolves());
dao.onConnect(imapClientStub).then(function() {
@@ -1894,8 +1994,8 @@ describe('Email DAO unit tests', function() {
describe('#onDisconnect', function() {
it('should discard imapClient and pgpMailer', function(done) {
- imapClientStub.stopListeningForChanges.yields();
- imapClientStub.logout.yields();
+ imapClientStub.stopListeningForChanges.returns(resolves());
+ imapClientStub.logout.returns(resolves());
dao.onDisconnect().then(function() {
expect(imapClientStub.stopListeningForChanges.calledOnce).to.be.true;
@@ -1923,12 +2023,12 @@ describe('Email DAO unit tests', function() {
setFlagsStub = sinon.stub(dao, 'setFlags');
});
- it('should get new message', function() {
+ it('should get new message', function(done) {
fetchMessagesStub.withArgs({
folder: inboxFolder,
firstUid: 1,
lastUid: 3
- }).yields();
+ }).returns(resolves());
dao._onSyncUpdate({
type: 'new',
@@ -1936,16 +2036,19 @@ describe('Email DAO unit tests', function() {
list: [1, 3]
});
- expect(dialogStub.error.calledOnce).to.be.true;
- expect(fetchMessagesStub.calledOnce).to.be.true;
+ setTimeout(function() {
+ expect(dialogStub.error.calledOnce).to.be.true;
+ expect(fetchMessagesStub.calledOnce).to.be.true;
+ done();
+ }, 0);
});
- it('should delete message', function() {
+ it('should delete message', function(done) {
deleteMessagesStub.withArgs({
folder: inboxFolder,
message: msgs[0],
localOnly: true
- }).yields();
+ }).returns(resolves());
dao._onSyncUpdate({
type: 'deleted',
@@ -1953,16 +2056,19 @@ describe('Email DAO unit tests', function() {
list: [5]
});
- expect(dialogStub.error.calledOnce).to.be.true;
- expect(deleteMessagesStub.calledOnce).to.be.true;
+ setTimeout(function() {
+ expect(dialogStub.error.calledOnce).to.be.true;
+ expect(deleteMessagesStub.calledOnce).to.be.true;
+ done();
+ }, 0);
});
- it('should fetch flags', function() {
+ it('should fetch flags', function(done) {
setFlagsStub.withArgs({
folder: inboxFolder,
message: msgs[0],
localOnly: true
- }).yields();
+ }).returns(resolves());
dao._onSyncUpdate({
type: 'messages',
@@ -1970,8 +2076,11 @@ describe('Email DAO unit tests', function() {
list: msgs
});
- expect(dialogStub.error.calledOnce).to.be.true;
- expect(setFlagsStub.calledOnce).to.be.true;
+ setTimeout(function() {
+ expect(dialogStub.error.calledOnce).to.be.true;
+ expect(setFlagsStub.calledOnce).to.be.true;
+ done();
+ }, 0);
});
});
});
@@ -2102,14 +2211,14 @@ describe('Email DAO unit tests', function() {
it('should initialize from imap if online', function(done) {
account.folders = [];
- imapClientStub.listWellKnownFolders.yieldsAsync(null, {
+ imapClientStub.listWellKnownFolders.returns(resolves({
Inbox: [inboxFolder],
Sent: [sentFolder],
Drafts: [draftsFolder],
Trash: [trashFolder],
Flagged: [flaggedFolder],
Other: [otherFolder]
- });
+ }));
devicestorageStub.storeList.withArgs(sinon.match(function(arg) {
expect(arg[0][0].name).to.deep.equal(inboxFolder.name);
expect(arg[0][0].path).to.deep.equal(inboxFolder.path);
@@ -2151,14 +2260,14 @@ describe('Email DAO unit tests', function() {
path: 'bar',
}];
- imapClientStub.listWellKnownFolders.yieldsAsync(null, {
+ imapClientStub.listWellKnownFolders.returns(resolves({
Inbox: [inboxFolder],
Sent: [sentFolder],
Drafts: [draftsFolder],
Trash: [trashFolder],
Flagged: [flaggedFolder],
Other: [otherFolder]
- });
+ }));
devicestorageStub.storeList.withArgs(sinon.match(function(arg) {
expect(arg[0]).to.deep.equal([{
name: inboxFolder.name,
@@ -2218,7 +2327,7 @@ describe('Email DAO unit tests', function() {
uid: 1,
unread: false,
answered: false
- }).yieldsAsync();
+ }).returns(resolves());
dao._imapMark({
folder: inboxFolder,
@@ -2238,7 +2347,7 @@ describe('Email DAO unit tests', function() {
path: inboxFolder.path,
destination: sentFolder.path,
uid: 123
- }).yieldsAsync();
+ }).returns(resolves());
dao._imapMoveMessage({
folder: inboxFolder,
@@ -2265,7 +2374,7 @@ describe('Email DAO unit tests', function() {
path: inboxFolder.path,
uid: uid,
destination: trashFolder.path
- }).yieldsAsync();
+ }).returns(resolves());
dao._imapDeleteMessage({
folder: inboxFolder,
@@ -2277,7 +2386,7 @@ describe('Email DAO unit tests', function() {
imapClientStub.deleteMessage.withArgs({
path: trashFolder.path,
uid: uid
- }).yieldsAsync();
+ }).returns(resolves());
dao._imapDeleteMessage({
folder: trashFolder,
@@ -2296,7 +2405,7 @@ describe('Email DAO unit tests', function() {
path: inboxFolder.path,
firstUid: firstUid,
lastUid: lastUid
- }).yieldsAsync(null, []);
+ }).returns(resolves([]));
dao._imapListMessages({
folder: inboxFolder,
@@ -2312,7 +2421,7 @@ describe('Email DAO unit tests', function() {
});
it('should fail when listMessages fails', function(done) {
- imapClientStub.listMessages.yieldsAsync({});
+ imapClientStub.listMessages.returns(rejects({}));
dao._imapListMessages({
folder: inboxFolder,
@@ -2343,7 +2452,7 @@ describe('Email DAO unit tests', function() {
imapClientStub.uploadMessage.withArgs({
path: draftsFolder.path,
message: msg
- }).yields();
+ }).returns(resolves());
dao._imapUploadMessage({
folder: draftsFolder,
@@ -2358,18 +2467,23 @@ describe('Email DAO unit tests', function() {
describe('#_getBodyParts', function() {
it('should get bodyParts', function(done) {
+ var bp = [{
+ type: 'text',
+ content: 'bender is great! bender is great!'
+ }];
+
imapClientStub.getBodyParts.withArgs({
folder: inboxFolder,
path: inboxFolder.path,
uid: 123,
- bodyParts: []
- }).yieldsAsync(null, {});
+ bodyParts: bp
+ }).returns(resolves(bp));
parseStub.yieldsAsync(null, []);
dao._getBodyParts({
folder: inboxFolder,
uid: 123,
- bodyParts: []
+ bodyParts: bp
}).then(function(parts) {
expect(parts).to.exist;
@@ -2380,8 +2494,52 @@ describe('Email DAO unit tests', function() {
});
});
+ it('should fail when deleted on IMAP', function(done) {
+ var bp = [{
+ type: 'text'
+ }];
+
+ imapClientStub.getBodyParts.withArgs({
+ folder: inboxFolder,
+ path: inboxFolder.path,
+ uid: 123,
+ bodyParts: bp
+ }).returns(resolves());
+ parseStub.yieldsAsync(null, []);
+
+ dao._getBodyParts({
+ folder: inboxFolder,
+ uid: 123,
+ bodyParts: bp
+ }).catch(function(err) {
+ expect(err).to.exist;
+
+ expect(imapClientStub.getBodyParts.calledOnce).to.be.true;
+ expect(parseStub.called).to.be.false;
+
+ done();
+ });
+ });
+
it('should fail when getBody fails', function(done) {
- imapClientStub.getBodyParts.yieldsAsync({});
+ imapClientStub.getBodyParts.returns(rejects({}));
+
+ dao._getBodyParts({
+ folder: inboxFolder,
+ uid: 123,
+ bodyParts: []
+ }).catch(function(err) {
+ expect(err).to.exist;
+
+ expect(imapClientStub.getBodyParts.calledOnce).to.be.true;
+ expect(parseStub.called).to.be.false;
+
+ done();
+ });
+ });
+
+ it('should fail when getBody fails', function(done) {
+ imapClientStub.getBodyParts.returns(rejects({}));
dao._getBodyParts({
folder: inboxFolder,
@@ -2476,7 +2634,7 @@ describe('Email DAO unit tests', function() {
imapClientStub.uploadMessage.withArgs({
path: sentFolder.path,
message: msg
- }).yields();
+ }).returns(resolves());
dao._uploadToSent({
message: msg
diff --git a/test/unit/util/connection-doctor-test.js b/test/unit/util/connection-doctor-test.js
index 18b7bbb..844781c 100644
--- a/test/unit/util/connection-doctor-test.js
+++ b/test/unit/util/connection-doctor-test.js
@@ -167,11 +167,11 @@ describe('Connection Doctor', function() {
describe('#_checkImap', function() {
it('should perform IMAP login, list folders, logout', function(done) {
- imapStub.login.yieldsAsync();
- imapStub.listWellKnownFolders.yieldsAsync(null, {
+ imapStub.login.returns(resolves());
+ imapStub.listWellKnownFolders.returns(resolves({
Inbox: [{}]
- });
- imapStub.logout.yieldsAsync();
+ }));
+ imapStub.logout.returns(resolves());
doctor._checkImap().then(function() {
expect(imapStub.login.calledOnce).to.be.true;
@@ -183,10 +183,11 @@ describe('Connection Doctor', function() {
});
it('should fail w/ generic error on logout', function(done) {
- imapStub.login.yieldsAsync();
- imapStub.listWellKnownFolders.yieldsAsync(null, {
+ imapStub.login.returns(resolves());
+ imapStub.listWellKnownFolders.returns(resolves({
Inbox: [{}]
- });
+ }));
+ imapStub.logout.returns(rejects(new Error()));
doctor._checkImap().catch(function(error) {
expect(error.code).to.equal(ConnectionDoctor.GENERIC_ERROR);
@@ -197,18 +198,13 @@ describe('Connection Doctor', function() {
done();
});
-
- setTimeout(function() {
- // this error is thrown while we're waiting for the logout
- imapStub.onError(new Error());
- }, 50);
});
it('should fail w/ generic error on inbox missing', function(done) {
- imapStub.login.yieldsAsync();
- imapStub.listWellKnownFolders.yieldsAsync(null, {
+ imapStub.login.returns(resolves());
+ imapStub.listWellKnownFolders.returns(resolves({
Inbox: []
- });
+ }));
doctor._checkImap().catch(function(error) {
expect(error.code).to.equal(ConnectionDoctor.NO_INBOX);
@@ -221,8 +217,8 @@ describe('Connection Doctor', function() {
});
it('should fail w/ generic error on listing folders fails', function(done) {
- imapStub.login.yieldsAsync();
- imapStub.listWellKnownFolders.yieldsAsync(new Error());
+ imapStub.login.returns(resolves());
+ imapStub.listWellKnownFolders.returns(rejects(new Error()));
doctor._checkImap().catch(function(error) {
expect(error.code).to.equal(ConnectionDoctor.GENERIC_ERROR);
@@ -236,6 +232,12 @@ describe('Connection Doctor', function() {
});
it('should fail w/ auth rejected', function(done) {
+ imapStub.login.returns(new Promise(function() {
+ setTimeout(function() {
+ imapStub.onError(new Error());
+ }, 0);
+ }));
+
doctor._checkImap().catch(function(error) {
expect(error.code).to.equal(ConnectionDoctor.AUTH_REJECTED);
expect(error.underlyingError).to.exist;
@@ -245,11 +247,6 @@ describe('Connection Doctor', function() {
done();
});
-
- setTimeout(function() {
- // this error is thrown while we're waiting for the login
- imapStub.onError(new Error());
- }, 50);
});
});