From 30610aa61567933f193fc19ee767f2fadc9c9ace Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 10 Mar 2021 11:54:43 +0100 Subject: [PATCH] Add integration tests for autocomplete/get (similar to sharees API) Signed-off-by: Joas Schilling --- .../autocomplete.feature | 175 ++++++++++++++++++ build/integration/config/behat.yml | 10 + .../features/bootstrap/BasicStructure.php | 34 ++++ .../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 diff --git a/build/integration/collaboration_features/autocomplete.feature b/build/integration/collaboration_features/autocomplete.feature new file mode 100644 index 0000000000..0ca8ebbc10 --- /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 79ffe58f6b..0e577f5925 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 5b01e80707..cc5ac2e14b 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 0000000000..8207267bf4 --- /dev/null +++ b/build/integration/features/bootstrap/CollaborationContext.php @@ -0,0 +1,71 @@ + + * + * @author Joas Schilling + * + * @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 + * + */ + +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'); + } +}