Files
opencloud/tests/acceptance/features/bootstrap/AppConfigurationContext.php
2023-02-28 15:13:36 +05:45

607 lines
17 KiB
PHP

<?php declare(strict_types=1);
/**
* ownCloud
*
* @author Joas Schilling <coding@schilljs.com>
* @author Sergio Bertolin <sbertolin@owncloud.com>
* @author Phillip Davis <phil@jankaritech.com>
* @copyright Copyright (c) 2018, ownCloud GmbH
*
* This code 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 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/>
*
*/
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use GuzzleHttp\Exception\GuzzleException;
use PHPUnit\Framework\Assert;
use TestHelpers\AppConfigHelper;
use TestHelpers\OcsApiHelper;
use Behat\Gherkin\Node\TableNode;
use Behat\Behat\Context\Context;
/**
* AppConfiguration trait
*/
class AppConfigurationContext implements Context {
/**
* @var FeatureContext
*/
private $featureContext;
/**
* @When /^the administrator sets parameter "([^"]*)" of app "([^"]*)" to ((?:'[^']*')|(?:"[^"]*"))$/
*
* @param string $parameter
* @param string $app
* @param string $value
*
* @return void
* @throws Exception
*/
public function adminSetsServerParameterToUsingAPI(
string $parameter,
string $app,
string $value
):void {
// The capturing group of the regex always includes the quotes at each
// end of the captured string, so trim them.
$value = \trim($value, $value[0]);
$this->modifyAppConfig($app, $parameter, $value);
}
/**
* @Given /^parameter "([^"]*)" of app "([^"]*)" has been set to ((?:'[^']*')|(?:"[^"]*"))$/
*
* @param string $parameter
* @param string $app
* @param string $value
*
* @return void
* @throws Exception
*/
public function serverParameterHasBeenSetTo(string $parameter, string $app, string $value):void {
// The capturing group of the regex always includes the quotes at each
// end of the captured string, so trim them.
if (\TestHelpers\OcisHelper::isTestingOnOcisOrReva()) {
return;
}
$value = \trim($value, $value[0]);
$this->modifyAppConfig($app, $parameter, $value);
$this->featureContext->clearStatusCodeArrays();
}
/**
* @Then the capabilities setting of :capabilitiesApp path :capabilitiesPath should be :expectedValue
* @Given the capabilities setting of :capabilitiesApp path :capabilitiesPath has been confirmed to be :expectedValue
*
* @param string $capabilitiesApp the "app" name in the capabilities response
* @param string $capabilitiesPath the path to the element
* @param string $expectedValue
*
* @return void
* @throws Exception
*/
public function theCapabilitiesSettingOfAppParameterShouldBe(
string $capabilitiesApp,
string $capabilitiesPath,
string $expectedValue
):void {
$this->theAdministratorGetsCapabilitiesCheckResponse();
$actualValue = $this->getAppParameter($capabilitiesApp, $capabilitiesPath);
Assert::assertEquals(
$expectedValue,
$actualValue,
__METHOD__
. " $capabilitiesApp path $capabilitiesPath should be $expectedValue but is $actualValue"
);
}
/**
* @param string $capabilitiesApp the "app" name in the capabilities response
* @param string $capabilitiesPath the path to the element
*
* @return string
* @throws Exception
*/
public function getAppParameter(string $capabilitiesApp, string $capabilitiesPath):string {
return $this->getParameterValueFromXml(
$this->getCapabilitiesXml(__METHOD__),
$capabilitiesApp,
$capabilitiesPath
);
}
/**
* @When user :username retrieves the capabilities using the capabilities API
*
* @param string $username
*
* @return void
* @throws GuzzleException
* @throws JsonException
*/
public function userRetrievesCapabilities(string $username): void {
$user = $this->featureContext->getActualUsername($username);
$this->userGetsCapabilities($user, true);
}
/**
*
* @param string $username
* @param boolean $formatJson // if true then formats the response in json
*
* @return void
* @throws GuzzleException
* @throws JsonException
*/
public function userGetsCapabilities(string $username, ?bool $formatJson = false):void {
$user = $this->featureContext->getActualUsername($username);
$password = $this->featureContext->getPasswordForUser($user);
$this->featureContext->setResponse(
OcsApiHelper::sendRequest(
$this->featureContext->getBaseUrl(),
$user,
$password,
'GET',
'/cloud/capabilities' . ($formatJson ? '?format=json' : ''),
$this->featureContext->getStepLineRef(),
[],
$this->featureContext->getOcsApiVersion()
)
);
}
/**
* @Given user :username has retrieved the capabilities
*
* @param string $username
*
* @return void
* @throws Exception
*/
public function userGetsCapabilitiesCheckResponse(string $username):void {
$this->userGetsCapabilities($username);
$statusCode = $this->featureContext->getResponse()->getStatusCode();
if ($statusCode !== 200) {
throw new \Exception(
__METHOD__
. " user $username returned unexpected status $statusCode"
);
}
}
/**
* @When the user retrieves the capabilities using the capabilities API
*
* @return void
*/
public function theUserGetsCapabilities():void {
$this->userGetsCapabilities($this->featureContext->getCurrentUser());
}
/**
* @Given the user has retrieved the capabilities
*
* @return void
* @throws Exception
*/
public function theUserGetsCapabilitiesCheckResponse():void {
$this->userGetsCapabilitiesCheckResponse($this->featureContext->getCurrentUser());
}
/**
* @return string
* @throws Exception
*/
public function getAdminUsernameForCapabilitiesCheck():string {
if (\TestHelpers\OcisHelper::isTestingOnReva()) {
// When testing on reva we don't have a user called "admin" to use
// to access the capabilities. So create an ordinary user on-the-fly
// with a default password. That user should be able to get a
// capabilities response that the test can process.
$adminUsername = "PseudoAdminForRevaTest";
$createdUsers = $this->featureContext->getCreatedUsers();
if (!\array_key_exists($adminUsername, $createdUsers)) {
$this->featureContext->createUser($adminUsername);
}
} else {
$adminUsername = $this->featureContext->getAdminUsername();
}
return $adminUsername;
}
/**
* @When the administrator retrieves the capabilities using the capabilities API
*
* @return void
*/
public function theAdministratorGetsCapabilities():void {
$user = $this->getAdminUsernameForCapabilitiesCheck();
$this->userGetsCapabilities($user, true);
}
/**
* @Given the administrator has retrieved the capabilities
*
* @return void
* @throws Exception
*/
public function theAdministratorGetsCapabilitiesCheckResponse():void {
$this->userGetsCapabilitiesCheckResponse($this->getAdminUsernameForCapabilitiesCheck());
}
/**
* @param string $exceptionText text to put at the front of exception messages
*
* @return SimpleXMLElement latest retrieved capabilities in XML format
* @throws Exception
*/
public function getCapabilitiesXml(string $exceptionText = ''): SimpleXMLElement {
if ($exceptionText === '') {
$exceptionText = __METHOD__;
}
return $this->featureContext->getResponseXml(null, $exceptionText)->data->capabilities;
}
/**
* @param string $exceptionText text to put at the front of exception messages
*
* @return SimpleXMLElement latest retrieved version data in XML format
* @throws Exception
*/
public function getVersionXml(string $exceptionText = ''): SimpleXMLElement {
if ($exceptionText === '') {
$exceptionText = __METHOD__;
}
return $this->featureContext->getResponseXml(null, $exceptionText)->data->version;
}
/**
* @param SimpleXMLElement $xml of the capabilities
* @param string $capabilitiesApp the "app" name in the capabilities response
* @param string $capabilitiesPath the path to the element
*
* @return string
*/
public function getParameterValueFromXml(
SimpleXMLElement $xml,
string $capabilitiesApp,
string $capabilitiesPath
):string {
$path_to_element = \explode('@@@', $capabilitiesPath);
$answeredValue = $xml->{$capabilitiesApp};
foreach ($path_to_element as $element) {
$nameIndexParts = \explode('[', $element);
if (isset($nameIndexParts[1])) {
// This part of the path should be something like "some_element[1]"
// Separately extract the name and the index
$name = $nameIndexParts[0];
$index = (int) \explode(']', $nameIndexParts[1])[0];
// and use those to construct the reference into the next XML level
$answeredValue = $answeredValue->{$name}[$index];
} else {
if ($element !== "") {
$answeredValue = $answeredValue->{$element};
}
}
}
return (string) $answeredValue;
}
/**
* @param SimpleXMLElement $xml of the capabilities
* @param string $capabilitiesApp the "app" name in the capabilities response
* @param string $capabilitiesPath the path to the element
*
* @return boolean
*/
public function parameterValueExistsInXml(
SimpleXMLElement $xml,
string $capabilitiesApp,
string $capabilitiesPath
):bool {
$path_to_element = \explode('@@@', $capabilitiesPath);
$answeredValue = $xml->{$capabilitiesApp};
foreach ($path_to_element as $element) {
$nameIndexParts = \explode('[', $element);
if (isset($nameIndexParts[1])) {
// This part of the path should be something like "some_element[1]"
// Separately extract the name and the index
$name = $nameIndexParts[0];
$index = (int) \explode(']', $nameIndexParts[1])[0];
// and use those to construct the reference into the next XML level
if (isset($answeredValue->{$name}[$index])) {
$answeredValue = $answeredValue->{$name}[$index];
} else {
// The path ends at this level
return false;
}
} else {
if (isset($answeredValue->{$element})) {
$answeredValue = $answeredValue->{$element};
} else {
// The path ends at this level
return false;
}
}
}
return true;
}
/**
* @param string $app
* @param string $parameter
* @param string $value
*
* @return void
* @throws Exception
*/
public function modifyAppConfig(string $app, string $parameter, string $value):void {
AppConfigHelper::modifyAppConfig(
$this->featureContext->getBaseUrl(),
$this->featureContext->getAdminUsername(),
$this->featureContext->getAdminPassword(),
$app,
$parameter,
$value,
$this->featureContext->getStepLineRef(),
$this->featureContext->getOcsApiVersion()
);
}
/**
* @param array $appParameterValues
*
* @return void
* @throws Exception
*/
public function modifyAppConfigs(array $appParameterValues):void {
AppConfigHelper::modifyAppConfigs(
$this->featureContext->getBaseUrl(),
$this->featureContext->getAdminUsername(),
$this->featureContext->getAdminPassword(),
$appParameterValues,
$this->featureContext->getStepLineRef(),
$this->featureContext->getOcsApiVersion()
);
}
/**
* @When the administrator adds url :url as trusted server using the testing API
*
* @param string $url
*
* @return void
* @throws GuzzleException
*/
public function theAdministratorAddsUrlAsTrustedServerUsingTheTestingApi(string $url):void {
$adminUser = $this->featureContext->getAdminUsername();
$response = OcsApiHelper::sendRequest(
$this->featureContext->getBaseUrl(),
$adminUser,
$this->featureContext->getAdminPassword(),
'POST',
"/apps/testing/api/v1/trustedservers",
$this->featureContext->getStepLineRef(),
['url' => $this->featureContext->substituteInLineCodes($url)]
);
$this->featureContext->setResponse($response);
$this->featureContext->pushToLastStatusCodesArrays();
}
/**
* Return text that contains the details of the URL, including any differences due to inline codes
*
* @param string $url
*
* @return string
*/
private function getUrlStringForMessage(string $url):string {
$text = $url;
$expectedUrl = $this->featureContext->substituteInLineCodes($url);
if ($expectedUrl !== $url) {
$text .= " ($expectedUrl)";
}
return $text;
}
/**
* @param string $url
*
* @return string
*/
private function getNotTrustedServerMessage(string $url):string {
return
"URL "
. $this->getUrlStringForMessage($url)
. " is not a trusted server but should be";
}
/**
* @Then url :url should be a trusted server
*
* @param string $url
*
* @return void
* @throws Exception
*/
public function urlShouldBeATrustedServer(string $url):void {
$trustedServers = $this->featureContext->getTrustedServers();
foreach ($trustedServers as $server => $id) {
if ($server === $this->featureContext->substituteInLineCodes($url)) {
return;
}
}
Assert::fail($this->getNotTrustedServerMessage($url));
}
/**
* @Then the trusted server list should include these urls:
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theTrustedServerListShouldIncludeTheseUrls(TableNode $table):void {
$trustedServers = $this->featureContext->getTrustedServers();
$expected = $table->getColumnsHash();
foreach ($expected as $server) {
$found = false;
foreach ($trustedServers as $url => $id) {
if ($url === $this->featureContext->substituteInLineCodes($server['url'])) {
$found = true;
break;
}
}
if (!$found) {
Assert::fail($this->getNotTrustedServerMessage($server['url']));
}
}
}
/**
* @Given the administrator has added url :url as trusted server
*
* @param string $url
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function theAdministratorHasAddedUrlAsTrustedServer(string $url):void {
$this->theAdministratorAddsUrlAsTrustedServerUsingTheTestingApi($url);
$status = $this->featureContext->getResponse()->getStatusCode();
if ($status !== 201) {
throw new \Exception(
__METHOD__ .
" Could not add trusted server " . $this->getUrlStringForMessage($url)
. ". The request failed with status $status"
);
}
}
/**
* @When the administrator deletes url :url from trusted servers using the testing API
*
* @param string $url
*
* @return void
* @throws GuzzleException
*/
public function theAdministratorDeletesUrlFromTrustedServersUsingTheTestingApi(string $url):void {
$adminUser = $this->featureContext->getAdminUsername();
$response = OcsApiHelper::sendRequest(
$this->featureContext->getBaseUrl(),
$adminUser,
$this->featureContext->getAdminPassword(),
'DELETE',
"/apps/testing/api/v1/trustedservers",
$this->featureContext->getStepLineRef(),
['url' => $this->featureContext->substituteInLineCodes($url)]
);
$this->featureContext->setResponse($response);
}
/**
* @Then url :url should not be a trusted server
*
* @param string $url
*
* @return void
* @throws Exception
*/
public function urlShouldNotBeATrustedServer(string $url):void {
$trustedServers = $this->featureContext->getTrustedServers();
foreach ($trustedServers as $server => $id) {
if ($server === $this->featureContext->substituteInLineCodes($url)) {
Assert::fail(
"URL " . $this->getUrlStringForMessage($url)
. " is a trusted server but is not expected to be"
);
}
}
}
/**
* @When the administrator deletes all trusted servers using the testing API
*
* @return void
* @throws GuzzleException
*/
public function theAdministratorDeletesAllTrustedServersUsingTheTestingApi():void {
$adminUser = $this->featureContext->getAdminUsername();
$response = OcsApiHelper::sendRequest(
$this->featureContext->getBaseUrl(),
$adminUser,
$this->featureContext->getAdminPassword(),
'DELETE',
"/apps/testing/api/v1/trustedservers/all",
$this->featureContext->getStepLineRef()
);
$this->featureContext->setResponse($response);
}
/**
* @Given the trusted server list is cleared
*
* @return void
* @throws Exception
*/
public function theTrustedServerListIsCleared():void {
$this->theAdministratorDeletesAllTrustedServersUsingTheTestingApi();
$statusCode = $this->featureContext->getResponse()->getStatusCode();
if ($statusCode !== 204) {
$contents = $this->featureContext->getResponse()->getBody()->getContents();
throw new \Exception(
__METHOD__
. " Failed to clear all trusted servers" . $contents
);
}
}
/**
* @Then the trusted server list should be empty
*
* @return void
* @throws Exception
*/
public function theTrustedServerListShouldBeEmpty():void {
$trustedServers = $this->featureContext->getTrustedServers();
Assert::assertEmpty(
$trustedServers,
__METHOD__ . " Trusted server list is not empty"
);
}
/**
* @BeforeScenario
*
* @param BeforeScenarioScope $scope
*
* @return void
*/
public function setUpScenario(BeforeScenarioScope $scope):void {
// Get the environment
$environment = $scope->getEnvironment();
// Get all the contexts you need in this context
$this->featureContext = $environment->getContext('FeatureContext');
}
}