diff --git a/tests/acceptance/config/behat.yml b/tests/acceptance/config/behat.yml index 8551f5c92c..9b4cb0756c 100644 --- a/tests/acceptance/config/behat.yml +++ b/tests/acceptance/config/behat.yml @@ -43,6 +43,7 @@ default: - PublicWebDavContext: - TrashbinContext: - WebDavPropertiesContext: + - TusContext: apiArchiver: paths: diff --git a/tests/acceptance/features/apiSpaces/filePreviews.feature b/tests/acceptance/features/apiSpaces/filePreviews.feature new file mode 100644 index 0000000000..72f5b94540 --- /dev/null +++ b/tests/acceptance/features/apiSpaces/filePreviews.feature @@ -0,0 +1,41 @@ +@api @skipOnOcV10 +Feature: Preview file in project space + As a user, I want to be able to download different files for the preview + + Note - this feature is run in CI with ACCOUNTS_HASH_DIFFICULTY set to the default for production + See https://github.com/owncloud/ocis/issues/1542 and https://github.com/owncloud/ocis/pull/839 + + Background: + Given these users have been created with default attributes and without skeleton files: + | username | + | Alice | + | Brian | + And the administrator has given "Alice" the role "Admin" using the settings api + And user "Alice" has created a space "previews of the files" with the default quota using the GraphApi + + + Scenario Outline: An user can preview created txt files in the project space + Given user "Alice" has uploaded a file inside space "previews of the files" with content "test" to "" + When user "Alice" downloads the preview of "" of the space "previews of the files" with width "" and height "" using the WebDAV API + Then the HTTP status code should be "200" + Examples: + | entity | width | height | + | /file.txt | 36 | 36 | + | /name with spaces.txt | 1200 | 1200 | + + + Scenario Outline: An user can preview image files in the project space + Given user "Alice" has uploaded a file "" via TUS inside of the space "previews of the files" using WebDAV API + When user "Alice" downloads the preview of "" of the space "previews of the files" with width "" and height "" using the WebDAV API + Then the HTTP status code should be "200" + Examples: + | entity | width | height | + | qrcode.png | 36 | 36 | + | qrcode.png | 1200 | 1200 | + | qrcode.png | 1920 | 1920 | + | testavatar.jpg | 36 | 36 | + | testavatar.jpg | 1200 | 1200 | + | testavatar.jpg | 1920 | 1920 | + | example.gif | 36 | 36 | + | example.gif | 1200 | 1200 | + | example.gif | 1280 | 1280 | diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php index 78d843fd0e..65f87e6c18 100644 --- a/tests/acceptance/features/bootstrap/SpacesContext.php +++ b/tests/acceptance/features/bootstrap/SpacesContext.php @@ -71,6 +71,11 @@ class SpacesContext implements Context { */ private $ocsApiUrl = '/ocs/v2.php/apps/files_sharing/api/v1/shares'; + /** + * @var string + */ + private $davSpacesUrl = '/remote.php/dav/spaces/'; + /** * @param string $spaceName * @@ -250,7 +255,7 @@ class SpacesContext implements Context { */ public function getFileData(string $user, string $spaceName, string $fileName): ResponseInterface { $space = $this->getSpaceByName($user, $spaceName); - $fullUrl = $this->baseUrl . "/remote.php/dav/spaces/" . $space["id"] . "/" . $fileName; + $fullUrl = $this->baseUrl . $this->davSpacesUrl . $space["id"] . "/" . $fileName; $this->featureContext->setResponse( HttpRequestHelper::get( @@ -2085,7 +2090,7 @@ class SpacesContext implements Context { string $spaceName ): void { $space = $this->getSpaceByName($user, $spaceName); - $fullUrl = $this->baseUrl . "/remote.php/dav/spaces/trash-bin/" . $space["id"]; + $fullUrl = $this->baseUrl . $this->davSpacesUrl . "trash-bin/" . $space["id"]; $this->featureContext->setResponse( HttpRequestHelper::sendRequest( $fullUrl, @@ -2191,7 +2196,7 @@ class SpacesContext implements Context { } }; - $destination = $this->baseUrl . "/remote.php/dav/spaces/" . $space["id"] . $destination; + $destination = $this->baseUrl . $this->davSpacesUrl . $space["id"] . $destination; $header = ["Destination" => $destination, "Overwrite" => "F"]; $fullUrl = $this->baseUrl . $pathToDeletedObject; @@ -2207,4 +2212,47 @@ class SpacesContext implements Context { ) ); } + + /** + * User downloads a priview of the file inside of the project space + * @When /^user "([^"]*)" downloads the preview of "([^"]*)" of the space "([^"]*)" with width "([^"]*)" and height "([^"]*)" using the WebDAV API$/ + * + * @param string $user + * @param string $fileName + * @param string $spaceName + * @param string $width + * @param string $height + * + * @throws GuzzleException + */ + public function downloadPreview( + string $user, + string $fileName, + string $spaceName, + string $width, + string $height + ): void { + $eTag = str_replace("\"", "", $this->getETag($user, $spaceName, $fileName)); + $urlParameters = [ + 'scalingup' => 0, + 'preview' => '1', + 'a' => '1', + 'c' => $eTag, + 'x' => $width, + 'y' => $height + ]; + $urlParameters = \http_build_query($urlParameters, '', '&'); + $space = $this->getSpaceByName($user, $spaceName); + + $fullUrl = $this->baseUrl . $this->davSpacesUrl . $space['id'] . '/' . $fileName . '?' . $urlParameters; + + $this->featureContext->setResponse( + HttpRequestHelper::get( + $fullUrl, + "", + $user, + $this->featureContext->getPasswordForUser($user) + ) + ); + } } diff --git a/tests/acceptance/features/bootstrap/TusContext.php b/tests/acceptance/features/bootstrap/TusContext.php new file mode 100644 index 0000000000..5cc3269b14 --- /dev/null +++ b/tests/acceptance/features/bootstrap/TusContext.php @@ -0,0 +1,152 @@ + + * @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 provisioning 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 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 + */ + 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]; + } + } +} diff --git a/tests/acceptance/filesForUpload/example.gif b/tests/acceptance/filesForUpload/example.gif new file mode 100644 index 0000000000..9639afcdb5 Binary files /dev/null and b/tests/acceptance/filesForUpload/example.gif differ diff --git a/tests/acceptance/filesForUpload/qrcode.png b/tests/acceptance/filesForUpload/qrcode.png new file mode 100644 index 0000000000..5b3cdb0972 Binary files /dev/null and b/tests/acceptance/filesForUpload/qrcode.png differ diff --git a/tests/acceptance/filesForUpload/testavatar.jpg b/tests/acceptance/filesForUpload/testavatar.jpg new file mode 100644 index 0000000000..fb9e54042c Binary files /dev/null and b/tests/acceptance/filesForUpload/testavatar.jpg differ