1
0
mirror of https://github.com/moparisthebest/mail synced 2024-12-01 13:22:16 -05:00

fix unread and answered flags are updated

This commit is contained in:
Felix Hammerl 2013-12-05 18:28:18 +01:00
parent f3ef8fdf91
commit b4115ed879
6 changed files with 397 additions and 117 deletions

View File

@ -60,9 +60,16 @@ define(function(require) {
} }
$scope.state.mailList.selected = email; $scope.state.mailList.selected = email;
$scope.state.read.toggle(true);
// // mark selected message as 'read' // if the email is unread, please sync the new state.
// markAsRead(email); // otherweise forget about it.
if (!email.unread) {
return;
}
email.unread = false;
$scope.synchronize();
}; };
$scope.synchronize = function(callback) { $scope.synchronize = function(callback) {
@ -204,34 +211,6 @@ define(function(require) {
function getFolder() { function getFolder() {
return $scope.state.nav.currentFolder; return $scope.state.nav.currentFolder;
} }
// function markAsRead(email) {
// // marking mails as read is meaningless in the outbox
// if (getFolder().type === 'Outbox') {
// return;
// }
// $scope.state.read.toggle(true);
// if (!window.chrome || !chrome.socket) {
// return;
// }
// if (!email.unread) {
// return;
// }
// email.unread = false;
// emailDao.imapMarkMessageRead({
// folder: getFolder().path,
// uid: email.uid
// }, function(err) {
// if (err) {
// updateStatus('Error marking read!');
// $scope.onError(err);
// return;
// }
// });
// }
}; };
function createDummyMails() { function createDummyMails() {

View File

@ -181,12 +181,6 @@ define(function(require) {
// mark list object // mark list object
$scope.replyTo.answered = true; $scope.replyTo.answered = true;
// mark remote imap object
emailDao.markAnswered({
uid: $scope.replyTo.uid,
folder: $scope.state.nav.currentFolder.path
}, $scope.onError);
} }
}; };

View File

@ -143,15 +143,26 @@ define(function(require) {
EmailDAO.prototype.sync = function(options, callback) { EmailDAO.prototype.sync = function(options, callback) {
/* /*
* Here's how delta sync works: * Here's how delta sync works:
* delta1: storage > memory => we deleted messages, remove from remote *
* First, we sync the messages between memory and local storage, based on their uid
* delta1: storage > memory => we deleted messages, remove from remote and memory
* delta2: memory > storage => we added messages, push to remote <<< not supported yet * delta2: memory > storage => we added messages, push to remote <<< not supported yet
* delta3: memory > imap => we deleted messages directly from the remote, remove from memory and storage *
* delta4: imap > memory => we have new messages available, fetch to memory and storage * Second, we check the delta for the flags
* deltaF1: memory > storage => we changed flags, sync them to the remote and memory
*
* Third, we go on to sync between imap and memory, again based on uid
* delta3: memory > imap => we deleted messages directly from the remote, remove from memory and storage
* delta4: imap > memory => we have new messages available, fetch to memory and storage
*
* Fourth, we pull changes in the flags downstream
* deltaF2: imap > memory => we changed flags directly on the remote, sync them to the storage and memory
*/ */
var self = this, var self = this,
folder, folder,
delta1 /*, delta2 */ , delta3, delta4, delta1 /*, delta2 */ , delta3, delta4, //message
deltaF1, deltaF2,
isFolderInitialized; isFolderInitialized;
@ -237,24 +248,22 @@ define(function(require) {
/* /*
* 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
* deltaF1: memory > storage => we changed flags, sync them to the remote and memory
*/ */
delta1 = checkDelta(messages, folder.messages); delta1 = checkDelta(messages, folder.messages);
// delta2 = checkDelta(folder.messages, messages); // not supported yet // delta2 = checkDelta(folder.messages, messages); // not supported yet
deltaF1 = checkFlags(folder.messages, messages);
if (_.isEmpty(delta1) /* && _.isEmpty(delta2)*/ ) {
// if there is no delta, head directly to imap sync
callback();
doImapDelta();
return;
}
doDelta1(); doDelta1();
function doDelta1() { function doDelta1() {
if (_.isEmpty(delta1)) {
doDeltaF1();
return;
}
var after = _.after(delta1.length, function() { var after = _.after(delta1.length, function() {
// doDelta2(); when it is implemented doDeltaF1();
callback();
doImapDelta();
}); });
delta1.forEach(function(message) { delta1.forEach(function(message) {
@ -282,6 +291,47 @@ define(function(require) {
}); });
}); });
} }
function doDeltaF1() {
if (_.isEmpty(deltaF1)) {
callback();
doImapDelta();
return;
}
var after = _.after(deltaF1.length, function() {
callback();
doImapDelta();
});
deltaF1.forEach(function(message) {
self._mark({
folder: folder.path,
uid: message.uid,
unread: message.unread,
answered: message.answered
}, function(err) {
if (err) {
self._account.busy = false;
callback(err);
return;
}
self._localStoreMessages({
folder: folder.path,
emails: [message]
}, function(err) {
if (err) {
self._account.busy = false;
callback(err);
return;
}
after();
});
});
});
}
}); });
} }
@ -304,18 +354,13 @@ define(function(require) {
}); });
/* /*
* delta3: memory > imap => we deleted messages directly from the remote, remove from memory and storage * delta3: memory > imap => we deleted messages directly from the remote, remove from memory and storage
* delta4: imap > memory => we have new messages available, fetch to memory and storage * delta4: imap > memory => we have new messages available, fetch to memory and storage
* deltaF2: imap > memory => we changed flags directly on the remote, sync them to the storage and memory
*/ */
delta3 = checkDelta(folder.messages, headers); delta3 = checkDelta(folder.messages, headers);
delta4 = checkDelta(headers, folder.messages); delta4 = checkDelta(headers, folder.messages);
deltaF2 = checkFlags(headers, folder.messages);
if (_.isEmpty(delta3) && _.isEmpty(delta4)) {
// if there is no delta, we're done
self._account.busy = false;
callback();
return;
}
doDelta3(); doDelta3();
@ -357,13 +402,11 @@ 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; doDeltaF2();
callback();
} }
var after = _.after(delta4.length, function() { var after = _.after(delta4.length, function() {
self._account.busy = false; doDeltaF2();
callback();
}); });
delta4.forEach(function(header) { delta4.forEach(function(header) {
@ -391,6 +434,9 @@ define(function(require) {
return; return;
} }
message.answered = header.answered;
message.unread = header.unread;
// add the encrypted message to the local storage // add the encrypted message to the local storage
self._localStoreMessages({ self._localStoreMessages({
folder: folder.path, folder: folder.path,
@ -417,6 +463,44 @@ define(function(require) {
}); });
}); });
} }
// we have a mismatch concerning flags between imap and memory.
// pull changes from imap.
function doDeltaF2() {
if (_.isEmpty(deltaF2)) {
self._account.busy = false;
callback();
return;
}
var after = _.after(deltaF2.length, function() {
self._account.busy = false;
callback();
});
deltaF2.forEach(function(header) {
// we don't work on the header, we work on the live object
var msg = _.findWhere(folder.messages, {
uid: header.uid
});
msg.unread = header.unread;
msg.answered = header.answered;
self._localStoreMessages({
folder: folder.path,
emails: [msg]
}, function(err) {
if (err) {
self._account.busy = false;
callback(err);
return;
}
after();
});
});
}
}); });
} }
@ -441,6 +525,27 @@ define(function(require) {
return delta; return delta;
} }
/*
* checks if there are some flags that have changed in a and b
*/
function checkFlags(a, b) {
var i, aI, bI,
delta = [];
// find the delta
for (i = a.length - 1; i >= 0; i--) {
aI = a[i];
bI = _.findWhere(b, {
uid: aI.uid
});
if (bI && (aI.unread !== bI.unread || aI.answered !== bI.answered)) {
delta.push(aI);
}
}
return delta;
}
function isVerificationMail(email) { function isVerificationMail(email) {
return email.subject === str.subjectPrefix + str.verificationSubject; return email.subject === str.subjectPrefix + str.verificationSubject;
} }
@ -472,9 +577,10 @@ define(function(require) {
} }
// public key has been verified, mark the message as read, delete it, and ignore it in the future // public key has been verified, mark the message as read, delete it, and ignore it in the future
self.markRead({ self._mark({
folder: options.folder, folder: options.folder,
uid: email.uid uid: email.uid,
unread: false
}, function(err) { }, function(err) {
if (err) { if (err) {
localCallback(err); localCallback(err);
@ -551,19 +657,12 @@ define(function(require) {
} }
}; };
EmailDAO.prototype.markRead = function(options, callback) { EmailDAO.prototype._mark = function(options, callback) {
this._imapClient.updateFlags({ this._imapClient.updateFlags({
path: options.folder, path: options.folder,
uid: options.uid, uid: options.uid,
unread: false unread: options.unread,
}, callback); answered: options.answered
};
EmailDAO.prototype.markAnswered = function(options, callback) {
this._imapClient.updateFlags({
path: options.folder,
uid: options.uid,
answered: true
}, callback); }, callback);
}; };

View File

@ -31,7 +31,9 @@ define(function(require) {
address: 'qwe@qwe.de' address: 'qwe@qwe.de'
}], }],
subject: '[whiteout] qweasd', subject: '[whiteout] qweasd',
body: '-----BEGIN PGP MESSAGE-----\nasd\n-----END PGP MESSAGE-----' body: '-----BEGIN PGP MESSAGE-----\nasd\n-----END PGP MESSAGE-----',
unread: false,
answered: false
}; };
verificationUuid = 'OMFG_FUCKING_BASTARD_UUID_FROM_HELL!'; verificationUuid = 'OMFG_FUCKING_BASTARD_UUID_FROM_HELL!';
verificationMail = { verificationMail = {
@ -44,7 +46,8 @@ define(function(require) {
}], // list of receivers }], // list of receivers
subject: "[whiteout] New public key uploaded", // Subject line subject: "[whiteout] New public key uploaded", // Subject line
body: 'yadda yadda bla blabla foo bar https://keys.whiteout.io/verify/' + verificationUuid, // plaintext body body: 'yadda yadda bla blabla foo bar https://keys.whiteout.io/verify/' + verificationUuid, // plaintext body
unread: true unread: true,
answered: false
}; };
dummyDecryptedMail = { dummyDecryptedMail = {
uid: 1234, uid: 1234,
@ -55,7 +58,9 @@ define(function(require) {
address: 'qwe@qwe.de' address: 'qwe@qwe.de'
}], }],
subject: 'qweasd', subject: 'qweasd',
body: 'asd' body: 'asd',
unread: false,
answered: false
}; };
nonWhitelistedMail = { nonWhitelistedMail = {
uid: 1234, uid: 1234,
@ -594,7 +599,9 @@ define(function(require) {
folder: folder folder: folder
}).yields(null, [{ }).yields(null, [{
uid: dummyEncryptedMail.uid, uid: dummyEncryptedMail.uid,
subject: '[whiteout] ' + dummyEncryptedMail // the object has already been manipulated as a side-effect... subject: '[whiteout] ' + dummyEncryptedMail.subject, // the object has already been manipulated as a side-effect...
unread: dummyEncryptedMail.unread,
answered: dummyEncryptedMail.answered
}]); }]);
dao.sync({ dao.sync({
@ -1234,9 +1241,10 @@ define(function(require) {
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]); imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]);
imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail); imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail);
keychainStub.verifyPublicKey.withArgs(verificationUuid).yields(); keychainStub.verifyPublicKey.withArgs(verificationUuid).yields();
markReadStub = sinon.stub(dao, 'markRead').withArgs({ markReadStub = sinon.stub(dao, '_mark').withArgs({
folder: folder, folder: folder,
uid: verificationMail.uid uid: verificationMail.uid,
unread: false
}).yields(); }).yields();
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage').withArgs({ imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage').withArgs({
folder: folder, folder: folder,
@ -1283,7 +1291,7 @@ define(function(require) {
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]); imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]);
imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail); imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail);
keychainStub.verifyPublicKey.yields(); keychainStub.verifyPublicKey.yields();
markReadStub = sinon.stub(dao, 'markRead').yields(); markReadStub = sinon.stub(dao, '_mark').yields();
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage').yields({}); imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage').yields({});
dao.sync({ dao.sync({
@ -1326,7 +1334,7 @@ define(function(require) {
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]); imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]);
imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail); imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail);
keychainStub.verifyPublicKey.yields(); keychainStub.verifyPublicKey.yields();
markReadStub = sinon.stub(dao, 'markRead').yields({}); markReadStub = sinon.stub(dao, '_mark').yields({});
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage'); imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage');
dao.sync({ dao.sync({
@ -1369,7 +1377,7 @@ define(function(require) {
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]); imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]);
imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail); imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail);
keychainStub.verifyPublicKey.yields({}); keychainStub.verifyPublicKey.yields({});
markReadStub = sinon.stub(dao, 'markRead'); markReadStub = sinon.stub(dao, '_mark');
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage'); imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage');
dao.sync({ dao.sync({
@ -1413,7 +1421,7 @@ define(function(require) {
localListStub = sinon.stub(dao, '_localListMessages').yields(null, []); localListStub = sinon.stub(dao, '_localListMessages').yields(null, []);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]); imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]);
imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail); imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail);
markReadStub = sinon.stub(dao, 'markRead'); markReadStub = sinon.stub(dao, '_mark');
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage'); imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage');
dao.sync({ dao.sync({
@ -1456,7 +1464,7 @@ define(function(require) {
localListStub = sinon.stub(dao, '_localListMessages').yields(null, []); localListStub = sinon.stub(dao, '_localListMessages').yields(null, []);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]); imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [verificationMail]);
imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail); imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, verificationMail);
markReadStub = sinon.stub(dao, 'markRead'); markReadStub = sinon.stub(dao, '_mark');
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage'); imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage');
dao.sync({ dao.sync({
@ -1482,38 +1490,239 @@ define(function(require) {
done(); done();
}); });
}); });
});
describe('markAsRead', function() { it('should sync tags from memory to imap and storage', function(done) {
it('should work', function(done) { var folder, localListStub, imapListStub, invocations,
imapClientStub.updateFlags.withArgs({ markStub, localStoreStub;
path: 'asdf',
uid: 1, invocations = 0;
unread: false folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: [dummyDecryptedMail]
}];
var inStorage = JSON.parse(JSON.stringify(dummyEncryptedMail));
var inImap = JSON.parse(JSON.stringify(dummyEncryptedMail));
dummyDecryptedMail.unread = inImap.unread = true;
localListStub = sinon.stub(dao, '_localListMessages').yields(null, [inStorage]);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [inImap]);
markStub = sinon.stub(dao, '_mark').withArgs({
folder: folder,
uid: dummyDecryptedMail.uid,
unread: dummyDecryptedMail.unread,
answered: dummyDecryptedMail.answered
}).yields();
localStoreStub = sinon.stub(dao, '_localStoreMessages').withArgs({
folder: folder,
emails: [dummyDecryptedMail]
}).yields(); }).yields();
dao.markRead({ dao.sync({
folder: 'asdf', folder: folder
uid: 1
}, function(err) { }, function(err) {
expect(imapClientStub.updateFlags.calledOnce).to.be.true;
expect(err).to.not.exist; 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(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true;
expect(markStub.calledOnce).to.be.true;
expect(localStoreStub.calledOnce).to.be.true;
done();
});
});
it('should error while syncing tags from memory to storage', function(done) {
var folder, localListStub, imapListStub, invocations,
markStub, localStoreStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: [dummyDecryptedMail]
}];
var inStorage = JSON.parse(JSON.stringify(dummyEncryptedMail));
var inImap = JSON.parse(JSON.stringify(dummyEncryptedMail));
dummyDecryptedMail.unread = inImap.unread = true;
localListStub = sinon.stub(dao, '_localListMessages').yields(null, [inStorage]);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [inImap]);
markStub = sinon.stub(dao, '_mark').yields();
localStoreStub = sinon.stub(dao, '_localStoreMessages').yields({});
dao.sync({
folder: folder
}, function(err) {
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(markStub.calledOnce).to.be.true;
expect(localStoreStub.calledOnce).to.be.true;
expect(imapListStub.called).to.be.false;
done();
});
});
it('should error while syncing tags from memory to imap', function(done) {
var folder, localListStub, imapListStub, invocations,
markStub, localStoreStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: [dummyDecryptedMail]
}];
var inStorage = JSON.parse(JSON.stringify(dummyEncryptedMail));
var inImap = JSON.parse(JSON.stringify(dummyEncryptedMail));
dummyDecryptedMail.unread = inImap.unread = true;
localListStub = sinon.stub(dao, '_localListMessages').yields(null, [inStorage]);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [inImap]);
markStub = sinon.stub(dao, '_mark').yields({});
localStoreStub = sinon.stub(dao, '_localStoreMessages');
dao.sync({
folder: folder
}, function(err) {
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(markStub.calledOnce).to.be.true;
expect(localStoreStub.called).to.be.false;
expect(imapListStub.called).to.be.false;
done();
});
});
it('should sync tags from imap to memory and storage', function(done) {
var folder, localListStub, imapListStub, invocations,
markStub, localStoreStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: [dummyDecryptedMail]
}];
var inStorage = JSON.parse(JSON.stringify(dummyEncryptedMail));
var inImap = JSON.parse(JSON.stringify(dummyEncryptedMail));
dummyDecryptedMail.unread = inStorage.unread = true;
localListStub = sinon.stub(dao, '_localListMessages').yields(null, [inStorage]);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [inImap]);
markStub = sinon.stub(dao, '_mark');
localStoreStub = sinon.stub(dao, '_localStoreMessages').withArgs({
folder: folder,
emails: [dummyDecryptedMail]
}).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]).to.not.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true;
expect(markStub.called).to.be.false;
expect(localStoreStub.calledOnce).to.be.true;
expect(dummyDecryptedMail.unread).to.equal(inImap.unread);
done();
});
});
it('should error while syncing tags from imap to storage', function(done) {
var folder, localListStub, imapListStub, invocations,
markStub, localStoreStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: [dummyDecryptedMail]
}];
var inStorage = JSON.parse(JSON.stringify(dummyEncryptedMail));
var inImap = JSON.parse(JSON.stringify(dummyEncryptedMail));
dummyDecryptedMail.unread = inStorage.unread = true;
localListStub = sinon.stub(dao, '_localListMessages').yields(null, [inStorage]);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [inImap]);
markStub = sinon.stub(dao, '_mark');
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]).to.not.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapListStub.calledOnce).to.be.true;
expect(markStub.called).to.be.false;
expect(localStoreStub.calledOnce).to.be.true;
expect(dummyDecryptedMail.unread).to.equal(inImap.unread);
done(); done();
}); });
}); });
}); });
describe('markAsAnswered', function() { describe('mark', function() {
it('should work', function(done) { it('should work', function(done) {
imapClientStub.updateFlags.withArgs({ imapClientStub.updateFlags.withArgs({
path: 'asdf', path: 'asdf',
uid: 1, uid: 1,
answered: true unread: false,
answered: false
}).yields(); }).yields();
dao.markAnswered({ dao._mark({
folder: 'asdf', folder: 'asdf',
uid: 1 uid: 1,
unread: false,
answered: false
}, function(err) { }, function(err) {
expect(imapClientStub.updateFlags.calledOnce).to.be.true; expect(imapClientStub.updateFlags.calledOnce).to.be.true;
expect(err).to.not.exist; expect(err).to.not.exist;

View File

@ -75,7 +75,11 @@ define(function(require) {
mocks.module('maillisttest'); mocks.module('maillisttest');
mocks.inject(function($rootScope, $controller) { mocks.inject(function($rootScope, $controller) {
scope = $rootScope.$new(); scope = $rootScope.$new();
scope.state = {}; scope.state = {
read: {
toggle: function() {}
}
};
ctrl = $controller(MailListCtrl, { ctrl = $controller(MailListCtrl, {
$scope: scope $scope: scope
}); });
@ -210,11 +214,12 @@ define(function(require) {
scope.state.nav = { scope.state.nav = {
currentFolder: currentFolder currentFolder: currentFolder
}; };
scope.state.mailList.selected = undefined;
scope.synchronize(); scope.synchronize();
// emails array is also used as the outbox's pending mail // emails array is also used as the outbox's pending mail
expect(scope.state.mailList.selected).to.deep.equal(emails[0]); expect(scope.state.mailList.selected).to.deep.equal(emails[emails.length - 1]);
}); });
}); });

View File

@ -141,7 +141,7 @@ define(function(require) {
}); });
describe('send to outbox', function() { describe('send to outbox', function() {
it('should work', function(done) { it('should work', function() {
var verifyToSpy = sinon.spy(scope, 'verifyTo'), var verifyToSpy = sinon.spy(scope, 'verifyTo'),
re = { re = {
from: [{ from: [{
@ -159,21 +159,15 @@ define(function(require) {
scope.emptyOutbox = function() {}; scope.emptyOutbox = function() {};
emailDaoMock.store.yields(); emailDaoMock.store.yields();
emailDaoMock.markAnswered.yields();
scope.onError = function(err) {
expect(err).to.not.exist;
expect(scope.state.writer.open).to.be.false;
expect(emailDaoMock.store.calledOnce).to.be.true;
expect(emailDaoMock.store.calledOnce).to.be.true;
expect(verifyToSpy.calledOnce).to.be.true;
scope.verifyTo.restore();
done();
};
scope.state.writer.write(re); scope.state.writer.write(re);
scope.sendToOutbox(); scope.sendToOutbox();
expect(scope.state.writer.open).to.be.false;
expect(emailDaoMock.store.calledOnce).to.be.true;
expect(verifyToSpy.calledOnce).to.be.true;
scope.verifyTo.restore();
}); });
it('should not work and not close the write view', function(done) { it('should not work and not close the write view', function(done) {