summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2018-09-28 16:03:24 +0200
committerGitHub <noreply@github.com>2018-09-28 16:03:24 +0200
commitd867f9f091933ebc134cc50ba1ed835dbd39d36d (patch)
treeed0d4f75fb529d0bf323dcee9937989f6e7bfe58 /apps
parenta23d5240987392f4eb140eefbb81882ef6ae6a5a (diff)
parentc5f77de3e270f3e6ad25e662ab77e1d68eaee67b (diff)
downloadnextcloud-server-d867f9f091933ebc134cc50ba1ed835dbd39d36d.tar.gz
nextcloud-server-d867f9f091933ebc134cc50ba1ed835dbd39d36d.zip
Merge pull request #11037 from nextcloud/trash-webui-dav
Use trashbin dav endpoint to list trash in webui
Diffstat (limited to 'apps')
-rw-r--r--apps/files_trashbin/ajax/delete.php93
-rw-r--r--apps/files_trashbin/ajax/isEmpty.php33
-rw-r--r--apps/files_trashbin/ajax/list.php48
-rw-r--r--apps/files_trashbin/ajax/undelete.php98
-rw-r--r--apps/files_trashbin/appinfo/routes.php10
-rw-r--r--apps/files_trashbin/composer/composer/autoload_classmap.php1
-rw-r--r--apps/files_trashbin/composer/composer/autoload_static.php1
-rw-r--r--apps/files_trashbin/js/app.js83
-rw-r--r--apps/files_trashbin/js/filelist.js202
-rw-r--r--apps/files_trashbin/lib/Sabre/AbstractTrash.php69
-rw-r--r--apps/files_trashbin/lib/Sabre/ITrash.php4
-rw-r--r--apps/files_trashbin/lib/Sabre/PropfindPlugin.php36
-rw-r--r--apps/files_trashbin/lib/Sabre/TrashFile.php37
-rw-r--r--apps/files_trashbin/lib/Sabre/TrashFolder.php27
-rw-r--r--apps/files_trashbin/lib/Sabre/TrashFolderFile.php39
-rw-r--r--apps/files_trashbin/lib/Sabre/TrashFolderFolder.php32
-rw-r--r--apps/files_trashbin/tests/js/filelistSpec.js284
17 files changed, 387 insertions, 710 deletions
diff --git a/apps/files_trashbin/ajax/delete.php b/apps/files_trashbin/ajax/delete.php
deleted file mode 100644
index 5fb69d7f2ee..00000000000
--- a/apps/files_trashbin/ajax/delete.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-use OCP\ILogger;
-
-\OC_JSON::checkLoggedIn();
-\OC_JSON::callCheck();
-\OC::$server->getSession()->close();
-
-$folder = isset($_POST['dir']) ? $_POST['dir'] : '/';
-
-// "empty trash" command
-if (isset($_POST['allfiles']) && (string)$_POST['allfiles'] === 'true'){
- $deleteAll = true;
- if ($folder === '/' || $folder === '') {
- OCA\Files_Trashbin\Trashbin::deleteAll();
- $list = array();
- } else {
- $list[] = $folder;
- $folder = dirname($folder);
- }
-}
-else {
- $deleteAll = false;
- $files = (string)$_POST['files'];
- $list = json_decode($files);
-}
-
-$folder = rtrim($folder, '/') . '/';
-$error = array();
-$success = array();
-
-$i = 0;
-foreach ($list as $file) {
- if ($folder === '/') {
- $file = ltrim($file, '/');
- $delimiter = strrpos($file, '.d');
- $filename = substr($file, 0, $delimiter);
- $timestamp = substr($file, $delimiter+2);
- } else {
- $filename = $folder . '/' . $file;
- $timestamp = null;
- }
-
- OCA\Files_Trashbin\Trashbin::delete($filename, \OCP\User::getUser(), $timestamp);
- if (OCA\Files_Trashbin\Trashbin::file_exists($filename, $timestamp)) {
- $error[] = $filename;
- \OCP\Util::writeLog('trashbin','can\'t delete ' . $filename . ' permanently.', ILogger::ERROR);
- }
- // only list deleted files if not deleting everything
- else if (!$deleteAll) {
- $success[$i]['filename'] = $file;
- $success[$i]['timestamp'] = $timestamp;
- $i++;
- }
-}
-
-if ( $error ) {
- $filelist = '';
- foreach ( $error as $e ) {
- $filelist .= $e.', ';
- }
- $l = \OC::$server->getL10N('files_trashbin');
- $message = $l->t("Couldn't delete %s permanently", array(rtrim($filelist, ', ')));
- \OC_JSON::error(array("data" => array("message" => $message,
- "success" => $success, "error" => $error)));
-} else {
- \OC_JSON::success(array("data" => array("success" => $success)));
-}
diff --git a/apps/files_trashbin/ajax/isEmpty.php b/apps/files_trashbin/ajax/isEmpty.php
deleted file mode 100644
index 73356047e74..00000000000
--- a/apps/files_trashbin/ajax/isEmpty.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-\OC_JSON::checkLoggedIn();
-\OC_JSON::callCheck();
-\OC::$server->getSession()->close();
-
-$trashStatus = OCA\Files_Trashbin\Trashbin::isEmpty(OCP\User::getUser());
-
-\OC_JSON::success(array("data" => array("isEmpty" => $trashStatus)));
-
-
diff --git a/apps/files_trashbin/ajax/list.php b/apps/files_trashbin/ajax/list.php
deleted file mode 100644
index e72c063f428..00000000000
--- a/apps/files_trashbin/ajax/list.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-\OC_JSON::checkLoggedIn();
-\OC::$server->getSession()->close();
-
-// Load the files
-$dir = isset($_GET['dir']) ? (string)$_GET['dir'] : '';
-$sortAttribute = isset($_GET['sort']) ? (string)$_GET['sort'] : 'name';
-$sortDirection = isset($_GET['sortdirection']) ? ($_GET['sortdirection'] === 'desc') : false;
-$data = array();
-
-// make filelist
-try {
- $files = \OCA\Files_Trashbin\Helper::getTrashFiles($dir, \OCP\User::getUser(), $sortAttribute, $sortDirection);
-} catch (Exception $e) {
- http_response_code(404);
- exit();
-}
-
-$encodedDir = \OCP\Util::encodePath($dir);
-
-$data['permissions'] = 0;
-$data['directory'] = $dir;
-$data['files'] = \OCA\Files_Trashbin\Helper::formatFileInfos($files);
-
-\OC_JSON::success(array('data' => $data));
-
diff --git a/apps/files_trashbin/ajax/undelete.php b/apps/files_trashbin/ajax/undelete.php
deleted file mode 100644
index 348148b03bc..00000000000
--- a/apps/files_trashbin/ajax/undelete.php
+++ /dev/null
@@ -1,98 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-use OCP\ILogger;
-
-\OC_JSON::checkLoggedIn();
-\OC_JSON::callCheck();
-\OC::$server->getSession()->close();
-
-$dir = '/';
-if (isset($_POST['dir'])) {
- $dir = rtrim((string)$_POST['dir'], '/'). '/';
-}
-$allFiles = false;
-if (isset($_POST['allfiles']) && (string)$_POST['allfiles'] === 'true') {
- $allFiles = true;
- $list = array();
- $dirListing = true;
- if ($dir === '' || $dir === '/') {
- $dirListing = false;
- }
- foreach (OCA\Files_Trashbin\Helper::getTrashFiles($dir, \OCP\User::getUser()) as $file) {
- $fileName = $file['name'];
- if (!$dirListing) {
- $fileName .= '.d' . $file['mtime'];
- }
- $list[] = $fileName;
- }
-} else {
- $list = json_decode($_POST['files']);
-}
-
-$error = array();
-$success = array();
-
-$i = 0;
-foreach ($list as $file) {
- $path = $dir . '/' . $file;
- if ($dir === '/') {
- $file = ltrim($file, '/');
- $delimiter = strrpos($file, '.d');
- $filename = substr($file, 0, $delimiter);
- $timestamp = substr($file, $delimiter+2);
- } else {
- $path_parts = pathinfo($file);
- $filename = $path_parts['basename'];
- $timestamp = null;
- }
-
- if ( !OCA\Files_Trashbin\Trashbin::restore($path, $filename, $timestamp) ) {
- $error[] = $filename;
- \OCP\Util::writeLog('trashbin', 'can\'t restore ' . $filename, ILogger::ERROR);
- } else {
- $success[$i]['filename'] = $file;
- $success[$i]['timestamp'] = $timestamp;
- $i++;
- }
-
-}
-
-if ( $error ) {
- $filelist = '';
- foreach ( $error as $e ) {
- $filelist .= $e.', ';
- }
- $l = OC::$server->getL10N('files_trashbin');
- $message = $l->t("Couldn't restore %s", array(rtrim($filelist, ', ')));
- \OC_JSON::error(array("data" => array("message" => $message,
- "success" => $success, "error" => $error)));
-} else {
- \OC_JSON::success(array("data" => array("success" => $success)));
-}
diff --git a/apps/files_trashbin/appinfo/routes.php b/apps/files_trashbin/appinfo/routes.php
index 21b4bc2d8c9..20d52adf3f0 100644
--- a/apps/files_trashbin/appinfo/routes.php
+++ b/apps/files_trashbin/appinfo/routes.php
@@ -34,13 +34,3 @@ $application->registerRoutes($this, [
],
],
]);
-
-$this->create('files_trashbin_ajax_delete', 'ajax/delete.php')
- ->actionInclude('files_trashbin/ajax/delete.php');
-$this->create('files_trashbin_ajax_isEmpty', 'ajax/isEmpty.php')
- ->actionInclude('files_trashbin/ajax/isEmpty.php');
-$this->create('files_trashbin_ajax_list', 'ajax/list.php')
- ->actionInclude('files_trashbin/ajax/list.php');
-$this->create('files_trashbin_ajax_undelete', 'ajax/undelete.php')
- ->actionInclude('files_trashbin/ajax/undelete.php');
-
diff --git a/apps/files_trashbin/composer/composer/autoload_classmap.php b/apps/files_trashbin/composer/composer/autoload_classmap.php
index 3713de530c6..164d64333ce 100644
--- a/apps/files_trashbin/composer/composer/autoload_classmap.php
+++ b/apps/files_trashbin/composer/composer/autoload_classmap.php
@@ -18,6 +18,7 @@ return array(
'OCA\\Files_Trashbin\\Expiration' => $baseDir . '/../lib/Expiration.php',
'OCA\\Files_Trashbin\\Helper' => $baseDir . '/../lib/Helper.php',
'OCA\\Files_Trashbin\\Hooks' => $baseDir . '/../lib/Hooks.php',
+ 'OCA\\Files_Trashbin\\Sabre\\AbstractTrash' => $baseDir . '/../lib/Sabre/AbstractTrash.php',
'OCA\\Files_Trashbin\\Sabre\\ITrash' => $baseDir . '/../lib/Sabre/ITrash.php',
'OCA\\Files_Trashbin\\Sabre\\PropfindPlugin' => $baseDir . '/../lib/Sabre/PropfindPlugin.php',
'OCA\\Files_Trashbin\\Sabre\\RestoreFolder' => $baseDir . '/../lib/Sabre/RestoreFolder.php',
diff --git a/apps/files_trashbin/composer/composer/autoload_static.php b/apps/files_trashbin/composer/composer/autoload_static.php
index b00778741b3..6ebb8c35f31 100644
--- a/apps/files_trashbin/composer/composer/autoload_static.php
+++ b/apps/files_trashbin/composer/composer/autoload_static.php
@@ -33,6 +33,7 @@ class ComposerStaticInitFiles_Trashbin
'OCA\\Files_Trashbin\\Expiration' => __DIR__ . '/..' . '/../lib/Expiration.php',
'OCA\\Files_Trashbin\\Helper' => __DIR__ . '/..' . '/../lib/Helper.php',
'OCA\\Files_Trashbin\\Hooks' => __DIR__ . '/..' . '/../lib/Hooks.php',
+ 'OCA\\Files_Trashbin\\Sabre\\AbstractTrash' => __DIR__ . '/..' . '/../lib/Sabre/AbstractTrash.php',
'OCA\\Files_Trashbin\\Sabre\\ITrash' => __DIR__ . '/..' . '/../lib/Sabre/ITrash.php',
'OCA\\Files_Trashbin\\Sabre\\PropfindPlugin' => __DIR__ . '/..' . '/../lib/Sabre/PropfindPlugin.php',
'OCA\\Files_Trashbin\\Sabre\\RestoreFolder' => __DIR__ . '/..' . '/../lib/Sabre/RestoreFolder.php',
diff --git a/apps/files_trashbin/js/app.js b/apps/files_trashbin/js/app.js
index 7cdc157fe47..82e47d510bf 100644
--- a/apps/files_trashbin/js/app.js
+++ b/apps/files_trashbin/js/app.js
@@ -17,12 +17,21 @@ OCA.Trashbin = {};
*/
OCA.Trashbin.App = {
_initialized: false,
+ /** @type {OC.Files.Client} */
+ client: null,
- initialize: function($el) {
+ initialize: function ($el) {
if (this._initialized) {
return;
}
this._initialized = true;
+
+ this.client = new OC.Files.Client({
+ host: OC.getHost(),
+ port: OC.getPort(),
+ root: OC.linkToRemoteBase('dav') + '/trashbin/' + OC.getCurrentUser().uid,
+ useHTTPS: OC.getProtocol() === 'https'
+ });
var urlParams = OC.Util.History.parseUrlQuery();
this.fileList = new OCA.Trashbin.FileList(
$('#app-content-trashbin'), {
@@ -31,22 +40,24 @@ OCA.Trashbin.App = {
scrollTo: urlParams.scrollto,
config: OCA.Files.App.getFilesConfig(),
multiSelectMenu: [
- {
- name: 'restore',
- displayName: t('files', 'Restore'),
- iconClass: 'icon-history',
- },
- {
- name: 'delete',
- displayName: t('files', 'Delete'),
- iconClass: 'icon-delete',
- }
- ]
+ {
+ name: 'restore',
+ displayName: t('files', 'Restore'),
+ iconClass: 'icon-history',
+ },
+ {
+ name: 'delete',
+ displayName: t('files', 'Delete'),
+ iconClass: 'icon-delete',
+ }
+ ],
+ client: this.client
}
);
},
- _createFileActions: function() {
+ _createFileActions: function () {
+ var client = this.client;
var fileActions = new OCA.Files.FileActions();
fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) {
var dir = context.fileList.getCurrentDirectory();
@@ -62,17 +73,19 @@ OCA.Trashbin.App = {
mime: 'all',
permissions: OC.PERMISSION_READ,
iconClass: 'icon-history',
- actionHandler: function(filename, context) {
+ actionHandler: function (filename, context) {
var fileList = context.fileList;
var tr = fileList.findFileEl(filename);
- var deleteAction = tr.children("td.date").children(".action.delete");
- deleteAction.removeClass('icon-delete').addClass('icon-loading-small');
- $.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'), {
- files: JSON.stringify([filename]),
- dir: fileList.getCurrentDirectory()
- },
- _.bind(fileList._removeCallback, fileList)
- );
+ fileList.showFileBusyState(tr, true);
+ var dir = context.fileList.getCurrentDirectory();
+ client.move(OC.joinPaths('trash', dir, filename), OC.joinPaths('restore', filename), true)
+ .then(
+ fileList._removeCallback.bind(fileList, [filename]),
+ function () {
+ fileList.showFileBusyState(tr, false);
+ OC.Notification.show(t('files_trashbin', 'Error while restoring file from trashbin'));
+ }
+ );
}
});
@@ -82,33 +95,35 @@ OCA.Trashbin.App = {
mime: 'all',
permissions: OC.PERMISSION_READ,
iconClass: 'icon-delete',
- render: function(actionSpec, isDefault, context) {
+ render: function (actionSpec, isDefault, context) {
var $actionLink = fileActions._makeActionLink(actionSpec, context);
$actionLink.attr('original-title', t('files_trashbin', 'Delete permanently'));
$actionLink.children('img').attr('alt', t('files_trashbin', 'Delete permanently'));
context.$file.find('td:last').append($actionLink);
return $actionLink;
},
- actionHandler: function(filename, context) {
+ actionHandler: function (filename, context) {
var fileList = context.fileList;
$('.tipsy').remove();
var tr = fileList.findFileEl(filename);
- var deleteAction = tr.children("td.date").children(".action.delete");
- deleteAction.removeClass('icon-delete').addClass('icon-loading-small');
- $.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'), {
- files: JSON.stringify([filename]),
- dir: fileList.getCurrentDirectory()
- },
- _.bind(fileList._removeCallback, fileList)
- );
+ fileList.showFileBusyState(tr, true);
+ var dir = context.fileList.getCurrentDirectory();
+ client.remove(OC.joinPaths('trash', dir, filename))
+ .then(
+ fileList._removeCallback.bind(fileList, [filename]),
+ function () {
+ fileList.showFileBusyState(tr, false);
+ OC.Notification.show(t('files_trashbin', 'Error while removing file from trashbin'));
+ }
+ );
}
});
return fileActions;
}
};
-$(document).ready(function() {
- $('#app-content-trashbin').one('show', function() {
+$(document).ready(function () {
+ $('#app-content-trashbin').one('show', function () {
var App = OCA.Trashbin.App;
App.initialize($('#app-content-trashbin'));
// force breadcrumb init
diff --git a/apps/files_trashbin/js/filelist.js b/apps/files_trashbin/js/filelist.js
index 324e4d8a7e0..3159506fae9 100644
--- a/apps/files_trashbin/js/filelist.js
+++ b/apps/files_trashbin/js/filelist.js
@@ -9,6 +9,8 @@
*/
(function() {
var DELETED_REGEXP = new RegExp(/^(.+)\.d[0-9]+$/);
+ var FILENAME_PROP = '{http://nextcloud.org/ns}trashbin-filename';
+ var DELETION_TIME_PROP = '{http://nextcloud.org/ns}trashbin-deletion-time';
/**
* Convert a file name in the format filename.d12345 to the real file name.
@@ -36,17 +38,30 @@
* @param [options] map of options
*/
var FileList = function($el, options) {
+ this.client = options.client;
this.initialize($el, options);
};
FileList.prototype = _.extend({}, OCA.Files.FileList.prototype,
/** @lends OCA.Trashbin.FileList.prototype */ {
id: 'trashbin',
appName: t('files_trashbin', 'Deleted files'),
+ /** @type {OC.Files.Client} */
+ client: null,
/**
* @private
*/
initialize: function() {
+ this.client.addFileInfoParser(function(response, data) {
+ var props = response.propStat[0].properties;
+ return {
+ displayName: props[FILENAME_PROP],
+ mtime: parseInt(props[DELETION_TIME_PROP], 10) * 1000,
+ hasPreview: true,
+ path: data.path.substr(6), // remove leading /trash
+ }
+ });
+
var result = OCA.Files.FileList.prototype.initialize.apply(this, arguments);
this.$el.find('.undelete').click('click', _.bind(this._onClickRestoreSelected, this));
@@ -91,23 +106,6 @@
return tr;
},
- _renderRow: function(fileData, options) {
- options = options || {};
- // make a copy to avoid changing original object
- fileData = _.extend({}, fileData);
- var dir = this.getCurrentDirectory();
- var dirListing = dir !== '' && dir !== '/';
- // show deleted time as mtime
- if (fileData.mtime) {
- fileData.mtime = parseInt(fileData.mtime, 10);
- }
- if (!dirListing) {
- fileData.displayName = fileData.name;
- fileData.name = fileData.name + '.d' + Math.floor(fileData.mtime / 1000);
- }
- return OCA.Files.FileList.prototype._renderRow.call(this, fileData, options);
- },
-
getAjaxUrl: function(action, params) {
var q = '';
if (params) {
@@ -140,15 +138,10 @@
this.$el.find('#filestable th').toggleClass('hidden', !exists);
},
- _removeCallback: function(result) {
- if (result.status !== 'success') {
- OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error'));
- }
-
- var files = result.data.success;
+ _removeCallback: function(files) {
var $el;
for (var i = 0; i < files.length; i++) {
- $el = this.remove(OC.basename(files[i].filename), {updateSummary: false});
+ $el = this.remove(OC.basename(files[i]), {updateSummary: false});
this.fileSummary.remove({type: $el.attr('data-type'), size: $el.attr('data-size')});
}
this.fileSummary.update();
@@ -158,97 +151,71 @@
_onClickRestoreSelected: function(event) {
event.preventDefault();
var self = this;
- var allFiles = this.$el.find('.select-all').is(':checked');
- var files = [];
- var params = {};
- this.fileMultiSelectMenu.toggleLoading('restore', true);
- if (allFiles) {
- this.showMask();
- params = {
- allfiles: true,
- dir: this.getCurrentDirectory()
- };
- }
- else {
- files = _.pluck(this.getSelectedFiles(), 'name');
- for (var i = 0; i < files.length; i++) {
- var deleteAction = this.findFileEl(files[i]).children("td.date").children(".action.delete");
- deleteAction.removeClass('icon-delete').addClass('icon-loading-small');
- }
- params = {
- files: JSON.stringify(files),
- dir: this.getCurrentDirectory()
- };
+ var files = _.pluck(this.getSelectedFiles(), 'name');
+ for (var i = 0; i < files.length; i++) {
+ var tr = this.findFileEl(files[i]);
+ this.showFileBusyState(tr, true);
}
- $.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'),
- params,
- function(result) {
- if (allFiles) {
- if (result.status !== 'success') {
- OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error'));
+ this.fileMultiSelectMenu.toggleLoading('restore', true);
+ var restorePromises = files.map(function(file) {
+ return self.client.move(OC.joinPaths('trash', self.getCurrentDirectory(), file), OC.joinPaths('restore', file), true)
+ .then(
+ function() {
+ self._removeCallback([file]);
}
- self.hideMask();
- // simply remove all files
- self.setFiles([]);
- }
- else {
- self._removeCallback(result);
- }
+ );
+ });
+ return Promise.all(restorePromises).then(
+ function() {
self.fileMultiSelectMenu.toggleLoading('restore', false);
+ },
+ function() {
+ OC.Notification.show(t('files_trashbin', 'Error while restoring files from trashbin'));
}
);
- event.preventDefault();
},
_onClickDeleteSelected: function(event) {
event.preventDefault();
var self = this;
var allFiles = this.$el.find('.select-all').is(':checked');
- var files = [];
- var params = {};
- if (allFiles) {
- params = {
- allfiles: true,
- dir: this.getCurrentDirectory()
- };
- }
- else {
- files = _.pluck(this.getSelectedFiles(), 'name');
- params = {
- files: JSON.stringify(files),
- dir: this.getCurrentDirectory()
- };
+ var files = _.pluck(this.getSelectedFiles(), 'name');
+ for (var i = 0; i < files.length; i++) {
+ var tr = this.findFileEl(files[i]);
+ this.showFileBusyState(tr, true);
}
- this.fileMultiSelectMenu.toggleLoading('delete', true);
if (allFiles) {
- this.showMask();
- }
- else {
- for (var i = 0; i < files.length; i++) {
- var deleteAction = this.findFileEl(files[i]).children("td.date").children(".action.delete");
- deleteAction.removeClass('icon-delete').addClass('icon-loading-small');
- }
- }
-
- $.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'),
- params,
- function(result) {
- if (allFiles) {
- if (result.status !== 'success') {
- OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error'));
- }
+ return this.client.remove(OC.joinPaths('trash', this.getCurrentDirectory()))
+ .then(
+ function() {
self.hideMask();
- // simply remove all files
self.setFiles([]);
+ },
+ function() {
+ OC.Notification.show(t('files_trashbin', 'Error while emptying trashbin'));
}
- else {
- self._removeCallback(result);
- }
+ );
+ } else {
+ this.fileMultiSelectMenu.toggleLoading('delete', true);
+ var deletePromises = files.map(function(file) {
+ return self.client.remove(OC.joinPaths('trash', self.getCurrentDirectory(), file))
+ .then(
+ function() {
+ self._removeCallback([file]);
+ }
+ );
+ });
+ return Promise.all(deletePromises).then(
+ function() {
self.fileMultiSelectMenu.toggleLoading('delete', false);
+ },
+ function() {
+ OC.Notification.show(t('files_trashbin', 'Error while removing files from trashbin'));
}
- );
+ );
+ }
},
_onClickFile: function(event) {
@@ -278,6 +245,13 @@
},
/**
+ * Returns list of webdav properties to request
+ */
+ _getWebdavProperties: function() {
+ return [FILENAME_PROP, DELETION_TIME_PROP].concat(this.filesClient.getPropfindProperties());
+ },
+
+ /**
* Reloads the file list using ajax call
*
* @return ajax call object
@@ -290,39 +264,25 @@
if (this._reloadCall) {
this._reloadCall.abort();
}
- this._reloadCall = $.ajax({
- url: this.getAjaxUrl('list'),
- data: {
- dir : this.getCurrentDirectory(),
- sort: this._sort,
- sortdirection: this._sortDirection
+ this._reloadCall = this.client.getFolderContents(
+ 'trash/' + this.getCurrentDirectory(), {
+ includeParent: false,
+ properties: this._getWebdavProperties()
}
- });
+ );
var callBack = this.reloadCallback.bind(this);
return this._reloadCall.then(callBack, callBack);
},
- reloadCallback: function(result) {
+ reloadCallback: function(status, result) {
delete this._reloadCall;
this.hideMask();
- if (!result || result.status === 'error') {
- // if the error is not related to folder we're trying to load, reload the page to handle logout etc
- if (result.data.error === 'authentication_error' ||
- result.data.error === 'token_expired' ||
- result.data.error === 'application_not_enabled'
- ) {
- OC.redirect(OC.generateUrl('apps/files'));
- }
- OC.Notification.show(result.data.message);
- return false;
- }
-
- if (result.status === 401) {
+ if (status === 401) {
return false;
}
// Firewall Blocked request?
- if (result.status === 403) {
+ if (status === 403) {
// Go home
this.changeDirectory('/');
OC.Notification.show(t('files', 'This operation is forbidden'));
@@ -330,24 +290,24 @@
}
// Did share service die or something else fail?
- if (result.status === 500) {
+ if (status === 500) {
// Go home
this.changeDirectory('/');
OC.Notification.show(t('files', 'This directory is unavailable, please check the logs or contact the administrator'));
return false;
}
- if (result.status === 404) {
+ if (status === 404) {
// go back home
this.changeDirectory('/');
return false;
}
// aborted ?
- if (result.status === 0){
+ if (status === 0){
return true;
}
- this.setFiles(result.data.files);
+ this.setFiles(result);
return true;
},
diff --git a/apps/files_trashbin/lib/Sabre/AbstractTrash.php b/apps/files_trashbin/lib/Sabre/AbstractTrash.php
new file mode 100644
index 00000000000..43f9cc02749
--- /dev/null
+++ b/apps/files_trashbin/lib/Sabre/AbstractTrash.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Files_Trashbin\Sabre;
+
+use OCP\Files\FileInfo;
+
+abstract class AbstractTrash implements ITrash {
+ /** @var FileInfo */
+ protected $data;
+
+ public function __construct(FileInfo $data) {
+ $this->data = $data;
+ }
+
+ public function getFilename(): string {
+ return $this->data->getName();
+ }
+
+ public function getDeletionTime(): int {
+ return $this->data->getMtime();
+ }
+
+ public function getFileId(): int {
+ return $this->data->getId();
+ }
+
+ public function getFileInfo(): FileInfo {
+ return $this->data;
+ }
+
+ public function getSize(): int {
+ return $this->data->getSize();
+ }
+
+ public function getLastModified(): int {
+ return $this->data->getMtime();
+ }
+
+ public function getContentType(): string {
+ return $this->data->getMimetype();
+ }
+
+ public function getETag(): string {
+ return $this->data->getEtag();
+ }
+
+ public function getName(): string {
+ return $this->data->getName();
+ }
+}
diff --git a/apps/files_trashbin/lib/Sabre/ITrash.php b/apps/files_trashbin/lib/Sabre/ITrash.php
index 6db9bccf0a2..49c600c3f18 100644
--- a/apps/files_trashbin/lib/Sabre/ITrash.php
+++ b/apps/files_trashbin/lib/Sabre/ITrash.php
@@ -23,6 +23,8 @@ declare(strict_types=1);
*/
namespace OCA\Files_Trashbin\Sabre;
+use OCP\Files\FileInfo;
+
interface ITrash {
public function restore(): bool;
@@ -35,4 +37,6 @@ interface ITrash {
public function getSize();
public function getFileId(): int;
+
+ public function getFileInfo(): FileInfo;
}
diff --git a/apps/files_trashbin/lib/Sabre/PropfindPlugin.php b/apps/files_trashbin/lib/Sabre/PropfindPlugin.php
index 492035304ba..19da79fd2a3 100644
--- a/apps/files_trashbin/lib/Sabre/PropfindPlugin.php
+++ b/apps/files_trashbin/lib/Sabre/PropfindPlugin.php
@@ -25,6 +25,8 @@ declare(strict_types=1);
namespace OCA\Files_Trashbin\Sabre;
use OCA\DAV\Connector\Sabre\FilesPlugin;
+use OCP\Constants;
+use OCP\IPreview;
use Sabre\DAV\INode;
use Sabre\DAV\PropFind;
use Sabre\DAV\Server;
@@ -39,7 +41,13 @@ class PropfindPlugin extends ServerPlugin {
/** @var Server */
private $server;
- public function __construct() {
+ /** @var IPreview */
+ private $previewManager;
+
+ public function __construct(
+ IPreview $previewManager
+ ) {
+ $this->previewManager = $previewManager;
}
public function initialize(Server $server) {
@@ -54,11 +62,11 @@ class PropfindPlugin extends ServerPlugin {
return;
}
- $propFind->handle(self::TRASHBIN_FILENAME, function() use ($node) {
+ $propFind->handle(self::TRASHBIN_FILENAME, function () use ($node) {
return $node->getFilename();
});
- $propFind->handle(self::TRASHBIN_ORIGINAL_LOCATION, function() use ($node) {
+ $propFind->handle(self::TRASHBIN_ORIGINAL_LOCATION, function () use ($node) {
return $node->getOriginalLocation();
});
@@ -73,6 +81,28 @@ class PropfindPlugin extends ServerPlugin {
$propFind->handle(FilesPlugin::FILEID_PROPERTYNAME, function () use ($node) {
return $node->getFileId();
});
+
+ $propFind->handle(FilesPlugin::PERMISSIONS_PROPERTYNAME, function () {
+ return 'GD'; // read + delete
+ });
+
+ $propFind->handle(FilesPlugin::GETETAG_PROPERTYNAME, function () use ($node) {
+ // add fake etag, it is only needed to identify the preview image
+ return $node->getLastModified();
+ });
+
+ $propFind->handle(FilesPlugin::INTERNAL_FILEID_PROPERTYNAME, function () use ($node) {
+ // add fake etag, it is only needed to identify the preview image
+ return $node->getFileId();
+ });
+
+ $propFind->handle(FilesPlugin::HAS_PREVIEW_PROPERTYNAME, function () use ($node) {
+ return $this->previewManager->isAvailable($node->getFileInfo());
+ });
+
+ $propFind->handle(FilesPlugin::MOUNT_TYPE_PROPERTYNAME, function () {
+ return '';
+ });
}
}
diff --git a/apps/files_trashbin/lib/Sabre/TrashFile.php b/apps/files_trashbin/lib/Sabre/TrashFile.php
index eba9eee641b..840ca6a1938 100644
--- a/apps/files_trashbin/lib/Sabre/TrashFile.php
+++ b/apps/files_trashbin/lib/Sabre/TrashFile.php
@@ -27,16 +27,13 @@ use OCP\Files\FileInfo;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\IFile;
-class TrashFile implements IFile, ITrash {
+class TrashFile extends AbstractTrash implements IFile, ITrash {
/** @var string */
private $userId;
- /** @var FileInfo */
- private $data;
-
public function __construct(string $userId, FileInfo $data) {
$this->userId = $userId;
- $this->data = $data;
+ parent::__construct($data);
}
public function put($data) {
@@ -47,18 +44,6 @@ class TrashFile implements IFile, ITrash {
return $this->data->getStorage()->fopen($this->data->getInternalPath().'.d'.$this->getLastModified(), 'rb');
}
- public function getContentType(): string {
- return $this->data->getMimetype();
- }
-
- public function getETag(): string {
- return $this->data->getEtag();
- }
-
- public function getSize(): int {
- return $this->data->getSize();
- }
-
public function delete() {
\OCA\Files_Trashbin\Trashbin::delete($this->data->getName(), $this->userId, $this->getLastModified());
}
@@ -71,29 +56,11 @@ class TrashFile implements IFile, ITrash {
throw new Forbidden();
}
- public function getLastModified(): int {
- return $this->data->getMtime();
- }
-
public function restore(): bool {
return \OCA\Files_Trashbin\Trashbin::restore($this->getName(), $this->data->getName(), $this->getLastModified());
}
- public function getFilename(): string {
- return $this->data->getName();
- }
-
public function getOriginalLocation(): string {
return $this->data['extraData'];
}
-
- public function getDeletionTime(): int {
- return $this->getLastModified();
- }
-
- public function getFileId(): int {
- return $this->data->getId();
- }
-
-
}
diff --git a/apps/files_trashbin/lib/Sabre/TrashFolder.php b/apps/files_trashbin/lib/Sabre/TrashFolder.php
index 6b7d71b80ee..d884eefcc9f 100644
--- a/apps/files_trashbin/lib/Sabre/TrashFolder.php
+++ b/apps/files_trashbin/lib/Sabre/TrashFolder.php
@@ -28,16 +28,13 @@ use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\ICollection;
-class TrashFolder implements ICollection, ITrash {
+class TrashFolder extends AbstractTrash implements ICollection, ITrash {
/** @var string */
private $userId;
- /** @var FileInfo */
- private $data;
-
public function __construct(string $root, string $userId, FileInfo $data) {
$this->userId = $userId;
- $this->data = $data;
+ parent::__construct($data);
}
public function createFile($name, $data = null) {
@@ -100,31 +97,11 @@ class TrashFolder implements ICollection, ITrash {
throw new Forbidden();
}
- public function getLastModified(): int {
- return $this->data->getMtime();
- }
-
public function restore(): bool {
return \OCA\Files_Trashbin\Trashbin::restore($this->getName(), $this->data->getName(), $this->getLastModified());
}
- public function getFilename(): string {
- return $this->data->getName();
- }
-
public function getOriginalLocation(): string {
return $this->data['extraData'];
}
-
- public function getDeletionTime(): int {
- return $this->getLastModified();
- }
-
- public function getSize(): int {
- return $this->data->getSize();
- }
-
- public function getFileId(): int {
- return $this->data->getId();
- }
}
diff --git a/apps/files_trashbin/lib/Sabre/TrashFolderFile.php b/apps/files_trashbin/lib/Sabre/TrashFolderFile.php
index 921c98b02fb..3e28d048b42 100644
--- a/apps/files_trashbin/lib/Sabre/TrashFolderFile.php
+++ b/apps/files_trashbin/lib/Sabre/TrashFolderFile.php
@@ -27,16 +27,13 @@ use OCP\Files\FileInfo;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\IFile;
-class TrashFolderFile implements IFile, ITrash {
+class TrashFolderFile extends AbstractTrash implements IFile, ITrash {
/** @var string */
private $root;
/** @var string */
private $userId;
- /** @var FileInfo */
- private $data;
-
/** @var string */
private $location;
@@ -46,8 +43,8 @@ class TrashFolderFile implements IFile, ITrash {
string $location) {
$this->root = $root;
$this->userId = $userId;
- $this->data = $data;
$this->location = $location;
+ parent::__construct($data);
}
public function put($data) {
@@ -58,51 +55,19 @@ class TrashFolderFile implements IFile, ITrash {
return $this->data->getStorage()->fopen($this->data->getInternalPath(), 'rb');
}
- public function getContentType(): string {
- return $this->data->getMimetype();
- }
-
- public function getETag(): string {
- return $this->data->getEtag();
- }
-
- public function getSize(): int {
- return $this->data->getSize();
- }
-
public function delete() {
\OCA\Files_Trashbin\Trashbin::delete($this->root . '/' . $this->getName(), $this->userId, null);
}
- public function getName(): string {
- return $this->data->getName();
- }
-
public function setName($name) {
throw new Forbidden();
}
- public function getLastModified(): int {
- return $this->data->getMtime();
- }
-
public function restore(): bool {
return \OCA\Files_Trashbin\Trashbin::restore($this->root . '/' . $this->getName(), $this->data->getName(), null);
}
- public function getFilename(): string {
- return $this->data->getName();
- }
-
public function getOriginalLocation(): string {
return $this->location . '/' . $this->getFilename();
}
-
- public function getDeletionTime(): int {
- return $this->getLastModified();
- }
-
- public function getFileId(): int {
- return $this->data->getId();
- }
}
diff --git a/apps/files_trashbin/lib/Sabre/TrashFolderFolder.php b/apps/files_trashbin/lib/Sabre/TrashFolderFolder.php
index 2fe75479c1b..4ee9a0e2db0 100644
--- a/apps/files_trashbin/lib/Sabre/TrashFolderFolder.php
+++ b/apps/files_trashbin/lib/Sabre/TrashFolderFolder.php
@@ -28,7 +28,7 @@ use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\ICollection;
-class TrashFolderFolder implements ICollection, ITrash {
+class TrashFolderFolder extends AbstractTrash implements ICollection, ITrash {
/** @var string */
private $root;
@@ -36,9 +36,6 @@ class TrashFolderFolder implements ICollection, ITrash {
/** @var string */
private $userId;
- /** @var FileInfo */
- private $data;
-
/** @var string */
private $location;
@@ -48,8 +45,8 @@ class TrashFolderFolder implements ICollection, ITrash {
string $location) {
$this->root = $root;
$this->userId = $userId;
- $this->data = $data;
$this->location = $location;
+ parent::__construct($data);
}
public function createFile($name, $data = null) {
@@ -104,40 +101,15 @@ class TrashFolderFolder implements ICollection, ITrash {
\OCA\Files_Trashbin\Trashbin::delete($this->root . '/' . $this->getName(), $this->userId, null);
}
- public function getName(): string {
- return $this->data->getName();
-
- }
-
public function setName($name) {
throw new Forbidden();
}
- public function getLastModified(): int {
- return $this->data->getMtime();
- }
-
public function restore(): bool {
return \OCA\Files_Trashbin\Trashbin::restore($this->root . '/' . $this->getName(), $this->data->getName(), null);
}
- public function getFilename(): string {
- return $this->data->getName();
- }
-
public function getOriginalLocation(): string {
return $this->location . '/' . $this->getFilename();
}
-
- public function getDeletionTime(): int {
- return $this->getLastModified();
- }
-
- public function getSize(): int {
- return $this->data->getSize();
- }
-
- public function getFileId(): int {
- return $this->data->getId();
- }
}
diff --git a/apps/files_trashbin/tests/js/filelistSpec.js b/apps/files_trashbin/tests/js/filelistSpec.js
index c5b1018856b..e9b519ad1fe 100644
--- a/apps/files_trashbin/tests/js/filelistSpec.js
+++ b/apps/files_trashbin/tests/js/filelistSpec.js
@@ -1,31 +1,38 @@
/**
-* 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/>.
-*
-*/
+ * 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/>.
+ *
+ */
-describe('OCA.Trashbin.FileList tests', function() {
- var testFiles, alertStub, notificationStub, fileList;
+describe('OCA.Trashbin.FileList tests', function () {
+ var testFiles, alertStub, notificationStub, fileList, client;
- beforeEach(function() {
+ beforeEach(function () {
alertStub = sinon.stub(OC.dialogs, 'alert');
notificationStub = sinon.stub(OC.Notification, 'show');
+ client = new OC.Files.Client({
+ host: 'localhost',
+ port: 80,
+ root: '/remote.php/dav/trashbin/user',
+ useHTTPS: OC.getProtocol() === 'https'
+ });
+
// init parameters and test table elements
$('#testArea').append(
'<div id="app-content-trashbin">' +
@@ -59,21 +66,24 @@ describe('OCA.Trashbin.FileList tests', function() {
testFiles = [{
id: 1,
type: 'file',
- name: 'One.txt',
+ name: 'One.txt.d11111',
+ displayName: 'One.txt',
mtime: 11111000,
mimetype: 'text/plain',
etag: 'abc'
}, {
id: 2,
type: 'file',
- name: 'Two.jpg',
+ name: 'Two.jpg.d22222',
+ displayName: 'Two.jpg',
mtime: 22222000,
mimetype: 'image/jpeg',
etag: 'def',
}, {
id: 3,
type: 'file',
- name: 'Three.pdf',
+ name: 'Three.pdf.d33333',
+ displayName: 'Three.pdf',
mtime: 33333000,
mimetype: 'application/pdf',
etag: '123',
@@ -81,7 +91,8 @@ describe('OCA.Trashbin.FileList tests', function() {
id: 4,
type: 'dir',
mtime: 99999000,
- name: 'somedir',
+ name: 'somedir.d99999',
+ displayName: 'somedir',
mimetype: 'httpd/unix-directory',
etag: '456'
}];
@@ -92,20 +103,21 @@ describe('OCA.Trashbin.FileList tests', function() {
$('#app-content-trashbin'), {
fileActions: fileActions,
multiSelectMenu: [{
- name: 'restore',
- displayName: t('files', 'Restore'),
- iconClass: 'icon-history',
- },
+ name: 'restore',
+ displayName: t('files', 'Restore'),
+ iconClass: 'icon-history',
+ },
{
name: 'delete',
displayName: t('files', 'Delete'),
iconClass: 'icon-delete',
}
- ]
+ ],
+ client: client
}
);
});
- afterEach(function() {
+ afterEach(function () {
testFiles = undefined;
fileList.destroy();
fileList = undefined;
@@ -114,17 +126,17 @@ describe('OCA.Trashbin.FileList tests', function() {
notificationStub.restore();
alertStub.restore();
});
- describe('Initialization', function() {
- it('Sorts by mtime by default', function() {
+ describe('Initialization', function () {
+ it('Sorts by mtime by default', function () {
expect(fileList._sort).toEqual('mtime');
expect(fileList._sortDirection).toEqual('desc');
});
- it('Always returns read and delete permission', function() {
+ it('Always returns read and delete permission', function () {
expect(fileList.getDirectoryPermissions()).toEqual(OC.PERMISSION_READ | OC.PERMISSION_DELETE);
});
});
- describe('Breadcrumbs', function() {
- beforeEach(function() {
+ describe('Breadcrumbs', function () {
+ beforeEach(function () {
var data = {
status: 'success',
data: {
@@ -133,13 +145,13 @@ describe('OCA.Trashbin.FileList tests', function() {
}
};
fakeServer.respondWith(/\/index\.php\/apps\/files_trashbin\/ajax\/list.php\?dir=%2Fsubdir/, [
- 200, {
- "Content-Type": "application/json"
- },
- JSON.stringify(data)
+ 200, {
+ "Content-Type": "application/json"
+ },
+ JSON.stringify(data)
]);
});
- it('links the breadcrumb to the trashbin view', function() {
+ it('links the breadcrumb to the trashbin view', function () {
fileList.changeDirectory('/subdir', false, true);
fakeServer.respond();
var $crumbs = fileList.$el.find('#controls .crumb');
@@ -152,8 +164,8 @@ describe('OCA.Trashbin.FileList tests', function() {
.toEqual(OC.webroot + '/index.php/apps/files?view=trashbin&dir=/subdir');
});
});
- describe('Rendering rows', function() {
- it('renders rows with the correct data when in root', function() {
+ describe('Rendering rows', function () {
+ it('renders rows with the correct data when in root', function () {
// dir listing is false when in root
$('#dir').val('/');
fileList.setFiles(testFiles);
@@ -174,7 +186,7 @@ describe('OCA.Trashbin.FileList tests', function() {
expect(fileList.findFileEl('One.txt.d11111')[0]).toEqual($tr[0]);
});
- it('renders rows with the correct data when in root after calling setFiles with the same data set', function() {
+ it('renders rows with the correct data when in root after calling setFiles with the same data set', function () {
// dir listing is false when in root
$('#dir').val('/');
fileList.setFiles(testFiles);
@@ -196,11 +208,14 @@ describe('OCA.Trashbin.FileList tests', function() {
expect(fileList.findFileEl('One.txt.d11111')[0]).toEqual($tr[0]);
});
- it('renders rows with the correct data when in subdirectory', function() {
+ it('renders rows with the correct data when in subdirectory', function () {
// dir listing is true when in a subdir
$('#dir').val('/subdir');
- fileList.setFiles(testFiles);
+ fileList.setFiles(testFiles.map(function (file) {
+ file.name = file.displayName;
+ return file;
+ }));
var $rows = fileList.$el.find('tbody tr');
var $tr = $rows.eq(0);
expect($rows.length).toEqual(4);
@@ -218,42 +233,42 @@ describe('OCA.Trashbin.FileList tests', function() {
expect(fileList.findFileEl('One.txt')[0]).toEqual($tr[0]);
});
- it('does not render a size column', function() {
+ it('does not render a size column', function () {
expect(fileList.$el.find('tbody tr .filesize').length).toEqual(0);
});
});
- describe('File actions', function() {
- describe('Deleting single files', function() {
+ describe('File actions', function () {
+ describe('Deleting single files', function () {
// TODO: checks ajax call
// TODO: checks spinner
// TODO: remove item after delete
// TODO: bring back item if delete failed
});
- describe('Restoring single files', function() {
+ describe('Restoring single files', function () {
// TODO: checks ajax call
// TODO: checks spinner
// TODO: remove item after restore
// TODO: bring back item if restore failed
});
});
- describe('file previews', function() {
+ describe('file previews', function () {
// TODO: check that preview URL is going through files_trashbin
});
- describe('loading file list', function() {
+ describe('loading file list', function () {
// TODO: check that ajax URL is going through files_trashbin
});
- describe('breadcrumbs', function() {
+ describe('breadcrumbs', function () {
// TODO: test label + URL
});
- describe('elementToFile', function() {
+ describe('elementToFile', function () {
var $tr;
- beforeEach(function() {
+ beforeEach(function () {
fileList.setFiles(testFiles);
$tr = fileList.findFileEl('One.txt.d11111');
});
- it('converts data attributes to file info structure', function() {
+ it('converts data attributes to file info structure', function () {
var fileInfo = fileList.elementToFile($tr);
expect(fileInfo.id).toEqual(1);
expect(fileInfo.name).toEqual('One.txt.d11111');
@@ -265,8 +280,8 @@ describe('OCA.Trashbin.FileList tests', function() {
expect(fileInfo.type).toEqual('file');
});
});
- describe('Global Actions', function() {
- beforeEach(function() {
+ describe('Global Actions', function () {
+ beforeEach(function () {
fileList.setFiles(testFiles);
fileList.findFileEl('One.txt.d11111').find('input:checkbox').click();
fileList.findFileEl('Three.pdf.d33333').find('input:checkbox').click();
@@ -274,12 +289,12 @@ describe('OCA.Trashbin.FileList tests', function() {
fileList.$el.find('.actions-selected').click();
});
- afterEach(function() {
+ afterEach(function () {
fileList.$el.find('.actions-selected').click();
});
- describe('Delete', function() {
- it('Shows trashbin actions', function() {
+ describe('Delete', function () {
+ it('Shows trashbin actions', function () {
// visible because a few files were selected
expect($('.selectedActions').is(':visible')).toEqual(true);
expect($('.selectedActions .item-delete').is(':visible')).toEqual(true);
@@ -301,99 +316,82 @@ describe('OCA.Trashbin.FileList tests', function() {
expect($('.selectedActions .item-delete').is(':visible')).toEqual(false);
expect($('.selectedActions .item-restore').is(':visible')).toEqual(false);
});
- it('Deletes selected files when "Delete" clicked', function() {
+ it('Deletes selected files when "Delete" clicked', function () {
var request;
- var $deleteLink = $('.selectedActions .filesSelectMenu .delete');
- $deleteLink.click();
- expect($deleteLink.find('.icon-loading-small').length).toEqual(1);
- expect(fakeServer.requests.length).toEqual(1);
- request = fakeServer.requests[0];
- expect(request.url).toEqual(OC.webroot + '/index.php/apps/files_trashbin/ajax/delete.php');
- expect(OC.parseQueryString(request.requestBody))
- .toEqual({'dir': '/', files: '["One.txt.d11111","Three.pdf.d33333","somedir.d99999"]'});
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- status: 'success',
- data: {
- success: [
- {filename: 'One.txt.d11111'},
- {filename: 'Three.pdf.d33333'},
- {filename: 'somedir.d99999'}
- ]
- }
- })
- );
- expect($deleteLink.find('.icon-loading-small').length).toEqual(0);
- expect(fileList.findFileEl('One.txt.d11111').length).toEqual(0);
- expect(fileList.findFileEl('Three.pdf.d33333').length).toEqual(0);
- expect(fileList.findFileEl('somedir.d99999').length).toEqual(0);
- expect(fileList.findFileEl('Two.jpg.d22222').length).toEqual(1);
+ var promise = fileList._onClickDeleteSelected({
+ preventDefault: function () {
+ }
+ });
+ var files = ["One.txt.d11111", "Three.pdf.d33333", "somedir.d99999"];
+ expect(fakeServer.requests.length).toEqual(files.length);
+ for (var i = 0; i < files.length; i++) {
+ request = fakeServer.requests[i];
+ expect(request.url).toEqual(OC.webroot + '/remote.php/dav/trashbin/user/trash/' + files[i]);
+ request.respond(200);
+ }
+ return promise.then(function () {
+ expect(fileList.findFileEl('One.txt.d11111').length).toEqual(0);
+ expect(fileList.findFileEl('Three.pdf.d33333').length).toEqual(0);
+ expect(fileList.findFileEl('somedir.d99999').length).toEqual(0);
+ expect(fileList.findFileEl('Two.jpg.d22222').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 () {
var request;
$('.select-all').click();
- $('.selectedActions .filesSelectMenu .delete').click();
+ var promise = fileList._onClickDeleteSelected({
+ preventDefault: function () {
+ }
+ });
expect(fakeServer.requests.length).toEqual(1);
request = fakeServer.requests[0];
- expect(request.url).toEqual(OC.webroot + '/index.php/apps/files_trashbin/ajax/delete.php');
- expect(OC.parseQueryString(request.requestBody))
- .toEqual({'dir': '/', allfiles: 'true'});
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({status: 'success'})
- );
- expect(fileList.isEmpty).toEqual(true);
+ expect(request.url).toEqual(OC.webroot + '/remote.php/dav/trashbin/user/trash');
+ request.respond(200);
+ return promise.then(function () {
+ expect(fileList.isEmpty).toEqual(true);
+ });
});
});
- describe('Restore', function() {
- it('Restores selected files when "Restore" clicked', function() {
+ describe('Restore', function () {
+ it('Restores selected files when "Restore" clicked', function () {
var request;
- var $restoreLink = $('.selectedActions .filesSelectMenu .restore');
- $restoreLink.click();
- expect($restoreLink.find('.icon-loading-small').length).toEqual(1);
- expect(fakeServer.requests.length).toEqual(1);
- request = fakeServer.requests[0];
- expect(request.url).toEqual(OC.webroot + '/index.php/apps/files_trashbin/ajax/undelete.php');
- expect(OC.parseQueryString(request.requestBody))
- .toEqual({'dir': '/', files: '["One.txt.d11111","Three.pdf.d33333","somedir.d99999"]'});
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- status: 'success',
- data: {
- success: [
- {filename: 'One.txt.d11111'},
- {filename: 'Three.pdf.d33333'},
- {filename: 'somedir.d99999'}
- ]
- }
- })
- );
- expect($restoreLink.find('.icon-loading-small').length).toEqual(0);
- expect(fileList.findFileEl('One.txt.d11111').length).toEqual(0);
- expect(fileList.findFileEl('Three.pdf.d33333').length).toEqual(0);
- expect(fileList.findFileEl('somedir.d99999').length).toEqual(0);
- expect(fileList.findFileEl('Two.jpg.d22222').length).toEqual(1);
+ var promise = fileList._onClickRestoreSelected({
+ preventDefault: function () {
+ }
+ });
+ var files = ["One.txt.d11111", "Three.pdf.d33333", "somedir.d99999"];
+ expect(fakeServer.requests.length).toEqual(files.length);
+ for (var i = 0; i < files.length; i++) {
+ request = fakeServer.requests[i];
+ expect(request.url).toEqual(OC.webroot + '/remote.php/dav/trashbin/user/trash/' + files[i]);
+ expect(request.requestHeaders.Destination).toEqual(OC.webroot + '/remote.php/dav/trashbin/user/restore/' + files[i]);
+ request.respond(200);
+ }
+ return promise.then(function() {
+ expect(fileList.findFileEl('One.txt.d11111').length).toEqual(0);
+ expect(fileList.findFileEl('Three.pdf.d33333').length).toEqual(0);
+ expect(fileList.findFileEl('somedir.d99999').length).toEqual(0);
+ expect(fileList.findFileEl('Two.jpg.d22222').length).toEqual(1);
+ });
});
- it('Restores all files when all selected when "Restore" clicked', function() {
+ it('Restores all files when all selected when "Restore" clicked', function () {
var request;
$('.select-all').click();
- $('.selectedActions .filesSelectMenu .restore').click();
- expect(fakeServer.requests.length).toEqual(1);
- request = fakeServer.requests[0];
- expect(request.url).toEqual(OC.webroot + '/index.php/apps/files_trashbin/ajax/undelete.php');
- expect(OC.parseQueryString(request.requestBody))
- .toEqual({'dir': '/', allfiles: 'true'});
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({status: 'success'})
- );
- expect(fileList.isEmpty).toEqual(true);
+ var promise = fileList._onClickRestoreSelected({
+ preventDefault: function () {
+ }
+ });
+ var files = ["One.txt.d11111", "Two.jpg.d22222", "Three.pdf.d33333", "somedir.d99999"];
+ expect(fakeServer.requests.length).toEqual(files.length);
+ for (var i = 0; i < files.length; i++) {
+ request = fakeServer.requests[i];
+ expect(request.url).toEqual(OC.webroot + '/remote.php/dav/trashbin/user/trash/' + files[i]);
+ expect(request.requestHeaders.Destination).toEqual(OC.webroot + '/remote.php/dav/trashbin/user/restore/' + files[i]);
+ request.respond(200);
+ }
+ return promise.then(function() {
+ expect(fileList.isEmpty).toEqual(true);
+ });
});
});
});