From 30610aa61567933f193fc19ee767f2fadc9c9ace Mon Sep 17 00:00:00 2001
From: Joas Schilling <coding@schilljs.com>
Date: Wed, 10 Mar 2021 11:54:43 +0100
Subject: Add integration tests for autocomplete/get (similar to sharees API)

Signed-off-by: Joas Schilling <coding@schilljs.com>
---
 .../collaboration_features/autocomplete.feature    | 175 +++++++++++++++++++++
 build/integration/config/behat.yml                 |  10 ++
 .../features/bootstrap/BasicStructure.php          |  34 ++++
 .../features/bootstrap/CollaborationContext.php    |  71 +++++++++
 4 files changed, 290 insertions(+)
 create mode 100644 build/integration/collaboration_features/autocomplete.feature
 create mode 100644 build/integration/features/bootstrap/CollaborationContext.php

(limited to 'build')

diff --git a/build/integration/collaboration_features/autocomplete.feature b/build/integration/collaboration_features/autocomplete.feature
new file mode 100644
index 00000000000..0ca8ebbc100
--- /dev/null
+++ b/build/integration/collaboration_features/autocomplete.feature
@@ -0,0 +1,175 @@
+Feature: autocomplete
+  Background:
+    Given using api version "2"
+    And group "commongroup" exists
+    And user "admin" belongs to group "commongroup"
+    And user "autocomplete" exists
+    And user "autocomplete2" exists
+    And user "autocomplete2" belongs to group "commongroup"
+
+  Scenario: getting autocomplete
+    Given As an "admin"
+    When get autocomplete for "auto"
+      | id | source |
+      | autocomplete | users |
+      | autocomplete2 | users |
+
+
+  Scenario: getting autocomplete without enumeration
+    Given As an "admin"
+    When parameter "shareapi_allow_share_dialog_user_enumeration" of app "core" is set to "no"
+    Then get autocomplete for "auto"
+      | id | source |
+    Then get autocomplete for "autocomplete"
+      | id | source |
+      | autocomplete | users |
+
+
+  Scenario: getting autocomplete with limited enumeration by group
+    Given As an "admin"
+    When parameter "shareapi_restrict_user_enumeration_to_group" of app "core" is set to "yes"
+    Then get autocomplete for "auto"
+      | id | source |
+      | autocomplete2 | users |
+    Then get autocomplete for "autocomplete"
+      | id | source |
+      | autocomplete | users |
+      | autocomplete2 | users |
+    Then get autocomplete for "autocomplete2"
+      | id | source |
+      | autocomplete2 | users |
+
+
+  Scenario: getting autocomplete with limited enumeration by phone
+    Given As an "admin"
+    When parameter "shareapi_restrict_user_enumeration_to_phone" of app "core" is set to "yes"
+    Then get autocomplete for "auto"
+      | id | source |
+
+    # autocomplete stores their phone number
+    Given As an "autocomplete"
+    And sending "PUT" to "/cloud/users/autocomplete" with
+      | key | phone |
+      | value | +49 711 / 25 24 28-90 |
+    And the HTTP status code should be "200"
+    And the OCS status code should be "200"
+
+    Given As an "admin"
+    Then get autocomplete for "auto"
+      | id | source |
+
+    # admin populates they have the phone number
+    When search users by phone for region "DE" with
+      | random-string1 | 0711 / 252 428-90 |
+    Then get autocomplete for "auto"
+      | id | source |
+      | autocomplete | users |
+
+
+  Scenario: getting autocomplete with limited enumeration by group or phone
+    Given As an "admin"
+    When parameter "shareapi_restrict_user_enumeration_to_group" of app "core" is set to "yes"
+    And parameter "shareapi_restrict_user_enumeration_to_phone" of app "core" is set to "yes"
+
+    # autocomplete stores their phone number
+    Given As an "autocomplete"
+    And sending "PUT" to "/cloud/users/autocomplete" with
+      | key | phone |
+      | value | +49 711 / 25 24 28-90 |
+    And the HTTP status code should be "200"
+    And the OCS status code should be "200"
+    # admin populates they have the phone number
+    Given As an "admin"
+    When search users by phone for region "DE" with
+      | random-string1 | 0711 / 252 428-90 |
+
+    Then get autocomplete for "auto"
+      | id | source |
+      | autocomplete | users |
+      | autocomplete2 | users |
+
+
+  Scenario: getting autocomplete with limited enumeration but sharing is group restricted
+    Given As an "admin"
+    When parameter "shareapi_restrict_user_enumeration_to_group" of app "core" is set to "yes"
+    And parameter "shareapi_restrict_user_enumeration_to_phone" of app "core" is set to "yes"
+
+    # autocomplete stores their phone number
+    Given As an "autocomplete"
+    And sending "PUT" to "/cloud/users/autocomplete" with
+      | key | phone |
+      | value | +49 711 / 25 24 28-90 |
+    And the HTTP status code should be "200"
+    And the OCS status code should be "200"
+    # admin populates they have the phone number
+    Given As an "admin"
+    When search users by phone for region "DE" with
+      | random-string1 | 0711 / 252 428-90 |
+
+    Then get autocomplete for "auto"
+      | id | source |
+      | autocomplete | users |
+      | autocomplete2 | users |
+    When parameter "shareapi_only_share_with_group_members" of app "core" is set to "yes"
+    Then get autocomplete for "auto"
+      | id | source |
+      | autocomplete2 | users |
+
+
+  Scenario: getting autocomplete with limited enumeration by phone but user changes it
+    Given As an "admin"
+    When parameter "shareapi_restrict_user_enumeration_to_phone" of app "core" is set to "yes"
+    Then get autocomplete for "auto"
+      | id | source |
+
+    # autocomplete stores their phone number
+    Given As an "autocomplete"
+    And sending "PUT" to "/cloud/users/autocomplete" with
+      | key | phone |
+      | value | +49 711 / 25 24 28-90 |
+    And the HTTP status code should be "200"
+    And the OCS status code should be "200"
+
+    Given As an "admin"
+    Then get autocomplete for "auto"
+      | id | source |
+
+    # admin populates they have the phone number
+    When search users by phone for region "DE" with
+      | random-string1 | 0711 / 252 428-90 |
+    Then get autocomplete for "auto"
+      | id | source |
+      | autocomplete | users |
+
+    # autocomplete changes their phone number
+    Given As an "autocomplete"
+    And sending "PUT" to "/cloud/users/autocomplete" with
+      | key | phone |
+      | value | +49 711 / 25 24 28-91 |
+    And the HTTP status code should be "200"
+    And the OCS status code should be "200"
+
+    Given As an "admin"
+    Then get autocomplete for "auto"
+      | id | source |
+
+    # admin populates they have the new phone number
+    When search users by phone for region "DE" with
+      | random-string1 | 0711 / 252 428-91 |
+    Then get autocomplete for "auto"
+      | id | source |
+      | autocomplete | users |
+
+
+  Scenario: getting autocomplete without enumeration and sharing is group restricted
+    Given As an "admin"
+    When parameter "shareapi_allow_share_dialog_user_enumeration" of app "core" is set to "no"
+    And parameter "shareapi_only_share_with_group_members" of app "core" is set to "yes"
+
+    Then get autocomplete for "auto"
+      | id | source |
+    Then get autocomplete for "autocomplete"
+      | id | source |
+    Then get autocomplete for "autocomplete2"
+      | id | source |
+      | autocomplete2 | users |
diff --git a/build/integration/config/behat.yml b/build/integration/config/behat.yml
index 79ffe58f6b6..0e577f5925e 100644
--- a/build/integration/config/behat.yml
+++ b/build/integration/config/behat.yml
@@ -45,6 +45,16 @@ default:
               - admin
               - admin
             regular_user_password: 123456
