From 296e69fe045363286cacdf37feccfde70d4f2444 Mon Sep 17 00:00:00 2001 From: Tomasz Grobelny Date: Mon, 12 Nov 2018 22:18:45 +0100 Subject: [PATCH 1/7] Restructuring code in file-upload.js Signed-off-by: Tomasz Grobelny --- apps/files/js/file-upload.js | 64 +++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 8d18761acc8..c16e734ac0a 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -757,14 +757,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 @@ -778,19 +770,49 @@ 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. + this._hideCancelButton(); + }, + + _hideProgressBar: function() { + var self = this; + $('#uploadprogresswrapper .stop').fadeOut(); + $('#uploadprogressbar').fadeOut(function() { + self.$uploadEl.trigger(new $.Event('resized')); + }); + }, + + _hideCancelButton: function() { $('#uploadprogresswrapper .stop').fadeOut(); }, _showProgressBar: function() { + $('#uploadprogresswrapper .stop').show(); + $('#uploadprogresswrapper .label').show(); $('#uploadprogressbar').fadeIn(); this.$uploadEl.trigger(new $.Event('resized')); }, + _setProgressBarValue: function(value) { + $('#uploadprogressbar').progressbar({value: value}); + }, + + _setProgressBarText: function(textDesktop, textMobile, title) { + $('#uploadprogressbar .ui-progressbar-value'). + html('' + + textDesktop + + '' + + textMobile + + ''); + $('#uploadprogressbar').tooltip({placement: 'bottom'}); + if(title) { + $('#uploadprogressbar').attr('original-title', title); + } + }, + /** * Returns whether the given file is known to be a received shared file * @@ -1096,16 +1118,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('' - + t('files', 'Uploading …') - + '' - + t('files', '…') - + ''); - $('#uploadprogressbar').tooltip({placement: 'bottom'}); + self._setProgressBarText(t('files', 'Uploading …'), t('files', '…')); + self._setProgressBarValue(0); self._showProgressBar(); // initial remaining time variables lastUpdate = new Date().getTime(); @@ -1155,16 +1169,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) { From e99340dc4da5f3a86ae32a14ef318b0d8b8f20fd Mon Sep 17 00:00:00 2001 From: Tomasz Grobelny Date: Tue, 13 Nov 2018 18:30:32 +0100 Subject: [PATCH 2/7] Move progress bar to separate component Signed-off-by: Tomasz Grobelny --- apps/files/js/file-upload.js | 34 +++------ apps/files/js/filelist.js | 5 ++ apps/files/js/merged-index.json | 1 + apps/files/js/operationprogressbar.js | 73 +++++++++++++++++++ apps/files/js/templates.js | 11 +++ .../templates/operationprogressbar.handlebars | 6 ++ apps/files/templates/list.php | 6 -- 7 files changed, 108 insertions(+), 28 deletions(-) create mode 100644 apps/files/js/operationprogressbar.js create mode 100644 apps/files/js/templates/operationprogressbar.handlebars diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index c16e734ac0a..741a6517af9 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -428,6 +428,11 @@ OC.Uploader.prototype = _.extend({ */ fileList: null, + /** + * @type OCA.Files.OperationProgressBar + */ + progressBar: null, + /** * @type OC.Files.Client */ @@ -778,39 +783,23 @@ OC.Uploader.prototype = _.extend({ }, _hideProgressBar: function() { - var self = this; - $('#uploadprogresswrapper .stop').fadeOut(); - $('#uploadprogressbar').fadeOut(function() { - self.$uploadEl.trigger(new $.Event('resized')); - }); + this.progressBar.hideProgressBar(); }, _hideCancelButton: function() { - $('#uploadprogresswrapper .stop').fadeOut(); + this.progressBar.hideCancelButton(); }, _showProgressBar: function() { - $('#uploadprogresswrapper .stop').show(); - $('#uploadprogresswrapper .label').show(); - $('#uploadprogressbar').fadeIn(); - this.$uploadEl.trigger(new $.Event('resized')); + this.progressBar.showProgressBar(); }, _setProgressBarValue: function(value) { - $('#uploadprogressbar').progressbar({value: value}); + this.progressBar.setProgressBarValue(value); }, _setProgressBarText: function(textDesktop, textMobile, title) { - $('#uploadprogressbar .ui-progressbar-value'). - html('' - + textDesktop - + '' - + textMobile - + ''); - $('#uploadprogressbar').tooltip({placement: 'bottom'}); - if(title) { - $('#uploadprogressbar').attr('original-title', title); - } + this.progressBar.setProgressBarText(textDesktop, textMobile, title); }, /** @@ -846,6 +835,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(), @@ -859,7 +849,7 @@ OC.Uploader.prototype = _.extend({ this.$uploadEl = $uploadEl; if ($uploadEl.exists()) { - $('#uploadprogresswrapper .stop').on('click', function() { + this.progressBar.on('cancel', function() { self.cancelUploads(); }); diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index bcecdb697fe..3ee5286a3db 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -379,11 +379,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'), diff --git a/apps/files/js/merged-index.json b/apps/files/js/merged-index.json index e891d10bdae..bc505e76034 100644 --- a/apps/files/js/merged-index.json +++ b/apps/files/js/merged-index.json @@ -22,6 +22,7 @@ "sidebarpreviewtext.js", "detailtabview.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..1d96c2374d4 --- /dev/null +++ b/apps/files/js/operationprogressbar.js @@ -0,0 +1,73 @@ +/* + * 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']({ + textDesktop: t('Uploading …'), + textMobile: t('…'), + textCancelButton: t('Cancel operation') + })); + }, + + 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() { + $('#uploadprogresswrapper .stop').show(); + $('#uploadprogresswrapper .label').show(); + $('#uploadprogressbar').fadeIn(); + this.$el.trigger(new $.Event('resized')); + }, + + setProgressBarValue: function(value) { + $('#uploadprogressbar').progressbar({value: value}); + }, + + setProgressBarText: function(textDesktop, textMobile, title) { + $('#uploadprogressbar .ui-progressbar-value'). + html('' + + textDesktop + + '' + + textMobile + + ''); + $('#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/templates.js b/apps/files/js/templates.js index a2bdae5b3c4..0d41c52797f 100644 --- a/apps/files/js/templates.js +++ b/apps/files/js/templates.js @@ -245,6 +245,17 @@ 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 \n\n"; },"useData":true}); +templates['operationprogressbar'] = 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 "
\n " + + 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))) + + "" + + 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))) + + "\n
\n\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..5d6a7e860f0 --- /dev/null +++ b/apps/files/js/templates/operationprogressbar.handlebars @@ -0,0 +1,6 @@ +
+ +
+ 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 @@
From 7bafa54ae168a25b47d579fdca4cec19f2e1534f Mon Sep 17 00:00:00 2001 From: Tomasz Grobelny Date: Tue, 13 Nov 2018 23:19:08 +0100 Subject: [PATCH 3/7] Fix progress bar label Signed-off-by: Tomasz Grobelny --- apps/files/js/operationprogressbar.js | 14 ++++++-------- apps/files/js/templates.js | 15 ++++++++++----- .../js/templates/operationprogressbar.handlebars | 2 +- .../operationprogressbarlabel.handlebars | 4 ++++ 4 files changed, 21 insertions(+), 14 deletions(-) create mode 100644 apps/files/js/templates/operationprogressbarlabel.handlebars diff --git a/apps/files/js/operationprogressbar.js b/apps/files/js/operationprogressbar.js index 1d96c2374d4..0ce532af494 100644 --- a/apps/files/js/operationprogressbar.js +++ b/apps/files/js/operationprogressbar.js @@ -18,10 +18,9 @@ render: function() { this.$el.html(OCA.Files.Templates['operationprogressbar']({ - textDesktop: t('Uploading …'), - textMobile: t('…'), textCancelButton: t('Cancel operation') })); + this.setProgressBarText(t('Uploading …'), t('…')); }, hideProgressBar: function() { @@ -50,12 +49,11 @@ }, setProgressBarText: function(textDesktop, textMobile, title) { - $('#uploadprogressbar .ui-progressbar-value'). - html('' - + textDesktop - + '' - + textMobile - + ''); + 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); diff --git a/apps/files/js/templates.js b/apps/files/js/templates.js index 0d41c52797f..be6b255d594 100644 --- a/apps/files/js/templates.js +++ b/apps/files/js/templates.js @@ -246,15 +246,20 @@ templates['newfilemenu_filename_form'] = template({"compiler":[7,">= 4.0.0"],"ma + "\" autocomplete=\"off\" autocapitalize=\"off\">\n \n\n"; },"useData":true}); templates['operationprogressbar'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { + var helper; + + return "
\n \n
\n\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 "
\n " + return "\n " + 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))) - + "" + + "\n " + 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))) - + "\n
\n\n"; + + "\n\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 index 5d6a7e860f0..c02ac623fab 100644 --- a/apps/files/js/templates/operationprogressbar.handlebars +++ b/apps/files/js/templates/operationprogressbar.handlebars @@ -1,5 +1,5 @@
- +
' ); $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); }); @@ -142,6 +144,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(); }); }); });