Copied acceptance tests infrastructures from oC/core

Signed-off-by: Kiran Parajuli <kiranparajuli589@gmail.com>
This commit is contained in:
Kiran Parajuli
2023-01-05 09:21:34 +05:45
committed by Phil Davis
parent b84f1f2048
commit 7d152e2ad1
61 changed files with 39555 additions and 28 deletions
@@ -0,0 +1,591 @@
<?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 userGetsCapabilities(string $username):void {
$user = $this->featureContext->getActualUsername($username);
$password = $this->featureContext->getPasswordForUser($user);
$this->featureContext->setResponse(
OcsApiHelper::sendRequest(
$this->featureContext->getBaseUrl(),
$user,
$password,
'GET',
'/cloud/capabilities',
$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 {
$this->userGetsCapabilities($this->getAdminUsernameForCapabilitiesCheck());
}
/**
* @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');
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,223 @@
<?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\TableNode;
use PHPUnit\Framework\Assert;
require_once 'bootstrap.php';
/**
* Capabilities context.
*/
class CapabilitiesContext implements Context {
/**
*
* @var FeatureContext
*/
private $featureContext;
/**
* @Then the capabilities should contain
*
* @param TableNode|null $formData
*
* @return void
* @throws Exception
*/
public function checkCapabilitiesResponse(TableNode $formData):void {
$capabilitiesXML = $this->featureContext->appConfigurationContext->getCapabilitiesXml(__METHOD__);
$assertedSomething = false;
$this->featureContext->verifyTableNodeColumns($formData, ['value', 'path_to_element', 'capability']);
foreach ($formData->getHash() as $row) {
$row['value'] = $this->featureContext->substituteInLineCodes($row['value']);
Assert::assertEquals(
$row['value'] === "EMPTY" ? '' : $row['value'],
$this->featureContext->appConfigurationContext->getParameterValueFromXml(
$capabilitiesXML,
$row['capability'],
$row['path_to_element']
),
"Failed field {$row['capability']} {$row['path_to_element']}"
);
$assertedSomething = true;
}
Assert::assertTrue(
$assertedSomething,
'there was nothing in the table of expected capabilities'
);
}
/**
* @Then the version data in the response should contain
*
* @param TableNode|null $formData
*
* @return void
* @throws Exception
*/
public function checkVersionResponse(TableNode $formData):void {
$versionXML = $this->featureContext->appConfigurationContext->getVersionXml(__METHOD__);
$assertedSomething = false;
$this->featureContext->verifyTableNodeColumns($formData, ['name', 'value']);
foreach ($formData->getHash() as $row) {
$row['value'] = $this->featureContext->substituteInLineCodes($row['value']);
$actualValue = $versionXML->{$row['name']};
Assert::assertEquals(
$row['value'] === "EMPTY" ? '' : $row['value'],
$actualValue,
"Failed field {$row['name']}"
);
$assertedSomething = true;
}
Assert::assertTrue(
$assertedSomething,
'there was nothing in the table of expected version data'
);
}
/**
* @Then the major-minor-micro version data in the response should match the version string
*
* @return void
* @throws Exception
*/
public function checkVersionMajorMinorMicroResponse():void {
$versionXML = $this->featureContext->appConfigurationContext->getVersionXml(__METHOD__);
$versionString = (string) $versionXML->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) $versionXML->major;
$actualMinor = (string) $versionXML->minor;
$actualMicro = (string) $versionXML->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 :pathToElement capability of files sharing app should be :value
*
* @param string $pathToElement
* @param string $value
*
* @return void
* @throws Exception
*/
public function theCapabilityOfFilesSharingAppShouldBe(
string $pathToElement,
string $value
):void {
$this->featureContext->appConfigurationContext->userGetsCapabilitiesCheckResponse(
$this->featureContext->getCurrentUser()
);
$capabilitiesXML = $this->featureContext->appConfigurationContext->getCapabilitiesXml(__METHOD__);
$actualValue = $this->featureContext->appConfigurationContext->getParameterValueFromXml(
$capabilitiesXML,
"files_sharing",
$pathToElement
);
Assert::assertEquals(
$value === "EMPTY" ? '' : $value,
$actualValue,
"Expected {$pathToElement} capability of files sharing app to be {$value}, but got {$actualValue}"
);
}
/**
* @Then the capabilities should not contain
*
* @param TableNode|null $formData
*
* @return void
*/
public function theCapabilitiesShouldNotContain(TableNode $formData):void {
$capabilitiesXML = $this->featureContext->appConfigurationContext->getCapabilitiesXml(__METHOD__);
$assertedSomething = false;
foreach ($formData->getHash() as $row) {
Assert::assertFalse(
$this->featureContext->appConfigurationContext->parameterValueExistsInXml(
$capabilitiesXML,
$row['capability'],
$row['path_to_element']
),
"Capability {$row['capability']} {$row['path_to_element']} exists but it should not exist"
);
$assertedSomething = true;
}
Assert::assertTrue(
$assertedSomething,
'there was nothing in the table of not expected capabilities'
);
}
/**
* 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');
}
}
@@ -0,0 +1,464 @@
<?php declare(strict_types=1);
/**
* @author Roeland Jago Douma <rullzer@owncloud.com>
*
* @copyright Copyright (c) 2018, ownCloud GmbH
* @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\Behat\Hook\Scope\BeforeScenarioScope;
use PHPUnit\Framework\Assert;
use TestHelpers\WebDavHelper;
require_once 'bootstrap.php';
/**
* Checksum functions
*/
class ChecksumContext implements Context {
/**
*
* @var FeatureContext
*/
private $featureContext;
/**
* @When user :user uploads file :source to :destination with checksum :checksum using the WebDAV API
*
* @param string $user
* @param string $source
* @param string $destination
* @param string $checksum
*
* @return void
*/
public function userUploadsFileToWithChecksumUsingTheAPI(
string $user,
string $source,
string $destination,
string $checksum
):void {
$file = \file_get_contents(
$this->featureContext->acceptanceTestsDirLocation() . $source
);
$response = $this->featureContext->makeDavRequest(
$user,
'PUT',
$destination,
['OC-Checksum' => $checksum],
$file,
"files"
);
$this->featureContext->setResponse($response);
}
/**
* @Given user :user has uploaded file :source to :destination with checksum :checksum
*
* @param string $user
* @param string $source
* @param string $destination
* @param string $checksum
*
* @return void
*/
public function userHasUploadedFileToWithChecksumUsingTheAPI(
string $user,
string $source,
string $destination,
string $checksum
):void {
$user = $this->featureContext->getActualUsername($user);
$this->userUploadsFileToWithChecksumUsingTheAPI(
$user,
$source,
$destination,
$checksum
);
$this->featureContext->theHTTPStatusCodeShouldBeSuccess();
}
/**
* @When user :user uploads file with content :content and checksum :checksum to :destination using the WebDAV API
*
* @param string $user
* @param string $content
* @param string $checksum
* @param string $destination
*
* @return void
*/
public function userUploadsFileWithContentAndChecksumToUsingTheAPI(
string $user,
string $content,
string $checksum,
string $destination
):void {
$response = $this->featureContext->makeDavRequest(
$user,
'PUT',
$destination,
['OC-Checksum' => $checksum],
$content,
"files"
);
$this->featureContext->setResponse($response);
}
/**
* @Given user :user has uploaded file with content :content and checksum :checksum to :destination
*
* @param string $user
* @param string $content
* @param string $checksum
* @param string $destination
*
* @return void
*/
public function userHasUploadedFileWithContentAndChecksumToUsingTheAPI(
string $user,
string $content,
string $checksum,
string $destination
):void {
$user = $this->featureContext->getActualUsername($user);
$this->userUploadsFileWithContentAndChecksumToUsingTheAPI(
$user,
$content,
$checksum,
$destination
);
$this->featureContext->theHTTPStatusCodeShouldBeSuccess();
}
/**
* @When user :user requests the checksum of :path via propfind
*
* @param string $user
* @param string $path
*
* @return void
*/
public function userRequestsTheChecksumOfViaPropfind(string $user, string $path):void {
$user = $this->featureContext->getActualUsername($user);
$body = '<?xml version="1.0"?>
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">
<d:prop>
<oc:checksums />
</d:prop>
</d:propfind>';
$password = $this->featureContext->getPasswordForUser($user);
$response = WebDavHelper::makeDavRequest(
$this->featureContext->getBaseUrl(),
$user,
$password,
'PROPFIND',
$path,
null,
$this->featureContext->getStepLineRef(),
$body,
$this->featureContext->getDavPathVersion()
);
$this->featureContext->setResponse($response);
}
/**
* @Then the webdav checksum should match :expectedChecksum
*
* @param string $expectedChecksum
*
* @return void
* @throws Exception
*/
public function theWebdavChecksumShouldMatch(string $expectedChecksum):void {
$service = new Sabre\Xml\Service();
$bodyContents = $this->featureContext->getResponse()->getBody()->getContents();
$parsed = $service->parse($bodyContents);
/*
* Fetch the checksum array
* The checksums are way down in the array:
* $checksums = $parsed[0]['value'][1]['value'][0]['value'][0];
* And inside is the actual checksum string:
* $checksums['value'][0]['value']
* The Asserts below check the existence of the expected key at every level
* of the nested array. This helps to see what happened if a test fails
* because the response structure is not as expected.
*/
Assert::assertIsArray(
$parsed,
__METHOD__ . " could not parse response as XML. Expected parsed XML to be an array but found " . $bodyContents
);
Assert::assertArrayHasKey(
0,
$parsed,
__METHOD__ . " parsed XML does not have key 0"
);
$parsed0 = $parsed[0];
Assert::assertArrayHasKey(
'value',
$parsed0,
__METHOD__ . " parsed XML parsed0 does not have key value"
);
$parsed0Value = $parsed0['value'];
Assert::assertArrayHasKey(
1,
$parsed0Value,
__METHOD__ . " parsed XML parsed0Value does not have key 1"
);
$parsed0Value1 = $parsed0Value[1];
Assert::assertArrayHasKey(
'value',
$parsed0Value1,
__METHOD__ . " parsed XML parsed0Value1 does not have key value after key 1"
);
$parsed0Value1Value = $parsed0Value1['value'];
Assert::assertArrayHasKey(
0,
$parsed0Value1Value,
__METHOD__ . " parsed XML parsed0Value1Value does not have key 0"
);
$parsed0Value1Value0 = $parsed0Value1Value[0];
Assert::assertArrayHasKey(
'value',
$parsed0Value1Value0,
__METHOD__ . " parsed XML parsed0Value1Value0 does not have key value"
);
$parsed0Value1Value0Value = $parsed0Value1Value0['value'];
Assert::assertArrayHasKey(
0,
$parsed0Value1Value0Value,
__METHOD__ . " parsed XML parsed0Value1Value0Value does not have key 0"
);
$checksums = $parsed0Value1Value0Value[0];
Assert::assertArrayHasKey(
'value',
$checksums,
__METHOD__ . " parsed XML checksums does not have key value"
);
$checksumsValue = $checksums['value'];
Assert::assertArrayHasKey(
0,
$checksumsValue,
__METHOD__ . " parsed XML checksumsValue does not have key 0"
);
$checksumsValue0 = $checksumsValue[0];
Assert::assertArrayHasKey(
'value',
$checksumsValue0,
__METHOD__ . " parsed XML checksumsValue0 does not have key value"
);
$actualChecksum = $checksumsValue0['value'];
Assert::assertEquals(
$expectedChecksum,
$actualChecksum,
"Expected: webDav checksum should be {$expectedChecksum} but got {$actualChecksum}"
);
}
/**
* @Then as user :user the webdav checksum of :path via propfind should match :expectedChecksum
*
* @param string $user
* @param string $path
* @param string $expectedChecksum
*
* @return void
* @throws Exception
*/
public function theWebdavChecksumOfViaPropfindShouldMatch(string $user, string $path, string $expectedChecksum):void {
$user = $this->featureContext->getActualUsername($user);
$this->userRequestsTheChecksumOfViaPropfind($user, $path);
$this->theWebdavChecksumShouldMatch($expectedChecksum);
}
/**
* @Then the header checksum should match :expectedChecksum
*
* @param string $expectedChecksum
*
* @return void
* @throws Exception
*/
public function theHeaderChecksumShouldMatch(string $expectedChecksum):void {
$headerChecksums
= $this->featureContext->getResponse()->getHeader('OC-Checksum');
Assert::assertIsArray(
$headerChecksums,
__METHOD__ . " getHeader('OC-Checksum') did not return an array"
);
Assert::assertNotEmpty(
$headerChecksums,
__METHOD__ . " getHeader('OC-Checksum') returned an empty array. No checksum header was found."
);
$checksumCount = \count($headerChecksums);
Assert::assertTrue(
$checksumCount === 1,
__METHOD__ . " Expected 1 checksum in the header but found $checksumCount checksums"
);
$headerChecksum
= $headerChecksums[0];
Assert::assertEquals(
$expectedChecksum,
$headerChecksum,
"Expected: header checksum should match {$expectedChecksum} but got {$headerChecksum}"
);
}
/**
* @Then the header checksum when user :arg1 downloads file :arg2 using the WebDAV API should match :arg3
*
* @param string $user
* @param string $fileName
* @param string $expectedChecksum
*
* @return void
* @throws Exception
*/
public function theHeaderChecksumWhenUserDownloadsFileUsingTheWebdavApiShouldMatch(string $user, string $fileName, string $expectedChecksum):void {
$this->featureContext->userDownloadsFileUsingTheAPI($user, $fileName);
$this->theHeaderChecksumShouldMatch($expectedChecksum);
}
/**
* @Then the webdav checksum should be empty
*
* @return void
* @throws Exception
*/
public function theWebdavChecksumShouldBeEmpty():void {
$service = new Sabre\Xml\Service();
$parsed = $service->parse(
$this->featureContext->getResponse()->getBody()->getContents()
);
/*
* Fetch the checksum array
* Maybe we want to do this a bit cleaner ;)
*/
$status = $parsed[0]['value'][1]['value'][1]['value'];
$expectedStatus = 'HTTP/1.1 404 Not Found';
Assert::assertEquals(
$expectedStatus,
$status,
"Expected status to be {$expectedStatus} but got {$status}"
);
}
/**
* @Then the OC-Checksum header should not be there
*
* @return void
* @throws Exception
*/
public function theOcChecksumHeaderShouldNotBeThere():void {
$isHeader = $this->featureContext->getResponse()->hasHeader('OC-Checksum');
Assert::assertFalse(
$isHeader,
"Expected no checksum header but got "
. $this->featureContext->getResponse()->getHeader('OC-Checksum')
);
}
/**
* @When user :user uploads chunk file :num of :total with :data to :destination with checksum :expectedChecksum using the WebDAV API
*
* @param string $user
* @param int $num
* @param int $total
* @param string $data
* @param string $destination
* @param string $expectedChecksum
*
* @return void
*/
public function userUploadsChunkFileOfWithToWithChecksum(
string $user,
int $num,
int $total,
string $data,
string $destination,
string $expectedChecksum
):void {
$user = $this->featureContext->getActualUsername($user);
$num -= 1;
$file = "$destination-chunking-42-$total-$num";
$response = $this->featureContext->makeDavRequest(
$user,
'PUT',
$file,
['OC-Checksum' => $expectedChecksum, 'OC-Chunked' => '1'],
$data,
"files"
);
$this->featureContext->setResponse($response);
}
/**
* @Given user :user has uploaded chunk file :num of :total with :data to :destination with checksum :expectedChecksum
*
* @param string $user
* @param int $num
* @param int $total
* @param string $data
* @param string $destination
* @param string $expectedChecksum
*
* @return void
*/
public function userHasUploadedChunkFileOfWithToWithChecksum(
string $user,
int $num,
int $total,
string $data,
string $destination,
string $expectedChecksum
):void {
$this->userUploadsChunkFileOfWithToWithChecksum(
$user,
$num,
$total,
$data,
$destination,
$expectedChecksum
);
$this->featureContext->theHTTPStatusCodeShouldBeOr(201, 206);
}
/**
* 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');
}
}
@@ -0,0 +1,361 @@
<?php declare(strict_types=1);
/**
* ownCloud
*
* @author Artur Neumann <artur@jankaritech.com>
* @copyright Copyright (c) 2018 Artur Neumann artur@jankaritech.com
*
* 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\TableNode;
use Psr\Http\Message\ResponseInterface;
use TestHelpers\WebDavHelper;
require_once 'bootstrap.php';
/**
* context containing favorites related API steps
*/
class FavoritesContext implements Context {
/**
*
* @var FeatureContext
*/
private $featureContext;
/**
*
* @var WebDavPropertiesContext
*/
private $webDavPropertiesContext;
/**
* @param string$user
* @param string $path
*
* @return void
*/
public function userFavoritesElement(string $user, string $path):void {
$response = $this->changeFavStateOfAnElement(
$user,
$path,
1
);
$this->featureContext->setResponse($response);
}
/**
* @When user :user favorites element :path using the WebDAV API
*
* @param string $user
* @param string $path
*
* @return void
*/
public function userFavoritesElementUsingWebDavApi(string $user, string $path):void {
$this->userFavoritesElement($user, $path);
}
/**
* @Given user :user has favorited element :path
*
* @param string $user
* @param string $path
*
* @return void
*/
public function userHasFavoritedElementUsingWebDavApi(string $user, string $path):void {
$this->userFavoritesElement($user, $path);
$this->featureContext->theHTTPStatusCodeShouldBeSuccess();
}
/**
* @When the user favorites element :path using the WebDAV API
*
* @param string $path
*
* @return void
*/
public function theUserFavoritesElement(string $path):void {
$this->userFavoritesElement(
$this->featureContext->getCurrentUser(),
$path
);
}
/**
* @Given the user has favorited element :path
*
* @param string $path
*
* @return void
*/
public function theUserHasFavoritedElement(string $path):void {
$this->userFavoritesElement(
$this->featureContext->getCurrentUser(),
$path
);
$this->featureContext->theHTTPStatusCodeShouldBe(
207,
"Expected response status code to be 207 (Multi-status), but not found! "
);
}
/**
* @param $user
* @param $path
*
* @return void
*/
public function userUnfavoritesElement(string $user, string $path):void {
$response = $this->changeFavStateOfAnElement(
$user,
$path,
0
);
$this->featureContext->setResponse($response);
}
/**
* @When user :user unfavorites element :path using the WebDAV API
*
* @param string $user
* @param string $path
*
* @return void
*/
public function userUnfavoritesElementUsingWebDavApi(string $user, string $path):void {
$this->userUnfavoritesElement($user, $path);
}
/**
* @Given user :user has unfavorited element :path
*
* @param string $user
* @param string $path
*
* @return void
*/
public function userHasUnfavoritedElementUsingWebDavApi(string $user, string $path):void {
$this->userUnfavoritesElement($user, $path);
$this->featureContext->theHTTPStatusCodeShouldBeSuccess();
}
/**
* @Then /^user "([^"]*)" should (not|)\s?have favorited the following elements$/
*
* @param string $user
* @param string $shouldOrNot (not|)
* @param TableNode $expectedElements
*
* @return void
*/
public function checkFavoritedElements(
string $user,
string $shouldOrNot,
TableNode $expectedElements
):void {
$user = $this->featureContext->getActualUsername($user);
$this->userListsFavorites($user, null);
$this->featureContext->propfindResultShouldContainEntries(
$shouldOrNot,
$expectedElements,
$user
);
}
/**
* @When /^user "([^"]*)" lists the favorites and limits the result to ([\d*]) elements using the WebDAV API$/
*
* @param string $user
* @param int|null $limit
*
* @return void
*/
public function userListsFavorites(string $user, ?int $limit = null):void {
$renamedUser = $this->featureContext->getActualUsername($user);
$baseUrl = $this->featureContext->getBaseUrl();
$password = $this->featureContext->getPasswordForUser($user);
$body
= "<?xml version='1.0' encoding='utf-8' ?>\n" .
" <oc:filter-files xmlns:a='DAV:' xmlns:oc='http://owncloud.org/ns' >\n" .
" <a:prop><oc:favorite/></a:prop>\n" .
" <oc:filter-rules><oc:favorite>1</oc:favorite></oc:filter-rules>\n";
if ($limit !== null) {
$body .= " <oc:search>\n" .
" <oc:limit>$limit</oc:limit>\n" .
" </oc:search>\n";
}
$body .= " </oc:filter-files>";
$response = WebDavHelper::makeDavRequest(
$baseUrl,
$renamedUser,
$password,
"REPORT",
"/",
null,
$this->featureContext->getStepLineRef(),
$body,
$this->featureContext->getDavPathVersion()
);
$this->featureContext->setResponse($response);
}
/**
* @param string $path
*
* @return void
*/
public function theUserUnfavoritesElement(string $path):void {
$this->userUnfavoritesElement(
$this->featureContext->getCurrentUser(),
$path
);
}
/**
* @When the user unfavorites element :path using the WebDAV API
*
* @param string $path
*
* @return void
*/
public function theUserUnfavoritesElementUsingWebDavApi(string $path):void {
$this->theUserUnfavoritesElement($path);
}
/**
* @Given the user has unfavorited element :path
*
* @param string $path
*
* @return void
*/
public function theUserHasUnfavoritedElementUsingWebDavApi(string $path):void {
$this->theUserUnfavoritesElement($path);
$this->featureContext->theHTTPStatusCodeShouldBeSuccess();
}
/**
* @Then /^as user "([^"]*)" (?:file|folder|entry) "([^"]*)" should be favorited$/
*
* @param string $user
* @param string $path
* @param integer $expectedValue 0|1
*
* @return void
*/
public function asUserFileOrFolderShouldBeFavorited(string $user, string $path, int $expectedValue = 1):void {
$property = "oc:favorite";
$this->webDavPropertiesContext->asUserFolderShouldContainAPropertyWithValue(
$user,
$path,
$property,
(string)$expectedValue
);
}
/**
* @Then /^as user "([^"]*)" (?:file|folder|entry) "([^"]*)" should not be favorited$/
*
* @param string $user
* @param string $path
*
* @return void
*/
public function asUserFileShouldNotBeFavorited(string $user, string $path):void {
$this->asUserFileOrFolderShouldBeFavorited($user, $path, 0);
}
/**
* @Then /^as the user (?:file|folder|entry) "([^"]*)" should be favorited$/
*
* @param string $path
* @param integer $expectedValue 0|1
*
* @return void
*/
public function asTheUserFileOrFolderShouldBeFavorited(string $path, int $expectedValue = 1):void {
$this->asUserFileOrFolderShouldBeFavorited(
$this->featureContext->getCurrentUser(),
$path,
$expectedValue
);
}
/**
* @Then /^as the user (?:file|folder|entry) "([^"]*)" should not be favorited$/
*
* @param string $path
*
* @return void
*/
public function asTheUserFileOrFolderShouldNotBeFavorited(string $path):void {
$this->asTheUserFileOrFolderShouldBeFavorited($path, 0);
}
/**
* Set the elements of a proppatch
*
* @param string $user
* @param string $path
* @param int|null $favOrUnfav 1 = favorite, 0 = unfavorite
*
* @return ResponseInterface
*/
public function changeFavStateOfAnElement(
string $user,
string $path,
?int $favOrUnfav
):ResponseInterface {
$renamedUser = $this->featureContext->getActualUsername($user);
return WebDavHelper::proppatch(
$this->featureContext->getBaseUrl(),
$renamedUser,
$this->featureContext->getPasswordForUser($user),
$path,
'favorite',
(string)$favOrUnfav,
$this->featureContext->getStepLineRef(),
"oc='http://owncloud.org/ns'",
$this->featureContext->getDavPathVersion()
);
}
/**
* 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');
$this->webDavPropertiesContext = $environment->getContext(
'WebDavPropertiesContext'
);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,443 @@
<?php declare(strict_types=1);
/**
* ownCloud
*
* @author Artur Neumann <artur@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\TableNode;
use PHPUnit\Framework\Assert;
use TestHelpers\HttpRequestHelper;
use TestHelpers\WebDavHelper;
require_once 'bootstrap.php';
/**
* Steps that relate to files_versions app
*/
class FilesVersionsContext implements Context {
/**
*
* @var FeatureContext
*/
private $featureContext;
/**
* @param string $fileId
*
* @return string
*/
private function getVersionsPathForFileId(string $fileId):string {
return "/meta/$fileId/v";
}
/**
* @When user :user tries to get versions of file :file from :fileOwner
*
* @param string $user
* @param string $file
* @param string $fileOwner
*
* @return void
* @throws Exception
*/
public function userTriesToGetFileVersions(string $user, string $file, string $fileOwner):void {
$user = $this->featureContext->getActualUsername($user);
$fileOwner = $this->featureContext->getActualUsername($fileOwner);
$fileId = $this->featureContext->getFileIdForPath($fileOwner, $file);
Assert::assertNotNull($fileId, __METHOD__ . " fileid of file $file user $fileOwner not found (the file may not exist)");
$response = $this->featureContext->makeDavRequest(
$user,
"PROPFIND",
$this->getVersionsPathForFileId($fileId),
null,
null,
null,
'2'
);
$this->featureContext->setResponse($response, $user);
}
/**
* @When user :user gets the number of versions of file :file
*
* @param string $user
* @param string $file
*
* @return void
* @throws Exception
*/
public function userGetsFileVersions(string $user, string $file):void {
$user = $this->featureContext->getActualUsername($user);
$fileId = $this->featureContext->getFileIdForPath($user, $file);
Assert::assertNotNull($fileId, __METHOD__ . " fileid of file $file user $user not found (the file may not exist)");
$response = $this->featureContext->makeDavRequest(
$user,
"PROPFIND",
$this->getVersionsPathForFileId($fileId),
null,
null,
null,
'2'
);
$this->featureContext->setResponse($response, $user);
}
/**
* @When user :user gets the version metadata of file :file
*
* @param string $user
* @param string $file
*
* @return void
* @throws Exception
*/
public function userGetsVersionMetadataOfFile(string $user, string $file):void {
$user = $this->featureContext->getActualUsername($user);
$fileId = $this->featureContext->getFileIdForPath($user, $file);
Assert::assertNotNull($fileId, __METHOD__ . " fileid of file $file user $user not found (the file may not exist)");
$body = '<?xml version="1.0"?>
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">
<d:prop>
<oc:meta-version-edited-by />
<oc:meta-version-edited-by-name />
</d:prop>
</d:propfind>';
$response = $this->featureContext->makeDavRequest(
$user,
"PROPFIND",
$this->getVersionsPathForFileId($fileId),
null,
$body,
null,
'2'
);
$this->featureContext->setResponse($response, $user);
}
/**
* @When user :user restores version index :versionIndex of file :path using the WebDAV API
* @Given user :user has restored version index :versionIndex of file :path
*
* @param string $user
* @param int $versionIndex
* @param string $path
*
* @return void
* @throws Exception
*/
public function userRestoresVersionIndexOfFile(string $user, int $versionIndex, string $path):void {
$user = $this->featureContext->getActualUsername($user);
$fileId = $this->featureContext->getFileIdForPath($user, $path);
Assert::assertNotNull($fileId, __METHOD__ . " fileid of file $path user $user not found (the file may not exist)");
$responseXml = $this->listVersionFolder($user, $fileId, 1);
$xmlPart = $responseXml->xpath("//d:response/d:href");
//restoring the version only works with DAV path v2
$destinationUrl = $this->featureContext->getBaseUrl() . "/" .
WebDavHelper::getDavPath($user, 2) . \trim($path, "/");
$fullUrl = $this->featureContext->getBaseUrlWithoutPath() .
$xmlPart[$versionIndex];
$response = HttpRequestHelper::sendRequest(
$fullUrl,
$this->featureContext->getStepLineRef(),
'COPY',
$user,
$this->featureContext->getPasswordForUser($user),
['Destination' => $destinationUrl]
);
$this->featureContext->setResponse($response, $user);
}
/**
* @Then the version folder of file :path for user :user should contain :count element(s)
*
* @param string $path
* @param string $user
* @param int $count
*
* @return void
* @throws Exception
*/
public function theVersionFolderOfFileShouldContainElements(
string $path,
string $user,
int $count
):void {
$user = $this->featureContext->getActualUsername($user);
$fileId = $this->featureContext->getFileIdForPath($user, $path);
Assert::assertNotNull($fileId, __METHOD__ . " file $path user $user not found (the file may not exist)");
$this->theVersionFolderOfFileIdShouldContainElements($fileId, $user, $count);
}
/**
* @Then the version folder of fileId :fileId for user :user should contain :count element(s)
*
* @param string $fileId
* @param string $user
* @param int $count
*
* @return void
* @throws Exception
*/
public function theVersionFolderOfFileIdShouldContainElements(
string $fileId,
string $user,
int $count
):void {
$responseXml = $this->listVersionFolder($user, $fileId, 1);
$xmlPart = $responseXml->xpath("//d:prop/d:getetag");
Assert::assertEquals(
$count,
\count($xmlPart) - 1,
"could not find $count version element(s) in \n" . $responseXml->asXML()
);
}
/**
* @Then the content length of file :path with version index :index for user :user in versions folder should be :length
*
* @param string $path
* @param int $index
* @param string $user
* @param int $length
*
* @return void
* @throws Exception
*/
public function theContentLengthOfFileForUserInVersionsFolderIs(
string $path,
int $index,
string $user,
int $length
):void {
$user = $this->featureContext->getActualUsername($user);
$fileId = $this->featureContext->getFileIdForPath($user, $path);
Assert::assertNotNull($fileId, __METHOD__ . " fileid of file $path user $user not found (the file may not exist)");
$responseXml = $this->listVersionFolder(
$user,
$fileId,
1,
['getcontentlength']
);
$xmlPart = $responseXml->xpath("//d:prop/d:getcontentlength");
Assert::assertEquals(
$length,
(int) $xmlPart[$index],
"The content length of file {$path} with version {$index} for user {$user} was
expected to be {$length} but the actual content length is {$xmlPart[$index]}"
);
}
/**
* @Then /^as (?:users|user) "([^"]*)" the authors of the versions of file "([^"]*)" should be:$/
*
* @param string $users comma-separated list of usernames
* @param string $filename
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function asUsersAuthorsOfVersionsOfFileShouldBe(
string $users,
string $filename,
TableNode $table
): void {
$this->featureContext->verifyTableNodeColumns(
$table,
['index', 'author']
);
$requiredVersionMetadata = $table->getHash();
$usersArray = \explode(",", $users);
foreach ($usersArray as $username) {
$actualUsername = $this->featureContext->getActualUsername($username);
$this->userGetsVersionMetadataOfFile($actualUsername, $filename);
foreach ($requiredVersionMetadata as $versionMetadata) {
$this->featureContext->theAuthorOfEditedVersionFile(
$versionMetadata['index'],
$versionMetadata['author']
);
}
}
}
/**
* @When user :user downloads the version of file :path with the index :index
*
* @param string $user
* @param string $path
* @param string $index
*
* @return void
* @throws Exception
*/
public function downloadVersion(string $user, string $path, string $index):void {
$user = $this->featureContext->getActualUsername($user);
$fileId = $this->featureContext->getFileIdForPath($user, $path);
Assert::assertNotNull($fileId, __METHOD__ . " fileid of file $path user $user not found (the file may not exist)");
$index = (int)$index;
$responseXml = $this->listVersionFolder($user, $fileId, 1);
$xmlPart = $responseXml->xpath("//d:response/d:href");
if (!isset($xmlPart[$index])) {
Assert::fail(
'could not find version of path "' . $path . '" with index "' . $index . '"'
);
}
// the href already contains the path
$url = WebDavHelper::sanitizeUrl(
$this->featureContext->getBaseUrlWithoutPath() . $xmlPart[$index]
);
$response = HttpRequestHelper::get(
$url,
$this->featureContext->getStepLineRef(),
$user,
$this->featureContext->getPasswordForUser($user)
);
$this->featureContext->setResponse($response, $user);
}
/**
* @Then /^the content of version index "([^"]*)" of file "([^"]*)" for user "([^"]*)" should be "([^"]*)"$/
*
* @param string $index
* @param string $path
* @param string $user
* @param string $content
*
* @return void
* @throws Exception
*/
public function theContentOfVersionIndexOfFileForUserShouldBe(
string $index,
string $path,
string $user,
string $content
): void {
$this->downloadVersion($user, $path, $index);
$this->featureContext->theHTTPStatusCodeShouldBe("200");
$this->featureContext->downloadedContentShouldBe($content);
}
/**
* @When /^user "([^"]*)" retrieves the meta information of (file|fileId) "([^"]*)" using the meta API$/
*
* @param string $user
* @param string $fileOrFileId
* @param string $path
*
* @return void
*/
public function userGetMetaInfo(string $user, string $fileOrFileId, string $path):void {
$user = $this->featureContext->getActualUsername($user);
$baseUrl = $this->featureContext->getBaseUrl();
$password = $this->featureContext->getPasswordForUser($user);
if ($fileOrFileId === "file") {
$fileId = $this->featureContext->getFileIdForPath($user, $path);
$metaPath = "/meta/$fileId/";
} else {
$metaPath = "/meta/$path/";
}
$body = '<?xml version="1.0" encoding="utf-8"?>
<a:propfind xmlns:a="DAV:" xmlns:oc="http://owncloud.org/ns">
<a:prop>
<oc:meta-path-for-user />
</a:prop>
</a:propfind>';
$response = WebDavHelper::makeDavRequest(
$baseUrl,
$user,
$password,
"PROPFIND",
$metaPath,
['Content-Type' => 'text/xml','Depth' => '0'],
$this->featureContext->getStepLineRef(),
$body,
$this->featureContext->getDavPathVersion(),
null
);
$this->featureContext->setResponse($response);
$responseXml = HttpRequestHelper::getResponseXml(
$response,
__METHOD__
);
$this->featureContext->setResponseXmlObject($responseXml);
}
/**
* returns the result parsed into an SimpleXMLElement
* with an registered namespace with 'd' as prefix and 'DAV:' as namespace
*
* @param string $user
* @param string $fileId
* @param int $folderDepth
* @param string[]|null $properties
*
* @return SimpleXMLElement
* @throws Exception
*/
public function listVersionFolder(
string $user,
string $fileId,
int $folderDepth,
?array $properties = null
):SimpleXMLElement {
if (!$properties) {
$properties = [
'getetag'
];
}
$user = $this->featureContext->getActualUsername($user);
$password = $this->featureContext->getPasswordForUser($user);
$response = WebDavHelper::propfind(
$this->featureContext->getBaseUrl(),
$user,
$password,
$this->getVersionsPathForFileId($fileId),
$properties,
$this->featureContext->getStepLineRef(),
(string) $folderDepth,
"versions"
);
return HttpRequestHelper::getResponseXml(
$response,
__METHOD__
);
}
/**
* 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');
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,192 @@
<?php declare(strict_types=1);
/**
* ownCloud
*
* @author Artur Neumann <artur@jankaritech.com>
* @copyright Copyright (c) 2018 Artur Neumann artur@jankaritech.com
*
* 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\TableNode;
use PHPUnit\Framework\Assert;
use TestHelpers\OcisHelper;
use TestHelpers\WebDavHelper;
require_once 'bootstrap.php';
/**
* context containing search related API steps
*/
class SearchContext implements Context {
/**
*
* @var FeatureContext
*/
private $featureContext;
/**
* @When user :user searches for :pattern using the WebDAV API
* @When user :user searches for :pattern and limits the results to :limit items using the WebDAV API
* @When user :user searches for :pattern using the WebDAV API requesting these properties:
* @When user :user searches for :pattern and limits the results to :limit items using the WebDAV API requesting these properties:
*
* @param string $user
* @param string $pattern
* @param string|null $limit
* @param TableNode|null $properties
*
* @return void
*/
public function userSearchesUsingWebDavAPI(
string $user,
string $pattern,
?string $limit = null,
TableNode $properties = null
):void {
// Because indexing of newly uploaded files or directories with ocis is decoupled and occurs asynchronously, a short wait is necessary before searching files or folders.
if (OcisHelper::isTestingOnOcis()) {
sleep(4);
}
$user = $this->featureContext->getActualUsername($user);
$baseUrl = $this->featureContext->getBaseUrl();
$password = $this->featureContext->getPasswordForUser($user);
$body
= "<?xml version='1.0' encoding='utf-8' ?>\n" .
" <oc:search-files xmlns:a='DAV:' xmlns:oc='http://owncloud.org/ns' >\n" .
" <oc:search>\n" .
" <oc:pattern>$pattern</oc:pattern>\n";
if ($limit !== null) {
$body .= " <oc:limit>$limit</oc:limit>\n";
}
$body .= " </oc:search>\n";
if ($properties !== null) {
$propertiesRows = $properties->getRows();
$body .= " <a:prop>";
foreach ($propertiesRows as $property) {
$body .= "<$property[0]/>";
}
$body .= " </a:prop>";
}
$body .= " </oc:search-files>";
$response = WebDavHelper::makeDavRequest(
$baseUrl,
$user,
$password,
"REPORT",
"/",
null,
$this->featureContext->getStepLineRef(),
$body,
$this->featureContext->getDavPathVersion()
);
$this->featureContext->setResponse($response);
}
/**
* @Then file/folder :path in the search result of user :user should contain these properties:
*
* @param string $path
* @param string $user
* @param TableNode $properties
*
* @return void
* @throws Exception
*/
public function fileOrFolderInTheSearchResultShouldContainProperties(
string $path,
string $user,
TableNode $properties
):void {
$user = $this->featureContext->getActualUsername($user);
$this->featureContext->verifyTableNodeColumns($properties, ['name', 'value']);
$properties = $properties->getHash();
$fileResult = $this->featureContext->findEntryFromPropfindResponse(
$path,
$user,
"REPORT",
);
Assert::assertNotFalse(
$fileResult,
"could not find file/folder '$path'"
);
$fileProperties = $fileResult['value'][1]['value'][0]['value'];
foreach ($properties as $property) {
$foundProperty = false;
$property['value'] = $this->featureContext->substituteInLineCodes(
$property['value'],
$user
);
foreach ($fileProperties as $fileProperty) {
if ($fileProperty['name'] === $property['name']) {
Assert::assertMatchesRegularExpression(
"/" . $property['value'] . "/",
$fileProperty['value']
);
$foundProperty = true;
break;
}
}
Assert::assertTrue(
$foundProperty,
"could not find property '" . $property['name'] . "'"
);
}
}
/**
* 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');
}
/**
* @Then the search result by tags for user :user should contain these entries:
*
* @param string|null $user
* @param TableNode $expectedEntries
*
* @return void
* @throws Exception
*/
public function theSearchResultByTagsForUserShouldContainTheseEntries(
?string $user,
TableNode $expectedEntries
):void {
$user = $this->featureContext->getActualUsername($user);
$this->featureContext->verifyTableNodeColumnsCount($expectedEntries, 1);
$expectedEntries = $expectedEntries->getRows();
$expectedEntriesArray = [];
$responseResourcesArray = $this->featureContext->findEntryFromReportResponse($user);
foreach ($expectedEntries as $item) {
\array_push($expectedEntriesArray, $item[0]);
}
Assert::assertEqualsCanonicalizing($expectedEntriesArray, $responseResourcesArray);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,489 @@
<?php declare(strict_types=1);
/**
* @author Artur Neumann <artur@jankaritech.com>
*
* @copyright Copyright (c) 2020, ownCloud GmbH
* @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\Behat\Hook\Scope\BeforeScenarioScope;
use Behat\Gherkin\Node\TableNode;
use GuzzleHttp\Exception\GuzzleException;
use TestHelpers\HttpRequestHelper;
use TestHelpers\WebDavHelper;
use TusPhp\Exception\ConnectionException;
use TusPhp\Exception\TusException;
use TusPhp\Tus\Client;
use PHPUnit\Framework\Assert;
require_once 'bootstrap.php';
/**
* TUS related test steps
*/
class TUSContext implements Context {
/**
*
* @var FeatureContext
*/
private $featureContext;
private $resourceLocation = null;
/**
* @When user :user creates a new TUS resource on the WebDAV API with these headers:
*
* @param string $user
* @param TableNode $headers
* @param string $content
*
* @return void
*
* @throws Exception
* @throws GuzzleException
*/
public function createNewTUSResourceWithHeaders(string $user, TableNode $headers, string $content = ''): void {
$this->featureContext->verifyTableNodeColumnsCount($headers, 2);
$user = $this->featureContext->getActualUsername($user);
$password = $this->featureContext->getUserPassword($user);
$this->resourceLocation = null;
$this->featureContext->setResponse(
$this->featureContext->makeDavRequest(
$user,
"POST",
null,
$headers->getRowsHash(),
$content,
"files",
null,
false,
$password
)
);
$locationHeader = $this->featureContext->getResponse()->getHeader('Location');
if (\sizeof($locationHeader) > 0) {
$this->resourceLocation = $locationHeader[0];
}
}
/**
* @Given user :user has created a new TUS resource on the WebDAV API with these headers:
*
* @param string $user
* @param TableNode $headers Tus-Resumable: 1.0.0 header is added automatically
*
* @return void
*
* @throws Exception
* @throws GuzzleException
*/
public function createNewTUSResource(string $user, TableNode $headers): void {
$rows = $headers->getRows();
$rows[] = ['Tus-Resumable', '1.0.0'];
$this->createNewTUSResourceWithHeaders($user, new TableNode($rows));
$this->featureContext->theHTTPStatusCodeShouldBe(201);
}
/**
* @When /^user "([^"]*)" sends a chunk to the last created TUS Location with offset "([^"]*)" and data "([^"]*)" using the WebDAV API$/
*
* @param string $user
* @param string $offset
* @param string $data
* @param string $checksum
*
* @return void
*
* @throws GuzzleException
* @throws JsonException
*/
public function sendsAChunkToTUSLocationWithOffsetAndData(string $user, string $offset, string $data, string $checksum = ''): void {
$user = $this->featureContext->getActualUsername($user);
$password = $this->featureContext->getUserPassword($user);
$this->featureContext->setResponse(
HttpRequestHelper::sendRequest(
$this->resourceLocation,
$this->featureContext->getStepLineRef(),
'PATCH',
$user,
$password,
[
'Content-Type' => 'application/offset+octet-stream',
'Tus-Resumable' => '1.0.0',
'Upload-Checksum' => $checksum,
'Upload-Offset' => $offset
],
$data
)
);
WebDavHelper::$SPACE_ID_FROM_OCIS = '';
}
/**
* @When user :user uploads file :source to :destination using the TUS protocol on the WebDAV API
*
* @param string|null $user
* @param string $source
* @param string $destination
* @param array $uploadMetadata array of metadata to be placed in the
* `Upload-Metadata` header.
* see https://tus.io/protocols/resumable-upload.html#upload-metadata
* Don't Base64 encode the value.
* @param int $noOfChunks
* @param int|null $bytes
* @param string $checksum
*
* @return void
* @throws ConnectionException
* @throws GuzzleException
* @throws JsonException
* @throws ReflectionException
* @throws TusException
*/
public function userUploadsUsingTusAFileTo(
?string $user,
string $source,
string $destination,
array $uploadMetadata = [],
int $noOfChunks = 1,
int $bytes = null,
string $checksum = ''
): void {
$user = $this->featureContext->getActualUsername($user);
$password = $this->featureContext->getUserPassword($user);
$headers = [
'Authorization' => 'Basic ' . \base64_encode($user . ':' . $password)
];
if ($bytes !== null) {
$creationWithUploadHeader = [
'Content-Type' => 'application/offset+octet-stream',
'Tus-Resumable' => '1.0.0'
];
$headers = \array_merge($headers, $creationWithUploadHeader);
}
if ($checksum != '') {
$checksumHeader = [
'Upload-Checksum' => $checksum
];
$headers = \array_merge($headers, $checksumHeader);
}
$client = new Client(
$this->featureContext->getBaseUrl(),
['verify' => false,
'headers' => $headers
]
);
$client->setApiPath(
WebDavHelper::getDavPath(
$user,
$this->featureContext->getDavPathVersion(),
"files",
WebDavHelper::$SPACE_ID_FROM_OCIS
? WebDavHelper::$SPACE_ID_FROM_OCIS
: $this->featureContext->getPersonalSpaceIdForUser($user)
)
);
WebDavHelper::$SPACE_ID_FROM_OCIS = '';
$client->setMetadata($uploadMetadata);
$sourceFile = $this->featureContext->acceptanceTestsDirLocation() . $source;
$client->setKey((string)rand())->file($sourceFile, $destination);
$this->featureContext->pauseUploadDelete();
if ($bytes !== null) {
$client->file($sourceFile, $destination)->createWithUpload($client->getKey(), $bytes);
} elseif ($noOfChunks === 1) {
$client->file($sourceFile, $destination)->upload();
} else {
$bytesPerChunk = (int)\ceil(\filesize($sourceFile) / $noOfChunks);
for ($i = 0; $i < $noOfChunks; $i++) {
$client->upload($bytesPerChunk);
}
}
$this->featureContext->setLastUploadDeleteTime(\time());
}
/**
* @When user :user uploads file with content :content to :destination using the TUS protocol on the WebDAV API
*
* @param string $user
* @param string $content
* @param string $destination
*
* @return void
* @throws GuzzleException
* @throws Exception
*/
public function userUploadsAFileWithContentToUsingTus(
string $user,
string $content,
string $destination
): void {
$tmpfname = $this->writeDataToTempFile($content);
try {
$this->userUploadsUsingTusAFileTo(
$user,
\basename($tmpfname),
$destination
);
} catch (Exception $e) {
Assert::assertStringContainsString('TusPhp\Exception\FileException: Unable to create resource', (string)$e);
}
\unlink($tmpfname);
}
/**
* @When user :user uploads file with content :content in :noOfChunks chunks to :destination using the TUS protocol on the WebDAV API
*
* @param string|null $user
* @param string $content
* @param int|null $noOfChunks
* @param string $destination
*
* @return void
* @throws ConnectionException
* @throws GuzzleException
* @throws JsonException
* @throws ReflectionException
* @throws TusException
* @throws Exception
* @throws GuzzleException
*/
public function userUploadsAFileWithContentInChunksUsingTus(
?string $user,
string $content,
?int $noOfChunks,
string $destination
): void {
$tmpfname = $this->writeDataToTempFile($content);
$this->userUploadsUsingTusAFileTo(
$user,
\basename($tmpfname),
$destination,
[],
$noOfChunks
);
\unlink($tmpfname);
}
/**
* @When user :user uploads file :source to :destination with mtime :mtime using the TUS protocol on the WebDAV API
*
* @param string $user
* @param string $source
* @param string $destination
* @param string $mtime Time in human readable format is taken as input which is converted into milliseconds that is used by API
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function userUploadsFileWithContentToWithMtimeUsingTUS(
string $user,
string $source,
string $destination,
string $mtime
): void {
$mtime = new DateTime($mtime);
$mtime = $mtime->format('U');
$user = $this->featureContext->getActualUsername($user);
$this->userUploadsUsingTusAFileTo(
$user,
$source,
$destination,
['mtime' => $mtime]
);
}
/**
* @param string $content
*
* @return string the file name
* @throws Exception
*/
private function writeDataToTempFile(string $content): string {
$tmpfname = \tempnam(
$this->featureContext->acceptanceTestsDirLocation(),
"tus-upload-test-"
);
if ($tmpfname === false) {
throw new \Exception("could not create a temporary filename");
}
$tempfile = \fopen($tmpfname, "w");
if ($tempfile === false) {
throw new \Exception("could not open " . $tmpfname . " for write");
}
\fwrite($tempfile, $content);
\fclose($tempfile);
return $tmpfname;
}
/**
* @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');
}
/**
* @When user :user creates a new TUS resource with content :content on the WebDAV API with these headers:
*
* @param string $user
* @param string $content
* @param TableNode $headers
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function userCreatesWithUpload(
string $user,
string $content,
TableNode $headers
): void {
$this->createNewTUSResourceWithHeaders($user, $headers, $content);
}
/**
* @When user :user creates file :source and uploads content :content in the same request using the TUS protocol on the WebDAV API
*
* @param string $user
* @param string $source
* @param string $content
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function userUploadsWithCreatesWithUpload(
string $user,
string $source,
string $content
): void {
$tmpfname = $this->writeDataToTempFile($content);
$this->userUploadsUsingTusAFileTo(
$user,
\basename($tmpfname),
$source,
[],
1,
-1
);
\unlink($tmpfname);
}
/**
* @When user :user uploads file with checksum :checksum to the last created TUS Location with offset :offset and content :content using the TUS protocol on the WebDAV API
*
* @param string $user
* @param string $checksum
* @param string $offset
* @param string $content
*
* @return void
* @throws Exception
*/
public function userUploadsFileWithChecksum(
string $user,
string $checksum,
string $offset,
string $content
): void {
$this->sendsAChunkToTUSLocationWithOffsetAndData($user, $offset, $content, $checksum);
}
/**
* @Given user :user has uploaded file with checksum :checksum to the last created TUS Location with offset :offset and content :content using the TUS protocol on the WebDAV API
*
* @param string $user
* @param string $checksum
* @param string $offset
* @param string $content
*
* @return void
* @throws Exception
*/
public function userHasUploadedFileWithChecksum(
string $user,
string $checksum,
string $offset,
string $content
): void {
$this->sendsAChunkToTUSLocationWithOffsetAndData($user, $offset, $content, $checksum);
$this->featureContext->theHTTPStatusCodeShouldBe(204, "");
}
/**
* @When user :user sends a chunk to the last created TUS Location with offset :offset and data :data with checksum :checksum using the TUS protocol on the WebDAV API
*
* @param string $user
* @param string $offset
* @param string $data
* @param string $checksum
*
* @return void
* @throws Exception
*/
public function userUploadsChunkFileWithChecksum(string $user, string $offset, string $data, string $checksum): void {
$this->sendsAChunkToTUSLocationWithOffsetAndData($user, $offset, $data, $checksum);
}
/**
* @Given user :user has uploaded a chunk to the last created TUS Location with offset :offset and data :data with checksum :checksum using the TUS protocol on the WebDAV API
*
* @param string $user
* @param string $offset
* @param string $data
* @param string $checksum
*
* @return void
* @throws Exception
*/
public function userHasUploadedChunkFileWithChecksum(string $user, string $offset, string $data, string $checksum): void {
$this->sendsAChunkToTUSLocationWithOffsetAndData($user, $offset, $data, $checksum);
$this->featureContext->theHTTPStatusCodeShouldBe(204, "");
}
/**
* @When user :user overwrites recently shared file with offset :offset and data :data with checksum :checksum using the TUS protocol on the WebDAV API with these headers:
* @When user :user overwrites existing file with offset :offset and data :data with checksum :checksum using the TUS protocol on the WebDAV API with these headers:
*
* @param string $user
* @param string $offset
* @param string $data
* @param string $checksum
* @param TableNode $headers Tus-Resumable: 1.0.0 header is added automatically
*
* @return void
*
* @throws GuzzleException
* @throws Exception
*/
public function userOverwritesFileWithChecksum(string $user, string $offset, string $data, string $checksum, TableNode $headers): void {
$this->createNewTUSResource($user, $headers);
$this->userHasUploadedChunkFileWithChecksum($user, $offset, $data, $checksum);
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -20,19 +20,44 @@
*
*/
$pathToCore = \getenv('PATH_TO_CORE');
if ($pathToCore === false) {
$pathToCore = "../core";
}
use Composer\Autoload\ClassLoader;
require_once $pathToCore . '/tests/acceptance/features/bootstrap/bootstrap.php';
$classLoader = new ClassLoader();
$classLoader = new \Composer\Autoload\ClassLoader();
$classLoader->addPsr4(
"",
$pathToCore . "/tests/acceptance/features/bootstrap",
true
);
$classLoader->addPsr4("TestHelpers\\", __DIR__ . "/../../../TestHelpers", true);
$classLoader->register();
// Sleep for 10 milliseconds
const STANDARD_SLEEP_TIME_MILLISEC = 10;
const STANDARD_SLEEP_TIME_MICROSEC = STANDARD_SLEEP_TIME_MILLISEC * 1000;
// Long timeout for use in code that needs to wait for known slow UI
const LONG_UI_WAIT_TIMEOUT_MILLISEC = 60000;
// Default timeout for use in code that needs to wait for the UI
const STANDARD_UI_WAIT_TIMEOUT_MILLISEC = 10000;
// Minimum timeout for use in code that needs to wait for the UI
const MINIMUM_UI_WAIT_TIMEOUT_MILLISEC = 500;
const MINIMUM_UI_WAIT_TIMEOUT_MICROSEC = MINIMUM_UI_WAIT_TIMEOUT_MILLISEC * 1000;
// Minimum timeout for emails
const EMAIL_WAIT_TIMEOUT_SEC = 10;
const EMAIL_WAIT_TIMEOUT_MILLISEC = EMAIL_WAIT_TIMEOUT_SEC * 1000;
// Default number of times to retry where retries are useful
const STANDARD_RETRY_COUNT = 5;
// Minimum number of times to retry where retries are useful
const MINIMUM_RETRY_COUNT = 2;
// The remote server-under-test might or might not happen to have this directory.
// If it does not exist, then the tests may end up creating it.
const ACCEPTANCE_TEST_DIR_ON_REMOTE_SERVER = "tests/acceptance";
// The following directory should NOT already exist on the remote server-under-test.
// Acceptance tests are free to do anything needed in this directory, and to
// delete it during or at the end of testing.
const TEMPORARY_STORAGE_DIR_ON_REMOTE_SERVER = ACCEPTANCE_TEST_DIR_ON_REMOTE_SERVER . "/server_tmp";
// The following directory is created, used, and deleted by tests that need to
// use some "local external storage" on the server.
const LOCAL_STORAGE_DIR_ON_REMOTE_SERVER = TEMPORARY_STORAGE_DIR_ON_REMOTE_SERVER . "/local_storage";