diff --git a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md index 591c12dcf5..49ce60e034 100644 --- a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md @@ -21,3 +21,9 @@ #### [Overwriting a file in the space within the allowed quota does not work](https://github.com/owncloud/ocis/issues/2829) - [apiSpaces/quota.feature:56](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/quota.feature#L56) +#### [Viewer has the possibility to delete the space](https://github.com/owncloud/ocis/issues/3031) +- [apiSpaces/removeSpaces.feature:130](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/removeSpaces.feature#L130) +- [apiSpaces/removeSpaces.feature:140](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/removeSpaces.feature#L140) +- [apiSpaces/removeSpaces.feature:150](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/removeSpaces.feature#L150) +- [apiSpaces/removeSpaces.feature:160](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/removeSpaces.feature#L160) +- [apiSpaces/removeSpaces.feature:171](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/removeSpaces.feature#L171) diff --git a/tests/acceptance/features/apiSpaces/removeSpaces.feature b/tests/acceptance/features/apiSpaces/removeSpaces.feature new file mode 100644 index 0000000000..b9e4d39b62 --- /dev/null +++ b/tests/acceptance/features/apiSpaces/removeSpaces.feature @@ -0,0 +1,181 @@ +@api @skipOnOcV10 +Feature: Remove files, folder and spaces + As a user + I want to be able to remove files, folders and space itself + Users with the editor role can also remove objects + Users with the viewer role cannot remove objects + + 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 user "Alice" has been created with default attributes and without skeleton files + And user "Brian" has been created with default attributes and without skeleton files + And the administrator has given "Alice" the role "Admin" using the settings api + +# owner of space + + Scenario: A owner can delete a folder with some subfolders in a Space via the webDav API + Given user "Alice" has created a space "Owner deletes folder" of type "project" with quota "10" + And user "Alice" has created a folder "folderForDeleting/sub1/sub2" in space "Owner deletes folder" + When user "Alice" removes the object "folderForDeleting" from space "Owner deletes folder" + Then the HTTP status code should be "200" + And for user "Alice" the space "Owner deletes folder" should not contain these entries: + | folderForDeleting | + + + Scenario: A owner can delete a subfolder in a Space via the webDav API + Given user "Alice" has created a space "Owner deletes subfolder" of type "project" with quota "10" + And user "Alice" has created a subfolder "folder/subFolderForDeleting" in space "Owner deletes subfolder" + When user "Alice" removes the object "folder/subFolderForDeleting" from space "Owner deletes subfolder" + Then the HTTP status code should be "200" + And for user "Alice" the space "Owner deletes subfolder" should contain these entries: + | folder | + And for user "Alice" folder "folder/" of the space "Owner deletes subfolder" should not contain these entries: + | subFolderForDeleting | + + + Scenario: A owner can delete a file in a Space via the webDav API + Given user "Alice" has created a space "Owner deletes file" of type "project" with quota "20" + And user "Alice" has uploaded a file inside space "Owner deletes file" with content "some content" to "text.txt" + When user "Alice" removes the object "text.txt" from space "Owner deletes file" + Then the HTTP status code should be "200" + And for user "Alice" the space "Owner deletes file" should not contain these entries: + | text.txt | + When user "Alice" lists all available spaces via the GraphApi + Then the json responded should contain a space "Owner deletes file" with these key and value pairs: + | key | value | + | name | Owner deletes file | + | quota@@@used | 0 | + + + Scenario: A owner can delete a empty Space via the webDav API + Given user "Alice" has created a space "Owner deletes empty space" of type "project" with quota "20" + When user "Alice" removes a space "Owner deletes empty space" + Then the HTTP status code should be "200" + When user "Alice" lists all available spaces via the GraphApi + Then the json responded should not contain a space with name "Owner deletes empty space" + + + Scenario: A owner can delete a Space containing folders and files via the webDav API + Given user "Alice" has created a space "Owner deletes space" of type "project" with quota "20" + And user "Alice" has created a folder "folderForDeleting/sub1/sub2" in space "Owner deletes space" + And user "Alice" has uploaded a file inside space "Owner deletes space" with content "some content" to "folderForDeleting/sub1/sub2/text.txt" + When user "Alice" removes a space "Owner deletes space" + Then the HTTP status code should be "200" + When user "Alice" lists all available spaces via the GraphApi + Then the json responded should not contain a space with name "Owner deletes space" + +# editor role + + Scenario: A editor can delete a folder with some subfolders in a Space via the webDav API + Given user "Alice" has created a space "Editor deletes folder" of type "project" with quota "10" + And user "Alice" has created a folder "folderForDeleting/sub1/sub2" in space "Editor deletes folder" + And user "Alice" has shared a space "Editor deletes folder" to user "Brian" with role "editor" + When user "Brian" removes the object "folderForDeleting" from space "Editor deletes folder" + Then the HTTP status code should be "200" + And for user "Brian" the space "Editor deletes folder" should not contain these entries: + | folderForDeleting | + + + Scenario: A editor can delete a subfolder in a Space via the webDav API + Given user "Alice" has created a space "Editor deletes subfolder" of type "project" with quota "10" + And user "Alice" has created a subfolder "folder/subFolderForDeleting" in space "Editor deletes subfolder" + And user "Alice" has shared a space "Editor deletes subfolder" to user "Brian" with role "editor" + When user "Brian" removes the object "folder/subFolderForDeleting" from space "Editor deletes subfolder" + Then the HTTP status code should be "200" + And for user "Brian" the space "Editor deletes subfolder" should contain these entries: + | folder | + And for user "Brian" folder "folder/" of the space "Editor deletes subfolder" should not contain these entries: + | subFolderForDeleting | + + + Scenario: A editor can delete a file in a Space via the webDav API + Given user "Alice" has created a space "Editor deletes file" of type "project" with quota "20" + And user "Alice" has uploaded a file inside space "Editor deletes file" with content "some content" to "text.txt" + And user "Alice" has shared a space "Editor deletes file" to user "Brian" with role "editor" + When user "Brian" removes the object "text.txt" from space "Editor deletes file" + Then the HTTP status code should be "200" + And for user "Brian" the space "Editor deletes file" should not contain these entries: + | text.txt | + When user "Brian" lists all available spaces via the GraphApi + Then the json responded should contain a space "Editor deletes file" with these key and value pairs: + | key | value | + | name | Editor deletes file | + | quota@@@used | 0 | + + + Scenario: A editor can delete a empty Space via the webDav API + Given user "Alice" has created a space "Editor deletes empty space" of type "project" with quota "20" + And user "Alice" has shared a space "Editor deletes empty space" to user "Brian" with role "editor" + When user "Brian" removes a space "Editor deletes empty space" + Then the HTTP status code should be "200" + When user "Brian" lists all available spaces via the GraphApi + Then the json responded should not contain a space with name "Editor deletes empty space" + + + Scenario: A editor can delete a Space containing folders and files via the webDav API + Given user "Alice" has created a space "Editor deletes space" of type "project" with quota "20" + And user "Alice" has created a folder "folderForDeleting/sub1/sub2" in space "Editor deletes space" + And user "Alice" has uploaded a file inside space "Editor deletes space" with content "some content" to "folderForDeleting/sub1/sub2/text.txt" + And user "Alice" has shared a space "Editor deletes space" to user "Brian" with role "editor" + When user "Brian" removes a space "Editor deletes space" + Then the HTTP status code should be "200" + When user "Brian" lists all available spaces via the GraphApi + Then the json responded should not contain a space with name "Editor deletes space" + + +# viewer role + + Scenario: A viewer cannot delete a folder with some subfolders in a Space via the webDav API + Given user "Alice" has created a space "Viewer deletes folder" of type "project" with quota "10" + And user "Alice" has created a folder "folderForDeleting/sub1/sub2" in space "Viewer deletes folder" + And user "Alice" has shared a space "Viewer deletes folder" to user "Brian" with role "viewer" + When user "Brian" removes the object "folderForDeleting" from space "Viewer deletes folder" + Then the HTTP status code should be "403" + And for user "Brian" the space "Viewer deletes folder" should contain these entries: + | folderForDeleting | + + + Scenario: A viewer cannot delete a subfolder in a Space via the webDav API + Given user "Alice" has created a space "Viewer deletes subfolder" of type "project" with quota "10" + And user "Alice" has created a subfolder "folder/subFolderForDeleting" in space "Viewer deletes subfolder" + And user "Alice" has shared a space "Viewer deletes subfolder" to user "Brian" with role "viewer" + When user "Brian" removes the object "folder/subFolderForDeleting" from space "Viewer deletes subfolder" + Then the HTTP status code should be "403" + And for user "Brian" folder "folder/" of the space "Viewer deletes subfolder" should contain these entries: + | subFolderForDeleting | + + + Scenario: A viewer cannot delete a file in a Space via the webDav API + Given user "Alice" has created a space "Viewer deletes file" of type "project" with quota "20" + And user "Alice" has uploaded a file inside space "Viewer deletes file" with content "some content" to "text.txt" + And user "Alice" has shared a space "Viewer deletes file" to user "Brian" with role "viewer" + When user "Brian" removes the object "text.txt" from space "Viewer deletes file" + Then the HTTP status code should be "403" + And for user "Brian" the space "Viewer deletes file" should contain these entries: + | text.txt | + + + Scenario: A viewer cannot delete a empty Space via the webDav API + Given user "Alice" has created a space "Viewer deletes empty space" of type "project" with quota "20" + And user "Alice" has shared a space "Viewer deletes empty space" to user "Brian" with role "viewer" + When user "Brian" removes a space "Viewer deletes empty space" + Then the HTTP status code should be "403" + When user "Brian" lists all available spaces via the GraphApi + Then the json responded should contain a space "Viewer deletes empty space" with these key and value pairs: + | key | value | + | name | Viewer deletes empty space | + + + Scenario: A viewer cannot delete a Space containing folders and files via the webDav API + Given user "Alice" has created a space "Viewer deletes space" of type "project" with quota "20" + And user "Alice" has created a folder "folderForDeleting/sub1/sub2" in space "Viewer deletes space" + And user "Alice" has uploaded a file inside space "Viewer deletes space" with content "some content" to "folderForDeleting/sub1/sub2/text.txt" + And user "Alice" has shared a space "Viewer deletes space" to user "Brian" with role "viewer" + When user "Brian" removes a space "Viewer deletes space" + Then the HTTP status code should be "403" + When user "Brian" lists all available spaces via the GraphApi + Then the json responded should contain a space "Viewer deletes space" with these key and value pairs: + | key | value | + | name | Viewer deletes space | diff --git a/tests/acceptance/features/apiSpaces/uploadSpaces.feature b/tests/acceptance/features/apiSpaces/uploadSpaces.feature index 638866a5bf..4e62cbb754 100644 --- a/tests/acceptance/features/apiSpaces/uploadSpaces.feature +++ b/tests/acceptance/features/apiSpaces/uploadSpaces.feature @@ -11,6 +11,7 @@ Feature: Upload files into a space And user "Bob" has been created with default attributes and without skeleton files And the administrator has given "Alice" the role "Admin" using the settings api + Scenario: A user can create a folder in a Space via the Graph API Given user "Alice" has created a space "Project Ceres" of type "project" with quota "2000" When user "Alice" creates a folder "mainFolder" in space "Project Ceres" using the WebDav Api @@ -18,6 +19,16 @@ Feature: Upload files into a space And for user "Alice" the space "Project Ceres" should contain these entries: | mainFolder | + + Scenario: A user can create a subfolders in a Space via the Graph API + Given user "Alice" has created a space "Subfolders in Project" of type "project" with quota "2000" + When user "Alice" creates a subfolder "mainFolder/subFolder1/subFolder2" in space "Subfolders in Project" using the WebDav Api + Then the HTTP status code should be "201" + And for user "Alice" the space "Subfolders in Project" should contain these entries: + | mainFolder | + And for user "Alice" folder "mainFolder/subFolder1/" of the space "Subfolders in Project" should contain these entries: + | subFolder2 | + Scenario: A user cannot create a folder in a Space if they do not have permission Given user "Alice" has created a space "Project Merkur" of type "project" with quota "2000" And user "Bob" creates a folder "forAlice" in space "Project Merkur" owned by the user "Alice" using the WebDav Api @@ -25,6 +36,7 @@ Feature: Upload files into a space And for user "Alice" the space "Project Merkur" should not contain these entries: | forAlice | + Scenario: A user can create a folder and upload a file to a Space Given user "Alice" has created a space "Project Moon" of type "project" with quota "2000" When user "Alice" creates a folder "NewFolder" in space "Project Moon" using the WebDav Api @@ -42,6 +54,7 @@ Feature: Upload files into a space And for user "Alice" the space "Project Pluto" should not contain these entries: | test.txt | + Scenario: A user can upload a file in a Space and see the remaining quota When user "Alice" creates a space "Project Saturn" of type "project" with quota "2000" using the GraphApi And the json responded should contain a space "Project Saturn" with these key and value pairs: @@ -65,6 +78,7 @@ Feature: Upload files into a space | quota@@@remaining| 1996 | | quota@@@used | 4 | + Scenario: A user with role editor can create a folder in shared Space via the Graph API Given user "Alice" has created a space "Editor can create folder" of type "project" with quota "2000" And user "Alice" has shared a space "Editor can create folder" to user "Bob" with role "editor" diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php index 153310be20..3e1b6af248 100644 --- a/tests/acceptance/features/bootstrap/SpacesContext.php +++ b/tests/acceptance/features/bootstrap/SpacesContext.php @@ -581,6 +581,7 @@ class SpacesContext implements Context { * * @param string $user * @param string $spaceName + * @param string $path * * @return void * @@ -588,7 +589,8 @@ class SpacesContext implements Context { */ public function theUserListsTheContentOfAPersonalSpaceRootUsingTheWebDAvApi( string $user, - string $spaceName + string $spaceName, + string $foldersPath = '' ): void { $space = $this->getSpaceByName($user, $spaceName); Assert::assertIsArray($space); @@ -596,7 +598,7 @@ class SpacesContext implements Context { Assert::assertNotEmpty($spaceWebDavUrl = $space["root"]["webDavUrl"]); $this->featureContext->setResponse( $this->sendPropfindRequestToUrl( - $spaceWebDavUrl, + $spaceWebDavUrl . '/' . $foldersPath, $user, $this->featureContext->getPasswordForUser($user), "", @@ -677,9 +679,41 @@ class SpacesContext implements Context { $user, $spaceName ); + $this->propfindResultShouldContainEntries( + $shouldOrNot, + $expectedFiles + ); + } + + /** + * @Then /^for user "([^"]*)" folder "([^"]*)" of the space "([^"]*)" should (not|)\s?contain these (?:files|entries):$/ + * + * @param string $user + * @param string $folderPath + * @param string $spaceName + * @param string $shouldOrNot (not|) + * @param TableNode $expectedFiles + * + * @return void + * + * @throws Exception|GuzzleException + */ + public function folderOfTheSpaceShouldContainEntries( + string $user, + string $folderPath, + string $spaceName, + string $shouldOrNot, + TableNode $expectedFiles + ): void { + $this->theUserListsTheContentOfAPersonalSpaceRootUsingTheWebDAvApi( + $user, + $spaceName, + $folderPath + ); $this->propfindResultShouldContainEntries( $shouldOrNot, $expectedFiles, + $folderPath ); } @@ -786,6 +820,7 @@ class SpacesContext implements Context { /** * @param string $shouldOrNot (not|) * @param TableNode $expectedFiles + * @param string $folderPath * * @return void * @@ -793,7 +828,8 @@ class SpacesContext implements Context { */ public function propfindResultShouldContainEntries( string $shouldOrNot, - TableNode $expectedFiles + TableNode $expectedFiles, + string $folderPath = '' ): void { $this->verifyTableNodeColumnsCount($expectedFiles, 1); $elementRows = $expectedFiles->getRows(); @@ -801,7 +837,8 @@ class SpacesContext implements Context { foreach ($elementRows as $expectedFile) { $fileFound = $this->findEntryFromPropfindResponse( - $expectedFile[0] + $expectedFile[0], + $folderPath ); if ($should) { Assert::assertNotEmpty( @@ -852,7 +889,8 @@ class SpacesContext implements Context { * boolean false if $entryNameToSearch is given and is not found */ public function findEntryFromPropfindResponse( - string $entryNameToSearch = null + string $entryNameToSearch = null, + string $folderPath = '' ): array { $spaceId = $this->getResponseSpaceId(); //if we are using that step the second time in a scenario e.g. 'But ... should not' @@ -870,7 +908,7 @@ class SpacesContext implements Context { // topWebDavPath should be something like /remote.php/webdav/ or // /remote.php/dav/files/alice/ - $topWebDavPath = "/" . "dav/spaces/" . $spaceId . "/"; + $topWebDavPath = "/" . "dav/spaces/" . $spaceId . "/" . $folderPath; Assert::assertIsArray( $this->responseXml, @@ -902,7 +940,7 @@ class SpacesContext implements Context { } /** - * @When /^user "([^"]*)" creates a folder "([^"]*)" in space "([^"]*)" using the WebDav Api$/ + * @When /^user "([^"]*)" creates a (?:folder|subfolder) "([^"]*)" in space "([^"]*)" using the WebDav Api$/ * * @param string $user * @param string $folder @@ -917,11 +955,16 @@ class SpacesContext implements Context { string $folder, string $spaceName ): void { - $this->theUserCreatesAFolderToAnotherOwnerSpaceUsingTheGraphApi($user, $folder, $spaceName); + $exploded = explode('/', $folder); + $path = ''; + for ($i = 0; $i < count($exploded); $i++) { + $path = $path . $exploded[$i] . '/'; + $this->theUserCreatesAFolderToAnotherOwnerSpaceUsingTheGraphApi($user, $path, $spaceName); + }; } /** - * @Given /^user "([^"]*)" has created a folder "([^"]*)" in space "([^"]*)"$/ + * @Given /^user "([^"]*)" has created a (?:folder|subfolder) "([^"]*)" in space "([^"]*)"$/ * * @param string $user * @param string $folder @@ -1331,4 +1374,42 @@ class SpacesContext implements Context { HttpRequestHelper::delete($fullUrl, "", $user, $this->featureContext->getPasswordForUser($user)); } + + /** + * @When /^user "([^"]*)" removes the object "([^"]*)" from space "([^"]*)"$/ + * + * @param string $user + * @param string $object + * @param string $spaceName + * + * @return void + * @throws GuzzleException + */ + public function sendRemoveObjectFromSpaceRequest( + string $user, + string $object, + string $spaceName + ): void { + $space = $this->getSpaceByName($user, $spaceName); + $spaceWebDavUrl = $space["root"]["webDavUrl"] . '/' . $object; + HttpRequestHelper::delete($spaceWebDavUrl, "", $user, $this->featureContext->getPasswordForUser($user)); + } + + /** + * @When /^user "([^"]*)" removes a space "([^"]*)"$/ + * + * @param string $user + * @param string $spaceName + * + * @return void + * @throws GuzzleException + */ + public function sendRemoveSpaceRequest( + string $user, + string $spaceName + ): void { + $space = $this->getSpaceByName($user, $spaceName); + $spaceWebDavUrl = $space["root"]["webDavUrl"]; + HttpRequestHelper::delete($spaceWebDavUrl, "", $user, $this->featureContext->getPasswordForUser($user)); + } }