From eaa98ed343e4663cf9281484b26531fecdd175ab Mon Sep 17 00:00:00 2001
From: Daniel Calviño Sánchez <danxuliu@gmail.com>
Date: Fri, 25 Oct 2019 01:54:17 +0200
Subject: Add integration tests for getting shares including subfiles
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
---
 build/integration/features/bootstrap/Sharing.php   | 108 ++++++++++++
 .../sharing_features/sharing-v1-part2.feature      | 186 +++++++++++++++++++++
 2 files changed, 294 insertions(+)

(limited to 'build')

diff --git a/build/integration/features/bootstrap/Sharing.php b/build/integration/features/bootstrap/Sharing.php
index d4a31f919d9..42d2f03221f 100644
--- a/build/integration/features/bootstrap/Sharing.php
+++ b/build/integration/features/bootstrap/Sharing.php
@@ -480,6 +480,114 @@ trait Sharing {
 		}
 	}
 
+	/**
+	 * @Then the list of returned shares has :count shares
+	 */
+	public function theListOfReturnedSharesHasShares(int $count) {
+		$this->theHTTPStatusCodeShouldBe('200');
+		$this->theOCSStatusCodeShouldBe('100');
+
+		$returnedShares = $this->getXmlResponse()->data[0];
+
+		Assert::assertEquals($count, count($returnedShares->element));
+	}
+
+	/**
+	 * @Then share :count is returned with
+	 *
+	 * @param int $number
+	 * @param TableNode $body
+	 */
+	public function shareXIsReturnedWith(int $number, TableNode $body) {
+		$this->theHTTPStatusCodeShouldBe('200');
+		$this->theOCSStatusCodeShouldBe('100');
+
+		if (!($body instanceof TableNode)) {
+			return;
+		}
+
+		$returnedShare = $this->getXmlResponse()->data[0];
+		if ($returnedShare->element) {
+			$returnedShare = $returnedShare->element[$number];
+		}
+
+		$defaultExpectedFields = [
+			'id' => 'A_NUMBER',
+			'permissions' => '19',
+			'stime' => 'A_NUMBER',
+			'parent' => '',
+			'expiration' => '',
+			'token' => '',
+			'storage' => 'A_NUMBER',
+			'item_source' => 'A_NUMBER',
+			'file_source' => 'A_NUMBER',
+			'file_parent' => 'A_NUMBER',
+			'mail_send' => '0'
+		];
+		$expectedFields = array_merge($defaultExpectedFields, $body->getRowsHash());
+
+		if (!array_key_exists('uid_file_owner', $expectedFields) &&
+				array_key_exists('uid_owner', $expectedFields)) {
+			$expectedFields['uid_file_owner'] = $expectedFields['uid_owner'];
+		}
+		if (!array_key_exists('displayname_file_owner', $expectedFields) &&
+				array_key_exists('displayname_owner', $expectedFields)) {
+			$expectedFields['displayname_file_owner'] = $expectedFields['displayname_owner'];
+		}
+
+		if (array_key_exists('share_type', $expectedFields) &&
+				$expectedFields['share_type'] == 10 /* IShare::TYPE_ROOM */ &&
+				array_key_exists('share_with', $expectedFields)) {
+			if ($expectedFields['share_with'] === 'private_conversation') {
+				$expectedFields['share_with'] = 'REGEXP /^private_conversation_[0-9a-f]{6}$/';
+			} else {
+				$expectedFields['share_with'] = FeatureContext::getTokenForIdentifier($expectedFields['share_with']);
+			}
+		}
+
+		foreach ($expectedFields as $field => $value) {
+			$this->assertFieldIsInReturnedShare($field, $value, $returnedShare);
+		}
+	}
+
+	/**
+	 * @return SimpleXMLElement
+	 */
+	private function getXmlResponse(): \SimpleXMLElement {
+		return simplexml_load_string($this->response->getBody());
+	}
+
+	/**
+	 * @param string $field
+	 * @param string $contentExpected
+	 * @param \SimpleXMLElement $returnedShare
+	 */
+	private function assertFieldIsInReturnedShare(string $field, string $contentExpected, \SimpleXMLElement $returnedShare){
+		if ($contentExpected === 'IGNORE') {
+			return;
+		}
+
+		if (!array_key_exists($field, $returnedShare)) {
+			Assert::fail("$field was not found in response");
+		}
+
+		if ($field === 'expiration' && !empty($contentExpected)){
+			$contentExpected = date('Y-m-d', strtotime($contentExpected)) . " 00:00:00";
+		}
+
+		if ($contentExpected === 'A_NUMBER') {
+			Assert::assertTrue(is_numeric((string)$returnedShare->$field), "Field '$field' is not a number: " . $returnedShare->$field);
+		} else if ($contentExpected === 'A_TOKEN') {
+			// A token is composed by 15 characters from
+			// ISecureRandom::CHAR_HUMAN_READABLE.
+			Assert::assertRegExp('/^[abcdefgijkmnopqrstwxyzABCDEFGHJKLMNPQRSTWXYZ23456789]{15}$/', (string)$returnedShare->$field, "Field '$field' is not a token");
+		} else if (strpos($contentExpected, 'REGEXP ') === 0) {
+			Assert::assertRegExp(substr($contentExpected, strlen('REGEXP ')), (string)$returnedShare->$field, "Field '$field' does not match");
+		} else {
+			Assert::assertEquals($contentExpected, (string)$returnedShare->$field, "Field '$field' does not match");
+		}
+	}
+
 	/**
 	 * @Then As :user remove all shares from the file named :fileName
 	 */
