mirror of
https://github.com/moparisthebest/mail
synced 2024-11-26 02:42:17 -05:00
adapt ui to async content fetching
This commit is contained in:
parent
0e9f68abee
commit
250aa4b886
@ -58,6 +58,16 @@ define(function(require) {
|
|||||||
// scope functions
|
// scope functions
|
||||||
//
|
//
|
||||||
|
|
||||||
|
$scope.getContent = function(email) {
|
||||||
|
emailDao.getMessageContent({
|
||||||
|
folder: getFolder().path,
|
||||||
|
message: email
|
||||||
|
}, function(error) {
|
||||||
|
$scope.$apply();
|
||||||
|
$scope.onError(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when clicking on an email list item
|
* Called when clicking on an email list item
|
||||||
*/
|
*/
|
||||||
@ -67,6 +77,13 @@ define(function(require) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emailDao.decryptMessageContent({
|
||||||
|
message: email
|
||||||
|
}, function(error) {
|
||||||
|
$scope.$apply();
|
||||||
|
$scope.onError(error);
|
||||||
|
});
|
||||||
|
|
||||||
$scope.state.mailList.selected = email;
|
$scope.state.mailList.selected = email;
|
||||||
$scope.state.read.toggle(true);
|
$scope.state.read.toggle(true);
|
||||||
|
|
||||||
@ -279,10 +296,88 @@ define(function(require) {
|
|||||||
}]; // list of receivers
|
}]; // list of receivers
|
||||||
if (attachments) {
|
if (attachments) {
|
||||||
// body structure with three attachments
|
// body structure with three attachments
|
||||||
this.bodystructure = {"1": {"part": "1","type": "text/plain","parameters": {"charset": "us-ascii"},"encoding": "7bit","size": 9,"lines": 2},"2": {"part": "2","type": "application/octet-stream","parameters": {"name": "a.md"},"encoding": "7bit","size": 123,"disposition": [{"type": "attachment","filename": "a.md"}]},"3": {"part": "3","type": "application/octet-stream","parameters": {"name": "b.md"},"encoding": "7bit","size": 456,"disposition": [{"type": "attachment","filename": "b.md"}]},"4": {"part": "4","type": "application/octet-stream","parameters": {"name": "c.md"},"encoding": "7bit","size": 789,"disposition": [{"type": "attachment","filename": "c.md"}]},"type": "multipart/mixed"};
|
this.bodystructure = {
|
||||||
this.attachments = [{"filename": "a.md","filesize": 123,"mimeType": "text/x-markdown","part": "2","content": null}, {"filename": "b.md","filesize": 456,"mimeType": "text/x-markdown","part": "3","content": null}, {"filename": "c.md","filesize": 789,"mimeType": "text/x-markdown","part": "4","content": null}];
|
"1": {
|
||||||
|
"part": "1",
|
||||||
|
"type": "text/plain",
|
||||||
|
"parameters": {
|
||||||
|
"charset": "us-ascii"
|
||||||
|
},
|
||||||
|
"encoding": "7bit",
|
||||||
|
"size": 9,
|
||||||
|
"lines": 2
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"part": "2",
|
||||||
|
"type": "application/octet-stream",
|
||||||
|
"parameters": {
|
||||||
|
"name": "a.md"
|
||||||
|
},
|
||||||
|
"encoding": "7bit",
|
||||||
|
"size": 123,
|
||||||
|
"disposition": [{
|
||||||
|
"type": "attachment",
|
||||||
|
"filename": "a.md"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"part": "3",
|
||||||
|
"type": "application/octet-stream",
|
||||||
|
"parameters": {
|
||||||
|
"name": "b.md"
|
||||||
|
},
|
||||||
|
"encoding": "7bit",
|
||||||
|
"size": 456,
|
||||||
|
"disposition": [{
|
||||||
|
"type": "attachment",
|
||||||
|
"filename": "b.md"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"part": "4",
|
||||||
|
"type": "application/octet-stream",
|
||||||
|
"parameters": {
|
||||||
|
"name": "c.md"
|
||||||
|
},
|
||||||
|
"encoding": "7bit",
|
||||||
|
"size": 789,
|
||||||
|
"disposition": [{
|
||||||
|
"type": "attachment",
|
||||||
|
"filename": "c.md"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"type": "multipart/mixed"
|
||||||
|
};
|
||||||
|
this.attachments = [{
|
||||||
|
"filename": "a.md",
|
||||||
|
"filesize": 123,
|
||||||
|
"mimeType": "text/x-markdown",
|
||||||
|
"part": "2",
|
||||||
|
"content": null
|
||||||
|
}, {
|
||||||
|
"filename": "b.md",
|
||||||
|
"filesize": 456,
|
||||||
|
"mimeType": "text/x-markdown",
|
||||||
|
"part": "3",
|
||||||
|
"content": null
|
||||||
|
}, {
|
||||||
|
"filename": "c.md",
|
||||||
|
"filesize": 789,
|
||||||
|
"mimeType": "text/x-markdown",
|
||||||
|
"part": "4",
|
||||||
|
"content": null
|
||||||
|
}];
|
||||||
} else {
|
} else {
|
||||||
this.bodystructure = {"part": "1","type": "text/plain","parameters": {"charset": "us-ascii"},"encoding": "7bit","size": 9,"lines": 2};
|
this.bodystructure = {
|
||||||
|
"part": "1",
|
||||||
|
"type": "text/plain",
|
||||||
|
"parameters": {
|
||||||
|
"charset": "us-ascii"
|
||||||
|
},
|
||||||
|
"encoding": "7bit",
|
||||||
|
"size": 9,
|
||||||
|
"lines": 2
|
||||||
|
};
|
||||||
this.attachments = [];
|
this.attachments = [];
|
||||||
}
|
}
|
||||||
this.unread = unread;
|
this.unread = unread;
|
||||||
@ -311,8 +406,37 @@ define(function(require) {
|
|||||||
var myScroll;
|
var myScroll;
|
||||||
// activate iscroll
|
// activate iscroll
|
||||||
myScroll = new IScroll(elm[0], {
|
myScroll = new IScroll(elm[0], {
|
||||||
mouseWheel: true
|
mouseWheel: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// load the visible message bodies, when the list is re-initialized and when scrolling stopped
|
||||||
|
loadVisible();
|
||||||
|
myScroll.on('scrollEnd', loadVisible);
|
||||||
|
|
||||||
|
function loadVisible() {
|
||||||
|
var list = elm[0].getBoundingClientRect(),
|
||||||
|
footerHeight = elm[0].nextElementSibling.getBoundingClientRect().height,
|
||||||
|
top = list.top,
|
||||||
|
bottom = list.bottom - footerHeight,
|
||||||
|
listItems = elm[0].children[0].children,
|
||||||
|
i = listItems.length,
|
||||||
|
listItem, message,
|
||||||
|
isPartiallyVisibleTop, isPartiallyVisibleBottom, isVisible;
|
||||||
|
|
||||||
|
while (i--) {
|
||||||
|
listItem = listItems.item(i).getBoundingClientRect();
|
||||||
|
message = scope.filteredMessages[i];
|
||||||
|
|
||||||
|
isPartiallyVisibleTop = listItem.top < top && listItem.bottom > top; // a portion of the list item is visible on the top
|
||||||
|
isPartiallyVisibleBottom = listItem.top < bottom && listItem.bottom > bottom; // a portion of the list item is visible on the bottom
|
||||||
|
isVisible = listItem.top >= top && listItem.bottom <= bottom; // the list item is visible as a whole
|
||||||
|
|
||||||
|
|
||||||
|
if (isPartiallyVisibleTop || isVisible || isPartiallyVisibleBottom) {
|
||||||
|
scope.getContent(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -742,12 +742,17 @@ define(function(require) {
|
|||||||
message = options.message,
|
message = options.message,
|
||||||
folder = options.folder;
|
folder = options.folder;
|
||||||
|
|
||||||
// the message already has a body, so no need to become active here
|
if (message.loadingBody) {
|
||||||
if (message.body) {
|
|
||||||
callback(null, message);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the message already has a body, so no need to become active here
|
||||||
|
if (message.body) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.loadingBody = true;
|
||||||
|
|
||||||
// the mail does not have its content in memory
|
// the mail does not have its content in memory
|
||||||
readFromDevice();
|
readFromDevice();
|
||||||
|
|
||||||
@ -760,6 +765,7 @@ define(function(require) {
|
|||||||
var localMessage;
|
var localMessage;
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
message.loadingBody = false;
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -785,10 +791,13 @@ define(function(require) {
|
|||||||
message: message
|
message: message
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
message.loadingBody = false;
|
||||||
callback(error);
|
callback(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message.loadingBody = false;
|
||||||
|
|
||||||
self._localStoreMessages({
|
self._localStoreMessages({
|
||||||
folder: folder,
|
folder: folder,
|
||||||
emails: [message]
|
emails: [message]
|
||||||
@ -813,6 +822,7 @@ define(function(require) {
|
|||||||
message.decrypted = false;
|
message.decrypted = false;
|
||||||
extractCiphertext();
|
extractCiphertext();
|
||||||
}
|
}
|
||||||
|
message.loadingBody = false;
|
||||||
callback(null, message);
|
callback(null, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -834,15 +844,17 @@ define(function(require) {
|
|||||||
var self = this,
|
var self = this,
|
||||||
message = options.message;
|
message = options.message;
|
||||||
|
|
||||||
// the message is not encrypted or has already been decrypted
|
// the message has no body, is not encrypted or has already been decrypted
|
||||||
if (!message.encrypted || message.decrypted) {
|
if (message.decryptingBody || !message.body || !message.encrypted || message.decrypted) {
|
||||||
callback(null, message);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message.decryptingBody = true;
|
||||||
|
|
||||||
// get the sender's public key for signature checking
|
// get the sender's public key for signature checking
|
||||||
self._keychain.getReceiverPublicKey(message.from[0].address, function(err, senderPublicKey) {
|
self._keychain.getReceiverPublicKey(message.from[0].address, function(err, senderPublicKey) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
message.decryptingBody = false;
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -850,6 +862,7 @@ define(function(require) {
|
|||||||
if (!senderPublicKey) {
|
if (!senderPublicKey) {
|
||||||
// this should only happen if a mail from another channel is in the inbox
|
// this should only happen if a mail from another channel is in the inbox
|
||||||
message.body = 'Public key for sender not found!';
|
message.body = 'Public key for sender not found!';
|
||||||
|
message.decryptingBody = false;
|
||||||
callback(null, message);
|
callback(null, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -863,6 +876,7 @@ define(function(require) {
|
|||||||
if (decrypted.indexOf('Content-Transfer-Encoding:') === -1 && decrypted.indexOf('Content-Type:') === -1) {
|
if (decrypted.indexOf('Content-Transfer-Encoding:') === -1 && decrypted.indexOf('Content-Type:') === -1) {
|
||||||
message.body = decrypted;
|
message.body = decrypted;
|
||||||
message.decrypted = true;
|
message.decrypted = true;
|
||||||
|
message.decryptingBody = false;
|
||||||
callback(null, message);
|
callback(null, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -873,6 +887,7 @@ define(function(require) {
|
|||||||
block: decrypted
|
block: decrypted
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
message.decryptingBody = false;
|
||||||
callback(error);
|
callback(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -885,7 +900,8 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// we're done here!
|
// we're done here!
|
||||||
callback(error, message);
|
message.decryptingBody = false;
|
||||||
|
callback(null, message);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
4
src/lib/iscroll/iscroll-min.js
vendored
4
src/lib/iscroll/iscroll-min.js
vendored
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<div class="list-wrapper" ng-iscroll="state.nav.currentFolder.messages.length">
|
<div class="list-wrapper" ng-iscroll="state.nav.currentFolder.messages.length">
|
||||||
<ul class="mail-list">
|
<ul class="mail-list">
|
||||||
<li ng-class="{'mail-list-active': email === state.mailList.selected, 'mail-list-attachment': email.attachments !== undefined && email.attachments.length > 0, 'mail-list-unread': email.unread, 'mail-list-replied': !email.unread && email.answered}" ng-click="select(email)" ng-repeat="email in state.nav.currentFolder.messages | orderBy:'uid':true | filter:searchText">
|
<li ng-class="{'mail-list-active': email === state.mailList.selected, 'mail-list-attachment': email.attachments !== undefined && email.attachments.length > 0, 'mail-list-unread': email.unread, 'mail-list-replied': !email.unread && email.answered}" ng-click="select(email)" ng-repeat="email in (filteredMessages = (state.nav.currentFolder.messages | orderBy:'uid':true | filter:searchText))">
|
||||||
<h3>{{email.from[0].name || email.from[0].address}}</h3>
|
<h3>{{email.from[0].name || email.from[0].address}}</h3>
|
||||||
<div class="head">
|
<div class="head">
|
||||||
<div class="flag" data-icon="{{(!email.unread && email.answered) ? '' : ''}}" ng-click="toggleUnread(email); $event.stopPropagation()"></div>
|
<div class="flag" data-icon="{{(!email.unread && email.answered) ? '' : ''}}" ng-click="toggleUnread(email); $event.stopPropagation()"></div>
|
||||||
|
@ -929,19 +929,16 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('getMessageContent', function() {
|
describe('getMessageContent', function() {
|
||||||
it('should not do anything if the message already has content', function(done) {
|
it('should not do anything if the message already has content', function() {
|
||||||
var message = {
|
var message = {
|
||||||
body: 'bender is great!'
|
body: 'bender is great!'
|
||||||
};
|
};
|
||||||
|
|
||||||
dao.getMessageContent({
|
dao.getMessageContent({
|
||||||
message: message
|
message: message
|
||||||
}, function(err, msg) {
|
|
||||||
expect(err).to.not.exist;
|
|
||||||
expect(msg).to.equal(message);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// should do nothing
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should read an unencrypted body from the device', function(done) {
|
it('should read an unencrypted body from the device', function(done) {
|
||||||
@ -957,7 +954,7 @@ define(function(require) {
|
|||||||
localListStub = sinon.stub(dao, '_localListMessages').withArgs({
|
localListStub = sinon.stub(dao, '_localListMessages').withArgs({
|
||||||
folder: folder,
|
folder: folder,
|
||||||
uid: uid
|
uid: uid
|
||||||
}).yields(null, [{
|
}).yieldsAsync(null, [{
|
||||||
body: body
|
body: body
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
@ -967,13 +964,17 @@ define(function(require) {
|
|||||||
folder: folder
|
folder: folder
|
||||||
}, function(err, msg) {
|
}, function(err, msg) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
|
|
||||||
expect(msg).to.equal(message);
|
expect(msg).to.equal(message);
|
||||||
expect(msg.body).to.not.be.empty;
|
expect(msg.body).to.not.be.empty;
|
||||||
expect(msg.encrypted).to.be.false;
|
expect(msg.encrypted).to.be.false;
|
||||||
|
expect(msg.loadingBody).to.be.false;
|
||||||
|
|
||||||
expect(localListStub.calledOnce).to.be.true;
|
expect(localListStub.calledOnce).to.be.true;
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
expect(message.loadingBody).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should read an encrypted body from the device', function(done) {
|
it('should read an encrypted body from the device', function(done) {
|
||||||
@ -989,7 +990,7 @@ define(function(require) {
|
|||||||
localListStub = sinon.stub(dao, '_localListMessages').withArgs({
|
localListStub = sinon.stub(dao, '_localListMessages').withArgs({
|
||||||
folder: folder,
|
folder: folder,
|
||||||
uid: uid
|
uid: uid
|
||||||
}).yields(null, [{
|
}).yieldsAsync(null, [{
|
||||||
body: body
|
body: body
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
@ -999,14 +1000,18 @@ define(function(require) {
|
|||||||
folder: folder
|
folder: folder
|
||||||
}, function(err, msg) {
|
}, function(err, msg) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
|
|
||||||
expect(msg).to.equal(message);
|
expect(msg).to.equal(message);
|
||||||
expect(msg.body).to.not.be.empty;
|
expect(msg.body).to.not.be.empty;
|
||||||
expect(msg.encrypted).to.be.true;
|
expect(msg.encrypted).to.be.true;
|
||||||
expect(msg.decrypted).to.be.false;
|
expect(msg.decrypted).to.be.false;
|
||||||
|
expect(message.loadingBody).to.be.false;
|
||||||
|
|
||||||
expect(localListStub.calledOnce).to.be.true;
|
expect(localListStub.calledOnce).to.be.true;
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
expect(message.loadingBody).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should stream an unencrypted body from imap', function(done) {
|
it('should stream an unencrypted body from imap', function(done) {
|
||||||
@ -1022,12 +1027,12 @@ define(function(require) {
|
|||||||
localListStub = sinon.stub(dao, '_localListMessages').withArgs({
|
localListStub = sinon.stub(dao, '_localListMessages').withArgs({
|
||||||
folder: folder,
|
folder: folder,
|
||||||
uid: uid
|
uid: uid
|
||||||
}).yields(null, [{}]);
|
}).yieldsAsync(null, [{}]);
|
||||||
|
|
||||||
localStoreStub = sinon.stub(dao, '_localStoreMessages').withArgs({
|
localStoreStub = sinon.stub(dao, '_localStoreMessages').withArgs({
|
||||||
folder: folder,
|
folder: folder,
|
||||||
emails: [message]
|
emails: [message]
|
||||||
}).yields();
|
}).yieldsAsync();
|
||||||
|
|
||||||
imapStreamStub = sinon.stub(dao, '_imapStreamText', function(opts, cb) {
|
imapStreamStub = sinon.stub(dao, '_imapStreamText', function(opts, cb) {
|
||||||
expect(opts).to.deep.equal({
|
expect(opts).to.deep.equal({
|
||||||
@ -1045,15 +1050,19 @@ define(function(require) {
|
|||||||
folder: folder
|
folder: folder
|
||||||
}, function(err, msg) {
|
}, function(err, msg) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
|
|
||||||
expect(msg).to.equal(message);
|
expect(msg).to.equal(message);
|
||||||
expect(msg.body).to.not.be.empty;
|
expect(msg.body).to.not.be.empty;
|
||||||
expect(msg.encrypted).to.be.false;
|
expect(msg.encrypted).to.be.false;
|
||||||
|
expect(msg.loadingBody).to.be.false;
|
||||||
|
|
||||||
expect(localListStub.calledOnce).to.be.true;
|
expect(localListStub.calledOnce).to.be.true;
|
||||||
expect(imapStreamStub.calledOnce).to.be.true;
|
expect(imapStreamStub.calledOnce).to.be.true;
|
||||||
expect(localStoreStub.calledOnce).to.be.true;
|
expect(localStoreStub.calledOnce).to.be.true;
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
expect(message.loadingBody).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should stream an encrypted body from imap', function(done) {
|
it('should stream an encrypted body from imap', function(done) {
|
||||||
@ -1069,12 +1078,12 @@ define(function(require) {
|
|||||||
localListStub = sinon.stub(dao, '_localListMessages').withArgs({
|
localListStub = sinon.stub(dao, '_localListMessages').withArgs({
|
||||||
folder: folder,
|
folder: folder,
|
||||||
uid: uid
|
uid: uid
|
||||||
}).yields(null, [{}]);
|
}).yieldsAsync(null, [{}]);
|
||||||
|
|
||||||
localStoreStub = sinon.stub(dao, '_localStoreMessages').withArgs({
|
localStoreStub = sinon.stub(dao, '_localStoreMessages').withArgs({
|
||||||
folder: folder,
|
folder: folder,
|
||||||
emails: [message]
|
emails: [message]
|
||||||
}).yields();
|
}).yieldsAsync();
|
||||||
|
|
||||||
imapStreamStub = sinon.stub(dao, '_imapStreamText', function(opts, cb) {
|
imapStreamStub = sinon.stub(dao, '_imapStreamText', function(opts, cb) {
|
||||||
expect(opts).to.deep.equal({
|
expect(opts).to.deep.equal({
|
||||||
@ -1092,17 +1101,20 @@ define(function(require) {
|
|||||||
folder: folder
|
folder: folder
|
||||||
}, function(err, msg) {
|
}, function(err, msg) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
|
|
||||||
expect(msg).to.equal(message);
|
expect(msg).to.equal(message);
|
||||||
expect(msg.body).to.not.be.empty;
|
expect(msg.body).to.not.be.empty;
|
||||||
expect(msg.encrypted).to.be.true;
|
expect(msg.encrypted).to.be.true;
|
||||||
expect(msg.decrypted).to.be.false;
|
expect(msg.decrypted).to.be.false;
|
||||||
|
expect(msg.loadingBody).to.be.false;
|
||||||
|
|
||||||
expect(localListStub.calledOnce).to.be.true;
|
expect(localListStub.calledOnce).to.be.true;
|
||||||
expect(imapStreamStub.calledOnce).to.be.true;
|
expect(imapStreamStub.calledOnce).to.be.true;
|
||||||
expect(localStoreStub.calledOnce).to.be.true;
|
expect(localStoreStub.calledOnce).to.be.true;
|
||||||
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
expect(message.loadingBody).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fail to stream from imap due to error when persisting', function(done) {
|
it('fail to stream from imap due to error when persisting', function(done) {
|
||||||
@ -1139,6 +1151,8 @@ define(function(require) {
|
|||||||
expect(imapStreamStub.calledOnce).to.be.true;
|
expect(imapStreamStub.calledOnce).to.be.true;
|
||||||
expect(localStoreStub.calledOnce).to.be.true;
|
expect(localStoreStub.calledOnce).to.be.true;
|
||||||
|
|
||||||
|
expect(message.loadingBody).to.be.false;
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1174,28 +1188,27 @@ define(function(require) {
|
|||||||
expect(imapStreamStub.calledOnce).to.be.true;
|
expect(imapStreamStub.calledOnce).to.be.true;
|
||||||
expect(localStoreStub.called).to.be.false;
|
expect(localStoreStub.called).to.be.false;
|
||||||
|
|
||||||
|
expect(message.loadingBody).to.be.false;
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('decryptMessageContent', function() {
|
describe('decryptMessageContent', function() {
|
||||||
it('should not do anything when the message is not encrypted', function(done) {
|
it('should not do anything when the message is not encrypted', function() {
|
||||||
var message = {
|
var message = {
|
||||||
encrypted: false
|
encrypted: false
|
||||||
};
|
};
|
||||||
|
|
||||||
dao.decryptMessageContent({
|
dao.decryptMessageContent({
|
||||||
message: message
|
message: message
|
||||||
}, function(error, msg) {
|
|
||||||
expect(error).to.not.exist;
|
|
||||||
expect(msg).to.equal(message);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// should do nothing
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not do anything when the message is already decrypted', function(done) {
|
it('should not do anything when the message is already decrypted', function() {
|
||||||
var message = {
|
var message = {
|
||||||
encrypted: true,
|
encrypted: true,
|
||||||
decrypted: true
|
decrypted: true
|
||||||
@ -1203,12 +1216,9 @@ define(function(require) {
|
|||||||
|
|
||||||
dao.decryptMessageContent({
|
dao.decryptMessageContent({
|
||||||
message: message
|
message: message
|
||||||
}, function(error, msg) {
|
|
||||||
expect(error).to.not.exist;
|
|
||||||
expect(msg).to.equal(message);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// should do nothing
|
||||||
});
|
});
|
||||||
|
|
||||||
it('decrypt a pgp/mime message', function(done) {
|
it('decrypt a pgp/mime message', function(done) {
|
||||||
@ -1224,8 +1234,8 @@ define(function(require) {
|
|||||||
mimeBody = 'Content-Transfer-Encoding: Content-Type:';
|
mimeBody = 'Content-Transfer-Encoding: Content-Type:';
|
||||||
parsedBody = 'body? yes.';
|
parsedBody = 'body? yes.';
|
||||||
|
|
||||||
keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yields(null, mockKeyPair.publicKey);
|
keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yieldsAsync(null, mockKeyPair.publicKey);
|
||||||
pgpStub.decrypt.withArgs(message.body, mockKeyPair.publicKey.publicKey).yields(null, mimeBody);
|
pgpStub.decrypt.withArgs(message.body, mockKeyPair.publicKey.publicKey).yieldsAsync(null, mimeBody);
|
||||||
parseStub = sinon.stub(dao, '_imapParseMessageBlock', function(o, cb){
|
parseStub = sinon.stub(dao, '_imapParseMessageBlock', function(o, cb){
|
||||||
expect(o.message).to.equal(message);
|
expect(o.message).to.equal(message);
|
||||||
expect(o.block).to.equal(mimeBody);
|
expect(o.block).to.equal(mimeBody);
|
||||||
@ -1238,15 +1248,20 @@ define(function(require) {
|
|||||||
message: message
|
message: message
|
||||||
}, function(error, msg) {
|
}, function(error, msg) {
|
||||||
expect(error).to.not.exist;
|
expect(error).to.not.exist;
|
||||||
|
|
||||||
expect(msg).to.equal(message);
|
expect(msg).to.equal(message);
|
||||||
expect(msg.decrypted).to.be.true;
|
expect(msg.decrypted).to.be.true;
|
||||||
expect(msg.body).to.equal(parsedBody);
|
expect(msg.body).to.equal(parsedBody);
|
||||||
|
expect(msg.decryptingBody).to.be.false;
|
||||||
|
|
||||||
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
|
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
|
||||||
expect(pgpStub.decrypt.calledOnce).to.be.true;
|
expect(pgpStub.decrypt.calledOnce).to.be.true;
|
||||||
expect(parseStub.calledOnce).to.be.true;
|
expect(parseStub.calledOnce).to.be.true;
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
expect(message.decryptingBody).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('decrypt a pgp/inline message', function(done) {
|
it('decrypt a pgp/inline message', function(done) {
|
||||||
@ -1261,23 +1276,27 @@ define(function(require) {
|
|||||||
|
|
||||||
plaintextBody = 'body? yes.';
|
plaintextBody = 'body? yes.';
|
||||||
|
|
||||||
keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yields(null, mockKeyPair.publicKey);
|
keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yieldsAsync(null, mockKeyPair.publicKey);
|
||||||
pgpStub.decrypt.withArgs(message.body, mockKeyPair.publicKey.publicKey).yields(null, plaintextBody);
|
pgpStub.decrypt.withArgs(message.body, mockKeyPair.publicKey.publicKey).yieldsAsync(null, plaintextBody);
|
||||||
parseStub = sinon.stub(dao, '_imapParseMessageBlock');
|
parseStub = sinon.stub(dao, '_imapParseMessageBlock');
|
||||||
|
|
||||||
dao.decryptMessageContent({
|
dao.decryptMessageContent({
|
||||||
message: message
|
message: message
|
||||||
}, function(error, msg) {
|
}, function(error, msg) {
|
||||||
expect(error).to.not.exist;
|
expect(error).to.not.exist;
|
||||||
|
|
||||||
expect(msg).to.equal(message);
|
expect(msg).to.equal(message);
|
||||||
expect(msg.decrypted).to.be.true;
|
expect(msg.decrypted).to.be.true;
|
||||||
expect(msg.body).to.equal(plaintextBody);
|
expect(msg.body).to.equal(plaintextBody);
|
||||||
|
expect(msg.decryptingBody).to.be.false;
|
||||||
|
|
||||||
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
|
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
|
||||||
expect(pgpStub.decrypt.calledOnce).to.be.true;
|
expect(pgpStub.decrypt.calledOnce).to.be.true;
|
||||||
expect(parseStub.called).to.be.false;
|
expect(parseStub.called).to.be.false;
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
expect(message.decryptingBody).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail during decryption message', function(done) {
|
it('should fail during decryption message', function(done) {
|
||||||
@ -1303,9 +1322,12 @@ define(function(require) {
|
|||||||
message: message
|
message: message
|
||||||
}, function(error, msg) {
|
}, function(error, msg) {
|
||||||
expect(error).to.not.exist;
|
expect(error).to.not.exist;
|
||||||
|
|
||||||
expect(msg).to.equal(message);
|
expect(msg).to.equal(message);
|
||||||
expect(msg.decrypted).to.be.true;
|
expect(msg.decrypted).to.be.true;
|
||||||
expect(msg.body).to.equal(errMsg);
|
expect(msg.body).to.equal(errMsg);
|
||||||
|
expect(msg.decryptingBody).to.be.false;
|
||||||
|
|
||||||
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
|
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
|
||||||
expect(pgpStub.decrypt.calledOnce).to.be.true;
|
expect(pgpStub.decrypt.calledOnce).to.be.true;
|
||||||
expect(parseStub.called).to.be.false;
|
expect(parseStub.called).to.be.false;
|
||||||
@ -1331,8 +1353,12 @@ define(function(require) {
|
|||||||
message: message
|
message: message
|
||||||
}, function(error, msg) {
|
}, function(error, msg) {
|
||||||
expect(error).to.exist;
|
expect(error).to.exist;
|
||||||
|
|
||||||
expect(msg).to.not.exist;
|
expect(msg).to.not.exist;
|
||||||
|
|
||||||
expect(message.decrypted).to.be.false;
|
expect(message.decrypted).to.be.false;
|
||||||
|
expect(message.decryptingBody).to.be.false;
|
||||||
|
|
||||||
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
|
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
|
||||||
expect(pgpStub.decrypt.called).to.be.false;
|
expect(pgpStub.decrypt.called).to.be.false;
|
||||||
expect(parseStub.called).to.be.false;
|
expect(parseStub.called).to.be.false;
|
||||||
|
@ -10,6 +10,8 @@ define(function(require) {
|
|||||||
KeychainDAO = require('js/dao/keychain-dao'),
|
KeychainDAO = require('js/dao/keychain-dao'),
|
||||||
appController = require('js/app-controller');
|
appController = require('js/app-controller');
|
||||||
|
|
||||||
|
chai.Assertion.includeStack = true;
|
||||||
|
|
||||||
describe('Mail List controller unit test', function() {
|
describe('Mail List controller unit test', function() {
|
||||||
var scope, ctrl, origEmailDao, emailDaoMock, keychainMock, deviceStorageMock,
|
var scope, ctrl, origEmailDao, emailDaoMock, keychainMock, deviceStorageMock,
|
||||||
emailAddress, notificationClickedHandler, emails,
|
emailAddress, notificationClickedHandler, emails,
|
||||||
@ -223,6 +225,72 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getContent', function() {
|
||||||
|
it('should get the mail content', function() {
|
||||||
|
scope.state.nav = {
|
||||||
|
currentFolder: {
|
||||||
|
type: 'asd',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.getContent();
|
||||||
|
expect(emailDaoMock.getMessageContent.calledOnce).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('select', function() {
|
||||||
|
it('should decrypt, focus mark an unread mail as read', function() {
|
||||||
|
var mail, synchronizeMock;
|
||||||
|
|
||||||
|
mail = {
|
||||||
|
unread: true
|
||||||
|
};
|
||||||
|
synchronizeMock = sinon.stub(scope, 'synchronize');
|
||||||
|
scope.state = {
|
||||||
|
nav: {
|
||||||
|
currentFolder: {
|
||||||
|
type: 'asd',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mailList: {},
|
||||||
|
read: {
|
||||||
|
toggle: function() {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.select(mail);
|
||||||
|
|
||||||
|
expect(emailDaoMock.decryptMessageContent.calledOnce).to.be.true;
|
||||||
|
expect(synchronizeMock.calledOnce).to.be.true;
|
||||||
|
expect(scope.state.mailList.selected).to.equal(mail);
|
||||||
|
|
||||||
|
scope.synchronize.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should decrypt and focus a read mail', function() {
|
||||||
|
var mail, synchronizeMock;
|
||||||
|
|
||||||
|
mail = {
|
||||||
|
unread: false
|
||||||
|
};
|
||||||
|
synchronizeMock = sinon.stub(scope, 'synchronize');
|
||||||
|
scope.state = {
|
||||||
|
mailList: {},
|
||||||
|
read: {
|
||||||
|
toggle: function() {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.select(mail);
|
||||||
|
|
||||||
|
expect(emailDaoMock.decryptMessageContent.calledOnce).to.be.true;
|
||||||
|
expect(synchronizeMock.called).to.be.false;
|
||||||
|
expect(scope.state.mailList.selected).to.equal(mail);
|
||||||
|
|
||||||
|
scope.synchronize.restore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('remove', function() {
|
describe('remove', function() {
|
||||||
it('should not delete without a selected mail', function() {
|
it('should not delete without a selected mail', function() {
|
||||||
scope.remove();
|
scope.remove();
|
||||||
|
Loading…
Reference in New Issue
Block a user