mirror of
https://github.com/moparisthebest/mail
synced 2024-12-01 13:22:16 -05:00
[WO-338] add notification for incoming unread mails
This commit is contained in:
parent
f5f8781a8c
commit
49cadecd2d
@ -11,7 +11,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"crypto-lib": "https://github.com/whiteout-io/crypto-lib/tarball/v0.1.1",
|
"crypto-lib": "https://github.com/whiteout-io/crypto-lib/tarball/v0.1.1",
|
||||||
"imap-client": "https://github.com/whiteout-io/imap-client/tarball/v0.2.4",
|
"imap-client": "https://github.com/whiteout-io/imap-client/tarball/dev/wo-338",
|
||||||
"mailreader": "https://github.com/whiteout-io/mailreader/tarball/v0.2.2",
|
"mailreader": "https://github.com/whiteout-io/mailreader/tarball/v0.2.2",
|
||||||
"pgpmailer": "https://github.com/whiteout-io/pgpmailer/tarball/v0.2.2",
|
"pgpmailer": "https://github.com/whiteout-io/pgpmailer/tarball/v0.2.2",
|
||||||
"pgpbuilder": "https://github.com/whiteout-io/pgpbuilder/tarball/v0.2.3",
|
"pgpbuilder": "https://github.com/whiteout-io/pgpbuilder/tarball/v0.2.3",
|
||||||
|
@ -72,7 +72,7 @@ define(function(require) {
|
|||||||
self._keychain = keychain = new KeychainDAO(lawnchairDao, pubkeyDao);
|
self._keychain = keychain = new KeychainDAO(lawnchairDao, pubkeyDao);
|
||||||
self._crypto = pgp = new PGP();
|
self._crypto = pgp = new PGP();
|
||||||
self._pgpbuilder = pgpbuilder = new PgpBuilder();
|
self._pgpbuilder = pgpbuilder = new PgpBuilder();
|
||||||
emailSync = new EmailSync(keychain, userStorage);
|
self._emailSync = emailSync = new EmailSync(keychain, userStorage);
|
||||||
self._emailDao = emailDao = new EmailDAO(keychain, pgp, userStorage, pgpbuilder, mailreader, emailSync);
|
self._emailDao = emailDao = new EmailDAO(keychain, pgp, userStorage, pgpbuilder, mailreader, emailSync);
|
||||||
self._outboxBo = new OutboxBO(emailDao, keychain, userStorage);
|
self._outboxBo = new OutboxBO(emailDao, keychain, userStorage);
|
||||||
self._updateHandler = new UpdateHandler(appConfigStore, userStorage);
|
self._updateHandler = new UpdateHandler(appConfigStore, userStorage);
|
||||||
|
@ -5,9 +5,8 @@ define(function(require) {
|
|||||||
_ = require('underscore'),
|
_ = require('underscore'),
|
||||||
appController = require('js/app-controller'),
|
appController = require('js/app-controller'),
|
||||||
IScroll = require('iscroll'),
|
IScroll = require('iscroll'),
|
||||||
str = require('js/app-config').string,
|
|
||||||
notification = require('js/util/notification'),
|
notification = require('js/util/notification'),
|
||||||
emailDao, outboxBo;
|
emailDao, outboxBo, emailSync;
|
||||||
|
|
||||||
var MailListCtrl = function($scope, $timeout) {
|
var MailListCtrl = function($scope, $timeout) {
|
||||||
//
|
//
|
||||||
@ -16,26 +15,66 @@ define(function(require) {
|
|||||||
|
|
||||||
emailDao = appController._emailDao;
|
emailDao = appController._emailDao;
|
||||||
outboxBo = appController._outboxBo;
|
outboxBo = appController._outboxBo;
|
||||||
|
emailSync = appController._emailSync;
|
||||||
|
|
||||||
// push handler
|
emailDao.onNeedsSync = function(error, folder) {
|
||||||
if (emailDao) {
|
if (error) {
|
||||||
emailDao.onIncomingMessage = function(email) {
|
$scope.onError(error);
|
||||||
// sync
|
return;
|
||||||
$scope.synchronize(function() {
|
}
|
||||||
// show notification
|
|
||||||
notificationForEmail(email);
|
$scope.synchronize({
|
||||||
|
folder: folder
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
notification.setOnClickedListener(notificationClicked);
|
|
||||||
|
emailSync.onIncomingMessage = function(msgs) {
|
||||||
|
var popupId, popupTitle, popupMessage, unreadMsgs;
|
||||||
|
|
||||||
|
unreadMsgs = msgs.filter(function(msg) {
|
||||||
|
return msg.unread;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (unreadMsgs.length === 0) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
popupId = '' + unreadMsgs[0].uid;
|
||||||
|
if (unreadMsgs.length > 1) {
|
||||||
|
popupTitle = unreadMsgs.length + ' new messages';
|
||||||
|
popupMessage = _.pluck(unreadMsgs, 'subject').join('\n');
|
||||||
|
} else {
|
||||||
|
popupTitle = unreadMsgs[0].from[0].name || unreadMsgs[0].from[0].address;
|
||||||
|
popupMessage = unreadMsgs[0].subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.create({
|
||||||
|
id: popupId,
|
||||||
|
title: popupTitle,
|
||||||
|
message: popupMessage
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
notification.setOnClickedListener(function(uidString) {
|
||||||
|
var uid = parseInt(uidString, 10);
|
||||||
|
|
||||||
|
if (isNaN(uid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.select(_.findWhere(currentFolder().messages, {
|
||||||
|
uid: uid
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// scope functions
|
// scope functions
|
||||||
//
|
//
|
||||||
|
|
||||||
$scope.getBody = function(email) {
|
$scope.getBody = function(email) {
|
||||||
emailDao.getBody({
|
emailDao.getBody({
|
||||||
folder: getFolder().path,
|
folder: currentFolder().path,
|
||||||
message: email
|
message: email
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
if (err && err.code !== 42) {
|
if (err && err.code !== 42) {
|
||||||
@ -93,17 +132,20 @@ define(function(require) {
|
|||||||
/**
|
/**
|
||||||
* Synchronize the selected imap folder to local storage
|
* Synchronize the selected imap folder to local storage
|
||||||
*/
|
*/
|
||||||
$scope.synchronize = function(callback) {
|
$scope.synchronize = function(options) {
|
||||||
updateStatus('Syncing ...');
|
updateStatus('Syncing ...');
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
options.folder = options.folder || currentFolder().path;
|
||||||
|
|
||||||
// let email dao handle sync transparently
|
// let email dao handle sync transparently
|
||||||
if ($scope.state.nav.currentFolder.type === 'Outbox') {
|
if (currentFolder().type === 'Outbox') {
|
||||||
emailDao.syncOutbox({
|
emailDao.syncOutbox({
|
||||||
folder: getFolder().path
|
folder: currentFolder().path
|
||||||
}, done);
|
}, done);
|
||||||
} else {
|
} else {
|
||||||
emailDao.sync({
|
emailDao.sync({
|
||||||
folder: getFolder().path
|
folder: options.folder || currentFolder().path
|
||||||
}, done);
|
}, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,18 +169,18 @@ define(function(require) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort emails
|
|
||||||
selectFirstMessage();
|
|
||||||
// display last update
|
// display last update
|
||||||
updateStatus('Last update: ', new Date());
|
updateStatus('Last update: ', new Date());
|
||||||
|
|
||||||
|
// do not change the selection if we just updated another folder in the background
|
||||||
|
if (currentFolder().path === options.folder) {
|
||||||
|
selectFirstMessage();
|
||||||
|
}
|
||||||
|
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
|
|
||||||
// fetch visible bodies at the end of a successful sync
|
// fetch visible bodies at the end of a successful sync
|
||||||
$scope.loadVisibleBodies();
|
$scope.loadVisibleBodies();
|
||||||
|
|
||||||
if (callback) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -150,7 +192,7 @@ define(function(require) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getFolder().type === 'Outbox') {
|
if (currentFolder().type === 'Outbox') {
|
||||||
$scope.onError({
|
$scope.onError({
|
||||||
errMsg: 'Deleting messages from the outbox is not yet supported.'
|
errMsg: 'Deleting messages from the outbox is not yet supported.'
|
||||||
});
|
});
|
||||||
@ -161,18 +203,18 @@ define(function(require) {
|
|||||||
$scope.synchronize();
|
$scope.synchronize();
|
||||||
|
|
||||||
function removeAndShowNext() {
|
function removeAndShowNext() {
|
||||||
var index = getFolder().messages.indexOf(email);
|
var index = currentFolder().messages.indexOf(email);
|
||||||
// show the next mail
|
// show the next mail
|
||||||
if (getFolder().messages.length > 1) {
|
if (currentFolder().messages.length > 1) {
|
||||||
// if we're about to delete the last entry of the array, show the previous (i.e. the one below in the list),
|
// if we're about to delete the last entry of the array, show the previous (i.e. the one below in the list),
|
||||||
// otherwise show the next one (i.e. the one above in the list)
|
// otherwise show the next one (i.e. the one above in the list)
|
||||||
$scope.select(_.last(getFolder().messages) === email ? getFolder().messages[index - 1] : getFolder().messages[index + 1]);
|
$scope.select(_.last(currentFolder().messages) === email ? currentFolder().messages[index - 1] : currentFolder().messages[index + 1]);
|
||||||
} else {
|
} else {
|
||||||
// if we have only one email in the array, show nothing
|
// if we have only one email in the array, show nothing
|
||||||
$scope.select();
|
$scope.select();
|
||||||
$scope.state.mailList.selected = undefined;
|
$scope.state.mailList.selected = undefined;
|
||||||
}
|
}
|
||||||
getFolder().messages.splice(index, 1);
|
currentFolder().messages.splice(index, 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -190,14 +232,14 @@ define(function(require) {
|
|||||||
* List emails from folder when user changes folder
|
* List emails from folder when user changes folder
|
||||||
*/
|
*/
|
||||||
$scope._stopWatchTask = $scope.$watch('state.nav.currentFolder', function() {
|
$scope._stopWatchTask = $scope.$watch('state.nav.currentFolder', function() {
|
||||||
if (!getFolder()) {
|
if (!currentFolder()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// development... display dummy mail objects
|
// development... display dummy mail objects
|
||||||
if (!window.chrome || !chrome.identity) {
|
if (!window.chrome || !chrome.identity) {
|
||||||
updateStatus('Last update: ', new Date());
|
updateStatus('Last update: ', new Date());
|
||||||
getFolder().messages = createDummyMails();
|
currentFolder().messages = createDummyMails();
|
||||||
selectFirstMessage();
|
selectFirstMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -229,30 +271,6 @@ define(function(require) {
|
|||||||
// helper functions
|
// helper functions
|
||||||
//
|
//
|
||||||
|
|
||||||
function notificationClicked(uidString) {
|
|
||||||
var email, uid = parseInt(uidString, 10);
|
|
||||||
|
|
||||||
if (isNaN(uid)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
email = _.findWhere(getFolder().messages, {
|
|
||||||
uid: uid
|
|
||||||
});
|
|
||||||
|
|
||||||
if (email) {
|
|
||||||
$scope.select(email);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function notificationForEmail(email) {
|
|
||||||
notification.create({
|
|
||||||
id: '' + email.uid,
|
|
||||||
title: email.from[0].name || email.from[0].address,
|
|
||||||
message: email.subject.replace(str.subjectPrefix, '')
|
|
||||||
}, function() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateStatus(lbl, time) {
|
function updateStatus(lbl, time) {
|
||||||
$scope.lastUpdateLbl = lbl;
|
$scope.lastUpdateLbl = lbl;
|
||||||
$scope.lastUpdate = (time) ? time : '';
|
$scope.lastUpdate = (time) ? time : '';
|
||||||
@ -272,7 +290,7 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFolder() {
|
function currentFolder() {
|
||||||
return $scope.state.nav.currentFolder;
|
return $scope.state.nav.currentFolder;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -59,6 +59,7 @@ define(function(require) {
|
|||||||
|
|
||||||
// init folders
|
// init folders
|
||||||
initFolders();
|
initFolders();
|
||||||
|
|
||||||
// select inbox as the current folder on init
|
// select inbox as the current folder on init
|
||||||
if ($scope.account.folders && $scope.account.folders.length > 0) {
|
if ($scope.account.folders && $scope.account.folders.length > 0) {
|
||||||
$scope.openFolder($scope.account.folders[0]);
|
$scope.openFolder($scope.account.folders[0]);
|
||||||
@ -89,8 +90,7 @@ define(function(require) {
|
|||||||
outboxBo.onSent = sentNotification;
|
outboxBo.onSent = sentNotification;
|
||||||
// start checking outbox periodically
|
// start checking outbox periodically
|
||||||
outboxBo.startChecking($scope.onOutboxUpdate);
|
outboxBo.startChecking($scope.onOutboxUpdate);
|
||||||
// make function available globally for write controller
|
|
||||||
$scope.emptyOutbox = outboxBo._processOutbox.bind(outboxBo);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,13 +86,6 @@ define(function(require) {
|
|||||||
self._imapClient = options.imapClient;
|
self._imapClient = options.imapClient;
|
||||||
self._pgpMailer = options.pgpMailer;
|
self._pgpMailer = options.pgpMailer;
|
||||||
|
|
||||||
// delegation-esque pattern to mitigate between node-style events and plain js
|
|
||||||
self._imapClient.onIncomingMessage = function(message) {
|
|
||||||
if (typeof self.onIncomingMessage === 'function') {
|
|
||||||
self.onIncomingMessage(message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// notify emailSync
|
// notify emailSync
|
||||||
self._emailSync.onConnect({
|
self._emailSync.onConnect({
|
||||||
imapClient: self._imapClient
|
imapClient: self._imapClient
|
||||||
@ -122,6 +115,20 @@ define(function(require) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var inbox = _.findWhere(folders, {
|
||||||
|
type: 'Inbox'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (inbox) {
|
||||||
|
self._imapClient.listenForChanges({
|
||||||
|
path: inbox.path
|
||||||
|
},function(error, path) {
|
||||||
|
if (typeof self.onNeedsSync === 'function') {
|
||||||
|
self.onNeedsSync(error, path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
self._account.folders = folders;
|
self._account.folders = folders;
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
|
@ -448,6 +448,7 @@ define(function(require) {
|
|||||||
|
|
||||||
// if persisting worked, add them to the messages array
|
// if persisting worked, add them to the messages array
|
||||||
folder.messages = folder.messages.concat(messages);
|
folder.messages = folder.messages.concat(messages);
|
||||||
|
self.onIncomingMessage(messages);
|
||||||
doDeltaF4();
|
doDeltaF4();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ define(function(require) {
|
|||||||
var self = {};
|
var self = {};
|
||||||
|
|
||||||
self.create = function(options, callback) {
|
self.create = function(options, callback) {
|
||||||
|
callback = callback || function() {};
|
||||||
if (window.chrome && chrome.notifications) {
|
if (window.chrome && chrome.notifications) {
|
||||||
chrome.notifications.create(options.id, {
|
chrome.notifications.create(options.id, {
|
||||||
type: 'basic',
|
type: 'basic',
|
||||||
|
@ -159,19 +159,6 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('push', function() {
|
|
||||||
it('should work', function(done) {
|
|
||||||
var o = {};
|
|
||||||
|
|
||||||
dao.onIncomingMessage = function(obj) {
|
|
||||||
expect(obj).to.equal(o);
|
|
||||||
done();
|
|
||||||
};
|
|
||||||
|
|
||||||
dao._imapClient.onIncomingMessage(o);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('init', function() {
|
describe('init', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
delete dao._account;
|
delete dao._account;
|
||||||
|
@ -800,7 +800,7 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch messages downstream from the remote', function(done) {
|
it('should fetch messages downstream from the remote', function(done) {
|
||||||
var invocations, folder, localListStub, imapSearchStub, localStoreStub, imapListMessagesStub;
|
var invocations, folder, localListStub, imapSearchStub, localStoreStub, imapListMessagesStub, incomingMessagesCalled;
|
||||||
|
|
||||||
invocations = 0;
|
invocations = 0;
|
||||||
folder = 'FOLDAAAA';
|
folder = 'FOLDAAAA';
|
||||||
@ -842,6 +842,13 @@ define(function(require) {
|
|||||||
emails: [dummyEncryptedMail]
|
emails: [dummyEncryptedMail]
|
||||||
}).yields();
|
}).yields();
|
||||||
|
|
||||||
|
incomingMessagesCalled = false;
|
||||||
|
emailSync.onIncomingMessage = function(msgs) {
|
||||||
|
incomingMessagesCalled = true;
|
||||||
|
expect(msgs).to.not.be.empty;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
emailSync.sync({
|
emailSync.sync({
|
||||||
folder: folder
|
folder: folder
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
@ -860,6 +867,8 @@ define(function(require) {
|
|||||||
expect(localListStub.calledOnce).to.be.true;
|
expect(localListStub.calledOnce).to.be.true;
|
||||||
expect(imapSearchStub.calledThrice).to.be.true;
|
expect(imapSearchStub.calledThrice).to.be.true;
|
||||||
expect(localStoreStub.calledOnce).to.be.true;
|
expect(localStoreStub.calledOnce).to.be.true;
|
||||||
|
expect(incomingMessagesCalled).to.be.true;
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1076,6 +1085,8 @@ define(function(require) {
|
|||||||
emails: [verificationMail]
|
emails: [verificationMail]
|
||||||
}).yields();
|
}).yields();
|
||||||
|
|
||||||
|
emailSync.onIncomingMessage = function() {};
|
||||||
|
|
||||||
emailSync.sync({
|
emailSync.sync({
|
||||||
folder: folder
|
folder: folder
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
@ -1146,6 +1157,8 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
imapDeleteStub = sinon.stub(emailSync, '_imapDeleteMessage').yields({});
|
imapDeleteStub = sinon.stub(emailSync, '_imapDeleteMessage').yields({});
|
||||||
|
|
||||||
|
emailSync.onIncomingMessage = function() {};
|
||||||
|
|
||||||
emailSync.sync({
|
emailSync.sync({
|
||||||
folder: folder
|
folder: folder
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
|
@ -6,35 +6,26 @@ define(function(require) {
|
|||||||
mocks = require('angularMocks'),
|
mocks = require('angularMocks'),
|
||||||
MailListCtrl = require('js/controller/mail-list'),
|
MailListCtrl = require('js/controller/mail-list'),
|
||||||
EmailDAO = require('js/dao/email-dao'),
|
EmailDAO = require('js/dao/email-dao'),
|
||||||
|
EmailSync = require('js/dao/email-sync'),
|
||||||
DeviceStorageDAO = require('js/dao/devicestorage-dao'),
|
DeviceStorageDAO = require('js/dao/devicestorage-dao'),
|
||||||
KeychainDAO = require('js/dao/keychain-dao'),
|
KeychainDAO = require('js/dao/keychain-dao'),
|
||||||
appController = require('js/app-controller');
|
appController = require('js/app-controller'),
|
||||||
|
notification = require('js/util/notification');
|
||||||
|
|
||||||
chai.Assertion.includeStack = true;
|
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, origEmailSync, emailDaoMock, emailSyncMock, keychainMock, deviceStorageMock,
|
||||||
emailAddress, notificationClickedHandler, emails,
|
emailAddress, notificationClickedHandler, emails,
|
||||||
hasChrome, hasNotifications, hasSocket, hasRuntime, hasIdentity;
|
hasChrome, hasSocket, hasRuntime, hasIdentity;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
hasChrome = !! window.chrome;
|
hasChrome = !! window.chrome;
|
||||||
hasNotifications = !! window.chrome.notifications;
|
|
||||||
hasSocket = !! window.chrome.socket;
|
hasSocket = !! window.chrome.socket;
|
||||||
hasIdentity = !! window.chrome.identity;
|
hasIdentity = !! window.chrome.identity;
|
||||||
if (!hasChrome) {
|
if (!hasChrome) {
|
||||||
window.chrome = {};
|
window.chrome = {};
|
||||||
}
|
}
|
||||||
if (!hasNotifications) {
|
|
||||||
window.chrome.notifications = {
|
|
||||||
onClicked: {
|
|
||||||
addListener: function(handler) {
|
|
||||||
notificationClickedHandler = handler;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
create: function() {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (!hasSocket) {
|
if (!hasSocket) {
|
||||||
window.chrome.socket = {};
|
window.chrome.socket = {};
|
||||||
}
|
}
|
||||||
@ -47,6 +38,10 @@ define(function(require) {
|
|||||||
window.chrome.identity = {};
|
window.chrome.identity = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sinon.stub(notification, 'setOnClickedListener', function(func) {
|
||||||
|
notificationClickedHandler = func;
|
||||||
|
});
|
||||||
|
|
||||||
emails = [{
|
emails = [{
|
||||||
unread: true
|
unread: true
|
||||||
}, {
|
}, {
|
||||||
@ -59,8 +54,11 @@ define(function(require) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
origEmailDao = appController._emailDao;
|
origEmailDao = appController._emailDao;
|
||||||
|
origEmailSync = appController._emailSync;
|
||||||
emailDaoMock = sinon.createStubInstance(EmailDAO);
|
emailDaoMock = sinon.createStubInstance(EmailDAO);
|
||||||
|
emailSyncMock = sinon.createStubInstance(EmailSync);
|
||||||
appController._emailDao = emailDaoMock;
|
appController._emailDao = emailDaoMock;
|
||||||
|
appController._emailSync = emailSyncMock;
|
||||||
emailAddress = 'fred@foo.com';
|
emailAddress = 'fred@foo.com';
|
||||||
emailDaoMock._account = {
|
emailDaoMock._account = {
|
||||||
emailAddress: emailAddress,
|
emailAddress: emailAddress,
|
||||||
@ -91,9 +89,8 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
if (!hasNotifications) {
|
notification.setOnClickedListener.restore();
|
||||||
delete window.chrome.notifications;
|
|
||||||
}
|
|
||||||
if (!hasSocket) {
|
if (!hasSocket) {
|
||||||
delete window.chrome.socket;
|
delete window.chrome.socket;
|
||||||
}
|
}
|
||||||
@ -109,6 +106,7 @@ define(function(require) {
|
|||||||
|
|
||||||
// restore the module
|
// restore the module
|
||||||
appController._emailDao = origEmailDao;
|
appController._emailDao = origEmailDao;
|
||||||
|
appController._emailSync = origEmailDao;
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('scope variables', function() {
|
describe('scope variables', function() {
|
||||||
@ -117,72 +115,105 @@ define(function(require) {
|
|||||||
expect(scope.synchronize).to.exist;
|
expect(scope.synchronize).to.exist;
|
||||||
expect(scope.remove).to.exist;
|
expect(scope.remove).to.exist;
|
||||||
expect(scope.state.mailList).to.exist;
|
expect(scope.state.mailList).to.exist;
|
||||||
// expect(emailDaoMock.onIncomingMessage).to.exist;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('push notification', function() {
|
describe('push notification', function() {
|
||||||
it('should focus mail and not mark it read', function(done) {
|
beforeEach(function() {
|
||||||
var uid, mail, currentFolder;
|
|
||||||
|
|
||||||
scope._stopWatchTask();
|
scope._stopWatchTask();
|
||||||
|
|
||||||
uid = 123;
|
|
||||||
mail = {
|
|
||||||
uid: uid,
|
|
||||||
from: [{
|
|
||||||
address: 'asd'
|
|
||||||
}],
|
|
||||||
subject: '[whiteout] asdasd',
|
|
||||||
unread: true
|
|
||||||
};
|
|
||||||
currentFolder = 'asd';
|
|
||||||
scope.state.nav = {
|
|
||||||
currentFolder: currentFolder
|
|
||||||
};
|
|
||||||
scope.state.read = {
|
|
||||||
toggle: function() {}
|
|
||||||
};
|
|
||||||
scope.emails = [mail];
|
|
||||||
emailDaoMock.sync.yieldsAsync();
|
|
||||||
window.chrome.notifications.create = function(id, opts) {
|
|
||||||
expect(id).to.equal('123');
|
|
||||||
expect(opts.type).to.equal('basic');
|
|
||||||
expect(opts.message).to.equal('asdasd');
|
|
||||||
expect(opts.title).to.equal('asd');
|
|
||||||
done();
|
|
||||||
};
|
|
||||||
|
|
||||||
emailDaoMock.onIncomingMessage(mail);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('clicking push notification', function() {
|
it('should succeed for single mail', function(done) {
|
||||||
it('should focus mail', function() {
|
var mail = {
|
||||||
var mail, currentFolder;
|
|
||||||
|
|
||||||
scope._stopWatchTask();
|
|
||||||
|
|
||||||
mail = {
|
|
||||||
uid: 123,
|
uid: 123,
|
||||||
from: [{
|
from: [{
|
||||||
address: 'asd'
|
address: 'asd'
|
||||||
}],
|
}],
|
||||||
subject: '[whiteout] asdasd',
|
subject: 'this is the subject!',
|
||||||
unread: true
|
unread: true
|
||||||
};
|
};
|
||||||
currentFolder = {
|
|
||||||
|
sinon.stub(notification, 'create', function(opts) {
|
||||||
|
expect(opts.id).to.equal('' + mail.uid);
|
||||||
|
expect(opts.title).to.equal(mail.from[0].address);
|
||||||
|
expect(opts.message).to.equal(mail.subject);
|
||||||
|
|
||||||
|
notification.create.restore();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
emailSyncMock.onIncomingMessage([mail]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should succeed for multiple mails', function(done) {
|
||||||
|
var mails = [{
|
||||||
|
uid: 1,
|
||||||
|
from: [{
|
||||||
|
address: 'asd'
|
||||||
|
}],
|
||||||
|
subject: 'this is the subject!',
|
||||||
|
unread: true
|
||||||
|
}, {
|
||||||
|
uid: 2,
|
||||||
|
from: [{
|
||||||
|
address: 'qwe'
|
||||||
|
}],
|
||||||
|
subject: 'this is the other subject!',
|
||||||
|
unread: true
|
||||||
|
}, {
|
||||||
|
uid: 3,
|
||||||
|
from: [{
|
||||||
|
address: 'qwe'
|
||||||
|
}],
|
||||||
|
subject: 'this is the other subject!',
|
||||||
|
unread: false
|
||||||
|
}];
|
||||||
|
|
||||||
|
sinon.stub(notification, 'create', function(opts) {
|
||||||
|
expect(opts.id).to.equal('' + mails[0].uid);
|
||||||
|
expect(opts.title).to.equal('2 new messages');
|
||||||
|
expect(opts.message).to.equal(mails[0].subject + '\n' + mails[1].subject);
|
||||||
|
|
||||||
|
notification.create.restore();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
emailSyncMock.onIncomingMessage(mails);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should focus mail when clicked', function() {
|
||||||
|
var mail = {
|
||||||
|
uid: 123,
|
||||||
|
from: [{
|
||||||
|
address: 'asd'
|
||||||
|
}],
|
||||||
|
subject: 'asdasd',
|
||||||
|
unread: true
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.state.nav = {
|
||||||
|
currentFolder: {
|
||||||
type: 'asd',
|
type: 'asd',
|
||||||
messages: [mail]
|
messages: [mail]
|
||||||
};
|
}
|
||||||
scope.state.nav = {
|
|
||||||
currentFolder: currentFolder
|
|
||||||
};
|
};
|
||||||
|
|
||||||
notificationClickedHandler('123');
|
notificationClickedHandler('123');
|
||||||
|
|
||||||
expect(scope.state.mailList.selected).to.equal(mail);
|
expect(scope.state.mailList.selected).to.equal(mail);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not change focus mail when popup id is NaN', function() {
|
||||||
|
scope.state.nav = {
|
||||||
|
currentFolder: {
|
||||||
|
type: 'asd',
|
||||||
|
messages: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var focus = scope.state.mailList.selected = {};
|
||||||
|
|
||||||
|
notificationClickedHandler('');
|
||||||
|
expect(scope.state.mailList.selected).to.equal(focus);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('synchronize', function() {
|
describe('synchronize', function() {
|
||||||
@ -200,15 +231,15 @@ define(function(require) {
|
|||||||
currentFolder: currentFolder
|
currentFolder: currentFolder
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadVisibleBodiesStub = sinon.stub(scope, 'loadVisibleBodies');
|
var loadVisibleBodiesStub = sinon.stub(scope, 'loadVisibleBodies', function() {
|
||||||
|
|
||||||
scope.synchronize(function() {
|
|
||||||
expect(scope.state.nav.currentFolder.messages).to.deep.equal(emails);
|
expect(scope.state.nav.currentFolder.messages).to.deep.equal(emails);
|
||||||
expect(loadVisibleBodiesStub.calledOnce).to.be.true;
|
expect(loadVisibleBodiesStub.calledOnce).to.be.true;
|
||||||
loadVisibleBodiesStub.restore();
|
loadVisibleBodiesStub.restore();
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
scope.synchronize();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user