From d4087811e595989f5e30adfbaaa150a526ea98fc Mon Sep 17 00:00:00 2001
From: Robin Appelman <robin@icewind.nl>
Date: Tue, 11 Sep 2018 14:24:35 +0200
Subject: [PATCH] more trashbin integration tests

Signed-off-by: Robin Appelman <robin@icewind.nl>
---
 .../features/bootstrap/Trashbin.php           | 74 ++++++++++++-------
 build/integration/features/trashbin.feature   | 53 ++++++++++++-
 2 files changed, 101 insertions(+), 26 deletions(-)

diff --git a/build/integration/features/bootstrap/Trashbin.php b/build/integration/features/bootstrap/Trashbin.php
index 2d7f93b6f66..fd90a726421 100644
--- a/build/integration/features/bootstrap/Trashbin.php
+++ b/build/integration/features/bootstrap/Trashbin.php
@@ -20,8 +20,6 @@
  *
  */
 
-use GuzzleHttp\Client;
-use GuzzleHttp\Message\ResponseInterface;
 use PHPUnit\Framework\Assert;
 
 require __DIR__ . '/../../vendor/autoload.php';
@@ -42,6 +40,36 @@ trait Trashbin {
 		Assert::assertEquals(204, $response['statusCode']);
 	}
 
