aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/tests
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2015-12-16 17:35:53 +0100
committerRoeland Jago Douma <roeland@famdouma.nl>2016-10-24 21:45:00 +0200
commit59c5be1cc572793a8d50e87ab589e1cc4cf2ed12 (patch)
tree97b096fee075115bac45d69f2e0da7af5ffb41f2 /apps/files/tests
parent4d01f23978549c2a33e9fdfdc3b9308cc9dc1078 (diff)
downloadnextcloud-server-59c5be1cc572793a8d50e87ab589e1cc4cf2ed12.tar.gz
nextcloud-server-59c5be1cc572793a8d50e87ab589e1cc4cf2ed12.zip
Use Webdav PUT for uploads in the web browser
- uses PUT method with jquery.fileupload for regular and public file lists - for IE and browsers that don't support it, use POST with iframe transport - implemented Sabre plugin to handle iframe transport and redirect the embedded PUT request to the proper handler - added RFC5995 POST to file collection with "add-member" property to make it possible to auto-rename conflicting file names - remove obsolete ajax/upload.php and obsolete ajax routes Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Diffstat (limited to 'apps/files/tests')
-rw-r--r--apps/files/tests/js/fileUploadSpec.js141
-rw-r--r--apps/files/tests/js/filelistSpec.js208
2 files changed, 257 insertions, 92 deletions
diff --git a/apps/files/tests/js/fileUploadSpec.js b/apps/files/tests/js/fileUploadSpec.js
index 0483d4649d4..bfaf0a9fe57 100644
--- a/apps/files/tests/js/fileUploadSpec.js
+++ b/apps/files/tests/js/fileUploadSpec.js
@@ -19,11 +19,11 @@
*
*/
-/* global FileList */
-
describe('OC.Upload tests', function() {
var $dummyUploader;
var testFile;
+ var uploader;
+ var failStub;
beforeEach(function() {
testFile = {
@@ -46,59 +46,64 @@ describe('OC.Upload tests', function() {
'</div>'
);
$dummyUploader = $('#file_upload_start');
+ uploader = new OC.Uploader($dummyUploader);
+ failStub = sinon.stub();
+ $dummyUploader.on('fileuploadfail', failStub);
});
afterEach(function() {
- delete window.file_upload_param;
$dummyUploader = undefined;
+ failStub = undefined;
});
- describe('Adding files for upload', function() {
- var params;
- var failStub;
- beforeEach(function() {
- params = OC.Upload.init();
- failStub = sinon.stub();
- $dummyUploader.on('fileuploadfail', failStub);
- });
- afterEach(function() {
- params = undefined;
- failStub = undefined;
- });
-
- /**
- * Add file for upload
- * @param file file data
- */
- function addFile(file) {
- return params.add.call(
+ /**
+ * Add file for upload
+ * @param {Array.<File>} files array of file data to simulate upload
+ * @return {Array.<Object>} array of uploadinfo or null if add() returned false
+ */
+ function addFiles(uploader, files) {
+ return _.map(files, function(file) {
+ var jqXHR = {status: 200};
+ var uploadInfo = {
+ originalFiles: files,
+ files: [file],
+ jqXHR: jqXHR,
+ response: sinon.stub.returns(jqXHR),
+ submit: sinon.stub()
+ };
+ if (uploader.fileUploadParam.add.call(
$dummyUploader[0],
{},
- {
- originalFiles: {},
- files: [file]
- });
- }
+ uploadInfo
+ )) {
+ return uploadInfo;
+ }
+ return null;
+ });
+ }
+ describe('Adding files for upload', function() {
it('adds file when size is below limits', function() {
- var result = addFile(testFile);
- expect(result).toEqual(true);
+ var result = addFiles(uploader, [testFile]);
+ expect(result[0]).not.toEqual(null);
+ expect(result[0].submit.calledOnce).toEqual(true);
});
it('adds file when free space is unknown', function() {
var result;
$('#free_space').val(-2);
- result = addFile(testFile);
+ result = addFiles(uploader, [testFile]);
- expect(result).toEqual(true);
+ expect(result[0]).not.toEqual(null);
+ expect(result[0].submit.calledOnce).toEqual(true);
expect(failStub.notCalled).toEqual(true);
});
it('does not add file if it exceeds upload limit', function() {
var result;
$('#upload_limit').val(1000);
- result = addFile(testFile);
+ result = addFiles(uploader, [testFile]);
- expect(result).toEqual(false);
+ expect(result[0]).toEqual(null);
expect(failStub.calledOnce).toEqual(true);
expect(failStub.getCall(0).args[1].textStatus).toEqual('sizeexceedlimit');
expect(failStub.getCall(0).args[1].errorThrown).toEqual(
@@ -109,9 +114,9 @@ describe('OC.Upload tests', function() {
var result;
$('#free_space').val(1000);
- result = addFile(testFile);
+ result = addFiles(uploader, [testFile]);
- expect(result).toEqual(false);
+ expect(result[0]).toEqual(null);
expect(failStub.calledOnce).toEqual(true);
expect(failStub.getCall(0).args[1].textStatus).toEqual('notenoughspace');
expect(failStub.getCall(0).args[1].errorThrown).toEqual(
@@ -120,12 +125,10 @@ describe('OC.Upload tests', function() {
});
});
describe('Upload conflicts', function() {
- var oldFileList;
var conflictDialogStub;
- var callbacks;
+ var fileList;
beforeEach(function() {
- oldFileList = FileList;
$('#testArea').append(
'<div id="tableContainer">' +
'<table id="filestable">' +
@@ -145,74 +148,56 @@ describe('OC.Upload tests', function() {
'</table>' +
'</div>'
);
- FileList = new OCA.Files.FileList($('#tableContainer'));
+ fileList = new OCA.Files.FileList($('#tableContainer'));
- FileList.add({name: 'conflict.txt', mimetype: 'text/plain'});
- FileList.add({name: 'conflict2.txt', mimetype: 'text/plain'});
+ fileList.add({name: 'conflict.txt', mimetype: 'text/plain'});
+ fileList.add({name: 'conflict2.txt', mimetype: 'text/plain'});
conflictDialogStub = sinon.stub(OC.dialogs, 'fileexists');
- callbacks = {
- onNoConflicts: sinon.stub()
- };
+
+ uploader = new OC.Uploader($dummyUploader, {
+ fileList: fileList
+ });
});
afterEach(function() {
conflictDialogStub.restore();
- FileList.destroy();
- FileList = oldFileList;
+ fileList.destroy();
});
it('does not show conflict dialog when no client side conflict', function() {
- var selection = {
- // yes, the format of uploads is weird...
- uploads: [
- {files: [{name: 'noconflict.txt'}]},
- {files: [{name: 'noconflict2.txt'}]}
- ]
- };
-
- OC.Upload.checkExistingFiles(selection, callbacks);
+ var result = addFiles(uploader, [{name: 'noconflict.txt'}, {name: 'noconflict2.txt'}]);
expect(conflictDialogStub.notCalled).toEqual(true);
- expect(callbacks.onNoConflicts.calledOnce).toEqual(true);
- expect(callbacks.onNoConflicts.calledWith(selection)).toEqual(true);
+ expect(result[0].submit.calledOnce).toEqual(true);
+ expect(result[1].submit.calledOnce).toEqual(true);
});
it('shows conflict dialog when no client side conflict', function() {
- var selection = {
- // yes, the format of uploads is weird...
- uploads: [
- {files: [{name: 'conflict.txt'}]},
- {files: [{name: 'conflict2.txt'}]},
- {files: [{name: 'noconflict.txt'}]}
- ]
- };
-
var deferred = $.Deferred();
conflictDialogStub.returns(deferred.promise());
deferred.resolve();
- OC.Upload.checkExistingFiles(selection, callbacks);
+ var result = addFiles(uploader, [
+ {name: 'conflict.txt'},
+ {name: 'conflict2.txt'},
+ {name: 'noconflict.txt'}
+ ]);
expect(conflictDialogStub.callCount).toEqual(3);
- expect(conflictDialogStub.getCall(1).args[0])
- .toEqual({files: [ { name: 'conflict.txt' } ]});
+ expect(conflictDialogStub.getCall(1).args[0].getFileName())
+ .toEqual('conflict.txt');
expect(conflictDialogStub.getCall(1).args[1])
.toEqual({ name: 'conflict.txt', mimetype: 'text/plain', directory: '/' });
expect(conflictDialogStub.getCall(1).args[2]).toEqual({ name: 'conflict.txt' });
// yes, the dialog must be called several times...
- expect(conflictDialogStub.getCall(2).args[0]).toEqual({
- files: [ { name: 'conflict2.txt' } ]
- });
+ expect(conflictDialogStub.getCall(2).args[0].getFileName()).toEqual('conflict2.txt');
expect(conflictDialogStub.getCall(2).args[1])
.toEqual({ name: 'conflict2.txt', mimetype: 'text/plain', directory: '/' });
expect(conflictDialogStub.getCall(2).args[2]).toEqual({ name: 'conflict2.txt' });
- expect(callbacks.onNoConflicts.calledOnce).toEqual(true);
- expect(callbacks.onNoConflicts.calledWith({
- uploads: [
- {files: [{name: 'noconflict.txt'}]}
- ]
- })).toEqual(true);
+ expect(result[0].submit.calledOnce).toEqual(false);
+ expect(result[1].submit.calledOnce).toEqual(false);
+ expect(result[2].submit.calledOnce).toEqual(true);
});
});
});
diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js
index 304f8438a59..55ab2c535af 100644
--- a/apps/files/tests/js/filelistSpec.js
+++ b/apps/files/tests/js/filelistSpec.js
@@ -159,7 +159,8 @@ describe('OCA.Files.FileList tests', function() {
pageSizeStub = sinon.stub(OCA.Files.FileList.prototype, 'pageSize').returns(20);
fileList = new OCA.Files.FileList($('#app-content-files'), {
filesClient: filesClient,
- config: filesConfig
+ config: filesConfig,
+ enableUpload: true
});
});
afterEach(function() {
@@ -2441,7 +2442,7 @@ describe('OCA.Files.FileList tests', function() {
deferredInfo.resolve(
200,
- new FileInfo({
+ new FileInfo({
path: '/subdir',
name: 'test.txt',
mimetype: 'text/plain'
@@ -2501,12 +2502,70 @@ describe('OCA.Files.FileList tests', function() {
// TODO: error cases
// TODO: unique name cases
});
+ describe('addAndFetchFileInfo', function() {
+ var getFileInfoStub;
+ var getFileInfoDeferred;
+
+ beforeEach(function() {
+ getFileInfoDeferred = $.Deferred();
+ getFileInfoStub = sinon.stub(OC.Files.Client.prototype, 'getFileInfo');
+ getFileInfoStub.returns(getFileInfoDeferred.promise());
+ });
+ afterEach(function() {
+ getFileInfoStub.restore();
+ });
+ it('does not fetch if the given folder is not the current one', function() {
+ var promise = fileList.addAndFetchFileInfo('testfile.txt', '/another');
+ expect(getFileInfoStub.notCalled).toEqual(true);
+
+ expect(promise.state()).toEqual('resolved');
+ });
+ it('fetches info when folder is the current one', function() {
+ fileList.addAndFetchFileInfo('testfile.txt', '/subdir');
+ expect(getFileInfoStub.calledOnce).toEqual(true);
+ expect(getFileInfoStub.getCall(0).args[0]).toEqual('/subdir/testfile.txt');
+ });
+ it('adds file data to list when fetching is done', function() {
+ fileList.addAndFetchFileInfo('testfile.txt', '/subdir');
+ getFileInfoDeferred.resolve(200, {
+ name: 'testfile.txt',
+ size: 100
+ });
+ expect(fileList.findFileEl('testfile.txt').attr('data-size')).toEqual('100');
+ });
+ it('replaces file data to list when fetching is done', function() {
+ fileList.addAndFetchFileInfo('testfile.txt', '/subdir', {replace: true});
+ fileList.add({
+ name: 'testfile.txt',
+ size: 95
+ });
+ getFileInfoDeferred.resolve(200, {
+ name: 'testfile.txt',
+ size: 100
+ });
+ expect(fileList.findFileEl('testfile.txt').attr('data-size')).toEqual('100');
+ });
+ it('resolves promise with file data when fetching is done', function() {
+ var promise = fileList.addAndFetchFileInfo('testfile.txt', '/subdir', {replace: true});
+ getFileInfoDeferred.resolve(200, {
+ name: 'testfile.txt',
+ size: 100
+ });
+ expect(promise.state()).toEqual('resolved');
+ promise.then(function(status, data) {
+ expect(status).toEqual(200);
+ expect(data.name).toEqual('testfile.txt');
+ expect(data.size).toEqual(100);
+ });
+ });
+ });
/**
* Test upload mostly by testing the code inside the event handlers
* that were registered on the magic upload object
*/
describe('file upload', function() {
var $uploader;
+ var uploadData;
beforeEach(function() {
// note: this isn't the real blueimp file uploader from jquery.fileupload
@@ -2514,14 +2573,52 @@ describe('OCA.Files.FileList tests', function() {
// test the response of the handlers
$uploader = $('#file_upload_start');
fileList.setFiles(testFiles);
+ // simulate data structure from jquery.upload
+ uploadData = {
+ files: [{
+ name: 'upload.txt'
+ }]
+ };
});
afterEach(function() {
$uploader = null;
+ uploadData = null;
});
+ describe('enableupload', function() {
+ it('sets up uploader when enableUpload is true', function() {
+ expect(fileList._uploader).toBeDefined();
+ });
+ it('does not sets up uploader when enableUpload is false', function() {
+ fileList.destroy();
+ fileList = new OCA.Files.FileList($('#app-content-files'), {
+ filesClient: filesClient
+ });
+ expect(fileList._uploader).toBeFalsy();
+ });
+ });
+
+ describe('adding files for upload', function() {
+ /**
+ * Simulate add event on the given target
+ *
+ * @return event object including the result
+ */
+ function addFile(data) {
+ var ev = new $.Event('fileuploadadd', {});
+ // using triggerHandler instead of trigger so we can pass
+ // extra data
+ $uploader.triggerHandler(ev, data || {});
+ return ev;
+ }
+
+ it('sets target dir to the current directory', function() {
+ addFile(uploadData);
+ expect(uploadData.targetDir).toEqual('/subdir');
+ });
+ });
describe('dropping external files', function() {
- var uploadData;
/**
* Simulate drop event on the given target
@@ -2540,17 +2637,6 @@ describe('OCA.Files.FileList tests', function() {
return ev;
}
- beforeEach(function() {
- // simulate data structure from jquery.upload
- uploadData = {
- files: [{
- relativePath: 'fileToUpload.txt'
- }]
- };
- });
- afterEach(function() {
- uploadData = null;
- });
it('drop on a tr or crumb outside file list does not trigger upload', function() {
var $anotherTable = $('<table><tbody><tr><td>outside<div class="crumb">crumb</div></td></tr></table>');
var ev;
@@ -2574,12 +2660,14 @@ describe('OCA.Files.FileList tests', function() {
ev = dropOn(fileList.$fileList.find('th:first'), uploadData);
expect(ev.result).not.toEqual(false);
+ expect(uploadData.targetDir).toEqual('/subdir');
});
it('drop on an element on the table container triggers upload', function() {
var ev;
ev = dropOn($('#app-content-files'), uploadData);
expect(ev.result).not.toEqual(false);
+ expect(uploadData.targetDir).toEqual('/subdir');
});
it('drop on an element inside the table does not trigger upload if no upload permission', function() {
$('#permissions').val(0);
@@ -2603,6 +2691,7 @@ describe('OCA.Files.FileList tests', function() {
ev = dropOn(fileList.findFileEl('One.txt').find('td:first'), uploadData);
expect(ev.result).not.toEqual(false);
+ expect(uploadData.targetDir).toEqual('/subdir');
});
it('drop on a folder row inside the table triggers upload to target folder', function() {
var ev;
@@ -2635,6 +2724,97 @@ describe('OCA.Files.FileList tests', function() {
expect(fileList.findFileEl('afile.txt').find('.uploadtext').length).toEqual(0);
});
});
+
+ describe('after folder creation due to folder upload', function() {
+ it('fetches folder info', function() {
+ var fetchInfoStub = sinon.stub(fileList, 'addAndFetchFileInfo');
+
+ var ev = new $.Event('fileuploadcreatedfolder', {});
+ $uploader.triggerHandler(ev, '/subdir/newfolder');
+
+ expect(fetchInfoStub.calledOnce).toEqual(true);
+ expect(fetchInfoStub.getCall(0).args[0]).toEqual('newfolder');
+ expect(fetchInfoStub.getCall(0).args[1]).toEqual('/subdir');
+
+ fetchInfoStub.restore();
+ });
+ });
+
+ describe('after upload', function() {
+ var fetchInfoStub;
+
+ beforeEach(function() {
+ fetchInfoStub = sinon.stub(fileList, 'addAndFetchFileInfo');
+
+ });
+ afterEach(function() {
+ fetchInfoStub.restore();
+ });
+
+
+ function createUpload(name, dir) {
+ var data = {
+ files: [{
+ name: name
+ }],
+ upload: {
+ getFileName: sinon.stub().returns(name),
+ getFullPath: sinon.stub().returns(dir)
+ },
+ jqXHR: {
+ status: 200
+ }
+ }
+ return data;
+ }
+
+ /**
+ * Simulate add event on the given target
+ *
+ * @return event object including the result
+ */
+ function addFile(data) {
+ var ev = new $.Event('fileuploaddone', {});
+ // using triggerHandler instead of trigger so we can pass
+ // extra data
+ var deferred = $.Deferred();
+ fetchInfoStub.returns(deferred.promise());
+ $uploader.triggerHandler(ev, data || {});
+ return deferred;
+ }
+
+ it('fetches file info', function() {
+ addFile(createUpload('upload.txt', '/subdir'));
+ expect(fetchInfoStub.calledOnce).toEqual(true);
+ expect(fetchInfoStub.getCall(0).args[0]).toEqual('upload.txt');
+ expect(fetchInfoStub.getCall(0).args[1]).toEqual('/subdir');
+ });
+ it('highlights all uploaded files after all fetches are done', function() {
+ var highlightStub = sinon.stub(fileList, 'highlightFiles');
+ var def1 = addFile(createUpload('upload.txt', '/subdir'));
+ var def2 = addFile(createUpload('upload2.txt', '/subdir'));
+ var def3 = addFile(createUpload('upload3.txt', '/another'));
+ $uploader.triggerHandler(new $.Event('fileuploadstop'));
+
+ expect(highlightStub.notCalled).toEqual(true);
+ def1.resolve();
+ expect(highlightStub.notCalled).toEqual(true);
+ def2.resolve();
+ def3.resolve();
+ expect(highlightStub.calledOnce).toEqual(true);
+ expect(highlightStub.getCall(0).args[0]).toEqual(['upload.txt', 'upload2.txt']);
+
+ highlightStub.restore();
+ });
+ it('queries storage stats', function() {
+ var statStub = sinon.stub(fileList, 'updateStorageStatistics');
+ addFile(createUpload('upload.txt', '/subdir'));
+ expect(statStub.notCalled).toEqual(true);
+ $uploader.triggerHandler(new $.Event('fileuploadstop'));
+ expect(statStub.calledOnce).toEqual(true);
+ statStub.restore();
+ });
+ });
});
describe('Handling errors', function () {
var deferredList;