* @copyright Copyright (c) 2022 Viktor Scharf v.scharf@owncloud.com */ use Behat\Behat\Context\Context; use Behat\Behat\Hook\Scope\BeforeScenarioScope; use Behat\Gherkin\Node\TableNode; use GuzzleHttp\Exception\GuzzleException; use PHPUnit\Framework\Assert; use TestHelpers\WebDavHelper; use TestHelpers\BehatHelper; require_once 'bootstrap.php'; /** * Context for the TUS-specific steps using the Graph API */ class SpacesTUSContext implements Context { private FeatureContext $featureContext; private TUSContext $tusContext; private SpacesContext $spacesContext; /** * 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 = BehatHelper::getContext($scope, $environment, 'FeatureContext'); $this->spacesContext = BehatHelper::getContext($scope, $environment, 'SpacesContext'); $this->tusContext = BehatHelper::getContext($scope, $environment, 'TUSContext'); } /** * @Given /^user "([^"]*)" has uploaded a file from "([^"]*)" to "([^"]*)" via TUS inside of the space "([^"]*)" using the WebDAV API$/ * * @param string $user * @param string $source * @param string $destination * @param string $spaceName * * @return void * * @throws Exception * @throws GuzzleException */ public function userHasUploadedFileViaTusInSpace( string $user, string $source, string $destination, string $spaceName ): void { $spaceId = $this->spacesContext->getSpaceIdByName($user, $spaceName); $this->tusContext->uploadFileUsingTus($user, $source, $destination, $spaceId); $this->featureContext->setLastUploadDeleteTime(\time()); } /** * @When /^user "([^"]*)" uploads a file from "([^"]*)" to "([^"]*)" via TUS inside of the space "([^"]*)" using the WebDAV API$/ * * @param string $user * @param string $source * @param string $destination * @param string $spaceName * * @return void * @throws Exception * @throws GuzzleException */ public function userUploadsAFileViaTusInsideOfTheSpaceUsingTheWebdavApi( string $user, string $source, string $destination, string $spaceName ): void { $spaceId = $this->spacesContext->getSpaceIdByName($user, $spaceName); $this->tusContext->uploadFileUsingTus($user, $source, $destination, $spaceId); $this->featureContext->setLastUploadDeleteTime(\time()); } /** * @Given user :user has created a new TUS resource in the space :spaceName with the following headers: * * @param string $user * @param string $spaceName * @param TableNode $headers * * @return void * * @throws Exception * @throws GuzzleException */ public function userHasCreatedANewTusResourceForTheSpaceUsingTheWebdavApiWithTheseHeaders( string $user, string $spaceName, TableNode $headers ): void { $spaceId = $this->spacesContext->getSpaceIdByName($user, $spaceName); $response = $this->tusContext->createNewTUSResourceWithHeaders($user, $headers, '', $spaceId); $this->featureContext->theHTTPStatusCodeShouldBe(201, "Expected response status code should be 201", $response); } /** * @When user :user creates a new TUS resource for the space :spaceName with content :content using the WebDAV API with these headers: * * @param string $user * @param string $spaceName * @param string $content * @param TableNode $headers * * @return void * * @throws Exception * @throws GuzzleException */ public function userCreatesANewTusResourceForTheSpaceUsingTheWebdavApiWithTheseHeaders( string $user, string $spaceName, string $content, TableNode $headers ): void { $spaceId = $this->spacesContext->getSpaceIdByName($user, $spaceName); $response = $this->tusContext->createNewTUSResourceWithHeaders($user, $headers, $content, $spaceId); $this->featureContext->setResponse($response); } /** * Uploads a file with content to the specified space using the TUS protocol via the WebDAV API. * * @param string $user * @param string $content * @param string $resource * @param string $spaceName * * @return void * @throws Exception|GuzzleException */ private function uploadFileViaTus(string $user, string $content, string $resource, string $spaceName): void { $spaceId = $this->spacesContext->getSpaceIdByName($user, $spaceName); $tmpFile = $this->tusContext->writeDataToTempFile($content); try { $this->tusContext->uploadFileUsingTus( $user, \basename($tmpFile), $resource, $spaceId ); $this->featureContext->setLastUploadDeleteTime(\time()); } catch (Exception $e) { Assert::assertStringContainsString('Unable to create resource', (string)$e); } \unlink($tmpFile); } /** * @When /^user "([^"]*)" uploads a file with content "([^"]*)" to "([^"]*)" inside federated share "([^"]*)" via TUS using the WebDAV API$/ * * @param string $user * @param string $content * @param string $file * @param string $destination * * @return void * @throws Exception|GuzzleException */ public function userUploadsAFileWithContentToInsideFederatedShareViaTusUsingTheWebdavApi( string $user, string $content, string $file, string $destination ): void { $remoteItemId = $this->spacesContext->getSharesRemoteItemId($user, $destination); $remoteItemId = \rawurlencode($remoteItemId); $tmpFile = $this->tusContext->writeDataToTempFile($content); $this->tusContext->uploadFileUsingTus( $user, \basename($tmpFile), $file, $remoteItemId ); $this->featureContext->setLastUploadDeleteTime(\time()); \unlink($tmpFile); } /** * @When /^user "([^"]*)" uploads a file with content "([^"]*)" to "([^"]*)" via TUS inside of the space "([^"]*)" using the WebDAV API$/ * * @param string $user * @param string $content * @param string $resource * @param string $spaceName * * @return void * @throws Exception|GuzzleException */ public function userUploadsAFileWithContentToViaTusInsideOfTheSpaceUsingTheWebdavApi( string $user, string $content, string $resource, string $spaceName ): void { $this->uploadFileViaTus($user, $content, $resource, $spaceName); } /** * @Given /^user "([^"]*)" has uploaded a file with content "([^"]*)" to "([^"]*)" via TUS inside of the space "([^"]*)"$/ * * @param string $user * @param string $content * @param string $resource * @param string $spaceName * * @return void * @throws Exception|GuzzleException */ public function userHasUploadedAFileWithContentToViaTusInsideOfTheSpace( string $user, string $content, string $resource, string $spaceName ): void { $this->uploadFileViaTus($user, $content, $resource, $spaceName); } /** * @When /^user "([^"]*)" uploads a file "([^"]*)" to "([^"]*)" with mtime "([^"]*)" via TUS inside of the space "([^"]*)" using 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 * @param string $spaceName * * @return void * * @throws Exception * @throws GuzzleException */ public function userUploadsAFileToWithMtimeViaTusInsideOfTheSpaceUsingTheWebdavApi( string $user, string $source, string $destination, string $mtime, string $spaceName ): void { switch ($mtime) { case "today": $mtime = date('Y-m-d', strtotime('today')); break; case "yesterday": $mtime = date('Y-m-d', strtotime('yesterday')); break; case "lastWeek": $mtime = date('Y-m-d', strtotime('-7 days')); break; case "lastMonth": $mtime = date('Y-m-d', strtotime('first day of previous month')); break; case "lastYear": $mtime = date('Y-m' . '-01', strtotime('-1 year')); break; default: } $spaceId = $this->spacesContext->getSpaceIdByName($user, $spaceName); $mtime = new DateTime($mtime); $mtime = $mtime->format('U'); $user = $this->featureContext->getActualUsername($user); $this->tusContext->uploadFileUsingTus( $user, $source, $destination, $spaceId, ['mtime' => $mtime] ); $this->featureContext->setLastUploadDeleteTime(\time()); } /** * @Given /^user "([^"]*)" has uploaded file with checksum "([^"]*)" to the last created TUS Location with offset "([^"]*)" and content "([^"]*)" via TUS inside of the space "([^"]*)" using the WebDAV API$/ * * @param string $user * @param string $checksum * @param string $offset * @param string $content * @param string $spaceName * * @return void * @throws Exception|GuzzleException * @codingStandardsIgnoreStart */ public function userHasUploadedFileWithChecksumToTheLastCreatedTusLocationWithOffsetAndContentViaTusInsideOfTheSpaceUsingTheWebdavApi( // @codingStandardsIgnoreEnd string $user, string $checksum, string $offset, string $content, string $spaceName ): void { $resourceLocation = $this->tusContext->getLastTusResourceLocation(); $response = $this->tusContext->uploadChunkToTUSLocation($user, $resourceLocation, $offset, $content, $checksum); $this->featureContext->theHTTPStatusCodeShouldBe(204, "", $response); } /** * @When /^user "([^"]*)" uploads file with checksum "([^"]*)" to the last created TUS Location with offset "([^"]*)" and content "([^"]*)" via TUS inside of the space "([^"]*)" using the WebDAV API$/ * * @param string $user * @param string $checksum * @param string $offset * @param string $content * @param string $spaceName * * @return void * @throws Exception|GuzzleException * @codingStandardsIgnoreStart */ public function userUploadsFileWithChecksumToTheLastCreatedTusLocationWithOffsetAndContentViaTusInsideOfTheSpaceUsingTheWebdavApi( // @codingStandardsIgnoreEnd string $user, string $checksum, string $offset, string $content, string $spaceName ): void { $resourceLocation = $this->tusContext->getLastTusResourceLocation(); $response = $this->tusContext->uploadChunkToTUSLocation($user, $resourceLocation, $offset, $content, $checksum); $this->featureContext->setResponse($response); } /** * @When /^user "([^"]*)" sends a chunk to the last created TUS Location with offset "([^"]*)" and data "([^"]*)" with checksum "([^"]*)" via TUS inside of the space "([^"]*)" using the WebDAV API$/ * * @param string $user * @param string $offset * @param string $data * @param string $checksum * @param string $spaceName * * @return void * @throws Exception|GuzzleException * @codingStandardsIgnoreStart */ public function userSendsAChunkToTheLastCreatedTusLocationWithOffsetAndDataWithChecksumViaTusInsideOfTheSpaceUsingTheWebdavApi( // @codingStandardsIgnoreEnd string $user, string $offset, string $data, string $checksum, string $spaceName ): void { $resourceLocation = $this->tusContext->getLastTusResourceLocation(); $response = $this->tusContext->uploadChunkToTUSLocation($user, $resourceLocation, $offset, $data, $checksum); $this->featureContext->setResponse($response); } /** * @When /^user "([^"]*)" sends a chunk to the last created TUS Location with data "([^"]*)" with the following headers:$/ * * @param string $user * @param string $data * @param TableNode $headers * * @return void * @throws Exception|GuzzleException */ public function userSendsAChunkToTheLastCreatedTusLocationWithDataInsideOfTheSpaceWithHeaders( string $user, string $data, TableNode $headers ): void { $rows = $headers->getRowsHash(); $resourceLocation = $this->tusContext->getLastTusResourceLocation(); $response = $this->tusContext->uploadChunkToTUSLocation( $user, $resourceLocation, $rows['Upload-Offset'], $data, $rows['Upload-Checksum'], ['Origin' => $rows['Origin']] ); $this->featureContext->setResponse($response); } /** * @When /^user "([^"]*)" overwrites recently shared file with offset "([^"]*)" and data "([^"]*)" with checksum "([^"]*)" via TUS inside of the space "([^"]*)" using the WebDAV API with these headers:$/ * * @param string $user * @param string $offset * @param string $data * @param string $checksum * @param string $spaceName * @param TableNode $headers * * @return void * @throws GuzzleException * @codingStandardsIgnoreStart */ public function userOverwritesRecentlySharedFileWithOffsetAndDataWithChecksumViaTusInsideOfTheSpaceUsingTheWebdavApiWithTheseHeaders( // @codingStandardsIgnoreEnd string $user, string $offset, string $data, string $checksum, string $spaceName, TableNode $headers ): void { $spaceId = $this->spacesContext->getSpaceIdByName($user, $spaceName); $createResponse = $this->tusContext->createNewTUSResource($user, $headers, $spaceId); $this->featureContext->theHTTPStatusCodeShouldBe(201, "", $createResponse); $resourceLocation = $this->tusContext->getLastTusResourceLocation(); $response = $this->tusContext->uploadChunkToTUSLocation($user, $resourceLocation, $offset, $data, $checksum); $this->featureContext->setResponse($response); } /** * @Then /^as "([^"]*)" the mtime of the file "([^"]*)" in space "([^"]*)" should be "([^"]*)"$/ * * @param string $user * @param string $resource * @param string $spaceName * @param string $mtime * * @return void * @throws Exception|GuzzleException */ public function theMtimeOfTheFileInSpaceShouldBe( string $user, string $resource, string $spaceName, string $mtime ): void { $spaceId = $this->spacesContext->getSpaceIdByName($user, $spaceName); $mtime = new DateTime($mtime); Assert::assertEquals( $mtime->format('U'), WebDavHelper::getMtimeOfResource( $this->featureContext->getActualUsername($user), $this->featureContext->getPasswordForUser($user), $this->featureContext->getBaseUrl(), $resource, $this->featureContext->getStepLineRef(), $this->featureContext->getDavPathVersion(), $spaceId, ) ); } }