+    collaboration:
+      paths:
+        - "%paths.base%/../collaboration_features"
+      contexts:
+        - CollaborationContext:
+            baseUrl:  http://localhost:8080/ocs/
+            admin:
+              - admin
+              - admin
+            regular_user_password: 123456
     sharees:
       paths:
         - "%paths.base%/../sharees_features"
diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php
index 5b01e80707d..cc5ac2e14b6 100644
--- a/build/integration/features/bootstrap/BasicStructure.php
+++ b/build/integration/features/bootstrap/BasicStructure.php
@@ -202,6 +202,40 @@ trait BasicStructure {
 		}
 	}
 
+	/**
+	 * @param string $verb
+	 * @param string $url
+	 * @param TableNode|array|null $body
+	 * @param array $headers
+	 */
+	protected function sendRequestForJSON(string $verb, string $url, $body = null, array $headers = []): void {
+		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php" . $url;
+		$client = new Client();
+		$options = [];
+		if ($this->currentUser === 'admin') {
+			$options['auth'] = ['admin', 'admin'];
+		} elseif (strpos($this->currentUser, 'guest') !== 0) {
+			$options['auth'] = [$this->currentUser, self::TEST_PASSWORD];
+		}
+		if ($body instanceof TableNode) {
+			$fd = $body->getRowsHash();
+			$options['form_params'] = $fd;
+		} elseif (is_array($body)) {
+			$options['form_params'] = $body;
+		}
+
+		$options['headers'] = array_merge($headers, [
+			'OCS-ApiRequest' => 'true',
+			'Accept' => 'application/json',
+		]);
+
+		try {
+			$this->response = $client->{$verb}($fullUrl, $options);
+		} catch (ClientException $ex) {
+			$this->response = $ex->getResponse();
+		}
+	}
+
 	/**
 	 * @When /^sending "([^"]*)" with exact url to "([^"]*)"$/
 	 * @param string $verb
diff --git a/build/integration/features/bootstrap/CollaborationContext.php b/build/integration/features/bootstrap/CollaborationContext.php
new file mode 100644
index 00000000000..8207267bf4d
--- /dev/null
+++ b/build/integration/features/bootstrap/CollaborationContext.php
@@ -0,0 +1,71 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2021, Joas Schilling <coding@schilljs.com>
+ *
+ * @author Joas Schilling <coding@schilljs.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 Behat\Behat\Context\Context;
+use Behat\Gherkin\Node\TableNode;
+use PHPUnit\Framework\Assert;
+
+require __DIR__ . '/../../vendor/autoload.php';
+
+class CollaborationContext implements Context {
+	use Provisioning;
+	use AppConfiguration;
+
+	/**
+	 * @Then /^get autocomplete for "([^"]*)"$/
+	 * @param TableNode|null $formData
+	 */
+	public function getAutocomplete(string $search, TableNode $formData): void {
+		$query = $search === 'null' ? null : $search;
+
+		$this->sendRequestForJSON('GET', '/core/autocomplete/get?itemType=files&itemId=123&search=' . $query, [
+			'itemType' => 'files',
+			'itemId' => '123',
+			'search' => $query,
+		]);
+		$this->theHTTPStatusCodeShouldBe(200);
+
+		$data = json_decode($this->response->getBody()->getContents(), true);
+		$suggestions = $data['ocs']['data'];
+
+		Assert::assertCount(count($formData->getHash()), $suggestions, 'Suggestion count does not match');
+		Assert::assertEquals($formData->getHash(), array_map(static function ($suggestion, $expected) {
+			$data = [];
+			if (isset($expected['id'])) {
+				$data['id'] = $suggestion['id'];
+			}
+			if (isset($expected['source'])) {
+				$data['source'] = $suggestion['source'];
+			}
+			return $data;
+		}, $suggestions, $formData->getHash()));
+	}
+
+	protected function resetAppConfigs(): void {
+		$this->deleteServerConfig('core', 'shareapi_allow_share_dialog_user_enumeration');
+		$this->deleteServerConfig('core', 'shareapi_restrict_user_enumeration_to_group');
+		$this->deleteServerConfig('core', 'shareapi_restrict_user_enumeration_to_phone');
+		$this->deleteServerConfig('core', 'shareapi_only_share_with_group_members');
+	}
+}
-- 
cgit v1.2.3