diff --git a/build/integration/sharing_features/sharing-v1-part2.feature b/build/integration/sharing_features/sharing-v1-part2.feature
index 3316f3d94ba..49a1afe106d 100644
--- a/build/integration/sharing_features/sharing-v1-part2.feature
+++ b/build/integration/sharing_features/sharing-v1-part2.feature
@@ -115,6 +115,192 @@ Feature: sharing
       | displayname_owner | user0 |
       | mimetype          | text/plain |
 
+  Scenario: getting all shares including subfiles in a directory
+    Given user "user0" exists
+    And user "user1" exists
+    And user "user2" exists
+    And file "PARENT/CHILD" of user "user0" is shared with user "user1"
+    And file "PARENT/parent.txt" of user "user0" is shared with user "user2"
+    When As an "user0"
+    And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=PARENT"
+    Then the list of returned shares has 2 shares
+    And share 0 is returned with
+      | share_type             | 0 |
+      | uid_owner              | user0 |
+      | displayname_owner      | user0 |
+      | path                   | /PARENT/CHILD |
+      | item_type              | folder |
+      | mimetype               | httpd/unix-directory |
+      | storage_id             | home::user0 |
+      | file_target            | /CHILD |
+      | share_with             | user1 |
+      | share_with_displayname | user1 |
+      | permissions            | 31 |
+    And share 1 is returned with
+      | share_type             | 0 |
+      | uid_owner              | user0 |
+      | displayname_owner      | user0 |
+      | path                   | /PARENT/parent.txt |
+      | item_type              | file |
+      | mimetype               | text/plain |
+      | storage_id             | home::user0 |
+      | file_target            | /parent.txt |
+      | share_with             | user2 |
+      | share_with_displayname | user2 |
+
+  Scenario: getting all shares including subfiles in a directory with received shares
+    Given user "user0" exists
+    And user "user1" exists
+    And file "textfile0.txt" of user "user0" is shared with user "user1"
+    And file "textfile0.txt" of user "user1" is shared with user "user0"
+    When As an "user0"
+    And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=/"
+    Then the list of returned shares has 1 shares
+    And share 0 is returned with
+      | share_type             | 0 |
+      | uid_owner              | user0 |
+      | displayname_owner      | user0 |
+      | path                   | /textfile0.txt |
+      | item_type              | file |
+      | mimetype               | text/plain |
+      | storage_id             | home::user0 |
+      | file_target            | /textfile0 (2).txt |
+      | share_with             | user1 |
+      | share_with_displayname | user1 |
+
+  Scenario: getting all shares including subfiles in a directory with shares in subdirectories
+    Given user "user0" exists
+    And user "user1" exists
+    And user "user2" exists
+    And file "PARENT/CHILD" of user "user0" is shared with user "user1"
+    And file "PARENT/CHILD/child.txt" of user "user0" is shared with user "user2"
+    When As an "user0"
+    And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=PARENT"
+    Then the list of returned shares has 1 shares
+    And share 0 is returned with
+      | share_type             | 0 |
+      | uid_owner              | user0 |
+      | displayname_owner      | user0 |
+      | path                   | /PARENT/CHILD |
+      | item_type              | folder |
+      | mimetype               | httpd/unix-directory |
+      | storage_id             | home::user0 |
+      | file_target            | /CHILD |
+      | share_with             | user1 |
+      | share_with_displayname | user1 |
+      | permissions            | 31 |
+
+  Scenario: getting all shares including subfiles in a shared directory with reshares
+    Given user "user0" exists
+    And user "user1" exists
+    And user "user2" exists
+    And user "user3" exists
+    And file "PARENT" of user "user0" is shared with user "user1"
+    And file "PARENT (2)/CHILD" of user "user1" is shared with user "user2"
+    And file "CHILD" of user "user2" is shared with user "user3"
+    When As an "user0"
+    And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=PARENT"
+    Then the list of returned shares has 2 shares
+    And share 0 is returned with
+      | share_type             | 0 |
+      | uid_owner              | user1 |
+      | displayname_owner      | user1 |
+      | uid_file_owner         | user0 |
+      | displayname_file_owner | user0 |
+      | path                   | /PARENT/CHILD |
+      | item_type              | folder |
+      | mimetype               | httpd/unix-directory |
+      | storage_id             | home::user0 |
+      | file_target            | /CHILD |
+      | share_with             | user2 |
+      | share_with_displayname | user2 |
+      | permissions            | 31 |
+    And share 1 is returned with
+      | share_type             | 0 |
+      | uid_owner              | user2 |
+      | displayname_owner      | user2 |
+      | uid_file_owner         | user0 |
+      | displayname_file_owner | user0 |
+      | path                   | /PARENT/CHILD |
+      | item_type              | folder |
+      | mimetype               | httpd/unix-directory |
+      | storage_id             | home::user0 |
+      | file_target            | /CHILD |
+      | share_with             | user3 |
+      | share_with_displayname | user3 |
+      | permissions            | 31 |
+
+  Scenario: getting all shares including subfiles in a directory by a resharer
+    Given user "user0" exists
+    And user "user1" exists
+    And user "user2" exists
+    And user "user3" exists
+    And file "PARENT" of user "user0" is shared with user "user1"
+    And file "PARENT (2)/CHILD" of user "user1" is shared with user "user2"
+    And file "CHILD" of user "user2" is shared with user "user3"
+    When As an "user1"
+    And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=PARENT (2)"
+    Then the list of returned shares has 2 shares
+    And share 0 is returned with
+      | share_type             | 0 |
+      | uid_owner              | user1 |
+      | displayname_owner      | user1 |
+      | uid_file_owner         | user0 |
+      | displayname_file_owner | user0 |
+      | path                   | /PARENT (2)/CHILD |
+      | item_type              | folder |
+      | mimetype               | httpd/unix-directory |
+      | storage_id             | shared::/PARENT (2) |
+      | file_target            | /CHILD |
+      | share_with             | user2 |
+      | share_with_displayname | user2 |
+      | permissions            | 31 |
+    And share 1 is returned with
+      | share_type             | 0 |
+      | uid_owner              | user2 |
+      | displayname_owner      | user2 |
+      | uid_file_owner         | user0 |
+      | displayname_file_owner | user0 |
+      | path                   | /PARENT (2)/CHILD |
+      | item_type              | folder |
+      | mimetype               | httpd/unix-directory |
+      | storage_id             | shared::/PARENT (2) |
+      | file_target            | /CHILD |
+      | share_with             | user3 |
+      | share_with_displayname | user3 |
+      | permissions            | 31 |
+
+  Scenario: getting all shares including subfiles in a directory by a resharer after revoking the resharing rights
+    Given user "user0" exists
+    And user "user1" exists
+    And user "user2" exists
+    And user "user3" exists
+    And file "PARENT" of user "user0" is shared with user "user1"
+    And save the last share data as "parent folder"
+    And file "PARENT (2)/CHILD" of user "user1" is shared with user "user2"
+    And file "CHILD" of user "user2" is shared with user "user3"
+    And As an "user0"
+    And restore the last share data from "parent folder"
+    And Updating last share with
+      | permissions | 1 |
+    When As an "user1"
+    And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=PARENT (2)"
+    Then the list of returned shares has 1 shares
+    And share 0 is returned with
+      | share_type             | 0 |
+      | uid_owner              | user1 |
+      | displayname_owner      | user1 |
+      | uid_file_owner         | user0 |
+      | displayname_file_owner | user0 |
+      | path                   | /PARENT (2)/CHILD |
+      | item_type              | folder |
+      | mimetype               | httpd/unix-directory |
+      | storage_id             | shared::/PARENT (2) |
+      | file_target            | /CHILD |
+      | share_with             | user2 |
+      | share_with_displayname | user2 |
+      | permissions            | 31 |
+
   Scenario: keep group permissions in sync
     Given As an "admin"
     Given user "user0" exists
-- 
cgit v1.2.3