+	private function findFullTrashname($user, $name) {
+		$rootListing = $this->listTrashbinFolder($user, '/');
+
+		foreach ($rootListing as $href => $rootItem) {
+			if ($rootItem['{http://nextcloud.org/ns}trashbin-filename'] === $name) {
+				return basename($href);
+			}
+		}
+
+		return null;
+	}
+
+	/**
+	 * Get the full /startofpath.dxxxx/rest/of/path from /startofpath/rest/of/path
+	 */
+	private function getFullTrashPath($user, $path) {
+		if ($path !== '' && $path !== '/') {
+			$parts = explode('/', $path);
+			$fullName = $this->findFullTrashname($user, $parts[1]);
+			if ($fullName === null) {
+				Assert::fail("cant find $path in trash");
+				return '/dummy_full_path_not_found';
+			}
+			$parts[1] = $fullName;
+
+			$path = implode('/', $parts);
+		}
+		return $path;
+	}
+
 	/**
 	 * List trashbin folder
 	 *
@@ -50,13 +78,21 @@ trait Trashbin {
 	 * @return array response
 	 */
 	public function listTrashbinFolder($user, $path) {
+		$path = $this->getFullTrashPath($user, $path);
 		$client = $this->getSabreClient($user);
 
-		return $client->propfind($this->makeSabrePath($user, 'trash' . $path, 'trashbin'), [
+		$results = $client->propfind($this->makeSabrePath($user, 'trash' . $path, 'trashbin'), [
 			'{http://nextcloud.org/ns}trashbin-filename',
 			'{http://nextcloud.org/ns}trashbin-original-location',
 			'{http://nextcloud.org/ns}trashbin-deletion-time'
 		], 1);
+		$results = array_filter($results, function (array $item) {
+			return isset($item['{http://nextcloud.org/ns}trashbin-filename']);
+		});
+		if ($path !== '' && $path !== '/') {
+			array_shift($results);
+		}
+		return $results;
 	}
 
 	/**
@@ -67,7 +103,7 @@ trait Trashbin {
 	 */
 	public function checkTrashContents($user, $folder, $expectedElements) {
 		$elementList = $this->listTrashbinFolder($user, $folder);
-		$trashContent = array_filter(array_map(function(array $item) {
+		$trashContent = array_filter(array_map(function (array $item) {
 			return $item['{http://nextcloud.org/ns}trashbin-filename'];
 		}, $elementList));
 		if ($expectedElements instanceof \Behat\Gherkin\Node\TableNode) {
@@ -90,8 +126,7 @@ trait Trashbin {
 	 */
 	public function checkTrashSize($user, $folder, $expectedCount) {
 		$elementList = $this->listTrashbinFolder($user, $folder);
-		// first item is listed folder
-		Assert::assertEquals($expectedCount, count($elementList) - 1);
+		Assert::assertEquals($expectedCount, count($elementList));
 	}
 
 	/**
@@ -100,25 +135,14 @@ trait Trashbin {
 	 * @param string $file
 	 */
 	public function restoreFromTrash($user, $file) {
-		// find the full name in trashbin
-		$file = ltrim($file, '/');
-		$parent = dirname($file);
-		if ($parent === '.') {
-			$parent = '';
-		}
-		$elementList = $this->listTrashbinFolder($user, $parent);
-		$name = basename($file);
-		foreach($elementList as $href => $item) {
-			if ($item['{http://nextcloud.org/ns}trashbin-filename'] === $name) {
-				$client = $this->getSabreClient($user);
-				$response = $client->request('MOVE', $href, null, [
-					'Destination' => $this->makeSabrePath($user, 'restore/' . $name, 'trashbin'),
-				]);
-				Assert::assertEquals(201, $response['statusCode']);
-				return;
-			}
-		}
-		Assert::fail("$file" . " is not in trash listing");
+		$file = $this->getFullTrashPath($user, $file);
+		$url = $this->makeSabrePath($user, 'trash' . $file, 'trashbin');
+		$client = $this->getSabreClient($user);
+		$response = $client->request('MOVE', $url, null, [
+			'Destination' => $this->makeSabrePath($user, 'restore/' . basename($file), 'trashbin'),
+		]);
+		Assert::assertEquals(201, $response['statusCode']);
+		return;
 	}
 }
 
diff --git a/build/integration/features/trashbin.feature b/build/integration/features/trashbin.feature
index 0b8bf3a81c4..3a9c29f7cb8 100644
--- a/build/integration/features/trashbin.feature
+++ b/build/integration/features/trashbin.feature
@@ -11,7 +11,7 @@ Feature: trashbin
 		When User "user0" deletes file "/textfile0.txt"
 		Then user "user0" in trash folder "/" should have 1 element
 		And user "user0" in trash folder "/" should have the following elements
-			| /textfile0.txt |
+			| textfile0.txt |
 
 	Scenario: clearing the trashbin
 		Given As an "admin"
@@ -28,3 +28,54 @@ Feature: trashbin
 		Then user "user0" in trash folder "/" should have 0 elements
 		And as "user0" the file "/textfile0.txt" exists
 
+	Scenario: deleting and restoring a folder
+		Given As an "admin"
+		And user "user0" exists
+		When User "user0" created a folder "/testfolder"
+		And User "user0" moves file "/textfile0.txt" to "/testfolder/textfile0.txt"
+		And as "user0" the file "/testfolder/textfile0.txt" exists
+		And User "user0" deletes file "/testfolder"
+		And user "user0" in trash folder "/" should have 1 element
+		And user "user0" in trash folder "/" should have the following elements
+			| testfolder |
+		And user "user0" in trash folder "/testfolder" should have 1 element
+		And user "user0" in trash folder "/testfolder" should have the following elements
+			| textfile0.txt |
+		And user "user0" in restores "/testfolder" from trash
+		Then user "user0" in trash folder "/" should have 0 elements
+		And as "user0" the file "/testfolder/textfile0.txt" exists
+
+	Scenario: deleting a file from a subfolder and restoring it moves it back to the subfolder
+		Given As an "admin"
+		And user "user0" exists
+		When User "user0" created a folder "/testfolder"
+		And User "user0" moves file "/textfile0.txt" to "/testfolder/textfile0.txt"
+		And as "user0" the file "/testfolder/textfile0.txt" exists
+		And User "user0" deletes file "/testfolder/textfile0.txt"
+		And user "user0" in trash folder "/" should have 1 element
+		And user "user0" in trash folder "/" should have the following elements
+			| textfile0.txt |
+		And user "user0" in restores "/textfile0.txt" from trash
+		Then user "user0" in trash folder "/" should have 0 elements
+		And as "user0" the file "/textfile0.txt" does not exist
+		And as "user0" the file "/testfolder/textfile0.txt" exists
+
+	Scenario: deleting and a folder and restoring a file inside it
+		Given As an "admin"
+		And user "user0" exists
+		When User "user0" created a folder "/testfolder"
+		And User "user0" moves file "/textfile0.txt" to "/testfolder/textfile0.txt"
+		And as "user0" the file "/testfolder/textfile0.txt" exists
+		And User "user0" deletes file "/testfolder"
+		And user "user0" in trash folder "/" should have 1 element
+		And user "user0" in trash folder "/" should have the following elements
+			| testfolder |
+		And user "user0" in trash folder "/testfolder" should have 1 element
+		And user "user0" in trash folder "/testfolder" should have the following elements
+			| textfile0.txt |
+		And user "user0" in restores "/testfolder/textfile0.txt" from trash
+		Then user "user0" in trash folder "/" should have 1 elements
+		And user "user0" in trash folder "/testfolder" should have 0 element
+		And as "user0" the file "/textfile0.txt" exists
+
+
-- 
GitLab