summaryrefslogtreecommitdiffstats
path: root/js
diff options
context:
space:
mode:
authorBernhard Posselt <nukeawhale@gmail.com>2013-04-22 16:05:45 +0200
committerBernhard Posselt <nukeawhale@gmail.com>2013-04-22 16:05:45 +0200
commitb9099435cb6535db835d25361e7b706b85744b20 (patch)
tree2a681b1f9ff0de9780f1f4a785be8378d7f577ab /js
parentac5c8f5f4faae74c034a5cfd1e7f85ca26815bc5 (diff)
add undo for feed and folder deletion, fix #56
Diffstat (limited to 'js')
-rw-r--r--js/app/directives/undonotification.coffee52
-rw-r--r--js/app/services/businesslayer/feedbusinesslayer.coffee21
-rw-r--r--js/app/services/businesslayer/folderbusinesslayer.coffee19
-rw-r--r--js/app/services/models/feedmodel.coffee3
-rw-r--r--js/app/services/undoqueue.coffee86
-rw-r--r--js/public/app.js207
-rw-r--r--js/tests/services/businesslayer/feedbusinesslayerSpec.coffee8
-rw-r--r--js/tests/services/businesslayer/folderbusinesslayerSpec.coffee6
-rw-r--r--js/tests/services/undoqueueSpec.coffee59
9 files changed, 434 insertions, 27 deletions
diff --git a/js/app/directives/undonotification.coffee b/js/app/directives/undonotification.coffee
new file mode 100644
index 000000000..5e30af169
--- /dev/null
+++ b/js/app/directives/undonotification.coffee
@@ -0,0 +1,52 @@
+###
+
+ownCloud - News
+
+@author Bernhard Posselt
+@copyright 2012 Bernhard Posselt nukeawhale@gmail.com
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+License as published by the Free Software Foundation; either
+version 3 of the License, or any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+
+You should have received a copy of the GNU Affero General Public
+License along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+###
+
+angular.module('News').directive 'undoNotification', ['$rootScope',
+($rootScope) ->
+
+ return (scope, elm, attr) ->
+
+ elm.click ->
+ $(@).fadeOut()
+
+ scope.$on 'notUndone', ->
+ $(elm).fadeOut()
+
+ undo = ->
+ caption = ''
+
+ link = $(elm).find('a')
+ link.click ->
+ undo()
+ $rootScope.$apply()
+ elm.fadeOut()
+
+ scope.getCaption = ->
+ return caption
+
+ scope.$on 'undoMessage', (scope, data) ->
+ undo = data.undoCallback
+ caption = data.caption
+ elm.fadeIn().css("display","inline")
+
+
+] \ No newline at end of file
diff --git a/js/app/services/businesslayer/feedbusinesslayer.coffee b/js/app/services/businesslayer/feedbusinesslayer.coffee
index 9d2f37390..93f89ad31 100644
--- a/js/app/services/businesslayer/feedbusinesslayer.coffee
+++ b/js/app/services/businesslayer/feedbusinesslayer.coffee
@@ -23,14 +23,16 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
angular.module('News').factory 'FeedBusinessLayer',
['_BusinessLayer', 'ShowAll', 'Persistence', 'ActiveFeed', 'FeedType',
-'ItemModel', 'FeedModel', 'NewLoading', '_ExistsError', 'Utils',
+'ItemModel', 'FeedModel', 'NewLoading', '_ExistsError', 'Utils', '$rootScope',
+'UndoQueue',
(_BusinessLayer, ShowAll, Persistence, ActiveFeed, FeedType, ItemModel,
-FeedModel, NewLoading, _ExistsError, Utils) ->
+FeedModel, NewLoading, _ExistsError, Utils, $rootScope, UndoQueue) ->
class FeedBusinessLayer extends _BusinessLayer
constructor: (@_showAll, @_feedModel, persistence, activeFeed, feedType,
- itemModel, @_newLoading, @_utils) ->
+ itemModel, @_newLoading, @_utils, @_$rootScope,
+ @_undoQueue) ->
super(activeFeed, persistence, itemModel, feedType.Feed)
@_feedType = feedType
@@ -52,8 +54,14 @@ FeedModel, NewLoading, _ExistsError, Utils) ->
delete: (feedId) ->
- @_feedModel.removeById(feedId)
- @_persistence.deleteFeed(feedId)
+ feed = @_feedModel.removeById(feedId)
+ callback = =>
+ @_persistence.deleteFeed(feedId)
+
+ undoCallback = =>
+ @_feedModel.add(feed)
+
+ @_undoQueue.add(feed.title, callback, 10*1000, undoCallback)
markFeedRead: (feedId) ->
@@ -185,6 +193,7 @@ FeedModel, NewLoading, _ExistsError, Utils) ->
return new FeedBusinessLayer(ShowAll, FeedModel, Persistence, ActiveFeed,
- FeedType, ItemModel, NewLoading, Utils)
+ FeedType, ItemModel, NewLoading, Utils,
+ $rootScope, UndoQueue)
] \ No newline at end of file
diff --git a/js/app/services/businesslayer/folderbusinesslayer.coffee b/js/app/services/businesslayer/folderbusinesslayer.coffee
index d19796d85..e35866f21 100644
--- a/js/app/services/businesslayer/folderbusinesslayer.coffee
+++ b/js/app/services/businesslayer/folderbusinesslayer.coffee
@@ -24,22 +24,31 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
angular.module('News').factory 'FolderBusinessLayer',
['_BusinessLayer', 'FolderModel', 'FeedBusinessLayer', 'Persistence',
'FeedType', 'ActiveFeed', 'ItemModel', 'ShowAll', '_ExistsError', 'OPMLParser',
+'UndoQueue',
(_BusinessLayer, FolderModel, FeedBusinessLayer, Persistence, FeedType,
-ActiveFeed, ItemModel, ShowAll, _ExistsError, OPMLParser) ->
+ActiveFeed, ItemModel, ShowAll, _ExistsError, OPMLParser, UndoQueue) ->
class FolderBusinessLayer extends _BusinessLayer
constructor: (@_folderModel, @_feedBusinessLayer, @_showAll, activeFeed,
- persistence, @_feedType, itemModel, @_opmlParser) ->
+ persistence, @_feedType, itemModel, @_opmlParser,
+ @_undoQueue) ->
super(activeFeed, persistence, itemModel, @_feedType.Folder)
getById: (folderId) ->
return @_folderModel.getById(folderId)
+
delete: (folderId) ->
- @_folderModel.removeById(folderId)
- @_persistence.deleteFolder(folderId)
+ folder = @_folderModel.removeById(folderId)
+ callback = =>
+ @_persistence.deleteFolder(folderId)
+
+ undoCallback = =>
+ @_folderModel.add(folder)
+
+ @_undoQueue.add(folder.name, callback, 10*1000, undoCallback)
hasFeeds: (folderId) ->
@@ -155,6 +164,6 @@ ActiveFeed, ItemModel, ShowAll, _ExistsError, OPMLParser) ->
return new FolderBusinessLayer(FolderModel, FeedBusinessLayer, ShowAll,
ActiveFeed, Persistence, FeedType, ItemModel,
- OPMLParser)
+ OPMLParser, UndoQueue)
] \ No newline at end of file
diff --git a/js/app/services/models/feedmodel.coffee b/js/app/services/models/feedmodel.coffee
index 4c925b94c..bddd647d3 100644
--- a/js/app/services/models/feedmodel.coffee
+++ b/js/app/services/models/feedmodel.coffee
@@ -40,7 +40,8 @@ angular.module('News').factory 'FeedModel',
if data.faviconLink == null
data.faviconLink = 'url(' +
@_utils.imagePath('news', 'rss.svg') + ')'
- else if angular.isDefined(data.faviconLink)
+ else if angular.isDefined(data.faviconLink) and
+ data.faviconLink.indexOf('url(') != 0
data.faviconLink = 'url(' + data.faviconLink + ')'
###
We want to add a feed on the client side before
diff --git a/js/app/services/undoqueue.coffee b/js/app/services/undoqueue.coffee
new file mode 100644
index 000000000..30418bacf
--- /dev/null
+++ b/js/app/services/undoqueue.coffee
@@ -0,0 +1,86 @@
+###
+
+ownCloud - App Framework
+
+@author Bernhard Posselt
+@copyright 2012 Bernhard Posselt nukeawhale@gmail.com
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+License as published by the Free Software Foundation; either
+version 3 of the License, or any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+
+You should have received a copy of the GNU Affero General Public
+License along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+###
+
+# A class which follows the command pattern
+# Can be used for actions that need need to be able to undo like folder deletion
+angular.module('News').factory 'UndoQueue',
+['$timeout', '$rootScope',
+($timeout, $rootScope) ->
+
+ class UndoQueue
+
+ constructor: (@_$timeout, @_$rootScope) ->
+ @_queue = []
+
+
+ add: (@_caption, @_callback, @_timeout=0, @_undoCallback=null) ->
+ ###
+ @_caption the caption which indentifies the item
+ @_callback function the callback which should be executed when it was
+ not undone, this will usually be a request to the server to finally
+ delete something
+ @_timeout int the timeout after the callback should be executed
+ defaults to 0
+ @_undoCallback function the function which should be executed when
+ an command has been canceled. Usually this will add back a deleted
+ object back to the interface, defaults to an empty function
+ ###
+ @_executeAll()
+
+ command =
+ _undoCallback: @_undoCallback or= ->
+ _callback: @_callback
+ execute: =>
+ command._callback()
+ undo: =>
+ command._undoCallback()
+ @_$timeout.cancel(command.promise)
+ @_queue = []
+ promise: @_$timeout =>
+ command.execute()
+ @_$rootScope.$broadcast('notUndone')
+ , @_timeout
+
+ data =
+ undoCallback: command.undo
+ caption: @_caption
+
+ @_$rootScope.$broadcast 'undoMessage', data
+
+ @_queue.push(command)
+
+
+ _executeAll: ->
+ ###
+ Executes the callback before the timeout has run out
+ This is useful to execute all remaining commands if a new command is
+ added
+ ###
+ for command in @_queue
+ @_$timeout.cancel(command.promise)
+ command.execute()
+ @_queue = []
+
+
+ return new UndoQueue($timeout, $rootScope)
+
+] \ No newline at end of file
diff --git a/js/public/app.js b/js/public/app.js
index 38c2c6219..ca7124ad7 100644
--- a/js/public/app.js
+++ b/js/public/app.js
@@ -313,6 +313,63 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
(function() {
+ angular.module('News').directive('undoNotification', [
+ '$rootScope', function($rootScope) {
+ return function(scope, elm, attr) {
+ var caption, link, undo;
+
+ elm.click(function() {
+ return $(this).fadeOut();
+ });
+ scope.$on('notUndone', function() {
+ return $(elm).fadeOut();
+ });
+ undo = function() {};
+ caption = '';
+ link = $(elm).find('a');
+ link.click(function() {
+ undo();
+ $rootScope.$apply();
+ return elm.fadeOut();
+ });
+ scope.getCaption = function() {
+ return caption;
+ };
+ return scope.$on('undoMessage', function(scope, data) {
+ undo = data.undoCallback;
+ caption = data.caption;
+ return elm.fadeIn().css("display", "inline");
+ });
+ };
+ }
+ ]);
+
+}).call(this);
+
+// Generated by CoffeeScript 1.6.2
+/*
+
+ownCloud - News
+
+@author Bernhard Posselt
+@copyright 2012 Bernhard Posselt nukeawhale@gmail.com
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+License as published by the Free Software Foundation; either
+version 3 of the License, or any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+
+You should have received a copy of the GNU Affero General Public
+License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+(function() {
angular.module('News').controller('FeedController', [
'$scope', '_ExistsError', 'Persistence', 'FolderBusinessLayer', 'FeedBusinessLayer', 'SubscriptionsBusinessLayer', 'StarredBusinessLayer', 'unreadCountFormatter', 'ActiveFeed', 'FeedType', '$window', function($scope, _ExistsError, Persistence, FolderBusinessLayer, FeedBusinessLayer, SubscriptionsBusinessLayer, StarredBusinessLayer, unreadCountFormatter, ActiveFeed, FeedType, $window) {
var FeedController;
@@ -711,17 +768,19 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
angular.module('News').factory('FeedBusinessLayer', [
- '_BusinessLayer', 'ShowAll', 'Persistence', 'ActiveFeed', 'FeedType', 'ItemModel', 'FeedModel', 'NewLoading', '_ExistsError', 'Utils', function(_BusinessLayer, ShowAll, Persistence, ActiveFeed, FeedType, ItemModel, FeedModel, NewLoading, _ExistsError, Utils) {
+ '_BusinessLayer', 'ShowAll', 'Persistence', 'ActiveFeed', 'FeedType', 'ItemModel', 'FeedModel', 'NewLoading', '_ExistsError', 'Utils', '$rootScope', 'UndoQueue', function(_BusinessLayer, ShowAll, Persistence, ActiveFeed, FeedType, ItemModel, FeedModel, NewLoading, _ExistsError, Utils, $rootScope, UndoQueue) {
var FeedBusinessLayer;
FeedBusinessLayer = (function(_super) {
__extends(FeedBusinessLayer, _super);
- function FeedBusinessLayer(_showAll, _feedModel, persistence, activeFeed, feedType, itemModel, _newLoading, _utils) {
+ function FeedBusinessLayer(_showAll, _feedModel, persistence, activeFeed, feedType, itemModel, _newLoading, _utils, _$rootScope, _undoQueue) {
this._showAll = _showAll;
this._feedModel = _feedModel;
this._newLoading = _newLoading;
this._utils = _utils;
+ this._$rootScope = _$rootScope;
+ this._undoQueue = _undoQueue;
FeedBusinessLayer.__super__.constructor.call(this, activeFeed, persistence, itemModel, feedType.Feed);
this._feedType = feedType;
}
@@ -743,8 +802,17 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
};
FeedBusinessLayer.prototype["delete"] = function(feedId) {
- this._feedModel.removeById(feedId);
- return this._persistence.deleteFeed(feedId);
+ var callback, feed, undoCallback,
+ _this = this;
+
+ feed = this._feedModel.removeById(feedId);
+ callback = function() {
+ return _this._persistence.deleteFeed(feedId);
+ };
+ undoCallback = function() {
+ return _this._feedModel.add(feed);
+ };
+ return this._undoQueue.add(feed.title, callback, 10 * 1000, undoCallback);
};
FeedBusinessLayer.prototype.markFeedRead = function(feedId) {
@@ -912,7 +980,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
return FeedBusinessLayer;
})(_BusinessLayer);
- return new FeedBusinessLayer(ShowAll, FeedModel, Persistence, ActiveFeed, FeedType, ItemModel, NewLoading, Utils);
+ return new FeedBusinessLayer(ShowAll, FeedModel, Persistence, ActiveFeed, FeedType, ItemModel, NewLoading, Utils, $rootScope, UndoQueue);
}
]);
@@ -946,18 +1014,19 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
angular.module('News').factory('FolderBusinessLayer', [
- '_BusinessLayer', 'FolderModel', 'FeedBusinessLayer', 'Persistence', 'FeedType', 'ActiveFeed', 'ItemModel', 'ShowAll', '_ExistsError', 'OPMLParser', function(_BusinessLayer, FolderModel, FeedBusinessLayer, Persistence, FeedType, ActiveFeed, ItemModel, ShowAll, _ExistsError, OPMLParser) {
+ '_BusinessLayer', 'FolderModel', 'FeedBusinessLayer', 'Persistence', 'FeedType', 'ActiveFeed', 'ItemModel', 'ShowAll', '_ExistsError', 'OPMLParser', 'UndoQueue', function(_BusinessLayer, FolderModel, FeedBusinessLayer, Persistence, FeedType, ActiveFeed, ItemModel, ShowAll, _ExistsError, OPMLParser, UndoQueue) {
var FolderBusinessLayer;
FolderBusinessLayer = (function(_super) {
__extends(FolderBusinessLayer, _super);
- function FolderBusinessLayer(_folderModel, _feedBusinessLayer, _showAll, activeFeed, persistence, _feedType, itemModel, _opmlParser) {
+ function FolderBusinessLayer(_folderModel, _feedBusinessLayer, _showAll, activeFeed, persistence, _feedType, itemModel, _opmlParser, _undoQueue) {
this._folderModel = _folderModel;
this._feedBusinessLayer = _feedBusinessLayer;
this._showAll = _showAll;
this._feedType = _feedType;
this._opmlParser = _opmlParser;
+ this._undoQueue = _undoQueue;
FolderBusinessLayer.__super__.constructor.call(this, activeFeed, persistence, itemModel, this._feedType.Folder);
}
@@ -966,8 +1035,17 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
};
FolderBusinessLayer.prototype["delete"] = function(folderId) {
- this._folderModel.removeById(folderId);
- return this._persistence.deleteFolder(folderId);
+ var callback, folder, undoCallback,
+ _this = this;
+
+ folder = this._folderModel.removeById(folderId);
+ callback = function() {
+ return _this._persistence.deleteFolder(folderId);
+ };
+ undoCallback = function() {
+ return _this._folderModel.add(folder);
+ };
+ return this._undoQueue.add(folder.name, callback, 10 * 1000, undoCallback);
};
FolderBusinessLayer.prototype.hasFeeds = function(folderId) {
@@ -1136,7 +1214,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
return FolderBusinessLayer;
})(_BusinessLayer);
- return new FolderBusinessLayer(FolderModel, FeedBusinessLayer, ShowAll, ActiveFeed, Persistence, FeedType, ItemModel, OPMLParser);
+ return new FolderBusinessLayer(FolderModel, FeedBusinessLayer, ShowAll, ActiveFeed, Persistence, FeedType, ItemModel, OPMLParser, UndoQueue);
}
]);
@@ -1626,7 +1704,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
}
if (data.faviconLink === null) {
data.faviconLink = 'url(' + this._utils.imagePath('news', 'rss.svg') + ')';
- } else if (angular.isDefined(data.faviconLink)) {
+ } else if (angular.isDefined(data.faviconLink) && data.faviconLink.indexOf('url(') !== 0) {
data.faviconLink = 'url(' + data.faviconLink + ')';
}
/*
@@ -2977,6 +3055,113 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
// Generated by CoffeeScript 1.6.2
/*
+ownCloud - App Framework
+
+@author Bernhard Posselt
+@copyright 2012 Bernhard Posselt nukeawhale@gmail.com
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+License as published by the Free Software Foundation; either
+version 3 of the License, or any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+
+You should have received a copy of the GNU Affero General Public
+License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+(function() {
+ angular.module('News').factory('UndoQueue', [
+ '$timeout', '$rootScope', function($timeout, $rootScope) {
+ var UndoQueue;
+
+ UndoQueue = (function() {
+ function UndoQueue(_$timeout, _$rootScope) {
+ this._$timeout = _$timeout;
+ this._$rootScope = _$rootScope;
+ this._queue = [];
+ }
+
+ UndoQueue.prototype.add = function(_caption, _callback, _timeout, _undoCallback) {
+ var command, data,
+ _this = this;
+
+ this._caption = _caption;
+ this._callback = _callback;
+ this._timeout = _timeout != null ? _timeout : 0;
+ this._undoCallback = _undoCallback != null ? _undoCallback : null;
+ /*
+ @_caption the caption which indentifies the item
+ @_callback function the callback which should be executed when it was
+ not undone, this will usually be a request to the server to finally
+ delete something
+ @_timeout int the timeout after the callback should be executed
+ defaults to 0
+ @_undoCallback function the function which should be executed when
+ an command has been canceled. Usually this will add back a deleted
+ object back to the interface, defaults to an empty function
+ */
+
+ this._executeAll();
+ command = {
+ _undoCallback: this._undoCallback || (this._undoCallback = function() {}),
+ _callback: this._callback,
+ execute: function() {
+ return command._callback();
+ },
+ undo: function() {
+ command._undoCallback();
+ _this._$timeout.cancel(command.promise);
+ return _this._queue = [];
+ },
+ promise: this._$timeout(function() {
+ command.execute();
+ return _this._$rootScope.$broadcast('notUndone');
+ }, this._timeout)
+ };
+ data = {
+ undoCallback: command.undo,
+ caption: this._caption
+ };
+ this._$rootScope.$broadcast('undoMessage', data);
+ return this._queue.push(command);
+ };
+
+ UndoQueue.prototype._executeAll = function() {
+ /*
+ Executes the callback before the timeout has run out
+ This is useful to execute all remaining commands if a new command is
+ added
+ */
+
+ var command, _i, _len, _ref;
+
+ _ref = this._queue;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ command = _ref[_i];
+ this._$timeout.cancel(command.promise);
+ command.execute();
+ }
+ return this._queue = [];
+ };
+
+ return UndoQueue;
+
+ })();
+ return new UndoQueue($timeout, $rootScope);
+ }
+ ]);
+
+}).call(this);
+
+// Generated by CoffeeScript 1.6.2
+/*
+
ownCloud - News
@author Bernhard Posselt
diff --git a/js/tests/services/businesslayer/feedbusinesslayerSpec.coffee b/js/tests/services/businesslayer/feedbusinesslayerSpec.coffee
index 2bb37c023..4f7e8f8b3 100644
--- a/js/tests/services/businesslayer/feedbusinesslayerSpec.coffee
+++ b/js/tests/services/businesslayer/feedbusinesslayerSpec.coffee
@@ -44,16 +44,20 @@ describe 'FeedBusinessLayer', ->
beforeEach inject (@FeedBusinessLayer, @FeedModel, @ItemModel, @FeedType,
- @ShowAll, @ActiveFeed, @_ExistsError) =>
+ @ShowAll, @ActiveFeed, @_ExistsError, @$timeout) =>
@ShowAll.setShowAll(false)
@ActiveFeed.handle({type: @FeedType.Folder, id:0})
it 'should delete feeds', =>
- @FeedModel.removeById = jasmine.createSpy('remove')
+ @FeedModel.removeById = jasmine.createSpy('remove').andCallFake ->
+ return {id: 3, title: 'test'}
@persistence.deleteFeed = jasmine.createSpy('deletequery')
@FeedBusinessLayer.delete(3)
expect(@FeedModel.removeById).toHaveBeenCalledWith(3)
+
+ @$timeout.flush()
+
expect(@persistence.deleteFeed).toHaveBeenCalledWith(3)
diff --git a/js/tests/services/businesslayer/folderbusinesslayerSpec.coffee b/js/tests/services/businesslayer/folderbusinesslayerSpec.coffee
index f0241979f..7179218c2 100644
--- a/js/tests/services/businesslayer/folderbusinesslayerSpec.coffee
+++ b/js/tests/services/businesslayer/folderbusinesslayerSpec.coffee
@@ -39,15 +39,17 @@ describe 'FolderBusinessLayer', ->
beforeEach inject (@FolderBusinessLayer, @FolderModel, @FeedModel, @ShowAll,
- @ActiveFeed, @FeedType, @_ExistsError) =>
+ @ActiveFeed, @FeedType, @_ExistsError, @$timeout) =>
@ShowAll.setShowAll(false)
@ActiveFeed.handle({type: @FeedType.Feed, id:0})
it 'should delete folders', =>
- @FolderModel.removeById = jasmine.createSpy('remove')
+ @FolderModel.removeById = jasmine.createSpy('remove').andCallFake ->
+ return {id: 3, name: 'test'}
@persistence.deleteFolder = jasmine.createSpy('deletequery')
@FolderBusinessLayer.delete(3)
+ @$timeout.flush()
expect(@FolderModel.removeById).toHaveBeenCalledWith(3)
expect(@persistence.deleteFolder).toHaveBeenCalledWith(3)
diff --git a/js/tests/services/undoqueueSpec.coffee b/js/tests/services/undoqueueSpec.coffee
new file mode 100644
index 000000000..dcb95e9fd
--- /dev/null
+++ b/js/tests/services/undoqueueSpec.coffee
@@ -0,0 +1,59 @@
+###
+
+ownCloud - App Framework
+
+@author Bernhard Posselt
+@copyright 2012 Bernhard Posselt nukeawhale@gmail.com
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+License as published by the Free Software Foundation; either
+version 3 of the License, or any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+
+You should have received a copy of the GNU Affero General Public
+License along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+###
+
+describe 'UndoQueue', ->
+
+ beforeEach module 'News'
+
+
+ beforeEach inject (@UndoQueue, @$timeout, @$rootScope) =>
+ @queue = @UndoQueue
+
+
+ it 'should execute a callback', =>
+ executed = false
+ callback = ->
+ executed = true
+
+ @queue.add('hi', callback, 3000)
+
+ @$timeout.flush()
+
+ expect(executed).toBe(true)
+
+
+ it 'should execute a task when a new one is added', =>
+ executed = 0
+ undone = 0
+ callback = ->
+ executed += 1
+
+ undoCallback = ->
+ undone += 1
+
+ @queue.add('hi', callback, 3000, undoCallback)
+ @queue.add('hi', callback, 3000, undoCallback)
+
+ expect(executed).toBe(1)
+ expect(undone).toBe(0)
+
+