* @copyright Copyright (c) 2022 Viktor Scharf v.scharf@owncloud.com */ use Behat\Behat\Context\Context; use Behat\Behat\Hook\Scope\BeforeScenarioScope; use GuzzleHttp\Exception\GuzzleException; use TestHelpers\HttpRequestHelper; require_once 'bootstrap.php'; /** * Context for the TUS-specific steps using the Graph API */ class TusContext implements Context { /** * @var FeatureContext */ private FeatureContext $featureContext; /** * @var SpacesContext */ private SpacesContext $spacesContext; /** * @var string */ private string $baseUrl; /** * @return string */ public function acceptanceTestsDirLocation(): string { return \dirname(__FILE__) . "/../../filesForUpload/"; } /** * 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 from here $this->featureContext = $environment->getContext('FeatureContext'); $this->spacesContext = $environment->getContext('SpacesContext'); $this->baseUrl = \trim($this->featureContext->getBaseUrl(), "/"); } /** * @Given /^user "([^"]*)" has uploaded a file "([^"]*)" via TUS inside of the space "([^"]*)" using the WebDAV API$/ * * @param string $user * @param string $resource * @param string $spaceName * * @return void * * @throws Exception * @throws GuzzleException */ public function uploadFileViaTus(string $user, string $resource, string $spaceName): void { $resourceLocation = $this->getResourceLocation($user, $resource, $spaceName); $file = \fopen($this->acceptanceTestsDirLocation() . $resource, 'r'); $this->featureContext->setResponse( HttpRequestHelper::sendRequest( $resourceLocation, "", 'HEAD', $user, $this->featureContext->getPasswordForUser($user), [], "" ) ); $this->featureContext->theHTTPStatusCodeShouldBe(200, "Expected response status code should be 200"); $this->featureContext->setResponse( HttpRequestHelper::sendRequest( $resourceLocation, "", 'PATCH', $user, $this->featureContext->getPasswordForUser($user), ["Tus-Resumable" => "1.0.0", "Upload-Offset" => 0, 'Content-Type' => 'application/offset+octet-stream'], $file ) ); $this->featureContext->theHTTPStatusCodeShouldBe(204, "Expected response status code should be 204"); } /** * send POST and return the url of the resource location in the response header * * @param string $user * @param string $resource * @param string $spaceName * * @return string * @throws Exception|GuzzleException */ public function getResourceLocation(string $user, string $resource, string $spaceName): string { $space = $this->spacesContext->getSpaceByName($user, $spaceName); $fullUrl = $this->baseUrl . "/remote.php/dav/spaces/" . $space["id"]; $tusEndpoint = "tusEndpoint " . base64_encode(str_replace("$", "%", $fullUrl)); $fileName = "filename " . base64_encode($resource); $headers = [ "Tus-Resumable" => "1.0.0", "Upload-Metadata" => $tusEndpoint . ',' . $fileName, "Upload-Length" => filesize($this->acceptanceTestsDirLocation() . $resource) ]; $this->featureContext->setResponse( HttpRequestHelper::post( $fullUrl, "", $this->featureContext->getActualUsername($user), $this->featureContext->getUserPassword($user), $headers, '' ) ); $this->featureContext->theHTTPStatusCodeShouldBe(201, "Expected response status code should be 201"); $locationHeader = $this->featureContext->getResponse()->getHeader('Location'); if (\sizeof($locationHeader) > 0) { return $locationHeader[0]; } throw new \Exception(__METHOD__ . " Location header could not be found"); } }