diff options
Diffstat (limited to 'apps/files')
-rw-r--r-- | apps/files/ajax/delete.php | 2 | ||||
-rw-r--r-- | apps/files/ajax/move.php | 2 | ||||
-rw-r--r-- | apps/files/ajax/rawlist.php | 59 | ||||
-rw-r--r-- | apps/files/js/admin.js | 19 | ||||
-rw-r--r-- | apps/files/js/file-upload.js | 1015 | ||||
-rw-r--r-- | apps/files/js/filelist.js | 17 | ||||
-rw-r--r-- | apps/files/js/files.js | 11 | ||||
-rw-r--r-- | apps/files/templates/part.list.php | 16 | ||||
-rw-r--r-- | apps/files/tests/js/fileUploadSpec.js | 127 | ||||
-rw-r--r-- | apps/files/tests/js/filesSpec.js | 35 |
10 files changed, 739 insertions, 564 deletions
diff --git a/apps/files/ajax/delete.php b/apps/files/ajax/delete.php index 69f859daa97..99f49188384 100644 --- a/apps/files/ajax/delete.php +++ b/apps/files/ajax/delete.php @@ -9,7 +9,7 @@ OCP\JSON::callCheck(); // Get data $dir = stripslashes($_POST["dir"]); $files = isset($_POST["file"]) ? $_POST["file"] : $_POST["files"]; -$allFiles = isset($_POST["allfiles"]) ? $_POST["allfiles"] : $_POST["allfiles"]; +$allFiles = isset($_POST["allfiles"]) ? $_POST["allfiles"] : false; if ($allFiles === 'true') { $allFiles = true; } diff --git a/apps/files/ajax/move.php b/apps/files/ajax/move.php index 93063e52eb0..04a260265c2 100644 --- a/apps/files/ajax/move.php +++ b/apps/files/ajax/move.php @@ -18,7 +18,7 @@ if(\OC\Files\Filesystem::file_exists($target . '/' . $file)) { exit; } -if ($dir != '' || $file != 'Shared') { +if ($target != '' || strtolower($file) != 'shared') { $targetFile = \OC\Files\Filesystem::normalizePath($target . '/' . $file); $sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file); if(\OC\Files\Filesystem::rename($sourceFile, $targetFile)) { diff --git a/apps/files/ajax/rawlist.php b/apps/files/ajax/rawlist.php index 40da32b223a..89c21a172fc 100644 --- a/apps/files/ajax/rawlist.php +++ b/apps/files/ajax/rawlist.php @@ -1,12 +1,12 @@ <?php // only need filesystem apps -$RUNTIME_APPTYPES=array('filesystem'); +$RUNTIME_APPTYPES = array('filesystem'); OCP\JSON::checkLoggedIn(); // Load the files -$dir = isset( $_GET['dir'] ) ? $_GET['dir'] : ''; +$dir = isset($_GET['dir']) ? $_GET['dir'] : ''; $mimetypes = isset($_GET['mimetypes']) ? json_decode($_GET['mimetypes'], true) : ''; // Clean up duplicates from array and deal with non-array requests @@ -18,43 +18,40 @@ if (is_array($mimetypes)) { // make filelist $files = array(); +/** + * @var \OCP\Files\FileInfo[] $files + */ // If a type other than directory is requested first load them. -if($mimetypes && !in_array('httpd/unix-directory', $mimetypes)) { - foreach( \OC\Files\Filesystem::getDirectoryContent( $dir, 'httpd/unix-directory' ) as $file ) { - $file['directory'] = $dir; - $file['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file['mimetype']); - $file["date"] = OCP\Util::formatDate($file["mtime"]); - $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file); - $files[] = $file; - } +if ($mimetypes && !in_array('httpd/unix-directory', $mimetypes)) { + $files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir, 'httpd/unix-directory')); } if (is_array($mimetypes) && count($mimetypes)) { foreach ($mimetypes as $mimetype) { - foreach( \OC\Files\Filesystem::getDirectoryContent( $dir, $mimetype ) as $file ) { - $file['directory'] = $dir; - $file['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file['mimetype']); - $file["date"] = OCP\Util::formatDate($file["mtime"]); - $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file); - $files[] = $file; - } + $files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir, $mimetype)); } } else { - foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $file ) { - $file['directory'] = $dir; - $file['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file['mimetype']); - $file["date"] = OCP\Util::formatDate($file["mtime"]); - $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file); - $files[] = $file; - } + $files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir)); +} + +$result = array(); +foreach ($files as $file) { + $fileData = array(); + $fileData['directory'] = $dir; + $fileData['name'] = $file->getName(); + $fileData['type'] = $file->getType(); + $fileData['path'] = $file['path']; + $fileData['id'] = $file->getId(); + $fileData['size'] = $file->getSize(); + $fileData['mtime'] = $file->getMtime(); + $fileData['mimetype'] = $file->getMimetype(); + $fileData['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file->getMimetype()); + $fileData["date"] = OCP\Util::formatDate($file->getMtime()); + $fileData['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file); + $result[] = $fileData; } // Sort by name -usort($files, function ($a, $b) { - if ($a['name'] === $b['name']) { - return 0; - } - return ($a['name'] < $b['name']) ? -1 : 1; -}); +usort($result, array('\OCA\Files\Helper', 'fileCmp')); -OC_JSON::success(array('data' => $files)); +OC_JSON::success(array('data' => $result)); diff --git a/apps/files/js/admin.js b/apps/files/js/admin.js index f735079fcbe..842b73c0cae 100644 --- a/apps/files/js/admin.js +++ b/apps/files/js/admin.js @@ -8,19 +8,22 @@ * */ -function switchPublicFolder() -{ +function switchPublicFolder() { var publicEnable = $('#publicEnable').is(':checked'); - var sharingaimGroup = $('input:radio[name=sharingaim]'); //find all radiobuttons of that group + // find all radiobuttons of that group + var sharingaimGroup = $('input:radio[name=sharingaim]'); $.each(sharingaimGroup, function(index, sharingaimItem) { - sharingaimItem.disabled = !publicEnable; //set all buttons to the correct state + // set all buttons to the correct state + sharingaimItem.disabled = !publicEnable; }); } -$(document).ready(function(){ - switchPublicFolder(); // Execute the function after loading DOM tree - $('#publicEnable').click(function(){ - switchPublicFolder(); // To get rid of onClick() +$(document).ready(function() { + // Execute the function after loading DOM tree + switchPublicFolder(); + $('#publicEnable').click(function() { + // To get rid of onClick() + switchPublicFolder(); }); $('#allowZipDownload').bind('change', function() { diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index f962a7044a8..ea4061c9b0b 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -82,7 +82,7 @@ OC.Upload = { */ isProcessing:function() { var count = 0; - + jQuery.each(this._uploads,function(i, data) { if (data.state() === 'pending') { count++; @@ -177,549 +177,556 @@ OC.Upload = { checkExistingFiles: function (selection, callbacks) { // TODO check filelist before uploading and show dialog on conflicts, use callbacks callbacks.onNoConflicts(selection); - } -}; + }, -$(document).ready(function() { + init: function() { + if ( $('#file_upload_start').exists() && $('#file_upload_start').is(':visible')) { - if ( $('#file_upload_start').exists() ) { - - var file_upload_param = { - dropZone: $('#content'), // restrict dropZone to content div - autoUpload: false, - sequentialUploads: true, - //singleFileUploads is on by default, so the data.files array will always have length 1 - /** - * on first add of every selection - * - check all files of originalFiles array with files in dir - * - on conflict show dialog - * - skip all -> remember as single skip action for all conflicting files - * - replace all -> remember as single replace action for all conflicting files - * - choose -> show choose dialog - * - mark files to keep - * - when only existing -> remember as single skip action - * - when only new -> remember as single replace action - * - when both -> remember as single autorename action - * - start uploading selection - * @param {object} e - * @param {object} data - * @returns {boolean} - */ - add: function(e, data) { - OC.Upload.log('add', e, data); - var that = $(this); - - // we need to collect all data upload objects before starting the upload so we can check their existence - // and set individual conflict actions. unfortunately there is only one variable that we can use to identify - // the selection a data upload is part of, so we have to collect them in data.originalFiles - // turning singleFileUploads off is not an option because we want to gracefully handle server errors like - // already exists - - // create a container where we can store the data objects - if ( ! data.originalFiles.selection ) { - // initialize selection and remember number of files to upload - data.originalFiles.selection = { - uploads: [], - filesToUpload: data.originalFiles.length, - totalBytes: 0 - }; - } - var selection = data.originalFiles.selection; - - // add uploads - if ( selection.uploads.length < selection.filesToUpload ) { - // remember upload - selection.uploads.push(data); - } - - //examine file - var file = data.files[0]; - try { - // FIXME: not so elegant... need to refactor that method to return a value - Files.isFileNameValid(file.name); - } - catch (errorMessage) { - data.textStatus = 'invalidcharacters'; - data.errorThrown = errorMessage; - } - - if (file.type === '' && file.size === 4096) { - data.textStatus = 'dirorzero'; - data.errorThrown = t('files', 'Unable to upload {filename} as it is a directory or has 0 bytes', - {filename: file.name} - ); - } - - // add size - selection.totalBytes += file.size; - - // check PHP upload limit - if (selection.totalBytes > $('#upload_limit').val()) { - data.textStatus = 'sizeexceedlimit'; - data.errorThrown = t('files', 'Total file size {size1} exceeds upload limit {size2}', { - 'size1': humanFileSize(selection.totalBytes), - 'size2': humanFileSize($('#upload_limit').val()) - }); - } + var file_upload_param = { + dropZone: $('#content'), // restrict dropZone to content div + autoUpload: false, + sequentialUploads: true, + //singleFileUploads is on by default, so the data.files array will always have length 1 + /** + * on first add of every selection + * - check all files of originalFiles array with files in dir + * - on conflict show dialog + * - skip all -> remember as single skip action for all conflicting files + * - replace all -> remember as single replace action for all conflicting files + * - choose -> show choose dialog + * - mark files to keep + * - when only existing -> remember as single skip action + * - when only new -> remember as single replace action + * - when both -> remember as single autorename action + * - start uploading selection + * @param {object} e + * @param {object} data + * @returns {boolean} + */ + add: function(e, data) { + OC.Upload.log('add', e, data); + var that = $(this); + var freeSpace; - // check free space - if (selection.totalBytes > $('#free_space').val()) { - data.textStatus = 'notenoughspace'; - data.errorThrown = t('files', 'Not enough free space, you are uploading {size1} but only {size2} is left', { - 'size1': humanFileSize(selection.totalBytes), - 'size2': humanFileSize($('#free_space').val()) - }); - } - - // end upload for whole selection on error - if (data.errorThrown) { - // trigger fileupload fail - var fu = that.data('blueimp-fileupload') || that.data('fileupload'); - fu._trigger('fail', e, data); - return false; //don't upload anything - } + // we need to collect all data upload objects before starting the upload so we can check their existence + // and set individual conflict actions. unfortunately there is only one variable that we can use to identify + // the selection a data upload is part of, so we have to collect them in data.originalFiles + // turning singleFileUploads off is not an option because we want to gracefully handle server errors like + // already exists - // check existing files when all is collected - if ( selection.uploads.length >= selection.filesToUpload ) { - - //remove our selection hack: - delete data.originalFiles.selection; - - var callbacks = { - - onNoConflicts: function (selection) { - $.each(selection.uploads, function(i, upload) { - upload.submit(); - }); - }, - onSkipConflicts: function (selection) { - //TODO mark conflicting files as toskip - }, - onReplaceConflicts: function (selection) { - //TODO mark conflicting files as toreplace - }, - onChooseConflicts: function (selection) { - //TODO mark conflicting files as chosen - }, - onCancel: function (selection) { - $.each(selection.uploads, function(i, upload) { - upload.abort(); - }); - } - }; + // create a container where we can store the data objects + if ( ! data.originalFiles.selection ) { + // initialize selection and remember number of files to upload + data.originalFiles.selection = { + uploads: [], + filesToUpload: data.originalFiles.length, + totalBytes: 0 + }; + } + var selection = data.originalFiles.selection; - OC.Upload.checkExistingFiles(selection, callbacks); - - } + // add uploads + if ( selection.uploads.length < selection.filesToUpload ) { + // remember upload + selection.uploads.push(data); + } - return true; // continue adding files - }, - /** - * called after the first add, does NOT have the data param - * @param {object} e - */ - start: function(e) { - OC.Upload.log('start', e, null); - }, - submit: function(e, data) { - OC.Upload.rememberUpload(data); - if ( ! data.formData ) { - // noone set update parameters, we set the minimum - data.formData = { - requesttoken: oc_requesttoken, - dir: $('#dir').val() - }; - } - }, - fail: function(e, data) { - OC.Upload.log('fail', e, data); - if (typeof data.textStatus !== 'undefined' && data.textStatus !== 'success' ) { - if (data.textStatus === 'abort') { - OC.Notification.show(t('files', 'Upload cancelled.')); - } else { - // HTTP connection problem - OC.Notification.show(data.errorThrown); - if (data.result) { - var result = JSON.parse(data.result); - if (result && result[0] && result[0].data && result[0].data.code === 'targetnotfound') { - // abort upload of next files if any - OC.Upload.cancelUploads(); + //examine file + var file = data.files[0]; + try { + // FIXME: not so elegant... need to refactor that method to return a value + Files.isFileNameValid(file.name, FileList.getCurrentDirectory()); + } + catch (errorMessage) { + data.textStatus = 'invalidcharacters'; + data.errorThrown = errorMessage; + } + + if (file.type === '' && file.size === 4096) { + data.textStatus = 'dirorzero'; + data.errorThrown = t('files', 'Unable to upload {filename} as it is a directory or has 0 bytes', + {filename: file.name} + ); + } + + // add size + selection.totalBytes += file.size; + + // check PHP upload limit + if (selection.totalBytes > $('#upload_limit').val()) { + data.textStatus = 'sizeexceedlimit'; + data.errorThrown = t('files', 'Total file size {size1} exceeds upload limit {size2}', { + 'size1': humanFileSize(selection.totalBytes), + 'size2': humanFileSize($('#upload_limit').val()) + }); + } + + // check free space + freeSpace = $('#free_space').val(); + if (freeSpace >= 0 && selection.totalBytes > freeSpace) { + data.textStatus = 'notenoughspace'; + data.errorThrown = t('files', 'Not enough free space, you are uploading {size1} but only {size2} is left', { + 'size1': humanFileSize(selection.totalBytes), + 'size2': humanFileSize($('#free_space').val()) + }); + } + + // end upload for whole selection on error + if (data.errorThrown) { + // trigger fileupload fail + var fu = that.data('blueimp-fileupload') || that.data('fileupload'); + fu._trigger('fail', e, data); + return false; //don't upload anything + } + + // check existing files when all is collected + if ( selection.uploads.length >= selection.filesToUpload ) { + + //remove our selection hack: + delete data.originalFiles.selection; + + var callbacks = { + + onNoConflicts: function (selection) { + $.each(selection.uploads, function(i, upload) { + upload.submit(); + }); + }, + onSkipConflicts: function (selection) { + //TODO mark conflicting files as toskip + }, + onReplaceConflicts: function (selection) { + //TODO mark conflicting files as toreplace + }, + onChooseConflicts: function (selection) { + //TODO mark conflicting files as chosen + }, + onCancel: function (selection) { + $.each(selection.uploads, function(i, upload) { + upload.abort(); + }); + } + }; + + OC.Upload.checkExistingFiles(selection, callbacks); + + } + + return true; // continue adding files + }, + /** + * called after the first add, does NOT have the data param + * @param {object} e + */ + start: function(e) { + OC.Upload.log('start', e, null); + }, + submit: function(e, data) { + OC.Upload.rememberUpload(data); + if ( ! data.formData ) { + // noone set update parameters, we set the minimum + data.formData = { + requesttoken: oc_requesttoken, + dir: $('#dir').val() + }; + } + }, + fail: function(e, data) { + OC.Upload.log('fail', e, data); + if (typeof data.textStatus !== 'undefined' && data.textStatus !== 'success' ) { + if (data.textStatus === 'abort') { + OC.Notification.show(t('files', 'Upload cancelled.')); + } else { + // HTTP connection problem + OC.Notification.show(data.errorThrown); + if (data.result) { + var result = JSON.parse(data.result); + if (result && result[0] && result[0].data && result[0].data.code === 'targetnotfound') { + // abort upload of next files if any + OC.Upload.cancelUploads(); + } } } + //hide notification after 10 sec + setTimeout(function() { + OC.Notification.hide(); + }, 10000); } - //hide notification after 10 sec - setTimeout(function() { - OC.Notification.hide(); - }, 10000); - } - OC.Upload.deleteUpload(data); - }, - /** - * called for every successful upload - * @param {object} e - * @param {object} data - */ - done:function(e, data) { - OC.Upload.log('done', e, data); - // handle different responses (json or body from iframe for ie) - var response; - if (typeof data.result === 'string') { - response = data.result; - } else { - //fetch response from iframe - response = data.result[0].body.innerText; - } - var result=$.parseJSON(response); - - delete data.jqXHR; - - if (result.status === 'error' && result.data && result.data.message){ - data.textStatus = 'servererror'; - data.errorThrown = result.data.message; - var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); - fu._trigger('fail', e, data); - } else if (typeof result[0] === 'undefined') { - data.textStatus = 'servererror'; - data.errorThrown = t('files', 'Could not get result from server.'); - var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); - fu._trigger('fail', e, data); - } else if (result[0].status === 'existserror') { - //show "file already exists" dialog - var original = result[0]; - var replacement = data.files[0]; - var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); - OC.dialogs.fileexists(data, original, replacement, OC.Upload, fu); - } else if (result[0].status !== 'success') { - //delete data.jqXHR; - data.textStatus = 'servererror'; - data.errorThrown = result[0].data.message; // error message has been translated on server - var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); - fu._trigger('fail', e, data); + OC.Upload.deleteUpload(data); + }, + /** + * called for every successful upload + * @param {object} e + * @param {object} data + */ + done:function(e, data) { + OC.Upload.log('done', e, data); + // handle different responses (json or body from iframe for ie) + var response; + if (typeof data.result === 'string') { + response = data.result; + } else { + //fetch response from iframe + response = data.result[0].body.innerText; + } + var result=$.parseJSON(response); + + delete data.jqXHR; + + if (result.status === 'error' && result.data && result.data.message){ + data.textStatus = 'servererror'; + data.errorThrown = result.data.message; + var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); + fu._trigger('fail', e, data); + } else if (typeof result[0] === 'undefined') { + data.textStatus = 'servererror'; + data.errorThrown = t('files', 'Could not get result from server.'); + var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); + fu._trigger('fail', e, data); + } else if (result[0].status === 'existserror') { + //show "file already exists" dialog + var original = result[0]; + var replacement = data.files[0]; + var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); + OC.dialogs.fileexists(data, original, replacement, OC.Upload, fu); + } else if (result[0].status !== 'success') { + //delete data.jqXHR; + data.textStatus = 'servererror'; + data.errorThrown = result[0].data.message; // error message has been translated on server + var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); + fu._trigger('fail', e, data); + } + }, + /** + * called after last upload + * @param {object} e + * @param {object} data + */ + stop: function(e, data) { + OC.Upload.log('stop', e, data); } - }, - /** - * called after last upload - * @param {object} e - * @param {object} data - */ - stop: function(e, data) { - OC.Upload.log('stop', e, data); - } - }; + }; - // initialize jquery fileupload (blueimp) - var fileupload = $('#file_upload_start').fileupload(file_upload_param); - window.file_upload_param = fileupload; + // initialize jquery fileupload (blueimp) + var fileupload = $('#file_upload_start').fileupload(file_upload_param); + window.file_upload_param = fileupload; - if (supportAjaxUploadWithProgress()) { + if (supportAjaxUploadWithProgress()) { + + // add progress handlers + fileupload.on('fileuploadadd', function(e, data) { + OC.Upload.log('progress handle fileuploadadd', e, data); + //show cancel button + //if (data.dataType !== 'iframe') { //FIXME when is iframe used? only for ie? + // $('#uploadprogresswrapper input.stop').show(); + //} + }); + // add progress handlers + fileupload.on('fileuploadstart', function(e, data) { + OC.Upload.log('progress handle fileuploadstart', e, data); + $('#uploadprogresswrapper input.stop').show(); + $('#uploadprogressbar').progressbar({value:0}); + $('#uploadprogressbar').fadeIn(); + }); + fileupload.on('fileuploadprogress', function(e, data) { + OC.Upload.log('progress handle fileuploadprogress', e, data); + //TODO progressbar in row + }); + fileupload.on('fileuploadprogressall', function(e, data) { + OC.Upload.log('progress handle fileuploadprogressall', e, data); + var progress = (data.loaded / data.total) * 100; + $('#uploadprogressbar').progressbar('value', progress); + }); + fileupload.on('fileuploadstop', function(e, data) { + OC.Upload.log('progress handle fileuploadstop', e, data); - // add progress handlers - fileupload.on('fileuploadadd', function(e, data) { - OC.Upload.log('progress handle fileuploadadd', e, data); - //show cancel button - //if (data.dataType !== 'iframe') { //FIXME when is iframe used? only for ie? - // $('#uploadprogresswrapper input.stop').show(); - //} - }); - // add progress handlers - fileupload.on('fileuploadstart', function(e, data) { - OC.Upload.log('progress handle fileuploadstart', e, data); - $('#uploadprogresswrapper input.stop').show(); - $('#uploadprogressbar').progressbar({value:0}); - $('#uploadprogressbar').fadeIn(); - }); - fileupload.on('fileuploadprogress', function(e, data) { - OC.Upload.log('progress handle fileuploadprogress', e, data); - //TODO progressbar in row - }); - fileupload.on('fileuploadprogressall', function(e, data) { - OC.Upload.log('progress handle fileuploadprogressall', e, data); - var progress = (data.loaded / data.total) * 100; - $('#uploadprogressbar').progressbar('value', progress); - }); - fileupload.on('fileuploadstop', function(e, data) { - OC.Upload.log('progress handle fileuploadstop', e, data); - - $('#uploadprogresswrapper input.stop').fadeOut(); - $('#uploadprogressbar').fadeOut(); - Files.updateStorageStatistics(); - }); - fileupload.on('fileuploadfail', function(e, data) { - OC.Upload.log('progress handle fileuploadfail', e, data); - //if user pressed cancel hide upload progress bar and cancel button - if (data.errorThrown === 'abort') { $('#uploadprogresswrapper input.stop').fadeOut(); $('#uploadprogressbar').fadeOut(); - } - }); - - } else { - console.log('skipping file progress because your browser is broken'); - } - } + Files.updateStorageStatistics(); + }); + fileupload.on('fileuploadfail', function(e, data) { + OC.Upload.log('progress handle fileuploadfail', e, data); + //if user pressed cancel hide upload progress bar and cancel button + if (data.errorThrown === 'abort') { + $('#uploadprogresswrapper input.stop').fadeOut(); + $('#uploadprogressbar').fadeOut(); + } + }); - $.assocArraySize = function(obj) { - // http://stackoverflow.com/a/6700/11236 - var size = 0, key; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - size++; + } else { + console.log('skipping file progress because your browser is broken'); } } - return size; - }; - // warn user not to leave the page while upload is in progress - $(window).on('beforeunload', function(e) { - if (OC.Upload.isProcessing()) { - return t('files', 'File upload is in progress. Leaving the page now will cancel the upload.'); - } - }); + $.assocArraySize = function(obj) { + // http://stackoverflow.com/a/6700/11236 + var size = 0, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + size++; + } + } + return size; + }; - //add multiply file upload attribute to all browsers except konqueror (which crashes when it's used) - if (navigator.userAgent.search(/konqueror/i) === -1) { - $('#file_upload_start').attr('multiple', 'multiple'); - } + // warn user not to leave the page while upload is in progress + $(window).on('beforeunload', function(e) { + if (OC.Upload.isProcessing()) { + return t('files', 'File upload is in progress. Leaving the page now will cancel the upload.'); + } + }); - //if the breadcrumb is to long, start by replacing foldernames with '...' except for the current folder - var crumb=$('div.crumb').first(); - while($('div.controls').height() > 40 && crumb.next('div.crumb').length > 0) { - crumb.children('a').text('...'); - crumb = crumb.next('div.crumb'); - } - //if that isn't enough, start removing items from the breacrumb except for the current folder and it's parent - var crumb = $('div.crumb').first(); - var next = crumb.next('div.crumb'); - while($('div.controls').height()>40 && next.next('div.crumb').length > 0) { - crumb.remove(); - crumb = next; - next = crumb.next('div.crumb'); - } - //still not enough, start shorting down the current folder name - var crumb=$('div.crumb>a').last(); - while($('div.controls').height() > 40 && crumb.text().length > 6) { - var text=crumb.text(); - text = text.substr(0,text.length-6)+'...'; - crumb.text(text); - } + //add multiply file upload attribute to all browsers except konqueror (which crashes when it's used) + if (navigator.userAgent.search(/konqueror/i) === -1) { + $('#file_upload_start').attr('multiple', 'multiple'); + } - $(document).click(function(ev) { - // do not close when clicking in the dropdown - if ($(ev.target).closest('#new').length){ - return; + //if the breadcrumb is to long, start by replacing foldernames with '...' except for the current folder + var crumb=$('div.crumb').first(); + while($('div.controls').height() > 40 && crumb.next('div.crumb').length > 0) { + crumb.children('a').text('...'); + crumb = crumb.next('div.crumb'); } - $('#new>ul').hide(); - $('#new').removeClass('active'); - if ($('#new .error').length > 0) { - $('#new .error').tipsy('hide'); + //if that isn't enough, start removing items from the breacrumb except for the current folder and it's parent + var crumb = $('div.crumb').first(); + var next = crumb.next('div.crumb'); + while($('div.controls').height()>40 && next.next('div.crumb').length > 0) { + crumb.remove(); + crumb = next; + next = crumb.next('div.crumb'); } - $('#new li').each(function(i,element) { - if ($(element).children('p').length === 0) { - $(element).children('form').remove(); - $(element).append('<p>'+$(element).data('text')+'</p>'); - } - }); - }); - $('#new').click(function(event) { - event.stopPropagation(); - }); - $('#new>a').click(function() { - $('#new>ul').toggle(); - $('#new').toggleClass('active'); - }); - $('#new li').click(function() { - if ($(this).children('p').length === 0) { - return; + //still not enough, start shorting down the current folder name + var crumb=$('div.crumb>a').last(); + while($('div.controls').height() > 40 && crumb.text().length > 6) { + var text=crumb.text(); + text = text.substr(0,text.length-6)+'...'; + crumb.text(text); } - - $('#new .error').tipsy('hide'); - $('#new li').each(function(i,element) { - if ($(element).children('p').length === 0) { - $(element).children('form').remove(); - $(element).append('<p>'+$(element).data('text')+'</p>'); + $(document).click(function(ev) { + // do not close when clicking in the dropdown + if ($(ev.target).closest('#new').length){ + return; + } + $('#new>ul').hide(); + $('#new').removeClass('active'); + if ($('#new .error').length > 0) { + $('#new .error').tipsy('hide'); } + $('#new li').each(function(i,element) { + if ($(element).children('p').length === 0) { + $(element).children('form').remove(); + $(element).append('<p>'+$(element).data('text')+'</p>'); + } + }); }); - - var type=$(this).data('type'); - var text=$(this).children('p').text(); - $(this).data('text',text); - $(this).children('p').remove(); - - // add input field - var form = $('<form></form>'); - var input = $('<input type="text">'); - var newName = $(this).attr('data-newname') || ''; - if (newName) { - input.val(newName); - } - form.append(input); - $(this).append(form); - var lastPos; - var checkInput = function () { - var filename = input.val(); - if (type === 'web' && filename.length === 0) { - throw t('files', 'URL cannot be empty'); - } else if (type !== 'web' && !Files.isFileNameValid(filename)) { - // Files.isFileNameValid(filename) throws an exception itself - } else if ($('#dir').val() === '/' && filename === 'Shared') { - throw t('files', 'In the home folder \'Shared\' is a reserved filename'); - } else if (FileList.inList(filename)) { - throw t('files', '{new_name} already exists', {new_name: filename}); - } else { - return true; + $('#new').click(function(event) { + event.stopPropagation(); + }); + $('#new>a').click(function() { + $('#new>ul').toggle(); + $('#new').toggleClass('active'); + }); + $('#new li').click(function() { + if ($(this).children('p').length === 0) { + return; } - }; - // verify filename on typing - input.keyup(function(event) { - try { - checkInput(); - input.tipsy('hide'); - input.removeClass('error'); - } catch (error) { - input.attr('title', error); - input.tipsy({gravity: 'w', trigger: 'manual'}); - input.tipsy('show'); - input.addClass('error'); - } - }); + $('#new .error').tipsy('hide'); - input.focus(); - // pre select name up to the extension - lastPos = newName.lastIndexOf('.'); - if (lastPos === -1) { - lastPos = newName.length; - } - input.selectRange(0, lastPos); - form.submit(function(event) { - event.stopPropagation(); - event.preventDefault(); - try { - checkInput(); - var newname = input.val(); - if (FileList.lastAction) { - FileList.lastAction(); + $('#new li').each(function(i,element) { + if ($(element).children('p').length === 0) { + $(element).children('form').remove(); + $(element).append('<p>'+$(element).data('text')+'</p>'); } - var name = getUniqueName(newname); - if (newname !== name) { - FileList.checkName(name, newname, true); - var hidden = true; + }); + + var type=$(this).data('type'); + var text=$(this).children('p').text(); + $(this).data('text',text); + $(this).children('p').remove(); + + // add input field + var form = $('<form></form>'); + var input = $('<input type="text">'); + var newName = $(this).attr('data-newname') || ''; + if (newName) { + input.val(newName); + } + form.append(input); + $(this).append(form); + var lastPos; + var checkInput = function () { + var filename = input.val(); + if (type === 'web' && filename.length === 0) { + throw t('files', 'URL cannot be empty'); + } else if (type !== 'web' && !Files.isFileNameValid(filename)) { + // Files.isFileNameValid(filename) throws an exception itself + } else if (FileList.getCurrentDirectory() === '/' && filename.toLowerCase() === 'shared') { + throw t('files', 'In the home folder \'Shared\' is a reserved filename'); + } else if (FileList.inList(filename)) { + throw t('files', '{new_name} already exists', {new_name: filename}); } else { - var hidden = false; + return true; + } + }; + + // verify filename on typing + input.keyup(function(event) { + try { + checkInput(); + input.tipsy('hide'); + input.removeClass('error'); + } catch (error) { + input.attr('title', error); + input.tipsy({gravity: 'w', trigger: 'manual'}); + input.tipsy('show'); + input.addClass('error'); } - switch(type) { - case 'file': - $.post( - OC.filePath('files', 'ajax', 'newfile.php'), - {dir:$('#dir').val(), filename:name}, - function(result) { - if (result.status === 'success') { - var date = new Date(); - // TODO: ideally addFile should be able to receive - // all attributes and set them automatically, - // and also auto-load the preview - var tr = FileList.addFile(name, 0, date, false, hidden); - tr.attr('data-size', result.data.size); - tr.attr('data-mime', result.data.mime); - tr.attr('data-id', result.data.id); - tr.attr('data-etag', result.data.etag); - tr.find('.filesize').text(humanFileSize(result.data.size)); - var path = getPathForPreview(name); - Files.lazyLoadPreview(path, result.data.mime, function(previewpath) { - tr.find('td.filename').attr('style','background-image:url('+previewpath+')'); - }, null, null, result.data.etag); - FileActions.display(tr.find('td.filename'), true); - } else { - OC.dialogs.alert(result.data.message, t('core', 'Could not create file')); + }); + + input.focus(); + // pre select name up to the extension + lastPos = newName.lastIndexOf('.'); + if (lastPos === -1) { + lastPos = newName.length; + } + input.selectRange(0, lastPos); + form.submit(function(event) { + event.stopPropagation(); + event.preventDefault(); + try { + checkInput(); + var newname = input.val(); + if (FileList.lastAction) { + FileList.lastAction(); + } + var name = getUniqueName(newname); + if (newname !== name) { + FileList.checkName(name, newname, true); + var hidden = true; + } else { + var hidden = false; + } + switch(type) { + case 'file': + $.post( + OC.filePath('files', 'ajax', 'newfile.php'), + {dir:$('#dir').val(), filename:name}, + function(result) { + if (result.status === 'success') { + var date = new Date(); + // TODO: ideally addFile should be able to receive + // all attributes and set them automatically, + // and also auto-load the preview + var tr = FileList.addFile(name, 0, date, false, hidden); + tr.attr('data-size', result.data.size); + tr.attr('data-mime', result.data.mime); + tr.attr('data-id', result.data.id); + tr.attr('data-etag', result.data.etag); + tr.find('.filesize').text(humanFileSize(result.data.size)); + var path = getPathForPreview(name); + Files.lazyLoadPreview(path, result.data.mime, function(previewpath) { + tr.find('td.filename').attr('style','background-image:url('+previewpath+')'); + }, null, null, result.data.etag); + FileActions.display(tr.find('td.filename'), true); + } else { + OC.dialogs.alert(result.data.message, t('core', 'Could not create file')); + } } - } - ); - break; - case 'folder': - $.post( - OC.filePath('files','ajax','newfolder.php'), - {dir:$('#dir').val(), foldername:name}, - function(result) { - if (result.status === 'success') { - var date=new Date(); - FileList.addDir(name, 0, date, hidden); - var tr = FileList.findFileEl(name); - tr.attr('data-id', result.data.id); - } else { - OC.dialogs.alert(result.data.message, t('core', 'Could not create folder')); + ); + break; + case 'folder': + $.post( + OC.filePath('files','ajax','newfolder.php'), + {dir:$('#dir').val(), foldername:name}, + function(result) { + if (result.status === 'success') { + var date=new Date(); + FileList.addDir(name, 0, date, hidden); + var tr = FileList.findFileEl(name); + tr.attr('data-id', result.data.id); + } else { + OC.dialogs.alert(result.data.message, t('core', 'Could not create folder')); + } } + ); + break; + case 'web': + if (name.substr(0,8) !== 'https://' && name.substr(0,7) !== 'http://') { + name = 'http://' + name; } - ); - break; - case 'web': - if (name.substr(0,8) !== 'https://' && name.substr(0,7) !== 'http://') { - name = 'http://' + name; - } - var localName=name; - if (localName.substr(localName.length-1,1)==='/') {//strip / - localName=localName.substr(0,localName.length-1); - } - if (localName.indexOf('/')) {//use last part of url - localName=localName.split('/').pop(); - } else { //or the domain - localName=(localName.match(/:\/\/(.[^\/]+)/)[1]).replace('www.',''); - } - localName = getUniqueName(localName); - //IE < 10 does not fire the necessary events for the progress bar. - if ($('html.lte9').length === 0) { - $('#uploadprogressbar').progressbar({value:0}); - $('#uploadprogressbar').fadeIn(); - } - - var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName}); - eventSource.listen('progress',function(progress) { + var localName=name; + if (localName.substr(localName.length-1,1)==='/') {//strip / + localName=localName.substr(0,localName.length-1); + } + if (localName.indexOf('/')) {//use last part of url + localName=localName.split('/').pop(); + } else { //or the domain + localName=(localName.match(/:\/\/(.[^\/]+)/)[1]).replace('www.',''); + } + localName = getUniqueName(localName); //IE < 10 does not fire the necessary events for the progress bar. if ($('html.lte9').length === 0) { - $('#uploadprogressbar').progressbar('value',progress); + $('#uploadprogressbar').progressbar({value:0}); + $('#uploadprogressbar').fadeIn(); } - }); - eventSource.listen('success',function(data) { - var mime = data.mime; - var size = data.size; - var id = data.id; - $('#uploadprogressbar').fadeOut(); - var date = new Date(); - FileList.addFile(localName, size, date, false, hidden); - var tr = FileList.findFileEl(localName); - tr.data('mime', mime).data('id', id); - tr.attr('data-id', id); - var path = $('#dir').val()+'/'+localName; - Files.lazyLoadPreview(path, mime, function(previewpath) { - tr.find('td.filename').attr('style', 'background-image:url('+previewpath+')'); - }, null, null, data.etag); - FileActions.display(tr.find('td.filename'), true); - }); - eventSource.listen('error',function(error) { - $('#uploadprogressbar').fadeOut(); - var message = (error && error.message) || t('core', 'Error fetching URL'); - OC.Notification.show(message); - //hide notification after 10 sec - setTimeout(function() { - OC.Notification.hide(); - }, 10000); - }); - break; + + var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName}); + eventSource.listen('progress',function(progress) { + //IE < 10 does not fire the necessary events for the progress bar. + if ($('html.lte9').length === 0) { + $('#uploadprogressbar').progressbar('value',progress); + } + }); + eventSource.listen('success',function(data) { + var mime = data.mime; + var size = data.size; + var id = data.id; + $('#uploadprogressbar').fadeOut(); + var date = new Date(); + FileList.addFile(localName, size, date, false, hidden); + var tr = FileList.findFileEl(localName); + tr.data('mime', mime).data('id', id); + tr.attr('data-id', id); + var path = $('#dir').val()+'/'+localName; + Files.lazyLoadPreview(path, mime, function(previewpath) { + tr.find('td.filename').attr('style', 'background-image:url('+previewpath+')'); + }, null, null, data.etag); + FileActions.display(tr.find('td.filename'), true); + }); + eventSource.listen('error',function(error) { + $('#uploadprogressbar').fadeOut(); + var message = (error && error.message) || t('core', 'Error fetching URL'); + OC.Notification.show(message); + //hide notification after 10 sec + setTimeout(function() { + OC.Notification.hide(); + }, 10000); + }); + break; + } + var li=form.parent(); + form.remove(); + /* workaround for IE 9&10 click event trap, 2 lines: */ + $('input').first().focus(); + $('#content').focus(); + li.append('<p>'+li.data('text')+'</p>'); + $('#new>a').click(); + } catch (error) { + input.attr('title', error); + input.tipsy({gravity: 'w', trigger: 'manual'}); + input.tipsy('show'); + input.addClass('error'); } - var li=form.parent(); - form.remove(); - /* workaround for IE 9&10 click event trap, 2 lines: */ - $('input').first().focus(); - $('#content').focus(); - li.append('<p>'+li.data('text')+'</p>'); - $('#new>a').click(); - } catch (error) { - input.attr('title', error); - input.tipsy({gravity: 'w', trigger: 'manual'}); - input.tipsy('show'); - input.addClass('error'); - } + }); }); - }); - window.file_upload_param = file_upload_param; + window.file_upload_param = file_upload_param; + return file_upload_param; + } +}; + +$(document).ready(function() { + OC.Upload.init(); }); + diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 550c10dba3e..503bf681139 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -137,7 +137,9 @@ window.FileList={ var download_url = null; if (!param.download_url) { - download_url = OC.Router.generate('download', { file: $('#dir').val()+'/'+name }); + download_url = OC.generateUrl( + 'apps/files/download{file}', + { file: $('#dir').val()+'/'+name }); } else { download_url = param.download_url; } @@ -419,15 +421,12 @@ window.FileList={ len = input.val().length; } input.selectRange(0, len); - var checkInput = function () { var filename = input.val(); if (filename !== oldname) { - if (!Files.isFileNameValid(filename)) { - // Files.isFileNameValid(filename) throws an exception itself - } else if($('#dir').val() === '/' && filename === 'Shared') { - throw t('files','In the home folder \'Shared\' is a reserved filename'); - } else if (FileList.inList(filename)) { + // Files.isFileNameValid(filename) throws an exception itself + Files.isFileNameValid(filename, FileList.getCurrentDirectory()); + if (FileList.inList(filename)) { throw t('files', '{new_name} already exists', {new_name: filename}); } } @@ -1156,9 +1155,9 @@ $(document).ready(function() { // need to initially switch the dir to the one from the hash (IE8) FileList.changeDirectory(parseCurrentDirFromUrl(), false, true); } - } - FileList.setCurrentDir(parseCurrentDirFromUrl(), false); + FileList.setCurrentDir(parseCurrentDirFromUrl(), false); + } FileList.createFileSummary(); }); diff --git a/apps/files/js/files.js b/apps/files/js/files.js index f4546120702..1186a72a44f 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -87,9 +87,12 @@ var Files = { * Throws a string exception with an error message if * the file name is not valid */ - isFileNameValid: function (name) { + isFileNameValid: function (name, root) { var trimmedName = name.trim(); - if (trimmedName === '.' || trimmedName === '..') { + if (trimmedName === '.' + || trimmedName === '..' + || (root === '/' && trimmedName.toLowerCase() === 'shared')) + { throw t('files', '"{name}" is an invalid file name.', {name: name}); } else if (trimmedName.length === 0) { throw t('files', 'File name cannot be empty.'); @@ -780,9 +783,9 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) { if ( $('#isPublic').length ) { urlSpec.t = $('#dirToken').val(); - previewURL = OC.Router.generate('core_ajax_public_preview', urlSpec); + previewURL = OC.generateUrl('/publicpreview.png?') + $.param(urlSpec); } else { - previewURL = OC.Router.generate('core_ajax_preview', urlSpec); + previewURL = OC.generateUrl('/core/preview.png?') + $.param(urlSpec); } previewURL = previewURL.replace('(', '%28'); previewURL = previewURL.replace(')', '%29'); diff --git a/apps/files/templates/part.list.php b/apps/files/templates/part.list.php index f4fb96a7a7c..8a7a1e370eb 100644 --- a/apps/files/templates/part.list.php +++ b/apps/files/templates/part.list.php @@ -17,7 +17,13 @@ $totalsize = 0; ?> data-mime="<?php p($file['mimetype'])?>" data-size="<?php p($file['size']);?>" data-etag="<?php p($file['etag']);?>" - data-permissions="<?php p($file['permissions']); ?>"> + data-permissions="<?php p($file['permissions']); ?>" + + <?php if(isset($file['displayname_owner'])): ?> + data-share-owner="<?php p($file['displayname_owner']) ?>" + <?php endif; ?> + > + <?php if(isset($file['isPreviewAvailable']) and $file['isPreviewAvailable']): ?> <td class="filename svg preview-icon" <?php else: ?> @@ -34,17 +40,15 @@ $totalsize = 0; ?> <span class="nametext"> <?php print_unescaped(htmlspecialchars($file['name']));?> </span> + <span class="uploadtext" currentUploads="0"> + </span> + </a> <?php else: ?> <a class="name" href="<?php p(rtrim($_['downloadURL'],'/').'/'.trim($directory,'/').'/'.$name); ?>"> <label class="filetext" title="" for="select-<?php p($file['fileid']); ?>"></label> <span class="nametext"><?php print_unescaped(htmlspecialchars($file['basename']));?><span class='extension'><?php p($file['extension']);?></span></span> </a> <?php endif; ?> - <?php if($file['type'] == 'dir'):?> - <span class="uploadtext" currentUploads="0"> - </span> - <?php endif;?> - </a> </td> <td class="filesize" style="color:rgb(<?php p($simple_size_color.','.$simple_size_color.','.$simple_size_color) ?>)"> diff --git a/apps/files/tests/js/fileUploadSpec.js b/apps/files/tests/js/fileUploadSpec.js new file mode 100644 index 00000000000..2b4341ef1c3 --- /dev/null +++ b/apps/files/tests/js/fileUploadSpec.js @@ -0,0 +1,127 @@ +/** +* ownCloud +* +* @author Vincent Petry +* @copyright 2014 Vincent Petry <pvince81@owncloud.com> +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +/* global OC */ +describe('OC.Upload tests', function() { + var $dummyUploader; + var testFile; + + beforeEach(function() { + testFile = { + name: 'test.txt', + size: 5000, // 5 KB + type: 'text/plain', + lastModifiedDate: new Date() + }; + // need a dummy button because file-upload checks on it + $('#testArea').append( + '<input type="file" id="file_upload_start" name="files[]" multiple="multiple">' + + '<input type="hidden" id="upload_limit" name="upload_limit" value="10000000">' + // 10 MB + '<input type="hidden" id="free_space" name="free_space" value="50000000">' // 50 MB + ); + $dummyUploader = $('#file_upload_start'); + }); + afterEach(function() { + delete window.file_upload_param; + $dummyUploader = 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( + $dummyUploader[0], + {}, + { + originalFiles: {}, + files: [file] + }); + } + + it('adds file when size is below limits', function() { + var result = addFile(testFile); + expect(result).toEqual(true); + }); + it('adds file when free space is unknown', function() { + var result; + $('#free_space').val(-2); + + result = addFile(testFile); + + expect(result).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); + + expect(result).toEqual(false); + expect(failStub.calledOnce).toEqual(true); + expect(failStub.getCall(0).args[1].textStatus).toEqual('sizeexceedlimit'); + expect(failStub.getCall(0).args[1].errorThrown).toEqual( + 'Total file size 5 kB exceeds upload limit 1000 B' + ); + }); + it('does not add file if it exceeds free space', function() { + var result; + $('#free_space').val(1000); + + result = addFile(testFile); + + expect(result).toEqual(false); + expect(failStub.calledOnce).toEqual(true); + expect(failStub.getCall(0).args[1].textStatus).toEqual('notenoughspace'); + expect(failStub.getCall(0).args[1].errorThrown).toEqual( + 'Not enough free space, you are uploading 5 kB but only 1000 B is left' + ); + }); + it('does not add file if it has invalid characters', function() { + var result; + testFile.name = 'stars*stars.txt'; + + result = addFile(testFile); + + expect(result).toEqual(false); + expect(failStub.calledOnce).toEqual(true); + expect(failStub.getCall(0).args[1].textStatus).toEqual('invalidcharacters'); + expect(failStub.getCall(0).args[1].errorThrown.substr(0, 12)).toEqual( + 'Invalid name' + ); + }); + }); +}); diff --git a/apps/files/tests/js/filesSpec.js b/apps/files/tests/js/filesSpec.js index 018c8ef0f3c..95bf87e03ec 100644 --- a/apps/files/tests/js/filesSpec.js +++ b/apps/files/tests/js/filesSpec.js @@ -48,6 +48,41 @@ describe('Files tests', function() { expect(error).toEqual(false); } }); + it('Validates correct file names do not create Shared folder in root', function() { + // create shared file in subfolder + var error = false; + try { + expect(Files.isFileNameValid('shared', '/foo')).toEqual(true); + expect(Files.isFileNameValid('Shared', '/foo')).toEqual(true); + } + catch (e) { + error = e; + } + expect(error).toEqual(false); + + // create shared file in root + var threwException = false; + try { + Files.isFileNameValid('Shared', '/'); + console.error('Invalid file name not detected'); + } + catch (e) { + threwException = true; + } + expect(threwException).toEqual(true); + + // create shared file in root + var threwException = false; + try { + Files.isFileNameValid('shared', '/'); + console.error('Invalid file name not detected'); + } + catch (e) { + threwException = true; + } + expect(threwException).toEqual(true); + + }); it('Detects invalid file names', function() { var fileNames = [ '', |