summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Molakvoæ <skjnldsv@users.noreply.github.com>2019-02-14 14:24:20 +0100
committerGitHub <noreply@github.com>2019-02-14 14:24:20 +0100
commit6a3f4e4957eb803ed4b764f01d50727403d7a3ba (patch)
treef3a7e8772e2f4e61b751fe645408b5f47de31462
parente65f7f05de6443bd66b1c31325cbc3cbe149d1e5 (diff)
parent08919eb19335825dc1f2cd950f9529a2b9caf29b (diff)
downloadnextcloud-server-6a3f4e4957eb803ed4b764f01d50727403d7a3ba.tar.gz
nextcloud-server-6a3f4e4957eb803ed4b764f01d50727403d7a3ba.zip
Merge pull request #12652 from tomasz-grobelny/operation_progress_improvements3
Operation progress improvements
-rw-r--r--apps/files/js/file-upload.js62
-rw-r--r--apps/files/js/filelist.js143
-rw-r--r--apps/files/js/merged-index.json2
-rw-r--r--apps/files/js/operationprogressbar.js79
-rw-r--r--apps/files/js/semaphore.js37
-rw-r--r--apps/files/js/templates.js16
-rw-r--r--apps/files/js/templates/operationprogressbar.handlebars6
-rw-r--r--apps/files/js/templates/operationprogressbarlabel.handlebars4
-rw-r--r--apps/files/templates/list.php6
-rw-r--r--apps/files/tests/js/fileUploadSpec.js5
-rw-r--r--apps/files/tests/js/filelistSpec.js450
-rw-r--r--core/js/files/client.js3
12 files changed, 525 insertions, 288 deletions
diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js
index 79d266a300b..e0b274cdc76 100644
--- a/apps/files/js/file-upload.js
+++ b/apps/files/js/file-upload.js
@@ -429,6 +429,11 @@ OC.Uploader.prototype = _.extend({
fileList: null,
/**
+ * @type OCA.Files.OperationProgressBar
+ */
+ progressBar: null,
+
+ /**
* @type OC.Files.Client
*/
filesClient: null,
@@ -759,14 +764,6 @@ OC.Uploader.prototype = _.extend({
callbacks.onNoConflicts(selection);
},
- _hideProgressBar: function() {
- var self = this;
- $('#uploadprogresswrapper .stop').fadeOut();
- $('#uploadprogressbar').fadeOut(function() {
- self.$uploadEl.trigger(new $.Event('resized'));
- });
- },
-
_updateProgressBarOnUploadStop: function() {
if (this._pendingUploadDoneCount === 0) {
// All the uploads ended and there is no pending operation, so hide
@@ -780,17 +777,31 @@ OC.Uploader.prototype = _.extend({
return;
}
- $('#uploadprogressbar .label .mobile').text(t('core', '…'));
- $('#uploadprogressbar .label .desktop').text(t('core', 'Processing files …'));
+ this._setProgressBarText(t('core', 'Processing files …'), t('core', '…'));
// Nothing is being uploaded at this point, and the pending operations
// can not be cancelled, so the cancel button should be hidden.
- $('#uploadprogresswrapper .stop').fadeOut();
+ this._hideCancelButton();
+ },
+
+ _hideProgressBar: function() {
+ this.progressBar.hideProgressBar();
+ },
+
+ _hideCancelButton: function() {
+ this.progressBar.hideCancelButton();
},
_showProgressBar: function() {
- $('#uploadprogressbar').fadeIn();
- this.$uploadEl.trigger(new $.Event('resized'));
+ this.progressBar.showProgressBar();
+ },
+
+ _setProgressBarValue: function(value) {
+ this.progressBar.setProgressBarValue(value);
+ },
+
+ _setProgressBarText: function(textDesktop, textMobile, title) {
+ this.progressBar.setProgressBarText(textDesktop, textMobile, title);
},
/**
@@ -826,6 +837,7 @@ OC.Uploader.prototype = _.extend({
options = options || {};
this.fileList = options.fileList;
+ this.progressBar = options.progressBar;
this.filesClient = options.filesClient || OC.Files.getClient();
this.davClient = new OC.Files.Client({
host: this.filesClient.getHost(),
@@ -839,7 +851,7 @@ OC.Uploader.prototype = _.extend({
this.$uploadEl = $uploadEl;
if ($uploadEl.exists()) {
- $('#uploadprogresswrapper .stop').on('click', function() {
+ this.progressBar.on('cancel', function() {
self.cancelUploads();
});
@@ -1099,16 +1111,8 @@ OC.Uploader.prototype = _.extend({
// add progress handlers
fileupload.on('fileuploadstart', function(e, data) {
self.log('progress handle fileuploadstart', e, data);
- $('#uploadprogresswrapper .stop').show();
- $('#uploadprogresswrapper .label').show();
- $('#uploadprogressbar').progressbar({value: 0});
- $('#uploadprogressbar .ui-progressbar-value').
- html('<em class="label inner"><span class="desktop">'
- + t('files', 'Uploading …')
- + '</span><span class="mobile">'
- + t('files', '…')
- + '</span></em>');
- $('#uploadprogressbar').tooltip({placement: 'bottom'});
+ self._setProgressBarText(t('files', 'Uploading …'), t('files', '…'));
+ self._setProgressBarValue(0);
self._showProgressBar();
// initial remaining time variables
lastUpdate = new Date().getTime();
@@ -1158,16 +1162,12 @@ OC.Uploader.prototype = _.extend({
// show "Uploading ..." for durations longer than 4 hours
h = t('files', 'Uploading …');
}
- $('#uploadprogressbar .label .mobile').text(h);
- $('#uploadprogressbar .label .desktop').text(h);
- $('#uploadprogressbar').attr('original-title',
- t('files', '{loadedSize} of {totalSize} ({bitrate})' , {
+ self._setProgressBarText(h, h, t('files', '{loadedSize} of {totalSize} ({bitrate})' , {
loadedSize: humanFileSize(data.loaded),
totalSize: humanFileSize(data.total),
bitrate: humanFileSize(data.bitrate / 8) + '/s'
- })
- );
- $('#uploadprogressbar').progressbar('value', progress);
+ }));
+ self._setProgressBarValue(progress);
self.trigger('progressall', e, data);
});
fileupload.on('fileuploadstop', function(e, data) {
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 363f81a1a73..868623d9a8a 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -386,11 +386,16 @@
});
}
+ this._operationProgressBar = new OCA.Files.OperationProgressBar();
+ this._operationProgressBar.render();
+ this.$el.find('#uploadprogresswrapper').replaceWith(this._operationProgressBar.$el);
+
if (options.enableUpload) {
// TODO: auto-create this element
var $uploadEl = this.$el.find('#file_upload_start');
if ($uploadEl.exists()) {
this._uploader = new OC.Uploader($uploadEl, {
+ progressBar: this._operationProgressBar,
fileList: this,
filesClient: this.filesClient,
dropZone: $('#content'),
@@ -2206,21 +2211,39 @@
remove: function(name, options){
options = options || {};
var fileEl = this.findFileEl(name);
- var fileId = fileEl.data('id');
- var index = fileEl.index();
- if (!fileEl.length) {
- return null;
+ var fileData = _.findWhere(this.files, {name: name});
+ if (!fileData) {
+ return;
}
+ var fileId = fileData.id;
if (this._selectedFiles[fileId]) {
// remove from selection first
this._selectFileEl(fileEl, false);
this.updateSelectionSummary();
}
+ if (this._selectedFiles[fileId]) {
+ delete this._selectedFiles[fileId];
+ this._selectionSummary.remove(fileData);
+ this.updateSelectionSummary();
+ }
+ var index = this.files.findIndex(function(el){return el.name==name;});
+ this.files.splice(index, 1);
+
+ // TODO: improve performance on batch update
+ this.isEmpty = !this.files.length;
+ if (typeof(options.updateSummary) === 'undefined' || !!options.updateSummary) {
+ this.updateEmptyContent();
+ this.fileSummary.remove({type: fileData.type, size: fileData.size}, true);
+ }
+
+ if (!fileEl.length) {
+ return null;
+ }
+
if (this._dragOptions && (fileEl.data('permissions') & OC.PERMISSION_DELETE)) {
// file is only draggable when delete permissions are set
fileEl.find('td.filename').draggable('destroy');
}
- this.files.splice(index, 1);
if (this._currentFileModel && this._currentFileModel.get('id') === fileId) {
// Note: in the future we should call destroy() directly on the model
// and the model will take care of the deletion.
@@ -2230,12 +2253,6 @@
this._updateDetailsView(null);
}
fileEl.remove();
- // TODO: improve performance on batch update
- this.isEmpty = !this.files.length;
- if (typeof(options.updateSummary) === 'undefined' || !!options.updateSummary) {
- this.updateEmptyContent();
- this.fileSummary.remove({type: fileEl.attr('data-type'), size: fileEl.attr('data-size')}, true);
- }
var lastIndex = this.$fileList.children().length;
// if there are less elements visible than one page
@@ -2282,29 +2299,6 @@
fileNames = [fileNames];
}
- function Semaphore(max) {
- var counter = 0;
- var waiting = [];
-
- this.acquire = function() {
- if(counter < max) {
- counter++;
- return new Promise(function(resolve) { resolve(); });
- } else {
- return new Promise(function(resolve) { waiting.push(resolve); });
- }
- };
-
- this.release = function() {
- counter--;
- if (waiting.length > 0 && counter < max) {
- counter++;
- var promise = waiting.shift();
- promise();
- }
- };
- }
-
var moveFileFunction = function(fileName) {
var $tr = self.findFileEl(fileName);
self.showFileBusyState($tr, true);
@@ -2316,7 +2310,7 @@
return self.filesClient.move(dir + fileName, targetPath + fileName)
.done(function() {
// if still viewing the same directory
- if (OC.joinPaths(self.getCurrentDirectory(), '/') === dir) {
+ if (OC.joinPaths(self.getCurrentDirectory(), '/') === OC.joinPaths(dir, '/')) {
// recalculate folder size
var oldFile = self.findFileEl(target);
var newFile = self.findFileEl(fileName);
@@ -2325,7 +2319,6 @@
oldFile.data('size', newSize);
oldFile.find('td.filesize').text(OC.Util.humanFileSize(newSize));
- // TODO: also update entry in FileList.files
self.remove(fileName);
}
})
@@ -2345,22 +2338,33 @@
self.showFileBusyState($tr, false);
});
};
+ return this.reportOperationProgress(fileNames, moveFileFunction, callback);
+ },
+
+ _reflect: function (promise){
+ return promise.then(function(v){ return {};}, function(e){ return {};});
+ },
- var mcSemaphore = new Semaphore(10);
+ reportOperationProgress: function (fileNames, operationFunction, callback){
+ var self = this;
+ self._operationProgressBar.showProgressBar(false);
+ var mcSemaphore = new OCA.Files.Semaphore(5);
var counter = 0;
var promises = _.map(fileNames, function(arg) {
return mcSemaphore.acquire().then(function(){
- moveFileFunction(arg).then(function(){
+ return operationFunction(arg).always(function(){
mcSemaphore.release();
counter++;
+ self._operationProgressBar.setProgressBarValue(100.0*counter/fileNames.length);
});
});
});
- return Promise.all(promises).then(function(){
+ return Promise.all(_.map(promises, self._reflect)).then(function(){
if (callback) {
callback();
}
+ self._operationProgressBar.hideProgressBar();
});
},
@@ -2385,7 +2389,7 @@
if (!_.isArray(fileNames)) {
fileNames = [fileNames];
}
- _.each(fileNames, function(fileName) {
+ var copyFileFunction = function(fileName) {
var $tr = self.findFileEl(fileName);
self.showFileBusyState($tr, true);
if (targetPath.charAt(targetPath.length - 1) !== '/') {
@@ -2441,12 +2445,12 @@
}
}
}
- self.filesClient.copy(dir + fileName, targetPathAndName)
+ return self.filesClient.copy(dir + fileName, targetPathAndName)
.done(function () {
filesToNotify.push(fileName);
// if still viewing the same directory
- if (OC.joinPaths(self.getCurrentDirectory(), '/') === dir) {
+ if (OC.joinPaths(self.getCurrentDirectory(), '/') === OC.joinPaths(dir, '/')) {
// recalculate folder size
var oldFile = self.findFileEl(target);
var newFile = self.findFileEl(fileName);
@@ -2513,11 +2517,8 @@
}
}
});
- });
-
- if (callback) {
- callback();
- }
+ };
+ return this.reportOperationProgress(fileNames, copyFileFunction, callback);
},
/**
@@ -2939,9 +2940,6 @@
// delete all files in directory
files = _.pluck(this.files, 'name');
}
- if (files) {
- this.showFileBusyState(files, true);
- }
// Finish any existing actions
if (this.lastAction) {
this.lastAction();
@@ -2949,43 +2947,38 @@
dir = dir || this.getCurrentDirectory();
- function removeFromList(file) {
- var fileEl = self.remove(file, {updateSummary: false});
- // FIXME: not sure why we need this after the
- // element isn't even in the DOM any more
- fileEl.find('.selectCheckBox').prop('checked', false);
- fileEl.removeClass('selected');
- self.fileSummary.remove({type: fileEl.attr('data-type'), size: fileEl.attr('data-size')});
- // TODO: this info should be returned by the ajax call!
- self.updateEmptyContent();
- self.fileSummary.update();
- self.updateSelectionSummary();
- // FIXME: don't repeat this, do it once all files are done
- self.updateStorageStatistics();
- self.updateStorageQuotas();
- }
-
- _.each(files, function(file) {
- self.filesClient.remove(dir + '/' + file)
+ var removeFunction = function(fileName) {
+ var $tr = self.findFileEl(fileName);
+ self.showFileBusyState($tr, true);
+ return self.filesClient.remove(dir + '/' + fileName)
.done(function() {
- removeFromList(file);
+ if (OC.joinPaths(self.getCurrentDirectory(), '/') === OC.joinPaths(dir, '/')) {
+ self.remove(fileName);
+ }
})
.fail(function(status) {
if (status === 404) {
// the file already did not exist, remove it from the list
- removeFromList(file);
+ if (OC.joinPaths(self.getCurrentDirectory(), '/') === OC.joinPaths(dir, '/')) {
+ self.remove(fileName);
+ }
} else {
// only reset the spinner for that one file
OC.Notification.show(t('files', 'Error deleting file "{fileName}".',
- {fileName: file}), {type: 'error'}
+ {fileName: fileName}), {type: 'error'}
);
- var deleteAction = self.findFileEl(file).find('.action.delete');
- deleteAction.removeClass('icon-loading-small').addClass('icon-delete');
- self.showFileBusyState(files, false);
}
+ })
+ .always(function() {
+ self.showFileBusyState($tr, false);
});
- });
+ };
+ return this.reportOperationProgress(files, removeFunction).then(function(){
+ self.updateStorageStatistics();
+ self.updateStorageQuotas();
+ });
},
+
/**
* Creates the file summary section
*/
diff --git a/apps/files/js/merged-index.json b/apps/files/js/merged-index.json
index e891d10bdae..8d25daa6b3c 100644
--- a/apps/files/js/merged-index.json
+++ b/apps/files/js/merged-index.json
@@ -21,7 +21,9 @@
"sidebarpreviewmanager.js",
"sidebarpreviewtext.js",
"detailtabview.js",
+ "semaphore.js",
"mainfileinfodetailview.js",
+ "operationprogressbar.js",
"detailsview.js",
"fileactions.js",
"fileactionsmenu.js",
diff --git a/apps/files/js/operationprogressbar.js b/apps/files/js/operationprogressbar.js
new file mode 100644
index 00000000000..efeea4ad78f
--- /dev/null
+++ b/apps/files/js/operationprogressbar.js
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018
+ *
+ * This file is licensed under the Affero General Public License version 3
+ * or later.
+ *
+ * See the COPYING-README file.
+ *
+ */
+
+(function() {
+ var OperationProgressBar = OC.Backbone.View.extend({
+ tagName: 'div',
+ id: 'uploadprogresswrapper',
+ events: {
+ 'click button.stop': '_onClickCancel'
+ },
+
+ render: function() {
+ this.$el.html(OCA.Files.Templates['operationprogressbar']({
+ textCancelButton: t('Cancel operation')
+ }));
+ this.setProgressBarText(t('Uploading …'), t('…'));
+ },
+
+ hideProgressBar: function() {
+ var self = this;
+ $('#uploadprogresswrapper .stop').fadeOut();
+ $('#uploadprogressbar').fadeOut(function() {
+ self.$el.trigger(new $.Event('resized'));
+ });
+ },
+
+ hideCancelButton: function() {
+ $('#uploadprogresswrapper .stop').fadeOut(function() {
+ this.$el.trigger(new $.Event('resized'));
+ });
+ },
+
+ showProgressBar: function(showCancelButton) {
+ if (showCancelButton) {
+ showCancelButton = true;
+ }
+ $('#uploadprogressbar').progressbar({value: 0});
+ if(showCancelButton) {
+ $('#uploadprogresswrapper .stop').show();
+ } else {
+ $('#uploadprogresswrapper .stop').hide();
+ }
+ $('#uploadprogresswrapper .label').show();
+ $('#uploadprogressbar').fadeIn();
+ this.$el.trigger(new $.Event('resized'));
+ },
+
+ setProgressBarValue: function(value) {
+ $('#uploadprogressbar').progressbar({value: value});
+ },
+
+ setProgressBarText: function(textDesktop, textMobile, title) {
+ var labelHtml = OCA.Files.Templates['operationprogressbarlabel']({textDesktop: textDesktop, textMobile: textMobile});
+ $('#uploadprogressbar .ui-progressbar-value').html(labelHtml);
+ $('#uploadprogressbar .ui-progressbar-value>em').addClass('inner');
+ $('#uploadprogressbar>em').replaceWith(labelHtml);
+ $('#uploadprogressbar>em').addClass('outer');
+ $('#uploadprogressbar').tooltip({placement: 'bottom'});
+ if(title) {
+ $('#uploadprogressbar').attr('original-title', title);
+ }
+ $('#uploadprogresswrapper .stop').show();
+ },
+
+ _onClickCancel: function (event) {
+ this.trigger('cancel');
+ return false;
+ }
+ });
+
+ OCA.Files.OperationProgressBar = OperationProgressBar;
+})(OC, OCA);
diff --git a/apps/files/js/semaphore.js b/apps/files/js/semaphore.js
new file mode 100644
index 00000000000..044f0af23f3
--- /dev/null
+++ b/apps/files/js/semaphore.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018
+ *
+ * This file is licensed under the Affero General Public License version 3
+ * or later.
+ *
+ * See the COPYING-README file.
+ *
+ */
+
+(function(){
+ var Semaphore = function(max) {
+ var counter = 0;
+ var waiting = [];
+
+ this.acquire = function() {
+ if(counter < max) {
+ counter++;
+ return new Promise(function(resolve) { resolve(); });
+ } else {
+ return new Promise(function(resolve) { waiting.push(resolve); });
+ }
+ };
+
+ this.release = function() {
+ counter--;
+ if (waiting.length > 0 && counter < max) {
+ counter++;
+ var promise = waiting.shift();
+ promise();
+ }
+ };
+ };
+
+ OCA.Files.Semaphore = Semaphore;
+
+})();
diff --git a/apps/files/js/templates.js b/apps/files/js/templates.js
index a2bdae5b3c4..be6b255d594 100644
--- a/apps/files/js/templates.js
+++ b/apps/files/js/templates.js
@@ -245,6 +245,22 @@ templates['newfilemenu_filename_form'] = template({"compiler":[7,">= 4.0.0"],"ma
+ alias4(((helper = (helper = helpers.fileName || (depth0 != null ? depth0.fileName : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"fileName","hash":{},"data":data}) : helper)))
+ "\" autocomplete=\"off\" autocapitalize=\"off\">\n <input type=\"submit\" value=\" \" class=\"icon-confirm\" />\n</form>\n";
},"useData":true});
+templates['operationprogressbar'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var helper;
+
+ return "<div id=\"uploadprogressbar\">\n <em class=\"label outer\" style=\"display:none\"></em>\n</div>\n<button class=\"stop icon-close\" style=\"display:none\">\n <span class=\"hidden-visually\">"
+ + container.escapeExpression(((helper = (helper = helpers.textCancelButton || (depth0 != null ? depth0.textCancelButton : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"textCancelButton","hash":{},"data":data}) : helper)))
+ + "</span>\n</button>\n";
+},"useData":true});
+templates['operationprogressbarlabel'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return "<em class=\"label\">\n <span class=\"desktop\">"
+ + alias4(((helper = (helper = helpers.textDesktop || (depth0 != null ? depth0.textDesktop : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"textDesktop","hash":{},"data":data}) : helper)))
+ + "</span>\n <span class=\"mobile\">"
+ + alias4(((helper = (helper = helpers.textMobile || (depth0 != null ? depth0.textMobile : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"textMobile","hash":{},"data":data}) : helper)))
+ + "</span>\n</em>\n";
+},"useData":true});
templates['template_addbutton'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
diff --git a/apps/files/js/templates/operationprogressbar.handlebars b/apps/files/js/templates/operationprogressbar.handlebars
new file mode 100644
index 00000000000..c02ac623fab
--- /dev/null
+++ b/apps/files/js/templates/operationprogressbar.handlebars
@@ -0,0 +1,6 @@
+<div id="uploadprogressbar">
+ <em class="label outer" style="display:none"></em>
+</div>
+<button class="stop icon-close" style="display:none">
+ <span class="hidden-visually">{{textCancelButton}}</span>
+</button>
diff --git a/apps/files/js/templates/operationprogressbarlabel.handlebars b/apps/files/js/templates/operationprogressbarlabel.handlebars
new file mode 100644
index 00000000000..24ac66994da
--- /dev/null
+++ b/apps/files/js/templates/operationprogressbarlabel.handlebars
@@ -0,0 +1,4 @@
+<em class="label">
+ <span class="desktop">{{textDesktop}}</span>
+ <span class="mobile">{{textMobile}}</span>
+</em>
diff --git a/apps/files/templates/list.php b/apps/files/templates/list.php
index 75dc2bee26f..8b20c84e008 100644
--- a/apps/files/templates/list.php
+++ b/apps/files/templates/list.php
@@ -1,12 +1,6 @@
<div id="controls">
<div class="actions creatable hidden">
<div id="uploadprogresswrapper">
- <div id="uploadprogressbar">
- <em class="label outer" style="display:none"><span class="desktop"><?php p($l->t('Uploading …'));?></span><span class="mobile"><?php p($l->t('…'));?></span></em>
- </div>
- <button class="stop icon-close" style="display:none">
- <span class="hidden-visually"><?php p($l->t('Cancel upload')) ?></span>
- </button>
</div>
</div>
<div id="file_action_panel"></div>
diff --git a/apps/files/tests/js/fileUploadSpec.js b/apps/files/tests/js/fileUploadSpec.js
index ecf29f979d8..0d2c9eb0697 100644
--- a/apps/files/tests/js/fileUploadSpec.js
+++ b/apps/files/tests/js/fileUploadSpec.js
@@ -24,6 +24,7 @@ describe('OC.Upload tests', function() {
var testFile;
var uploader;
var failStub;
+ var progressBarStub;
beforeEach(function() {
testFile = {
@@ -45,7 +46,8 @@ describe('OC.Upload tests', function() {
'</div>'
);
$dummyUploader = $('#file_upload_start');
- uploader = new OC.Uploader($dummyUploader);
+ progressBarStub = {on: function(){}};
+ uploader = new OC.Uploader($dummyUploader, {progressBar: progressBarStub});
failStub = sinon.stub();
uploader.on('fail', failStub);
});
@@ -143,6 +145,7 @@ describe('OC.Upload tests', function() {
conflictDialogStub = sinon.stub(OC.dialogs, 'fileexists');
uploader = new OC.Uploader($dummyUploader, {
+ progressBar: progressBarStub,
fileList: fileList
});
diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js
index eae72ff05dc..402cfaa1073 100644
--- a/apps/files/tests/js/filelistSpec.js
+++ b/apps/files/tests/js/filelistSpec.js
@@ -522,7 +522,7 @@ describe('OCA.Files.FileList tests', function() {
beforeEach(function() {
deferredDelete = $.Deferred();
- deleteStub = sinon.stub(filesClient, 'remove').returns(deferredDelete.promise());
+ deleteStub = sinon.stub(filesClient, 'remove');
});
afterEach(function() {
deleteStub.restore();
@@ -530,92 +530,153 @@ describe('OCA.Files.FileList tests', function() {
function doDelete() {
// note: normally called from FileActions
- fileList.do_delete(['One.txt', 'Two.jpg']);
+ return fileList.do_delete(['One.txt', 'Two.jpg']).then(function(){
- expect(deleteStub.calledTwice).toEqual(true);
- expect(deleteStub.getCall(0).args[0]).toEqual('/subdir/One.txt');
- expect(deleteStub.getCall(1).args[0]).toEqual('/subdir/Two.jpg');
+ expect(deleteStub.calledTwice).toEqual(true);
+ expect(deleteStub.getCall(0).args[0]).toEqual('/subdir/One.txt');
+ expect(deleteStub.getCall(1).args[0]).toEqual('/subdir/Two.jpg');
+ });
}
- it('calls delete.php, removes the deleted entries and updates summary', function() {
+ it('calls delete.php, removes the deleted entries and updates summary', function(done) {
var $summary;
fileList.setFiles(testFiles);
- doDelete();
+ deferredDelete1 = $.Deferred();
+ deferredDelete2 = $.Deferred();
+ deleteStub.onCall(0).callsFake(function(src){
+ expect(deleteStub.calledOnce).toEqual(true);
+ expect(src).toEqual('/subdir/One.txt');
+ return deferredDelete1.promise();
+ });
+ deleteStub.onCall(1).callsFake(function(src){
+ expect(deleteStub.calledTwice).toEqual(true);
+ expect(src).toEqual('/subdir/Two.jpg');
+ return deferredDelete2.promise();
+ });
- deferredDelete.resolve(200);
+ var promise = fileList.do_delete(['One.txt', 'Two.jpg']);
+ deferredDelete1.resolve(200);
+ deferredDelete2.resolve(200);
+ return promise.then(function(){
- expect(fileList.findFileEl('One.txt').length).toEqual(0);
- expect(fileList.findFileEl('Two.jpg').length).toEqual(0);
- expect(fileList.findFileEl('Three.pdf').length).toEqual(1);
- expect(fileList.$fileList.find('tr').length).toEqual(2);
-
- $summary = $('#filestable .summary');
- expect($summary.hasClass('hidden')).toEqual(false);
- expect($summary.find('.dirinfo').text()).toEqual('1 folder');
- expect($summary.find('.fileinfo').text()).toEqual('1 file');
- expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(false);
- expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false);
- expect($summary.find('.filesize').text()).toEqual('57 KB');
- expect(fileList.isEmpty).toEqual(false);
- expect($('#filestable thead th').hasClass('hidden')).toEqual(false);
- expect($('#emptycontent').hasClass('hidden')).toEqual(true);
+ expect(fileList.findFileEl('One.txt').length).toEqual(0);
+ expect(fileList.findFileEl('Two.jpg').length).toEqual(0);
+ expect(fileList.findFileEl('Three.pdf').length).toEqual(1);
+ expect(fileList.$fileList.find('tr').length).toEqual(2);
+
+ $summary = $('#filestable .summary');
+ expect($summary.hasClass('hidden')).toEqual(false);
+ expect($summary.find('.dirinfo').text()).toEqual('1 folder');
+ expect($summary.find('.fileinfo').text()).toEqual('1 file');
+ expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(false);
+ expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false);
+ expect($summary.find('.filesize').text()).toEqual('57 KB');
+ expect(fileList.isEmpty).toEqual(false);
+ expect($('#filestable thead th').hasClass('hidden')).toEqual(false);
+ expect($('#emptycontent').hasClass('hidden')).toEqual(true);
- expect(notificationStub.notCalled).toEqual(true);
+ expect(notificationStub.notCalled).toEqual(true);
+ done();
+ });
});
- it('shows busy state on files to be deleted', function() {
+ it('shows busy state on files to be deleted', function(done) {
fileList.setFiles(testFiles);
- doDelete();
-
- expect(fileList.findFileEl('One.txt').hasClass('busy')).toEqual(true);
- expect(fileList.findFileEl('Three.pdf').hasClass('busy')).toEqual(false);
+ deferredDelete1 = $.Deferred();
+ deferredDelete2 = $.Deferred();
+ deleteStub.onCall(0).callsFake(function(src){
+ expect(fileList.findFileEl('One.txt').hasClass('busy')).toEqual(true);
+ expect(fileList.findFileEl('Three.pdf').hasClass('busy')).toEqual(false);
+
+ expect(deleteStub.calledOnce).toEqual(true);
+ expect(src).toEqual('/subdir/One.txt');
+ return deferredDelete1.promise();
+ });
+ deleteStub.onCall(1).callsFake(function(src){
+ expect(fileList.findFileEl('Two.jpg').hasClass('busy')).toEqual(true);
+ expect(fileList.findFileEl('Three.pdf').hasClass('busy')).toEqual(false);
+
+ expect(deleteStub.calledTwice).toEqual(true);
+ expect(src).toEqual('/subdir/Two.jpg');
+ return deferredDelete2.promise();
+ });
+ var promise = fileList.do_delete(['One.txt', 'Two.jpg']).then(function(){
+ expect(deleteStub.calledTwice).toEqual(true);
+ });
+ deferredDelete1.resolve(200);
+ deferredDelete2.resolve(200);
+ return promise.then(function(){
+ expect(fileList.findFileEl('One.txt').hasClass('busy')).toEqual(false);
+ expect(fileList.findFileEl('Two.jpg').hasClass('busy')).toEqual(false);
+ done();
+ });
});
- it('shows busy state on all files when deleting all', function() {
+ it('shows busy state on all files when deleting all', function(done) {
fileList.setFiles(testFiles);
-
- fileList.do_delete();
-
- expect(fileList.$fileList.find('tr.busy').length).toEqual(4);
+ var deferredDeleteArray = [];
+ var count = 0;
+ for (var i = 0; i < 4; i++) {
+ (function(i, fn){
+ deferredDeleteArray.push($.Deferred());
+ deleteStub.onCall(i).callsFake(function(src){
+ expect(fileList.findFileEl(fn).hasClass('busy')).toEqual(true);
+ count++;
+ return deferredDeleteArray[i].promise();
+ });
+ })(i, testFiles[i].name);
+ }
+ var promise = fileList.do_delete();
+ for (var i = 0; i < 4; i++) {
+ deferredDeleteArray[i].resolve(200);
+ }
+ return promise.then(function(){
+ expect(count).toEqual(4);
+ done();
+ });
});
- it('updates summary when deleting last file', function() {
+ it('updates summary when deleting last file', function(done) {
var $summary;
fileList.setFiles([testFiles[0], testFiles[1]]);
- doDelete();
-
+ deleteStub.returns(deferredDelete.promise());
deferredDelete.resolve(200);
- expect(fileList.$fileList.find('tr').length).toEqual(0);
-
- $summary = $('#filestable .summary');
- expect($summary.hasClass('hidden')).toEqual(true);
- expect(fileList.isEmpty).toEqual(true);
- expect(fileList.files.length).toEqual(0);
- expect($('#filestable thead th').hasClass('hidden')).toEqual(true);
- expect($('#emptycontent').hasClass('hidden')).toEqual(false);
+ return doDelete().then(function(){
+ expect(fileList.$fileList.find('tr').length).toEqual(0);
+ $summary = $('#filestable .summary');
+ expect($summary.hasClass('hidden')).toEqual(true);
+ expect(fileList.isEmpty).toEqual(true);
+ expect(fileList.files.length).toEqual(0);
+ expect($('#filestable thead th').hasClass('hidden')).toEqual(true);
+ expect($('#emptycontent').hasClass('hidden')).toEqual(false);
+ done();
+ });
});
- it('bring back deleted item when delete call failed', function() {
+ it('bring back deleted item when delete call failed', function(done) {
fileList.setFiles(testFiles);
- doDelete();
-
+ deleteStub.returns(deferredDelete.promise());
+ var promise = doDelete();
deferredDelete.reject(403);
+ return promise.then(function(){
+ // files are still in the list
+ expect(fileList.findFileEl('One.txt').length).toEqual(1);
+ expect(fileList.findFileEl('Two.jpg').length).toEqual(1);
+ expect(fileList.$fileList.find('tr').length).toEqual(4);
- // files are still in the list
- expect(fileList.findFileEl('One.txt').length).toEqual(1);
- expect(fileList.findFileEl('Two.jpg').length).toEqual(1);
- expect(fileList.$fileList.find('tr').length).toEqual(4);
-
- expect(notificationStub.calledTwice).toEqual(true);
+ expect(notificationStub.calledTwice).toEqual(true);
+ done();
+ });
});
- it('remove file from list if delete call returned 404 not found', function() {
+ it('remove file from list if delete call returned 404 not found', function(done) {
fileList.setFiles(testFiles);
- doDelete();
-
+ deleteStub.returns(deferredDelete.promise());
+ var promise = doDelete();
deferredDelete.reject(404);
+ return promise.then(function(){
+ expect(fileList.findFileEl('One.txt').length).toEqual(0);
+ expect(fileList.findFileEl('Two.jpg').length).toEqual(0);
+ expect(fileList.$fileList.find('tr').length).toEqual(2);
- // files are still in the list
- expect(fileList.findFileEl('One.txt').length).toEqual(0);
- expect(fileList.findFileEl('Two.jpg').length).toEqual(0);
- expect(fileList.$fileList.find('tr').length).toEqual(2);
-
- expect(notificationStub.notCalled).toEqual(true);
+ expect(notificationStub.notCalled).toEqual(true);
+ done();
+ });
});
});
describe('Renaming files', function() {
@@ -831,7 +892,7 @@ describe('OCA.Files.FileList tests', function() {
beforeEach(function() {
deferredMove = $.Deferred();
- moveStub = sinon.stub(filesClient, 'move').returns(deferredMove.promise());
+ moveStub = sinon.stub(filesClient, 'move');
fileList.setFiles(testFiles);
});
@@ -840,14 +901,18 @@ describe('OCA.Files.FileList tests', function() {
});
it('Moves single file to target folder', function(done) {
- return fileList.move('One.txt', '/somedir').then(function(){
+ var promise = fileList.move('One.txt', '/somedir');
+ moveStub.callsFake(function(src, dst){
expect(moveStub.calledOnce).toEqual(true);
- expect(moveStub.getCall(0).args[0]).toEqual('/subdir/One.txt');
- expect(moveStub.getCall(0).args[1]).toEqual('/somedir/One.txt');
+ expect(src).toEqual('/subdir/One.txt');
+ expect(dst).toEqual('/somedir/One.txt');
+ return deferredMove.promise();
+ });
- deferredMove.resolve(201);
+ deferredMove.resolve(201);
+ return promise.then(function(){
expect(fileList.findFileEl('One.txt').length).toEqual(0);
// folder size has increased
@@ -861,26 +926,29 @@ describe('OCA.Files.FileList tests', function() {
it('Moves list of files to target folder', function(done) {
var deferredMove1 = $.Deferred();
var deferredMove2 = $.Deferred();
- moveStub.onCall(0).returns(deferredMove1.promise());
- moveStub.onCall(1).returns(deferredMove2.promise());
-
- return fileList.move(['One.txt', 'Two.jpg'], '/somedir').then(function(){
-
- expect(moveStub.calledTwice).toEqual(true);
- expect(moveStub.getCall(0).args[0]).toEqual('/subdir/One.txt');
- expect(moveStub.getCall(0).args[1]).toEqual('/somedir/One.txt');
- expect(moveStub.getCall(1).args[0]).toEqual('/subdir/Two.jpg');
- expect(moveStub.getCall(1).args[1]).toEqual('/somedir/Two.jpg');
-
- deferredMove1.resolve(201);
-
+ moveStub.onCall(0).callsFake(function(src, dst){
+ expect(moveStub.calledOnce).toEqual(true);
+ expect(src).toEqual('/subdir/One.txt');
+ expect(dst).toEqual('/somedir/One.txt');
+ return deferredMove1.promise();
+ });
+ moveStub.onCall(1).callsFake(function(src, dst){
expect(fileList.findFileEl('One.txt').length).toEqual(0);
// folder size has increased during move
expect(fileList.findFileEl('somedir').data('size')).toEqual(262);
expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B');
- deferredMove2.resolve(201);
+ expect(src).toEqual('/subdir/Two.jpg');
+ expect(dst).toEqual('/somedir/Two.jpg');
+ return deferredMove2.promise();
+ });
+
+ var promise = fileList.move(['One.txt', 'Two.jpg'], '/somedir');
+ deferredMove1.resolve(201);
+ deferredMove2.resolve(201);
+ return promise.then(function(){
+ expect(moveStub.calledTwice).toEqual(true);
expect(fileList.findFileEl('Two.jpg').length).toEqual(0);
@@ -893,34 +961,32 @@ describe('OCA.Files.FileList tests', function() {
});
});
it('Shows notification if a file could not be moved', function(done) {
- return fileList.move('One.txt', '/somedir').then(function(){
-
+ moveStub.callsFake(function(){
expect(moveStub.calledOnce).toEqual(true);
-
- deferredMove.reject(409);
-
+ return deferredMove.promise();
+ });
+ var promise = fileList.move('One.txt', '/somedir');
+ deferredMove.reject(409);
+ return promise.then(function(){
expect(fileList.findFileEl('One.txt').length).toEqual(1);
-
expect(notificationStub.calledOnce).toEqual(true);
expect(notificationStub.getCall(0).args[0]).toEqual('Could not move "One.txt"');
done();
});
});
it('Restores thumbnail if a file could not be moved', function(done) {
- return fileList.move('One.txt', '/somedir').then(function(){
-
+ moveStub.callsFake(function(){
expect(fileList.findFileEl('One.txt').find('.thumbnail').parent().attr('class'))
.toContain('icon-loading-small');
-
expect(moveStub.calledOnce).toEqual(true);
-
- deferredMove.reject(409);
-
+ return deferredMove.promise();
+ });
+ var promise = fileList.move('One.txt', '/somedir');
+ deferredMove.reject(409);
+ return promise.then(function(){
expect(fileList.findFileEl('One.txt').length).toEqual(1);
-
expect(notificationStub.calledOnce).toEqual(true);
expect(notificationStub.getCall(0).args[0]).toEqual('Could not move "One.txt"');
-
expect(OC.TestUtil.getImageUrl(fileList.findFileEl('One.txt').find('.thumbnail')))
.toEqual(OC.imagePath('core', 'filetypes/text.svg'));
done();
@@ -934,7 +1000,7 @@ describe('OCA.Files.FileList tests', function() {
beforeEach(function() {
deferredCopy = $.Deferred();
- copyStub = sinon.stub(filesClient, 'copy').returns(deferredCopy.promise());
+ copyStub = sinon.stub(filesClient, 'copy');
fileList.setFiles(testFiles);
});
@@ -942,86 +1008,100 @@ describe('OCA.Files.FileList tests', function() {
copyStub.restore();
});
- it('Copies single file to target folder', function() {
- fileList.copy('One.txt', '/somedir');
+ it('Copies single file to target folder', function(done) {
+ copyStub.callsFake(function(){
+ expect(copyStub.calledOnce).toEqual(true);
+ expect(copyStub.getCall(0).args[0]).toEqual('/subdir/One.txt');
+ expect(copyStub.getCall(0).args[1]).toEqual('/somedir/One.txt');
- expect(copyStub.calledOnce).toEqual(true);
- expect(copyStub.getCall(0).args[0]).toEqual('/subdir/One.txt');
- expect(copyStub.getCall(0).args[1]).toEqual('/somedir/One.txt');
+ return deferredCopy.promise();
+ });
+ var promise = fileList.copy('One.txt', '/somedir');
deferredCopy.resolve(201);
+ return promise.then(function(){
+ // File is still here
+ expect(fileList.findFileEl('One.txt').length).toEqual(1);
- // File is still here
- expect(fileList.findFileEl('One.txt').length).toEqual(1);
-
- // folder size has increased
- expect(fileList.findFileEl('somedir').data('size')).toEqual(262);
- expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B');
+ // folder size has increased
+ expect(fileList.findFileEl('somedir').data('size')).toEqual(262);
+ expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B');
- // Copying sents a notification to tell that we've successfully copied file
- expect(notificationStub.notCalled).toEqual(false);
+ // Copying sents a notification to tell that we've successfully copied file
+ expect(notificationStub.notCalled).toEqual(false);
+ done();
+ });
});
- it('Copies list of files to target folder', function() {
+ it('Copies list of files to target folder', function(done) {
var deferredCopy1 = $.Deferred();
var deferredCopy2 = $.Deferred();
- copyStub.onCall(0).returns(deferredCopy1.promise());
- copyStub.onCall(1).returns(deferredCopy2.promise());
-
- fileList.copy(['One.txt', 'Two.jpg'], '/somedir');
+ copyStub.onCall(0).callsFake(function(src, dst){
+ expect(src).toEqual('/subdir/One.txt');
+ expect(dst).toEqual('/somedir/One.txt');
+ return deferredCopy1.promise();
+ });
+ copyStub.onCall(1).callsFake(function(src, dst){
+ // folder size has increased during copy
+ expect(fileList.findFileEl('somedir').data('size')).toEqual(262);
+ expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B');
- expect(copyStub.calledTwice).toEqual(true);
- expect(copyStub.getCall(0).args[0]).toEqual('/subdir/One.txt');
- expect(copyStub.getCall(0).args[1]).toEqual('/somedir/One.txt');
- expect(copyStub.getCall(1).args[0]).toEqual('/subdir/Two.jpg');
- expect(copyStub.getCall(1).args[1]).toEqual('/somedir/Two.jpg');
+ expect(src).toEqual('/subdir/Two.jpg');
+ expect(dst).toEqual('/somedir/Two.jpg');
+ return deferredCopy2.promise();
+ });
+ var promise = fileList.copy(['One.txt', 'Two.jpg'], '/somedir');
deferredCopy1.resolve(201);
-
- expect(fileList.findFileEl('One.txt').length).toEqual(1);
-
- // folder size has increased during copy
- expect(fileList.findFileEl('somedir').data('size')).toEqual(262);
- expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B');
-
deferredCopy2.resolve(201);
- expect(fileList.findFileEl('Two.jpg').length).toEqual(1);
+ return promise.then(function(){
+ expect(copyStub.calledTwice).toEqual(true);
+ expect(fileList.findFileEl('Two.jpg').length).toEqual(1);
+ expect(fileList.findFileEl('One.txt').length).toEqual(1);
- // folder size has increased
- expect(fileList.findFileEl('somedir').data('size')).toEqual(12311);
- expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('12 KB');
+ // folder size has increased
+ expect(fileList.findFileEl('somedir').data('size')).toEqual(12311);
+ expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('12 KB');
- expect(notificationStub.notCalled).toEqual(false);
+ expect(notificationStub.notCalled).toEqual(false);
+ done();
+ });
});
- it('Shows notification if a file could not be copied', function() {
- fileList.copy('One.txt', '/somedir');
-
- expect(copyStub.calledOnce).toEqual(true);
+ it('Shows notification if a file could not be copied', function(done) {
+ copyStub.callsFake(function(){
+ expect(copyStub.calledOnce).toEqual(true);
+ return deferredCopy.promise();
+ });
+ var promise = fileList.copy('One.txt', '/somedir');
deferredCopy.reject(409);
-
- expect(fileList.findFileEl('One.txt').length).toEqual(1);
-
- expect(notificationStub.calledOnce).toEqual(true);
- expect(notificationStub.getCall(0).args[0]).toEqual('Could not copy "One.txt"');
+ return promise.then(function(){
+ expect(fileList.findFileEl('One.txt').length).toEqual(1);
+ expect(notificationStub.calledOnce).toEqual(true);
+ expect(notificationStub.getCall(0).args[0]).toEqual('Could not copy "One.txt"');
+ done();
+ });
});
- it('Restores thumbnail if a file could not be copied', function() {
- fileList.copy('One.txt', '/somedir');
-
- expect(fileList.findFileEl('One.txt').find('.thumbnail').parent().attr('class'))
- .toContain('icon-loading-small');
-
- expect(copyStub.calledOnce).toEqual(true);
+ it('Restores thumbnail if a file could not be copied', function(done) {
+ copyStub.callsFake(function(){
+ expect(fileList.findFileEl('One.txt').find('.thumbnail').parent().attr('class'))
+ .toContain('icon-loading-small');
+ expect(copyStub.calledOnce).toEqual(true);
+ return deferredCopy.promise();
+ });
+ var promise = fileList.copy('One.txt', '/somedir');
deferredCopy.reject(409);
+ return promise.then(function(){
+ expect(fileList.findFileEl('One.txt').length).toEqual(1);
- expect(fileList.findFileEl('One.txt').length).toEqual(1);
-
- expect(notificationStub.calledOnce).toEqual(true);
- expect(notificationStub.getCall(0).args[0]).toEqual('Could not copy "One.txt"');
+ expect(notificationStub.calledOnce).toEqual(true);
+ expect(notificationStub.getCall(0).args[0]).toEqual('Could not copy "One.txt"');
- expect(OC.TestUtil.getImageUrl(fileList.findFileEl('One.txt').find('.thumbnail')))
- .toEqual(OC.imagePath('core', 'filetypes/text.svg'));
+ expect(OC.TestUtil.getImageUrl(fileList.findFileEl('One.txt').find('.thumbnail')))
+ .toEqual(OC.imagePath('core', 'filetypes/text.svg'));
+ done();
+ });
});
});
@@ -2283,7 +2363,7 @@ describe('OCA.Files.FileList tests', function() {
var deleteStub, deferredDelete;
beforeEach(function() {
deferredDelete = $.Deferred();
- deleteStub = sinon.stub(filesClient, 'remove').returns(deferredDelete.promise());
+ deleteStub = sinon.stub(filesClient, 'remove');
fileList.$el.find('.actions-selected').click();
});
@@ -2292,34 +2372,54 @@ describe('OCA.Files.FileList tests', function() {
deleteStub.restore();
});
- it('Deletes selected files when "Delete" clicked', function() {
+ it('Deletes selected files when "Delete" clicked', function(done) {
+ var deferred = $.Deferred();
+
+ deleteStub.returns(deferredDelete.promise());
+ deleteStub.onCall(2).callsFake(function(){
+ expect(deleteStub.callCount).toEqual(3);
+ expect(deleteStub.getCall(0).args[0]).toEqual('/subdir/One.txt');
+ expect(deleteStub.getCall(1).args[0]).toEqual('/subdir/Three.pdf');
+ expect(deleteStub.getCall(2).args[0]).toEqual('/subdir/somedir');
+ return deferredDelete.promise();
+ });
+
+ stub = sinon.stub(fileList._operationProgressBar, 'hideProgressBar').callsFake(function(){
+ expect(fileList.findFileEl('One.txt').length).toEqual(0);
+ expect(fileList.findFileEl('Three.pdf').length).toEqual(0);
+ expect(fileList.findFileEl('somedir').length).toEqual(0);
+ expect(fileList.findFileEl('Two.jpg').length).toEqual(1);
+ done();
+ deferred.resolve();
+ });
$('.selectedActions .filesSelectMenu .delete').click();
-
- expect(deleteStub.callCount).toEqual(3);
- expect(deleteStub.getCall(0).args[0]).toEqual('/subdir/One.txt');
- expect(deleteStub.getCall(1).args[0]).toEqual('/subdir/Three.pdf');
- expect(deleteStub.getCall(2).args[0]).toEqual('/subdir/somedir');
-
deferredDelete.resolve(204);
+ return deferred.promise();
- expect(fileList.findFileEl('One.txt').length).toEqual(0);
- expect(fileList.findFileEl('Three.pdf').length).toEqual(0);
- expect(fileList.findFileEl('somedir').length).toEqual(0);
- expect(fileList.findFileEl('Two.jpg').length).toEqual(1);
});
- it('Deletes all files when all selected when "Delete" clicked', function() {
+ it('Deletes all files when all selected when "Delete" clicked', function(done) {
+ var deferred = $.Deferred();
+
+ deleteStub.returns(deferredDelete.promise());
+ deleteStub.onCall(3).callsFake(function(){
+ expect(deleteStub.getCall(0).args[0]).toEqual('/subdir/One.txt');
+ expect(deleteStub.getCall(1).args[0]).toEqual('/subdir/Two.jpg');
+ expect(deleteStub.getCall(2).args[0]).toEqual('/subdir/Three.pdf');
+ expect(deleteStub.getCall(3).args[0]).toEqual('/subdir/somedir');
+ return deferredDelete.promise();
+ });
+
+ stub = sinon.stub(fileList._operationProgressBar, 'hideProgressBar').callsFake(function(){
+ expect(fileList.isEmpty).toEqual(true);
+ expect(deleteStub.callCount).toEqual(4);
+ done();
+ deferred.resolve();
+ });
$('.select-all').click();
$('.selectedActions .filesSelectMenu .delete').click();
-
- expect(deleteStub.callCount).toEqual(4);
- expect(deleteStub.getCall(0).args[0]).toEqual('/subdir/One.txt');
- expect(deleteStub.getCall(1).args[0]).toEqual('/subdir/Two.jpg');
- expect(deleteStub.getCall(2).args[0]).toEqual('/subdir/Three.pdf');
- expect(deleteStub.getCall(3).args[0]).toEqual('/subdir/somedir');
-
deferredDelete.resolve(204);
- expect(fileList.isEmpty).toEqual(true);
+ return deferred.promise();
});
});
});
diff --git a/core/js/files/client.js b/core/js/files/client.js
index 9de732b3bd4..2017becf87c 100644
--- a/core/js/files/client.js
+++ b/core/js/files/client.js
@@ -427,6 +427,9 @@
_getSabreException: function(response) {
var result = {};
var xml = response.xhr.responseXML;
+ if (xml === null) {
+ return result;
+ }
var messages = xml.getElementsByTagNameNS('http://sabredav.org/ns', 'message');
var exceptions = xml.getElementsByTagNameNS('http://sabredav.org/ns', 'exception');
if (messages.length) {