mirror of
https://github.com/owncloud/ocis.git
synced 2025-04-18 23:44:07 +03:00
328 lines
10 KiB
PHP
328 lines
10 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\Context\Context;
|
|
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
|
|
use Behat\Gherkin\Node\PyStringNode;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use PHPUnit\Framework\Assert;
|
|
use TestHelpers\OcsApiHelper;
|
|
|
|
require_once 'bootstrap.php';
|
|
|
|
/**
|
|
* Capabilities context.
|
|
*/
|
|
class CapabilitiesContext implements Context {
|
|
private FeatureContext $featureContext;
|
|
|
|
/**
|
|
* This will run before EVERY scenario.
|
|
* It will set the properties for this object.
|
|
*
|
|
* @BeforeScenario
|
|
*
|
|
* @param BeforeScenarioScope $scope
|
|
*
|
|
* @return void
|
|
*/
|
|
public function before(BeforeScenarioScope $scope):void {
|
|
// Get the environment
|
|
$environment = $scope->getEnvironment();
|
|
// Get all the contexts you need in this context
|
|
$this->featureContext = $environment->getContext('FeatureContext');
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param string $username
|
|
* @param boolean $formatJson // if true then formats the response in json
|
|
*
|
|
* @return ResponseInterface
|
|
* @throws GuzzleException
|
|
* @throws JsonException
|
|
*/
|
|
public function userGetsCapabilities(string $username, ?bool $formatJson = false): ResponseInterface {
|
|
$user = $this->featureContext->getActualUsername($username);
|
|
$password = $this->featureContext->getPasswordForUser($user);
|
|
return OcsApiHelper::sendRequest(
|
|
$this->featureContext->getBaseUrl(),
|
|
$user,
|
|
$password,
|
|
'GET',
|
|
'/cloud/capabilities' . ($formatJson ? '?format=json' : ''),
|
|
$this->featureContext->getStepLineRef(),
|
|
[],
|
|
$this->featureContext->getOcsApiVersion()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
* @throws Exception|GuzzleException
|
|
*/
|
|
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->userHasBeenCreated(["userName" => $adminUsername]);
|
|
}
|
|
} else {
|
|
$adminUsername = $this->featureContext->getAdminUsername();
|
|
}
|
|
return $adminUsername;
|
|
}
|
|
|
|
/**
|
|
* @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;
|
|
}
|
|
|
|
/**
|
|
* @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->featureContext->setResponse($this->userGetsCapabilities($user, true));
|
|
}
|
|
|
|
/**
|
|
* @When the administrator retrieves the capabilities using the capabilities API
|
|
*
|
|
* @return void
|
|
*/
|
|
public function theAdministratorGetsCapabilities(): void {
|
|
$user = $this->getAdminUsernameForCapabilitiesCheck();
|
|
$this->featureContext->setResponse($this->userGetsCapabilities($user, true));
|
|
}
|
|
|
|
/**
|
|
* @Then the major-minor-micro version data in the response should match the version string
|
|
*
|
|
* @return void
|
|
* @throws Exception
|
|
*/
|
|
public function checkVersionMajorMinorMicroResponse():void {
|
|
$jsonResponse = $this->featureContext->getJsonDecodedResponseBodyContent();
|
|
$versionData = $jsonResponse->ocs->data->version;
|
|
$versionString = (string) $versionData->string;
|
|
// We expect that versionString will be in a format like "10.9.2 beta" or "10.9.2-alpha" or "10.9.2"
|
|
$result = \preg_match('/^[0-9]+\.[0-9]+\.[0-9]+/', $versionString, $matches);
|
|
Assert::assertSame(
|
|
1,
|
|
$result,
|
|
__METHOD__ . " version string '$versionString' does not start with a semver version"
|
|
);
|
|
// semVerParts should have an array with the 3 semver components of the version, e.g. "1", "9" and "2".
|
|
$semVerParts = \explode('.', $matches[0]);
|
|
$expectedMajor = $semVerParts[0];
|
|
$expectedMinor = $semVerParts[1];
|
|
$expectedMicro = $semVerParts[2];
|
|
$actualMajor = (string) $versionData->major;
|
|
$actualMinor = (string) $versionData->minor;
|
|
$actualMicro = (string) $versionData->micro;
|
|
Assert::assertSame(
|
|
$expectedMajor,
|
|
$actualMajor,
|
|
__METHOD__ . "'major' data item does not match with major version in string '$versionString'"
|
|
);
|
|
Assert::assertSame(
|
|
$expectedMinor,
|
|
$actualMinor,
|
|
__METHOD__ . "'minor' data item does not match with minor version in string '$versionString'"
|
|
);
|
|
Assert::assertSame(
|
|
$expectedMicro,
|
|
$actualMicro,
|
|
__METHOD__ . "'micro' data item does not match with micro (patch) version in string '$versionString'"
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @Then the status.php response should include
|
|
*
|
|
* @param PyStringNode $jsonExpected
|
|
*
|
|
* @return void
|
|
* @throws Exception
|
|
*/
|
|
public function statusPhpRespondedShouldMatch(PyStringNode $jsonExpected): void {
|
|
$jsonExpectedDecoded = \json_decode($jsonExpected->getRaw(), true);
|
|
$jsonRespondedDecoded = $this->featureContext->getJsonDecodedResponse();
|
|
|
|
$response = $this->userGetsCapabilities($this->getAdminUsernameForCapabilitiesCheck());
|
|
$this->featureContext->theHTTPStatusCodeShouldBe(200, '', $response);
|
|
$responseXml = $this->featureContext->getResponseXml($response)->data->capabilities;
|
|
$edition = $this->getParameterValueFromXml(
|
|
$responseXml,
|
|
'core',
|
|
'status@@@edition'
|
|
);
|
|
|
|
if (!\strlen($edition)) {
|
|
Assert::fail(
|
|
"Cannot get edition from core capabilities"
|
|
);
|
|
}
|
|
|
|
$product = $this->getParameterValueFromXml(
|
|
$responseXml,
|
|
'core',
|
|
'status@@@product'
|
|
);
|
|
if (!\strlen($product)) {
|
|
Assert::fail(
|
|
"Cannot get product from core capabilities"
|
|
);
|
|
}
|
|
|
|
$productName = $this->getParameterValueFromXml(
|
|
$responseXml,
|
|
'core',
|
|
'status@@@productname'
|
|
);
|
|
|
|
if (!\strlen($productName)) {
|
|
Assert::fail(
|
|
"Cannot get productname from core capabilities"
|
|
);
|
|
}
|
|
|
|
$jsonExpectedDecoded['edition'] = $edition;
|
|
$jsonExpectedDecoded['product'] = $product;
|
|
$jsonExpectedDecoded['productname'] = $productName;
|
|
|
|
// We are on oCIS or reva or some other implementation. We cannot do "occ status".
|
|
// So get the expected version values by looking in the capabilities response.
|
|
$version = $this->getParameterValueFromXml(
|
|
$responseXml,
|
|
'core',
|
|
'status@@@version'
|
|
);
|
|
|
|
if (!\strlen($version)) {
|
|
Assert::fail(
|
|
"Cannot get version from core capabilities"
|
|
);
|
|
}
|
|
|
|
$versionString = $this->getParameterValueFromXml(
|
|
$responseXml,
|
|
'core',
|
|
'status@@@versionstring'
|
|
);
|
|
|
|
if (!\strlen($versionString)) {
|
|
Assert::fail(
|
|
"Cannot get versionstring from core capabilities"
|
|
);
|
|
}
|
|
|
|
$jsonExpectedDecoded['version'] = $version;
|
|
$jsonExpectedDecoded['versionstring'] = $versionString;
|
|
$errorMessage = "";
|
|
$errorFound = false;
|
|
foreach ($jsonExpectedDecoded as $key => $expectedValue) {
|
|
if (\array_key_exists($key, $jsonRespondedDecoded)) {
|
|
$actualValue = $jsonRespondedDecoded[$key];
|
|
if ($actualValue !== $expectedValue) {
|
|
$errorMessage .= "$key expected value was $expectedValue but actual value was $actualValue\n";
|
|
$errorFound = true;
|
|
}
|
|
} else {
|
|
$errorMessage .= "$key was not found in the status response\n";
|
|
$errorFound = true;
|
|
}
|
|
}
|
|
Assert::assertFalse($errorFound, $errorMessage);
|
|
// We have checked that the status.php response has data that matches up with
|
|
// data found in the capabilities response and/or the "occ status" command output.
|
|
// But the output might be reported wrongly in all of these in the same way.
|
|
// So check that the values also seem "reasonable".
|
|
$version = $jsonExpectedDecoded['version'];
|
|
$versionString = $jsonExpectedDecoded['versionstring'];
|
|
Assert::assertMatchesRegularExpression(
|
|
"/^\d+\.\d+\.\d+\.\d+$/",
|
|
$version,
|
|
"version should be in a form like 10.9.8.1 but is $version"
|
|
);
|
|
if (\preg_match("/^(\d+\.\d+\.\d+)\.\d+(-[0-9A-Za-z-]+)?(\+[0-9A-Za-z-]+)?$/", $version, $matches)) {
|
|
// We should have matched something like 10.9.8 - the first 3 numbers in the version.
|
|
// Ignore pre-releases and meta information
|
|
Assert::assertArrayHasKey(
|
|
1,
|
|
$matches,
|
|
"version $version could not match the pattern Major.Minor.Patch"
|
|
);
|
|
$majorMinorPatchVersion = $matches[1];
|
|
} else {
|
|
Assert::fail("version '$version' does not start in a form like 10.9.8");
|
|
}
|
|
Assert::assertStringStartsWith(
|
|
$majorMinorPatchVersion,
|
|
$versionString,
|
|
"versionstring should start with $majorMinorPatchVersion but is $versionString"
|
|
);
|
|
}
|
|
}
|