From 1dbc2a426b6ca43cf3bebffb26f78576813af205 Mon Sep 17 00:00:00 2001 From: Viktor Scharf Date: Thu, 26 Oct 2023 15:27:50 +0200 Subject: [PATCH 1/3] add new lock tests --- tests/acceptance/config/behat.yml | 1 + ...ected-failures-localAPI-on-OCIS-storage.md | 11 + .../features/apiSpaces/lockFiles.feature | 217 +++++++++++++++++ .../features/bootstrap/SpacesContext.php | 15 +- .../bootstrap/WebDavLockingContext.php | 222 +++++++++++++----- 5 files changed, 402 insertions(+), 64 deletions(-) create mode 100644 tests/acceptance/features/apiSpaces/lockFiles.feature diff --git a/tests/acceptance/config/behat.yml b/tests/acceptance/config/behat.yml index 1190559c554..910f1ccd74c 100644 --- a/tests/acceptance/config/behat.yml +++ b/tests/acceptance/config/behat.yml @@ -46,6 +46,7 @@ default: - SpacesTUSContext: - GraphContext: - OcisConfigContext: + - WebDavLockingContext: apiSpacesShares: paths: diff --git a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md index 1867a4319f9..b3113aa76fa 100644 --- a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md @@ -143,5 +143,16 @@ The expected failures in this file are from features in the owncloud/ocis repo. - [apiGraph/addUserToGroup.feature:420](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/addUserToGroup.feature#L420) +### [500 error if viewer tries to lock file](https://github.com/owncloud/ocis/issues/7600) + +- [apiSpaces/lockFiles.feature:144](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/lockFiles.feature#L144) +- [apiSpaces/lockFiles.feature:207](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/lockFiles.feature#L207) + +### [Shared file locking is not possible using different path](https://github.com/owncloud/ocis/issues/7599) + +- [apiSpaces/lockFiles.feature:179](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/lockFiles.feature#L179) +- [apiSpaces/lockFiles.feature:180](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/lockFiles.feature#L180) +- [apiSpaces/lockFiles.feature:181](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/lockFiles.feature#L181) + Note: always have an empty line at the end of this file. The bash script that processes this file requires that the last line has a newline on the end. diff --git a/tests/acceptance/features/apiSpaces/lockFiles.feature b/tests/acceptance/features/apiSpaces/lockFiles.feature new file mode 100644 index 00000000000..c742899a0d9 --- /dev/null +++ b/tests/acceptance/features/apiSpaces/lockFiles.feature @@ -0,0 +1,217 @@ +Feature: lock files + As a user + I want to lock files + + Background: + Given these users have been created with default attributes and without skeleton files: + | username | + | Alice | + | Brian | + + + Scenario Outline: locking a file + Given using DAV path + And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" + When user "Alice" locks file "textfile.txt" using the WebDAV API setting the following properties + | lockscope | exclusive | + Then the HTTP status code should be "200" + When user "Alice" sends PROPFIND request from the space "Alice Hansen" to the resource "textfile.txt" using the WebDAV API + Then the HTTP status code should be "207" + And the "PROPFIND" response to user "Alice" should contain a space "Alice Hansen" with these key and value pairs: + | key | value | + | d:lockdiscovery/d:activelock/d:lockscope/d:exclusive | | + | d:lockdiscovery/d:activelock/d:depth | Infinity | + | d:lockdiscovery/d:activelock/d:timeout | Infinity | + | d:lockdiscovery/d:activelock/oc:ownername | Alice Hansen | + Examples: + | dav-path-version | + | old | + | new | + | spaces | + + + Scenario Outline: locking a file with a set timeout + Given using DAV path + And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" + When user "Alice" locks file "textfile.txt" using the WebDAV API setting the following properties + | lockscope | exclusive | + | timeout | Second-5000 | + Then the HTTP status code should be "200" + When user "Alice" sends PROPFIND request from the space "Alice Hansen" to the resource "textfile.txt" using the WebDAV API + Then the HTTP status code should be "207" + And the "PROPFIND" response to user "Alice" should contain a space "Alice Hansen" with these key and value pairs: + | key | value | + | d:lockdiscovery/d:activelock/d:lockscope/d:exclusive | | + | d:lockdiscovery/d:activelock/d:depth | Infinity | + | d:lockdiscovery/d:activelock/d:timeout | Second-5000 | + | d:lockdiscovery/d:activelock/oc:ownername | Alice Hansen | + Examples: + | dav-path-version | + | old | + | new | + | spaces | + + + Scenario Outline: locking a file by file-id + Given user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" + And we save it into "FILEID" + When user "Alice" locks file using file-id path "" using the WebDAV API setting the following properties + | lockscope | exclusive | + | timeout | Second-3600 | + Then the HTTP status code should be "200" + When user "Alice" sends PROPFIND request from the space "Alice Hansen" to the resource "textfile.txt" using the WebDAV API + Then the HTTP status code should be "207" + And the "PROPFIND" response to user "Alice" should contain a space "Alice Hansen" with these key and value pairs: + | key | value | + | d:lockdiscovery/d:activelock/d:lockscope/d:exclusive | | + | d:lockdiscovery/d:activelock/d:depth | Infinity | + | d:lockdiscovery/d:activelock/d:timeout | Second-3600 | + | d:lockdiscovery/d:activelock/oc:ownername | Alice Hansen | + Examples: + | dav-path | + | /remote.php/dav/spaces/<> | + | /dav/spaces/<> | + + + Scenario Outline: user cannot lock file twice + Given using DAV path + And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" + And user "Alice" has locked file "textfile.txt" setting the following properties + | lockscope | exclusive | + When user "Alice" tries to lock file "textfile.txt" using the WebDAV API setting the following properties + | lockscope | exclusive | + Then the HTTP status code should be "423" + Examples: + | dav-path-version | + | old | + | new | + | spaces | + + + Scenario Outline: locking a file in the project space + Given the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And using spaces DAV path + And user "Alice" has created a space "Project" with the default quota using the GraphApi + And user "Alice" has uploaded a file inside space "Project" with content "some content" to "textfile.txt" + And user "Alice" has shared a space "Project" with settings: + | shareWith | Brian | + | role | | + When user "Brian" locks file "textfile.txt" inside the space "Project" using the WebDAV API setting the following properties + | lockscope | exclusive | + | timeout | Second-3600 | + Then the HTTP status code should be "200" + When user "Brian" sends PROPFIND request from the space "Project" to the resource "textfile.txt" using the WebDAV API + Then the HTTP status code should be "207" + And the "PROPFIND" response to user "Brian" should contain a space "Project" with these key and value pairs: + | key | value | + | d:lockdiscovery/d:activelock/d:lockscope/d:exclusive | | + | d:lockdiscovery/d:activelock/d:depth | Infinity | + | d:lockdiscovery/d:activelock/d:timeout | Second-3600 | + | d:lockdiscovery/d:activelock/oc:ownername | Brian Murphy | + Examples: + | role | + | manager | + | editor | + + + Scenario Outline: locking a file in the project space by file-id + Given the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And using spaces DAV path + And user "Alice" has created a space "Project" with the default quota using the GraphApi + And user "Alice" has uploaded a file inside space "Project" with content "some content" to "textfile.txt" + And we save it into "FILEID" + And user "Alice" has shared a space "Project" with settings: + | shareWith | Brian | + | role | | + When user "Brian" locks file using file-id path "" using the WebDAV API setting the following properties + | lockscope | exclusive | + | timeout | Second-3600 | + Then the HTTP status code should be "200" + When user "Brian" sends PROPFIND request from the space "Project" to the resource "textfile.txt" using the WebDAV API + Then the HTTP status code should be "207" + And the "PROPFIND" response to user "Brian" should contain a space "Project" with these key and value pairs: + | key | value | + | d:lockdiscovery/d:activelock/d:lockscope/d:exclusive | | + | d:lockdiscovery/d:activelock/d:depth | Infinity | + | d:lockdiscovery/d:activelock/d:timeout | Second-3600 | + | d:lockdiscovery/d:activelock/oc:ownername | Brian Murphy | + Examples: + | role | dav-path | + | manager | /remote.php/dav/spaces/<> | + | editor | /dav/spaces/<> | + + + Scenario: viewer cannot lock a file in the project space + Given the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And using spaces DAV path + And user "Alice" has created a space "Project" with the default quota using the GraphApi + And user "Alice" has uploaded a file inside space "Project" with content "some content" to "textfile.txt" + And we save it into "FILEID" + And user "Alice" has shared a space "Project" with settings: + | shareWith | Brian | + | role | viewer | + When user "Brian" locks file "textfile.txt" inside the space "Project" using the WebDAV API setting the following properties + | lockscope | exclusive | + Then the HTTP status code should be "403" + When user "Brian" locks file using file-id path "/dav/spaces/<>" using the WebDAV API setting the following properties + | lockscope | exclusive | + Then the HTTP status code should be "403" + + + Scenario Outline: locking a file in the shares + Given using DAV path + And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" + When user "Alice" creates a share inside of space "Alice Hansen" with settings: + | path | textfile.txt | + | shareWith | Brian | + | role | editor | + When user "Brian" locks file "/Shares/textfile.txt" using the WebDAV API setting the following properties + | lockscope | exclusive | + Then the HTTP status code should be "200" + When user "Alice" sends PROPFIND request from the space "Alice Hansen" to the resource "textfile.txt" using the WebDAV API + Then the HTTP status code should be "207" + And the "PROPFIND" response to user "Alice" should contain a space "Alice Hansen" with these key and value pairs: + | key | value | + | d:lockdiscovery/d:activelock/d:lockscope/d:exclusive | | + | d:lockdiscovery/d:activelock/oc:ownername | Brian Murphy | + Examples: + | dav-path-version | + | old | + | new | + | spaces | + + + Scenario Outline: locking a file in the shares using file-id + And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" + And we save it into "FILEID" + When user "Alice" creates a share inside of space "Alice Hansen" with settings: + | path | textfile.txt | + | shareWith | Brian | + | role | editor | + When user "Brian" locks file using file-id path "" using the WebDAV API setting the following properties + | lockscope | exclusive | + | timeout | Second-3600 | + Then the HTTP status code should be "200" + When user "Alice" sends PROPFIND request from the space "Alice Hansen" to the resource "textfile.txt" using the WebDAV API + Then the HTTP status code should be "207" + And the "PROPFIND" response to user "Alice" should contain a space "Alice Hansen" with these key and value pairs: + | key | value | + | d:lockdiscovery/d:activelock/d:lockscope/d:exclusive | | + | d:lockdiscovery/d:activelock/oc:ownername | Brian Murphy | + Examples: + | dav-path | + | /remote.php/dav/spaces/<> | + | /dav/spaces/<> | + + + Scenario: viewer cannot lock a file in the shares using file-id + And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" + And we save it into "FILEID" + When user "Alice" creates a share inside of space "Alice Hansen" with settings: + | path | textfile.txt | + | shareWith | Brian | + | role | viewer | + When user "Brian" locks file using file-id path "" using the WebDAV API setting the following properties + | lockscope | exclusive | + Then the HTTP status code should be "403" + \ No newline at end of file diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php index 232578d8c44..e2ef6d259c1 100644 --- a/tests/acceptance/features/bootstrap/SpacesContext.php +++ b/tests/acceptance/features/bootstrap/SpacesContext.php @@ -3476,7 +3476,7 @@ public function searchResultShouldContainSpace(string $user, string $spaceName): */ public function userSendsPropfindRequestToSpace(string $user, string $spaceName, ?string $resource = ""): void { $this->setSpaceIDByName($user, $spaceName); - $properties = ['oc:permissions','oc:file-parent','oc:fileid','oc:share-types','oc:privatelink','d:resourcetype','oc:size','oc:name','d:getcontenttype', 'oc:tags']; + $properties = ['oc:permissions','oc:file-parent','oc:fileid','oc:share-types','oc:privatelink','d:resourcetype','oc:size','oc:name','d:getcontenttype','oc:tags','d:lockdiscovery','d:activelock']; $this->featureContext->setResponse( WebDavHelper::propfind( $this->featureContext->getBaseUrl(), @@ -3510,6 +3510,7 @@ public function theResponseShouldContainSpace(string $method, string $space, Tab /** * @Then /^the "([^"]*)" response to user "([^"]*)" should contain a mountpoint "([^"]*)" with these key and value pairs:$/ + * @Then /^the "([^"]*)" response to user "([^"]*)" should contain a space "([^"]*)" with these key and value pairs:$/ * * @param string $method # method should be either PROPFIND or REPORT * @param string $user @@ -3577,6 +3578,18 @@ public function theResponseShouldContain(string $method, string $user, string $s $actualTags = \sort($actualTags); Assert::assertEquals($expectedTags, $actualTags, "wrong $findItem in the response"); break; + case "d:lockdiscovery/d:activelock/d:timeout": + if ($value === "Infinity") { + Assert::assertEquals($value, $responseValue, "wrong $findItem in the response"); + } else { + // some time may be required between a lock and propfind request. + $responseValue = explode('-', $responseValue); + $responseValue = \intval($responseValue[1]); + $value = explode('-', $value); + $value = \intval($value[1]); + Assert::assertTrue($responseValue >= ($value - 3)); + } + break; default: Assert::assertEquals($value, $responseValue, "wrong $findItem in the response"); break; diff --git a/tests/acceptance/features/bootstrap/WebDavLockingContext.php b/tests/acceptance/features/bootstrap/WebDavLockingContext.php index b79d8c56d20..8330bd52d3a 100644 --- a/tests/acceptance/features/bootstrap/WebDavLockingContext.php +++ b/tests/acceptance/features/bootstrap/WebDavLockingContext.php @@ -39,6 +39,7 @@ class WebDavLockingContext implements Context { private FeatureContext $featureContext; private PublicWebDavContext $publicWebDavContext; + private SpacesContext $spacesContext; /** * @@ -76,10 +77,12 @@ private function lockFile( = "" . " "; $headers = []; - $this->featureContext->verifyTableNodeRows($properties, [], ['lockscope', 'depth', 'timeout']); + // depth is only 0 or infinity. We don't need to set it more, as there is no lock for the folder + $this->featureContext->verifyTableNodeRows($properties, [], ['lockscope', 'timeout']); $propertiesRows = $properties->getRowsHash(); + foreach ($propertiesRows as $property => $value) { - if ($property === "depth" || $property === "timeout") { + if ($property === "timeout") { //properties that are set in the header not in the xml $headers[$property] = $value; } else { @@ -113,7 +116,121 @@ private function lockFile( } /** - * @When user :user locks file/folder :file using the WebDAV API setting the following properties + * + * @param string $user + * @param string $file + * @param string $space + * @param TableNode $properties table with no heading with | property | value | + * @param boolean $expectToSucceed + * + * @return void + */ + private function lockFileInProjectSpace( + string $user, + string $file, + string $space, + TableNode $properties, + bool $expectToSucceed = true + ):ResponseInterface { + $spaceId = $this->spacesContext->getSpaceIdByName($user, $space); + $fullUrl = $this->featureContext->getBaseUrl() . '/dav/spaces/' . $spaceId . '/' . $file; + $body + = "" . + " "; + $headers = []; + // depth is only 0 or infinity. We don't need to set it more, as there is no lock for the folder + $this->featureContext->verifyTableNodeRows($properties, [], ['lockscope', 'timeout']); + $propertiesRows = $properties->getRowsHash(); + + foreach ($propertiesRows as $property => $value) { + if ($property === "timeout") { + //properties that are set in the header not in the xml + $headers[$property] = $value; + } else { + $body .= ""; + } + } + $body .= ""; + + $response = HttpRequestHelper::sendRequest( + $fullUrl, + $this->featureContext->getStepLineRef(), + "LOCK", + $this->featureContext->getActualUsername($user), + $this->featureContext->getPasswordForUser($user), + $headers, + $body + ); + $responseXml = $this->featureContext->getResponseXml($response, __METHOD__); + $xmlPart = $responseXml->xpath("//d:locktoken/d:href"); + if (isset($xmlPart[0])) { + $this->tokenOfLastLock[$user][$file] = (string) $xmlPart[0]; + } else { + if ($expectToSucceed === true) { + Assert::fail("could not find lock token after trying to lock '$file'"); + } + } + return $response; + } + + /** + * + * @param string $user + * @param string $filePath + * @param TableNode $properties table with no heading with | property | value | + * @param boolean $expectToSucceed + * + * @return void + */ + private function lockFileUsingFileId( + string $user, + string $filePath, + TableNode $properties, + bool $expectToSucceed = true + ):ResponseInterface { + $fullUrl = $this->featureContext->getBaseUrl() . $filePath; + $body + = "" . + " "; + $headers = []; + // depth is only 0 or infinity. We don't need to set it more, as there is no lock for the folder + $this->featureContext->verifyTableNodeRows($properties, [], ['lockscope', 'timeout']); + $propertiesRows = $properties->getRowsHash(); + + foreach ($propertiesRows as $property => $value) { + if ($property === "timeout") { + //properties that are set in the header not in the xml + $headers[$property] = $value; + } else { + $body .= ""; + } + } + $body .= ""; + + $response = HttpRequestHelper::sendRequest( + $fullUrl, + $this->featureContext->getStepLineRef(), + "LOCK", + $this->featureContext->getActualUsername($user), + $this->featureContext->getPasswordForUser($user), + $headers, + $body + ); + $responseXml = $this->featureContext->getResponseXml($response, __METHOD__); + $xmlPart = $responseXml->xpath("//d:locktoken/d:href"); + if (isset($xmlPart[0])) { + $this->tokenOfLastLock[$user][$filePath] = (string) $xmlPart[0]; + } else { + if ($expectToSucceed === true) { + Assert::fail("could not find lock token after trying to lock '$filePath'"); + } + } + return $response; + } + + /** + * @When user :user locks file :file using the WebDAV API setting the following properties + * @When user :user tries to lock file :file using the WebDAV API setting the following properties * * @param string $user * @param string $file @@ -127,7 +244,36 @@ public function lockFileUsingWebDavAPI(string $user, string $file, TableNode $pr } /** - * @Given user :user has locked file/folder :file setting the following properties + * @When user :user locks file :file inside the space :space using the WebDAV API setting the following properties + * + * @param string $user + * @param string $file + * @param string $space + * @param TableNode $properties table with no heading with | property | value | + * + * @return void + */ + public function lockFileInProjectSpaceUsingWebDavAPI(string $user, string $file, string $space, TableNode $properties) { + $response = $this->lockFileInProjectSpace($user, $file, $space, $properties, false, false); + $this->featureContext->setResponse($response); + } + + /** + * @When user :user locks file using file-id path :path using the WebDAV API setting the following properties + * + * @param string $user + * @param string $filePath + * @param TableNode $properties table with no heading with | property | value | + * + * @return void + */ + public function lockFileUsingFileIdUsingWebDavAPI(string $user, string $filePath, TableNode $properties) { + $response = $this->lockFileUsingFileId($user, $filePath, $properties, false, false); + $this->featureContext->setResponse($response); + } + + /** + * @Given user :user has locked file :file setting the following properties * * @param string $user * @param string $file @@ -221,7 +367,7 @@ public function publicLocksFileLastSharedFolder( } /** - * @When user :user unlocks the last created lock of file/folder :file using the WebDAV API + * @When user :user unlocks the last created lock of file :file using the WebDAV API * * @param string $user * @param string $file @@ -239,7 +385,7 @@ public function unlockLastLockUsingWebDavAPI(string $user, string $file) { } /** - * @When user :user unlocks file/folder :itemToUnlock with the last created lock of file/folder :itemToUseLockOf using the WebDAV API + * @When user :user unlocks file :itemToUnlock with the last created lock of file :itemToUseLockOf using the WebDAV API * * @param string $user * @param string $itemToUnlock @@ -262,7 +408,7 @@ public function unlockItemWithLastLockOfOtherItemUsingWebDavAPI( } /** - * @When user :user unlocks file/folder :itemToUnlock with the last created public lock of file/folder :itemToUseLockOf using the WebDAV API + * @When user :user unlocks file :itemToUnlock with the last created public lock of file :itemToUseLockOf using the WebDAV API * * @param string $user * @param string $itemToUnlock @@ -327,7 +473,7 @@ private function countLockOfResources( } /** - * @Given user :user has unlocked file/folder :itemToUnlock with the last created lock of file/folder :itemToUseLockOf of user :lockOwner using the WebDAV API + * @Given user :user has unlocked file :itemToUnlock with the last created lock of file :itemToUseLockOf of user :lockOwner using the WebDAV API * * @param string $user * @param string $itemToUnlock @@ -409,7 +555,7 @@ public function unlockItemWithLastLockOfUserAndItemUsingWebDavAPI( } /** - * @When user :user unlocks file/folder :itemToUnlock with the last created lock of file/folder :itemToUseLockOf of user :lockOwner using the WebDAV API + * @When user :user unlocks file :itemToUnlock with the last created lock of file :itemToUseLockOf of user :lockOwner using the WebDAV API * * @param string $user * @param string $itemToUnlock @@ -434,7 +580,7 @@ public function userUnlocksItemWithLastLockOfUserAndItemUsingWebDavAPI( } /** - * @When the public unlocks file/folder :itemToUnlock with the last created lock of file/folder :itemToUseLockOf of user :lockOwner using the WebDAV API + * @When the public unlocks file :itemToUnlock with the last created lock of file :itemToUseLockOf of user :lockOwner using the WebDAV API * * @param string $itemToUnlock * @param string $lockOwner @@ -459,7 +605,7 @@ public function unlockItemAsPublicWithLastLockOfUserAndItemUsingWebDavAPI( } /** - * @When the public unlocks file/folder :itemToUnlock using the WebDAV API + * @When the public unlocks file :itemToUnlock using the WebDAV API * * @param string $itemToUnlock * @@ -657,7 +803,7 @@ public function publicUploadFileSendingLockTokenOfPublic( } /** - * @Then :count locks should be reported for file/folder :file of user :user by the WebDAV API + * @Then :count locks should be reported for file :file of user :user by the WebDAV API * * @param int $count * @param string $file @@ -675,57 +821,6 @@ public function numberOfLockShouldBeReported(int $count, string $file, string $u ); } - /** - * @Then group :expectedGroup should exist as a lock breaker group - * - * @param string $expectedGroup - * - * @return void - * - * @throws Exception - */ - public function groupShouldExistAsLockBreakerGroups(string $expectedGroup) { - $baseUrl = $this->featureContext->getBaseUrl(); - $admin = $this->featureContext->getAdminUsername(); - $password = $this->featureContext->getAdminPassword(); - $ocsApiVersion = $this->featureContext->getOcsApiVersion(); - - $response = OcsApiHelper::sendRequest( - $baseUrl, - $admin, - $password, - 'GET', - "/apps/testing/api/v1/app/core/lock-breaker-groups", - $this->featureContext->getStepLineRef(), - (string) $ocsApiVersion - ); - - $responseXml = HttpRequestHelper::getResponseXml($response, __METHOD__)->data->element; - $lockbreakergroup = trim(\json_decode(\json_encode($responseXml), true)['value'], '\'[]"'); - $actualgroup = explode("\",\"", $lockbreakergroup); - if (!\in_array($expectedGroup, $actualgroup)) { - Assert::fail("could not find group '$expectedGroup' in lock breakers group"); - } - } - - /** - * @Then following groups should exist as lock breaker groups - * - * @param TableNode $table - * - * @return void - * - * @throws Exception - */ - public function followingGroupShouldExistAsLockBreakerGroups(TableNode $table) { - $this->featureContext->verifyTableNodeColumns($table, ["groups"]); - $paths = $table->getHash(); - - foreach ($paths as $group) { - $this->groupShouldExistAsLockBreakerGroups($group["groups"]); - } - } - /** * This will run before EVERY scenario. * It will set the properties for this object. @@ -742,5 +837,6 @@ public function before(BeforeScenarioScope $scope) { // Get all the contexts you need in this context $this->featureContext = $environment->getContext('FeatureContext'); $this->publicWebDavContext = $environment->getContext('PublicWebDavContext'); + $this->spacesContext = $environment->getContext('SpacesContext'); } } From f0d85e6dcf8976a6155a106c3c1a7ea69bdeb8cc Mon Sep 17 00:00:00 2001 From: Viktor Scharf Date: Fri, 27 Oct 2023 11:47:22 +0200 Subject: [PATCH 2/3] fix after review --- .../features/apiSpaces/lockFiles.feature | 24 +++--- .../bootstrap/WebDavLockingContext.php | 83 ++++--------------- 2 files changed, 26 insertions(+), 81 deletions(-) diff --git a/tests/acceptance/features/apiSpaces/lockFiles.feature b/tests/acceptance/features/apiSpaces/lockFiles.feature index c742899a0d9..fdc46f98f20 100644 --- a/tests/acceptance/features/apiSpaces/lockFiles.feature +++ b/tests/acceptance/features/apiSpaces/lockFiles.feature @@ -9,7 +9,7 @@ Feature: lock files | Brian | - Scenario Outline: locking a file + Scenario Outline: lock a file Given using DAV path And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" When user "Alice" locks file "textfile.txt" using the WebDAV API setting the following properties @@ -30,7 +30,7 @@ Feature: lock files | spaces | - Scenario Outline: locking a file with a set timeout + Scenario Outline: lock a file with a timeout Given using DAV path And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" When user "Alice" locks file "textfile.txt" using the WebDAV API setting the following properties @@ -52,7 +52,7 @@ Feature: lock files | spaces | - Scenario Outline: locking a file by file-id + Scenario Outline: lock a file using file-id Given user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" And we save it into "FILEID" When user "Alice" locks file using file-id path "" using the WebDAV API setting the following properties @@ -88,7 +88,7 @@ Feature: lock files | spaces | - Scenario Outline: locking a file in the project space + Scenario Outline: lock a file in the project space Given the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API And using spaces DAV path And user "Alice" has created a space "Project" with the default quota using the GraphApi @@ -114,7 +114,7 @@ Feature: lock files | editor | - Scenario Outline: locking a file in the project space by file-id + Scenario Outline: lock a file in the project space using file-id Given the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API And using spaces DAV path And user "Alice" has created a space "Project" with the default quota using the GraphApi @@ -158,10 +158,10 @@ Feature: lock files Then the HTTP status code should be "403" - Scenario Outline: locking a file in the shares + Scenario Outline: lock a file in the shares Given using DAV path And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" - When user "Alice" creates a share inside of space "Alice Hansen" with settings: + And user "Alice" has created a share inside of space "Alice Hansen" with settings: | path | textfile.txt | | shareWith | Brian | | role | editor | @@ -181,10 +181,10 @@ Feature: lock files | spaces | - Scenario Outline: locking a file in the shares using file-id - And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" + Scenario Outline: lock a file in the shares using file-id + Given user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" And we save it into "FILEID" - When user "Alice" creates a share inside of space "Alice Hansen" with settings: + And user "Alice" has created a share inside of space "Alice Hansen" with settings: | path | textfile.txt | | shareWith | Brian | | role | editor | @@ -205,9 +205,9 @@ Feature: lock files Scenario: viewer cannot lock a file in the shares using file-id - And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" + Given user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "textfile.txt" And we save it into "FILEID" - When user "Alice" creates a share inside of space "Alice Hansen" with settings: + And user "Alice" has created a share inside of space "Alice Hansen" with settings: | path | textfile.txt | | shareWith | Brian | | role | viewer | diff --git a/tests/acceptance/features/bootstrap/WebDavLockingContext.php b/tests/acceptance/features/bootstrap/WebDavLockingContext.php index 8330bd52d3a..ec4d00922ee 100644 --- a/tests/acceptance/features/bootstrap/WebDavLockingContext.php +++ b/tests/acceptance/features/bootstrap/WebDavLockingContext.php @@ -23,13 +23,12 @@ use Behat\Behat\Context\Context; use Behat\Behat\Hook\Scope\BeforeScenarioScope; use Behat\Gherkin\Node\TableNode; -use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Exception\GuzzleException; use PHPUnit\Framework\Assert; use TestHelpers\HttpRequestHelper; -use TestHelpers\OcsApiHelper; use TestHelpers\WebDavHelper; use Psr\Http\Message\ResponseInterface; +use TestHelpers\OcisHelper; require_once 'bootstrap.php'; @@ -118,77 +117,18 @@ private function lockFile( /** * * @param string $user - * @param string $file - * @param string $space - * @param TableNode $properties table with no heading with | property | value | - * @param boolean $expectToSucceed - * - * @return void - */ - private function lockFileInProjectSpace( - string $user, - string $file, - string $space, - TableNode $properties, - bool $expectToSucceed = true - ):ResponseInterface { - $spaceId = $this->spacesContext->getSpaceIdByName($user, $space); - $fullUrl = $this->featureContext->getBaseUrl() . '/dav/spaces/' . $spaceId . '/' . $file; - $body - = "" . - " "; - $headers = []; - // depth is only 0 or infinity. We don't need to set it more, as there is no lock for the folder - $this->featureContext->verifyTableNodeRows($properties, [], ['lockscope', 'timeout']); - $propertiesRows = $properties->getRowsHash(); - - foreach ($propertiesRows as $property => $value) { - if ($property === "timeout") { - //properties that are set in the header not in the xml - $headers[$property] = $value; - } else { - $body .= ""; - } - } - $body .= ""; - - $response = HttpRequestHelper::sendRequest( - $fullUrl, - $this->featureContext->getStepLineRef(), - "LOCK", - $this->featureContext->getActualUsername($user), - $this->featureContext->getPasswordForUser($user), - $headers, - $body - ); - $responseXml = $this->featureContext->getResponseXml($response, __METHOD__); - $xmlPart = $responseXml->xpath("//d:locktoken/d:href"); - if (isset($xmlPart[0])) { - $this->tokenOfLastLock[$user][$file] = (string) $xmlPart[0]; - } else { - if ($expectToSucceed === true) { - Assert::fail("could not find lock token after trying to lock '$file'"); - } - } - return $response; - } - - /** - * - * @param string $user - * @param string $filePath + * @param string $fullUrl * @param TableNode $properties table with no heading with | property | value | * @param boolean $expectToSucceed * * @return void */ - private function lockFileUsingFileId( + private function lockFileInSpace( string $user, - string $filePath, + string $fullUrl, TableNode $properties, bool $expectToSucceed = true ):ResponseInterface { - $fullUrl = $this->featureContext->getBaseUrl() . $filePath; $body = "" . " "; @@ -219,10 +159,10 @@ private function lockFileUsingFileId( $responseXml = $this->featureContext->getResponseXml($response, __METHOD__); $xmlPart = $responseXml->xpath("//d:locktoken/d:href"); if (isset($xmlPart[0])) { - $this->tokenOfLastLock[$user][$filePath] = (string) $xmlPart[0]; + $this->tokenOfLastLock[$user] = (string) $xmlPart[0]; } else { if ($expectToSucceed === true) { - Assert::fail("could not find lock token after trying to lock '$filePath'"); + Assert::fail("could not find lock token after the last lock"); } } return $response; @@ -254,7 +194,9 @@ public function lockFileUsingWebDavAPI(string $user, string $file, TableNode $pr * @return void */ public function lockFileInProjectSpaceUsingWebDavAPI(string $user, string $file, string $space, TableNode $properties) { - $response = $this->lockFileInProjectSpace($user, $file, $space, $properties, false, false); + $spaceId = $this->spacesContext->getSpaceIdByName($user, $space); + $fullUrl = $this->featureContext->getBaseUrl() . '/dav/spaces/' . $spaceId . '/' . $file; + $response = $this->lockFileInSpace($user, $fullUrl, $properties, false, false); $this->featureContext->setResponse($response); } @@ -268,7 +210,8 @@ public function lockFileInProjectSpaceUsingWebDavAPI(string $user, string $file, * @return void */ public function lockFileUsingFileIdUsingWebDavAPI(string $user, string $filePath, TableNode $properties) { - $response = $this->lockFileUsingFileId($user, $filePath, $properties, false, false); + $fullUrl = $this->featureContext->getBaseUrl() . $filePath; + $response = $this->lockFileInSpace($user, $fullUrl, $properties, false, false); $this->featureContext->setResponse($response); } @@ -837,6 +780,8 @@ public function before(BeforeScenarioScope $scope) { // Get all the contexts you need in this context $this->featureContext = $environment->getContext('FeatureContext'); $this->publicWebDavContext = $environment->getContext('PublicWebDavContext'); - $this->spacesContext = $environment->getContext('SpacesContext'); + if (!OcisHelper::isTestingOnReva()) { + $this->spacesContext = $environment->getContext('SpacesContext'); + } } } From b1b27b3bf08ba13e62c0692f051bad3120259020 Mon Sep 17 00:00:00 2001 From: Viktor Scharf Date: Fri, 27 Oct 2023 13:43:56 +0200 Subject: [PATCH 3/3] Update WebDavLockingContext.php --- tests/acceptance/features/bootstrap/WebDavLockingContext.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/features/bootstrap/WebDavLockingContext.php b/tests/acceptance/features/bootstrap/WebDavLockingContext.php index ec4d00922ee..fc4b7fca559 100644 --- a/tests/acceptance/features/bootstrap/WebDavLockingContext.php +++ b/tests/acceptance/features/bootstrap/WebDavLockingContext.php @@ -196,7 +196,7 @@ public function lockFileUsingWebDavAPI(string $user, string $file, TableNode $pr public function lockFileInProjectSpaceUsingWebDavAPI(string $user, string $file, string $space, TableNode $properties) { $spaceId = $this->spacesContext->getSpaceIdByName($user, $space); $fullUrl = $this->featureContext->getBaseUrl() . '/dav/spaces/' . $spaceId . '/' . $file; - $response = $this->lockFileInSpace($user, $fullUrl, $properties, false, false); + $response = $this->lockFileInSpace($user, $fullUrl, $properties); $this->featureContext->setResponse($response); } @@ -211,7 +211,7 @@ public function lockFileInProjectSpaceUsingWebDavAPI(string $user, string $file, */ public function lockFileUsingFileIdUsingWebDavAPI(string $user, string $filePath, TableNode $properties) { $fullUrl = $this->featureContext->getBaseUrl() . $filePath; - $response = $this->lockFileInSpace($user, $fullUrl, $properties, false, false); + $response = $this->lockFileInSpace($user, $fullUrl, $properties); $this->featureContext->setResponse($response); }