From 3da5a552515df9b67e8366b65d5b02b13ef21dd7 Mon Sep 17 00:00:00 2001 From: Felix Hammerl Date: Thu, 12 Feb 2015 16:10:46 +0100 Subject: [PATCH] [WO-795] Port to promises --- package.json | 6 +- src/js/email/email.js | 174 ++++++----------------- src/js/util/connection-doctor.js | 30 ++-- test/integration/email-dao-test.js | 10 +- test/unit/email/email-dao-test.js | 101 +++++++------ test/unit/util/connection-doctor-test.js | 41 +++--- 6 files changed, 139 insertions(+), 223 deletions(-) diff --git a/package.json b/package.json index b12c4cf..2bdae6c 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": "https://github.com/whiteout-io/imap-client/tarball/dev/WO-794", "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": "https://github.com/whiteout-io/pgpbuilder/tarball/dev/WO-795", + "pgpmailer": "https://github.com/whiteout-io/pgpmailer/tarball/dev/WO-795", "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..b0a75fa 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); - } - }); }); }; /** @@ -960,15 +953,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 +975,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 +1022,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 +1156,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 +1172,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 +1199,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 +1247,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 +1380,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 +1434,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 +1465,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 +1477,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 +1489,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 +1513,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 +1530,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 +1545,14 @@ 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; - } - - // interpret the raw content of the email - self._mailreader.parse(options, function(err, message) { - if (err) { - reject(err); - return; - } - - resolve(message); - }); - }); + return self._imapClient.getBodyParts(options); + }).then(function() { + 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/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..4ef5b81 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, @@ -1641,7 +1641,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 +1649,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 +1672,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 +1687,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 +1703,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 +1754,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 +1779,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 +1793,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 +1809,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 +1840,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 +1869,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 +1894,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 +1923,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 +1936,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 +1956,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 +1976,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 +2111,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 +2160,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 +2227,7 @@ describe('Email DAO unit tests', function() { uid: 1, unread: false, answered: false - }).yieldsAsync(); + }).returns(resolves()); dao._imapMark({ folder: inboxFolder, @@ -2238,7 +2247,7 @@ describe('Email DAO unit tests', function() { path: inboxFolder.path, destination: sentFolder.path, uid: 123 - }).yieldsAsync(); + }).returns(resolves()); dao._imapMoveMessage({ folder: inboxFolder, @@ -2265,7 +2274,7 @@ describe('Email DAO unit tests', function() { path: inboxFolder.path, uid: uid, destination: trashFolder.path - }).yieldsAsync(); + }).returns(resolves()); dao._imapDeleteMessage({ folder: inboxFolder, @@ -2277,7 +2286,7 @@ describe('Email DAO unit tests', function() { imapClientStub.deleteMessage.withArgs({ path: trashFolder.path, uid: uid - }).yieldsAsync(); + }).returns(resolves()); dao._imapDeleteMessage({ folder: trashFolder, @@ -2296,7 +2305,7 @@ describe('Email DAO unit tests', function() { path: inboxFolder.path, firstUid: firstUid, lastUid: lastUid - }).yieldsAsync(null, []); + }).returns(resolves([])); dao._imapListMessages({ folder: inboxFolder, @@ -2312,7 +2321,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 +2352,7 @@ describe('Email DAO unit tests', function() { imapClientStub.uploadMessage.withArgs({ path: draftsFolder.path, message: msg - }).yields(); + }).returns(resolves()); dao._imapUploadMessage({ folder: draftsFolder, @@ -2363,7 +2372,7 @@ describe('Email DAO unit tests', function() { path: inboxFolder.path, uid: 123, bodyParts: [] - }).yieldsAsync(null, {}); + }).returns(resolves({})); parseStub.yieldsAsync(null, []); dao._getBodyParts({ @@ -2381,7 +2390,7 @@ describe('Email DAO unit tests', function() { }); it('should fail when getBody fails', function(done) { - imapClientStub.getBodyParts.yieldsAsync({}); + imapClientStub.getBodyParts.returns(rejects({})); dao._getBodyParts({ folder: inboxFolder, @@ -2476,7 +2485,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); }); });