mirror of
https://github.com/moparisthebest/mail
synced 2024-11-12 20:25:01 -05:00
commit
b3f1f4b3fe
@ -185,6 +185,7 @@ module.exports = function(grunt) {
|
||||
'test/unit/navigation-ctrl-test.js',
|
||||
'test/unit/mail-list-ctrl-test.js',
|
||||
'test/unit/write-ctrl-test.js',
|
||||
'test/unit/action-bar-ctrl-test.js',
|
||||
'test/unit/outbox-bo-test.js',
|
||||
'test/unit/invitation-dao-test.js',
|
||||
'test/unit/update-handler-test.js',
|
||||
@ -301,6 +302,7 @@ module.exports = function(grunt) {
|
||||
},
|
||||
options: {
|
||||
mangle: false,
|
||||
compress: false,
|
||||
sourceMap: true,
|
||||
sourceMapIn: 'test/unit/index.browserified.js.map',
|
||||
sourceMapIncludeSources: true,
|
||||
@ -319,6 +321,7 @@ module.exports = function(grunt) {
|
||||
},
|
||||
options: {
|
||||
mangle: false,
|
||||
compress: false,
|
||||
sourceMap: true,
|
||||
sourceMapIn: 'test/integration/index.browserified.js.map',
|
||||
sourceMapIncludeSources: true,
|
||||
@ -417,7 +420,7 @@ module.exports = function(grunt) {
|
||||
tasks: ['dist-css', 'manifest']
|
||||
},
|
||||
js: {
|
||||
files: ['src/js/**/*.js'],
|
||||
files: ['src/js/**/*.js', 'test/unit/*.js', 'test/integration/*.js'],
|
||||
tasks: ['dist-js', 'manifest']
|
||||
},
|
||||
icons: {
|
||||
|
@ -31,6 +31,7 @@ var DialogCtrl = require('./controller/dialog'),
|
||||
ReadCtrl = require('./controller/read'),
|
||||
WriteCtrl = require('./controller/write'),
|
||||
NavigationCtrl = require('./controller/navigation'),
|
||||
ActionBarCtrl = require('./controller/action-bar'),
|
||||
errorUtil = require('./util/error'),
|
||||
backButtonUtil = require('./util/backbutton-handler');
|
||||
require('./directives/common');
|
||||
@ -113,4 +114,5 @@ app.controller('SetPassphraseCtrl', SetPassphraseCtrl);
|
||||
app.controller('PrivateKeyUploadCtrl', PrivateKeyUploadCtrl);
|
||||
app.controller('ContactsCtrl', ContactsCtrl);
|
||||
app.controller('AboutCtrl', AboutCtrl);
|
||||
app.controller('DialogCtrl', DialogCtrl);
|
||||
app.controller('DialogCtrl', DialogCtrl);
|
||||
app.controller('ActionBarCtrl', ActionBarCtrl);
|
168
src/js/controller/action-bar.js
Normal file
168
src/js/controller/action-bar.js
Normal file
@ -0,0 +1,168 @@
|
||||
'use strict';
|
||||
|
||||
var appController = require('../app-controller'),
|
||||
emailDao;
|
||||
|
||||
//
|
||||
// Controller
|
||||
//
|
||||
|
||||
var ActionBarCtrl = function($scope) {
|
||||
|
||||
emailDao = appController._emailDao;
|
||||
|
||||
/**
|
||||
* Move a single message from the currently selected folder to another folder
|
||||
* @param {Object} message The message that is to be moved
|
||||
* @param {Object} destination The folder object where the message should be moved to
|
||||
*/
|
||||
$scope.moveMessage = function(message, destination) {
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
|
||||
// close read state
|
||||
$scope.state.read.open = false;
|
||||
|
||||
$scope.state.mailList.updateStatus('Moving message...');
|
||||
|
||||
emailDao.moveMessage({
|
||||
folder: currentFolder(),
|
||||
destination: destination,
|
||||
message: message
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
// show errors where appropriate
|
||||
if (err.code === 42) {
|
||||
$scope.select(message);
|
||||
$scope.state.mailList.updateStatus('Unable to move message in offline mode!');
|
||||
return;
|
||||
}
|
||||
$scope.state.mailList.updateStatus('Error during move!');
|
||||
$scope.onError(err);
|
||||
return;
|
||||
}
|
||||
$scope.state.mailList.updateStatus('Message moved.');
|
||||
$scope.$apply();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Move all checked messages from the currently selected folder to another folder
|
||||
* @param {Object} destination The folder object where the message should be moved to
|
||||
*/
|
||||
$scope.moveCheckedMessages = function(destination) {
|
||||
getCheckMessages().forEach(function(message) {
|
||||
$scope.moveMessage(message, destination);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a message. This moves the message from the current folder to the trash folder,
|
||||
* or if the current folder is the trash folder, the message will be purged.
|
||||
* @param {Object} message The message that is to be deleted
|
||||
*/
|
||||
$scope.deleteMessage = function(message) {
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
|
||||
// close read state
|
||||
$scope.state.read.open = false;
|
||||
|
||||
$scope.state.mailList.updateStatus('Deleting message...');
|
||||
|
||||
emailDao.deleteMessage({
|
||||
folder: currentFolder(),
|
||||
message: message
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
// show errors where appropriate
|
||||
if (err.code === 42) {
|
||||
$scope.select(message);
|
||||
$scope.state.mailList.updateStatus('Unable to delete message in offline mode!');
|
||||
return;
|
||||
}
|
||||
$scope.state.mailList.updateStatus('Error during delete!');
|
||||
$scope.onError(err);
|
||||
return;
|
||||
}
|
||||
$scope.state.mailList.updateStatus('Message deleted.');
|
||||
$scope.$apply();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete all of the checked messages. This moves the messages from the current folder to the trash folder,
|
||||
* or if the current folder is the trash folder, the messages will be purged.
|
||||
*/
|
||||
$scope.deleteCheckedMessages = function() {
|
||||
getCheckMessages().forEach($scope.deleteMessage);
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark a single message as either read or unread
|
||||
* @param {Object} message The message to be marked
|
||||
* @param {boolean} unread If the message should be marked as read or unread
|
||||
*/
|
||||
$scope.markMessage = function(message, unread) {
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.state.mailList.updateStatus('Updating unread flag...');
|
||||
|
||||
// close read state
|
||||
$scope.state.read.open = false;
|
||||
|
||||
var originalState = message.unread;
|
||||
message.unread = unread;
|
||||
emailDao.setFlags({
|
||||
folder: currentFolder(),
|
||||
message: message
|
||||
}, function(err) {
|
||||
if (err && err.code === 42) {
|
||||
// offline, restore
|
||||
message.unread = originalState;
|
||||
$scope.state.mailList.updateStatus('Unable to mark message in offline mode!');
|
||||
return;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
$scope.state.mailList.updateStatus('Error on sync!');
|
||||
$scope.onError(err);
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.state.mailList.updateStatus('Online');
|
||||
$scope.$apply();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark all of the checked messages as either read or unread.
|
||||
* @param {boolean} unread If the message should be marked as read or unread
|
||||
*/
|
||||
$scope.markCheckedMessages = function(unread) {
|
||||
getCheckMessages().forEach(function(message) {
|
||||
$scope.markMessage(message, unread);
|
||||
});
|
||||
};
|
||||
|
||||
// share local scope functions with root state
|
||||
$scope.state.actionBar = {
|
||||
markMessage: $scope.markMessage
|
||||
};
|
||||
|
||||
function currentFolder() {
|
||||
return $scope.state.nav.currentFolder;
|
||||
}
|
||||
|
||||
function getCheckMessages() {
|
||||
return currentFolder().messages.filter(function(message) {
|
||||
return message.checked;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = ActionBarCtrl;
|
@ -97,74 +97,13 @@ var MailListCtrl = function($scope, $routeParams) {
|
||||
}
|
||||
}
|
||||
|
||||
$scope.toggleUnread(email);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark an email as unread or read, respectively
|
||||
*/
|
||||
$scope.toggleUnread = function(message) {
|
||||
updateStatus('Updating unread flag...');
|
||||
|
||||
message.unread = !message.unread;
|
||||
emailDao.setFlags({
|
||||
folder: currentFolder(),
|
||||
message: message
|
||||
}, function(err) {
|
||||
if (err && err.code === 42) {
|
||||
// offline, restore
|
||||
message.unread = !message.unread;
|
||||
updateStatus('Unable to mark unread flag in offline mode!');
|
||||
return;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
updateStatus('Error on sync!');
|
||||
$scope.onError(err);
|
||||
return;
|
||||
}
|
||||
|
||||
updateStatus('Online');
|
||||
$scope.$apply();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a message
|
||||
*/
|
||||
$scope.remove = function(message) {
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateStatus('Deleting message...');
|
||||
remove();
|
||||
|
||||
function remove() {
|
||||
emailDao.deleteMessage({
|
||||
folder: currentFolder(),
|
||||
message: message
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
// show errors where appropriate
|
||||
if (err.code === 42) {
|
||||
$scope.select(message);
|
||||
updateStatus('Unable to delete message in offline mode!');
|
||||
return;
|
||||
}
|
||||
updateStatus('Error during delete!');
|
||||
$scope.onError(err);
|
||||
}
|
||||
updateStatus('Message deleted!');
|
||||
$scope.$apply();
|
||||
});
|
||||
$scope.state.actionBar.markMessage(email, false);
|
||||
}
|
||||
};
|
||||
|
||||
// share local scope functions with root state
|
||||
$scope.state.mailList = {
|
||||
remove: $scope.remove
|
||||
updateStatus: updateStatus
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -132,6 +132,10 @@
|
||||
}
|
||||
&__folders + .nav__folders {
|
||||
border-top-color: $color-border-light;
|
||||
|
||||
.nav__folder {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
&__folder {
|
||||
font-size: $font-size-base;
|
||||
@ -151,9 +155,6 @@
|
||||
top: 0.25em;
|
||||
}
|
||||
}
|
||||
&__folder__other {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
&__counter {
|
||||
display: inline;
|
||||
position: static;
|
||||
|
@ -1,18 +1,20 @@
|
||||
<div class="action-bar">
|
||||
<div class="action-bar" ng-controller="ActionBarCtrl">
|
||||
<div class="action-bar__primary">
|
||||
<button class="btn btn--light">Delete</button>
|
||||
<button class="btn btn--light">Spam</button>
|
||||
<button class="btn btn--light" wo-touch="state.read.open ? deleteMessage(state.mailList.selected) : deleteCheckedMessages()">Delete</button>
|
||||
<button class="btn btn--light" disabled>Spam</button>
|
||||
<button class="btn btn--light-dropdown" wo-dropdown="#dropdown-folder">
|
||||
<svg><use xlink:href="#icon-folder" /><title>Folder</title></svg>
|
||||
<svg class="btn__dropdown" role="presentation"><use xlink:href="#icon-dropdown" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div><!--/action-bar__primary-->
|
||||
|
||||
<div class="action-bar__secondary">
|
||||
<button class="btn btn--light-dropdown" wo-dropdown="#dropdown-more">
|
||||
More
|
||||
<svg class="btn__dropdown" role="presentation"><use xlink:href="#icon-dropdown" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div><!--/action-bar__secondary-->
|
||||
|
||||
<div class="action-bar__search">
|
||||
<div class="search">
|
||||
<svg><use xlink:href="#icon-search" /><title>Search</title></svg>
|
||||
@ -20,15 +22,20 @@
|
||||
ng-change="displaySearchResults(searchText)"
|
||||
placeholder="Search" focus-me="state.mailList.searching">
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/action-bar__search-->
|
||||
|
||||
<!-- dropdowns -->
|
||||
<ul id="dropdown-folder" class="dropdown">
|
||||
<li><button><svg><use xlink:href="#icon-folder" /></svg> Lorem</button></li>
|
||||
<li><button><svg><use xlink:href="#icon-folder" /></svg> Ipsum</button></li>
|
||||
</ul>
|
||||
<li ng-repeat="folder in account.folders">
|
||||
<button wo-touch="state.read.open ? moveMessage(state.mailList.selected, folder) : moveCheckedMessages(folder)">
|
||||
<svg><use xlink:href="#icon-folder" /></svg>
|
||||
{{folder.wellknown ? folder.type : folder.name}}
|
||||
</button>
|
||||
</li>
|
||||
</ul><!--/dropdown-->
|
||||
|
||||
<ul id="dropdown-more" class="dropdown">
|
||||
<li><button>Mark as read</button></li>
|
||||
<li><button>Mark as unread</button></li>
|
||||
</ul>
|
||||
<li><button wo-touch="state.read.open ? markMessage(state.mailList.selected, false) : markCheckedMessages(false)">Mark as read</button></li>
|
||||
<li><button wo-touch="state.read.open ? markMessage(state.mailList.selected, true) : markCheckedMessages(true)">Mark as unread</button></li>
|
||||
</ul><!--/dropdown-->
|
||||
</div>
|
||||
|
@ -30,9 +30,9 @@
|
||||
ng-repeat="email in displayMessages">
|
||||
<ul class="mail-list-entry__flags">
|
||||
<li class="mail-list-entry__flags-unread"></li>
|
||||
<li class="mail-list-entry__flags-checked">
|
||||
<li class="mail-list-entry__flags-checked" wo-touch="$event.stopPropagation()">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox">
|
||||
<input type="checkbox" ng-model="email.checked">
|
||||
<span><svg role="presentation"><use xlink:href="#icon-check" /></svg></span>
|
||||
</label>
|
||||
</li>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<ul class="nav__folders">
|
||||
<li ng-repeat="folder in account.folders" ng-if="folder.wellknown" ng-hide="folder.type === 'Outbox' && folder.count < 1"
|
||||
class="nav__folder" ng-class="{'nav__folder--open': state.nav.currentFolder === folder}">
|
||||
<a href="javascript:;" wo-touch="openFolder(folder)">
|
||||
<a href="#" wo-touch="$event.preventDefault(); openFolder(folder)">
|
||||
<svg role="presentation">
|
||||
<use ng-if="folder.type === 'Inbox'" xlink:href="#icon-inbox" />
|
||||
<use ng-if="folder.type === 'Sent'" xlink:href="#icon-sent" />
|
||||
@ -26,9 +26,9 @@
|
||||
</ul><!--/nav__folders-->
|
||||
|
||||
<ul class="nav__folders">
|
||||
<li ng-repeat="folder in account.folders | orderBy:folder.name" ng-if="!folder.wellknown"
|
||||
class="nav__folder nav__folder__other" ng-class="{'nav__folder--open': state.nav.currentFolder === folder}">
|
||||
<a href="javascript:;" wo-touch="openFolder(folder)">
|
||||
<li ng-repeat="folder in account.folders" ng-if="!folder.wellknown"
|
||||
class="nav__folder" ng-class="{'nav__folder--open': state.nav.currentFolder === folder}">
|
||||
<a href="#" wo-touch="$event.preventDefault(); openFolder(folder)">
|
||||
<svg role="presentation"><use xlink:href="#icon-folder" /></svg>
|
||||
{{folder.name}}
|
||||
<span ng-show="folder.count > 0" class="nav__counter">{{folder.count}}</span>
|
||||
@ -38,32 +38,32 @@
|
||||
|
||||
<ul class="nav__secondary">
|
||||
<li>
|
||||
<a href="javascript:;" wo-touch="state.account.toggle(true)">
|
||||
<a href="#" wo-touch="$event.preventDefault(); state.account.toggle(true)">
|
||||
<svg role="presentation"><use xlink:href="#icon-account" /></svg> Account
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:;" wo-touch="state.contacts.toggle(true)">
|
||||
<a href="#" wo-touch="$event.preventDefault(); state.contacts.toggle(true)">
|
||||
<svg role="presentation"><use xlink:href="#icon-contact" /></svg> Contacts
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:;" wo-touch="state.privateKeyUpload.toggle(true)">
|
||||
<a href="#" wo-touch="$event.preventDefault(); state.privateKeyUpload.toggle(true)">
|
||||
<svg role="presentation"><use xlink:href="#icon-key" /></svg> Key sync (experimental)
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:;" wo-touch="state.writer.reportBug()">
|
||||
<a href="#" wo-touch="$event.preventDefault(); state.writer.reportBug()">
|
||||
<svg role="presentation"><use xlink:href="#icon-bug" /></svg> Report a bug
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:;" wo-touch="state.about.toggle(true)">
|
||||
<a href="#" wo-touch="$event.preventDefault(); state.about.toggle(true)">
|
||||
<svg role="presentation"><use xlink:href="#icon-about" /></svg> About
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:;" wo-touch="logout()">
|
||||
<a href="#" wo-touch="$event.preventDefault(); logout()">
|
||||
<svg role="presentation"><use xlink:href="#icon-account" /></svg> Logout
|
||||
</a>
|
||||
</li>
|
||||
|
@ -11,8 +11,9 @@
|
||||
{{state.nav.currentFolder.wellknown ? state.nav.currentFolder.type : state.nav.currentFolder.name}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="read__action-toolbar">
|
||||
</div><!--/read__folder-toolbar-->
|
||||
|
||||
<div class="read__action-toolbar" ng-controller="ActionBarCtrl">
|
||||
<div class="toolbar">
|
||||
<ul class="toolbar__actions">
|
||||
<li>
|
||||
@ -32,7 +33,7 @@
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button wo-touch="state.mailList.remove(state.mailList.selected)" class="btn-icon-light" title="Delete mail">
|
||||
<button wo-touch="deleteMessage(state.mailList.selected)" class="btn-icon-light" title="Delete mail">
|
||||
<svg><use xlink:href="#icon-trash" /><title>Delete mail</title></svg>
|
||||
</button>
|
||||
</li>
|
||||
@ -51,13 +52,14 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/read__action-toolbar-->
|
||||
|
||||
<header class="read__header">
|
||||
<div class="read__controls">
|
||||
<button class="btn-icon-light" wo-touch="state.writer.write(state.mailList.selected)" title="Reply"><svg><use xlink:href="#icon-reply_light" /></svg></button>
|
||||
<button class="btn-icon-light" wo-touch="state.writer.write(state.mailList.selected, true)" title="Reply All"><svg><use xlink:href="#icon-reply_all_light" /></svg></button>
|
||||
<button class="btn-icon-light" wo-touch="state.writer.write(state.mailList.selected, null, true)" title="Forward"><svg><use xlink:href="#icon-forward_light" /></svg></button>
|
||||
</div>
|
||||
</div><!--/read__controls-->
|
||||
|
||||
<h2 class="read__subject" wo-touch="notStripped = !notStripped">
|
||||
<button ng-hide="notStripped" class="btn-icon-very-light">
|
||||
@ -114,7 +116,7 @@
|
||||
{{attachment.filename}}
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
</header><!--/read__header-->
|
||||
|
||||
<!-- working spinner -->
|
||||
<div class="read__working"
|
||||
@ -140,7 +142,7 @@
|
||||
<iframe sandbox="allow-popups allow-scripts" src="tpl/read-sandbox.html"
|
||||
frame-load>
|
||||
</iframe>
|
||||
</div>
|
||||
</div><!--/read__body-->
|
||||
|
||||
<!-- tooltips -->
|
||||
<div id="fingerprint-info" class="tooltip">
|
||||
@ -153,10 +155,15 @@
|
||||
<li><button wo-touch="state.writer.write(state.mailList.selected)"><svg><use xlink:href="#icon-reply_light" /></svg> Reply</button></li>
|
||||
<li><button wo-touch="state.writer.write(state.mailList.selected, true)"><svg><use xlink:href="#icon-reply_all_light" /></svg> Reply All</button></li>
|
||||
<li><button wo-touch="state.writer.write(state.mailList.selected, null, true)"><svg><use xlink:href="#icon-forward_light" /></svg> Forward</button></li>
|
||||
</ul>
|
||||
<ul id="read-dropdown-folder" class="dropdown">
|
||||
<li><button><svg><use xlink:href="#icon-folder" /></svg> Lorem</button></li>
|
||||
<li><button><svg><use xlink:href="#icon-folder" /></svg> Ipsum</button></li>
|
||||
</ul>
|
||||
</ul><!--/dropdown-->
|
||||
|
||||
<ul id="read-dropdown-folder" class="dropdown" ng-controller="ActionBarCtrl">
|
||||
<li ng-repeat="folder in account.folders">
|
||||
<button wo-touch="moveMessage(state.mailList.selected, folder)">
|
||||
<svg><use xlink:href="#icon-folder" /></svg>
|
||||
{{folder.wellknown ? folder.type : folder.name}}
|
||||
</button>
|
||||
</li>
|
||||
</ul><!--/dropdown-->
|
||||
|
||||
</div>
|
||||
|
149
test/unit/action-bar-ctrl-test.js
Normal file
149
test/unit/action-bar-ctrl-test.js
Normal file
@ -0,0 +1,149 @@
|
||||
'use strict';
|
||||
|
||||
var mocks = angular.mock,
|
||||
EmailDAO = require('../../src/js/dao/email-dao'),
|
||||
appController = require('../../src/js/app-controller'),
|
||||
ActionBarCtrl = require('../../src/js/controller/action-bar');
|
||||
|
||||
describe('Action Bar Controller unit test', function() {
|
||||
var scope, actionBarCtrl, emailDaoMock, origEmailDao;
|
||||
|
||||
beforeEach(function() {
|
||||
origEmailDao = appController._emailDao;
|
||||
emailDaoMock = sinon.createStubInstance(EmailDAO);
|
||||
appController._emailDao = emailDaoMock;
|
||||
|
||||
angular.module('actionbartest', []);
|
||||
mocks.module('actionbartest');
|
||||
mocks.inject(function($rootScope, $controller) {
|
||||
scope = $rootScope.$new();
|
||||
scope.state = {
|
||||
mailList: {
|
||||
updateStatus: function() {}
|
||||
}
|
||||
};
|
||||
|
||||
scope.state.nav = {
|
||||
currentFolder: {
|
||||
type: 'Inbox',
|
||||
path: 'INBOX',
|
||||
messages: [{
|
||||
checked: true
|
||||
}, {
|
||||
checked: false
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
scope.state.read = {
|
||||
open: true
|
||||
};
|
||||
|
||||
actionBarCtrl = $controller(ActionBarCtrl, {
|
||||
$scope: scope
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
// restore the module
|
||||
appController._emailDao = origEmailDao;
|
||||
});
|
||||
|
||||
describe('deleteMessage', function() {
|
||||
it('should not delete without a selected mail', function() {
|
||||
scope.deleteMessage();
|
||||
});
|
||||
|
||||
it('should delete the selected mail', function() {
|
||||
emailDaoMock.deleteMessage.yields();
|
||||
|
||||
scope.deleteMessage({});
|
||||
|
||||
expect(emailDaoMock.deleteMessage.calledOnce).to.be.true;
|
||||
expect(scope.state.read.open).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteCheckedMessages', function() {
|
||||
var deleteMessageStub;
|
||||
|
||||
beforeEach(function() {
|
||||
deleteMessageStub = sinon.stub(scope, 'deleteMessage');
|
||||
});
|
||||
afterEach(function() {
|
||||
deleteMessageStub.restore();
|
||||
});
|
||||
|
||||
it('should delete the selected mail', function() {
|
||||
scope.deleteCheckedMessages();
|
||||
|
||||
expect(deleteMessageStub.calledOnce).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('moveMessage', function() {
|
||||
it('should not move without a selected mail', function() {
|
||||
scope.moveMessage();
|
||||
});
|
||||
|
||||
it('should move the selected mail', function() {
|
||||
emailDaoMock.moveMessage.yields();
|
||||
|
||||
scope.moveMessage({}, {});
|
||||
|
||||
expect(emailDaoMock.moveMessage.calledOnce).to.be.true;
|
||||
expect(scope.state.read.open).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('moveCheckedMessages', function() {
|
||||
var moveMessageStub;
|
||||
|
||||
beforeEach(function() {
|
||||
moveMessageStub = sinon.stub(scope, 'moveMessage');
|
||||
});
|
||||
afterEach(function() {
|
||||
moveMessageStub.restore();
|
||||
});
|
||||
|
||||
it('should delete the selected mail', function() {
|
||||
scope.moveCheckedMessages();
|
||||
|
||||
expect(moveMessageStub.calledOnce).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('markMessage', function() {
|
||||
it('should not move without a selected mail', function() {
|
||||
scope.markMessage();
|
||||
});
|
||||
|
||||
it('should move the selected mail', function() {
|
||||
emailDaoMock.setFlags.yields();
|
||||
|
||||
scope.markMessage({}, true);
|
||||
|
||||
expect(emailDaoMock.setFlags.calledOnce).to.be.true;
|
||||
expect(scope.state.read.open).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('markCheckedMessages', function() {
|
||||
var markMessageStub;
|
||||
|
||||
beforeEach(function() {
|
||||
markMessageStub = sinon.stub(scope, 'markMessage');
|
||||
});
|
||||
afterEach(function() {
|
||||
markMessageStub.restore();
|
||||
});
|
||||
|
||||
it('should delete the selected mail', function() {
|
||||
scope.markCheckedMessages();
|
||||
|
||||
expect(markMessageStub.calledOnce).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@ -29,7 +29,9 @@
|
||||
if (window.mochaPhantomJS) {
|
||||
mochaPhantomJS.run();
|
||||
} else {
|
||||
mocha.run();
|
||||
setTimeout(function() {
|
||||
mocha.run();
|
||||
}, 1000)
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
@ -241,7 +241,6 @@ describe('Mail List controller unit test', function() {
|
||||
describe('scope variables', function() {
|
||||
it('should be set correctly', function() {
|
||||
expect(scope.select).to.exist;
|
||||
expect(scope.remove).to.exist;
|
||||
expect(scope.state.mailList).to.exist;
|
||||
});
|
||||
});
|
||||
@ -361,6 +360,9 @@ describe('Mail List controller unit test', function() {
|
||||
mailList: {},
|
||||
read: {
|
||||
toggle: function() {}
|
||||
},
|
||||
actionBar: {
|
||||
markMessage: function() {}
|
||||
}
|
||||
};
|
||||
|
||||
@ -399,7 +401,9 @@ describe('Mail List controller unit test', function() {
|
||||
}
|
||||
};
|
||||
|
||||
keychainMock.refreshKeyForUserId.withArgs({userId: mail.from[0].address}).yields();
|
||||
keychainMock.refreshKeyForUserId.withArgs({
|
||||
userId: mail.from[0].address
|
||||
}).yields();
|
||||
|
||||
scope.select(mail);
|
||||
|
||||
@ -408,42 +412,4 @@ describe('Mail List controller unit test', function() {
|
||||
expect(scope.state.mailList.selected).to.equal(mail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove', function() {
|
||||
it('should not delete without a selected mail', function() {
|
||||
scope.remove();
|
||||
});
|
||||
|
||||
it('should delete the selected mail', function() {
|
||||
var uid, mail, currentFolder;
|
||||
|
||||
scope._stopWatchTask();
|
||||
|
||||
scope.account = {};
|
||||
uid = 123;
|
||||
mail = {
|
||||
uid: uid,
|
||||
from: [{
|
||||
address: 'asd'
|
||||
}],
|
||||
subject: '[whiteout] asdasd',
|
||||
unread: true
|
||||
};
|
||||
currentFolder = {
|
||||
type: 'Inbox',
|
||||
path: 'INBOX',
|
||||
messages: [mail]
|
||||
};
|
||||
scope.account.folders = [currentFolder];
|
||||
scope.state.nav = {
|
||||
currentFolder: currentFolder
|
||||
};
|
||||
emailDaoMock.deleteMessage.yields();
|
||||
|
||||
scope.remove(mail);
|
||||
|
||||
expect(emailDaoMock.deleteMessage.calledOnce).to.be.true;
|
||||
expect(scope.state.mailList.selected).to.exist;
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user