diff options
Diffstat (limited to 'build')
-rw-r--r-- | build/integration/features/bootstrap/Sharing.php | 129 | ||||
-rw-r--r-- | build/integration/sharing_features/sharing-v1-part2.feature | 310 | ||||
-rw-r--r-- | build/integration/sharing_features/sharing-v1.feature | 4 |
3 files changed, 431 insertions, 12 deletions
diff --git a/build/integration/features/bootstrap/Sharing.php b/build/integration/features/bootstrap/Sharing.php index 4e62ea73c5d..42d2f03221f 100644 --- a/build/integration/features/bootstrap/Sharing.php +++ b/build/integration/features/bootstrap/Sharing.php @@ -25,6 +25,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ +use Behat\Gherkin\Node\TableNode; use GuzzleHttp\Client; use PHPUnit\Framework\Assert; use Psr\Http\Message\ResponseInterface; @@ -54,7 +55,7 @@ trait Sharing { /** * @Given /^as "([^"]*)" creating a share with$/ * @param string $user - * @param \Behat\Gherkin\Node\TableNode|null $body + * @param TableNode|null $body */ public function asCreatingAShareWith($user, $body) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares"; @@ -70,7 +71,7 @@ trait Sharing { $options['auth'] = [$user, $this->regularUser]; } - if ($body instanceof \Behat\Gherkin\Node\TableNode) { + if ($body instanceof TableNode) { $fd = $body->getRowsHash(); if (array_key_exists('expireDate', $fd)){ $dateModification = $fd['expireDate']; @@ -104,7 +105,7 @@ trait Sharing { /** * @When /^creating a share with$/ - * @param \Behat\Gherkin\Node\TableNode|null $body + * @param TableNode|null $body */ public function creatingShare($body) { $this->asCreatingAShareWith($this->currentUser, $body); @@ -187,7 +188,7 @@ trait Sharing { /** * @When /^Updating last share with$/ - * @param \Behat\Gherkin\Node\TableNode|null $body + * @param TableNode|null $body */ public function updatingLastShare($body) { $share_id = (string) $this->lastShareData->data[0]->id; @@ -204,7 +205,7 @@ trait Sharing { $options['auth'] = [$this->currentUser, $this->regularUser]; } - if ($body instanceof \Behat\Gherkin\Node\TableNode) { + if ($body instanceof TableNode) { $fd = $body->getRowsHash(); if (array_key_exists('expireDate', $fd)){ $dateModification = $fd['expireDate']; @@ -457,10 +458,10 @@ trait Sharing { /** * @Then /^Share fields of last share match with$/ - * @param \Behat\Gherkin\Node\TableNode|null $body + * @param TableNode|null $body */ public function checkShareFields($body){ - if ($body instanceof \Behat\Gherkin\Node\TableNode) { + if ($body instanceof TableNode) { $fd = $body->getRowsHash(); foreach($fd as $field => $value) { @@ -480,6 +481,114 @@ trait Sharing { } /** + * @Then the list of returned shares has :count shares + */ + public function theListOfReturnedSharesHasShares(int $count) { + $this->theHTTPStatusCodeShouldBe('200'); + $this->theOCSStatusCodeShouldBe('100'); + + $returnedShares = $this->getXmlResponse()->data[0]; + + Assert::assertEquals($count, count($returnedShares->element)); + } + + /** + * @Then share :count is returned with + * + * @param int $number + * @param TableNode $body + */ + public function shareXIsReturnedWith(int $number, TableNode $body) { + $this->theHTTPStatusCodeShouldBe('200'); + $this->theOCSStatusCodeShouldBe('100'); + + if (!($body instanceof TableNode)) { + return; + } + + $returnedShare = $this->getXmlResponse()->data[0]; + if ($returnedShare->element) { + $returnedShare = $returnedShare->element[$number]; + } + + $defaultExpectedFields = [ + 'id' => 'A_NUMBER', + 'permissions' => '19', + 'stime' => 'A_NUMBER', + 'parent' => '', + 'expiration' => '', + 'token' => '', + 'storage' => 'A_NUMBER', + 'item_source' => 'A_NUMBER', + 'file_source' => 'A_NUMBER', + 'file_parent' => 'A_NUMBER', + 'mail_send' => '0' + ]; + $expectedFields = array_merge($defaultExpectedFields, $body->getRowsHash()); + + if (!array_key_exists('uid_file_owner', $expectedFields) && + array_key_exists('uid_owner', $expectedFields)) { + $expectedFields['uid_file_owner'] = $expectedFields['uid_owner']; + } + if (!array_key_exists('displayname_file_owner', $expectedFields) && + array_key_exists('displayname_owner', $expectedFields)) { + $expectedFields['displayname_file_owner'] = $expectedFields['displayname_owner']; + } + + if (array_key_exists('share_type', $expectedFields) && + $expectedFields['share_type'] == 10 /* IShare::TYPE_ROOM */ && + array_key_exists('share_with', $expectedFields)) { + if ($expectedFields['share_with'] === 'private_conversation') { + $expectedFields['share_with'] = 'REGEXP /^private_conversation_[0-9a-f]{6}$/'; + } else { + $expectedFields['share_with'] = FeatureContext::getTokenForIdentifier($expectedFields['share_with']); + } + } + + foreach ($expectedFields as $field => $value) { + $this->assertFieldIsInReturnedShare($field, $value, $returnedShare); + } + } + + /** + * @return SimpleXMLElement + */ + private function getXmlResponse(): \SimpleXMLElement { + return simplexml_load_string($this->response->getBody()); + } + + /** + * @param string $field + * @param string $contentExpected + * @param \SimpleXMLElement $returnedShare + */ + private function assertFieldIsInReturnedShare(string $field, string $contentExpected, \SimpleXMLElement $returnedShare){ + if ($contentExpected === 'IGNORE') { + return; + } + + if (!array_key_exists($field, $returnedShare)) { + Assert::fail("$field was not found in response"); + } + + if ($field === 'expiration' && !empty($contentExpected)){ + $contentExpected = date('Y-m-d', strtotime($contentExpected)) . " 00:00:00"; + } + + if ($contentExpected === 'A_NUMBER') { + Assert::assertTrue(is_numeric((string)$returnedShare->$field), "Field '$field' is not a number: " . $returnedShare->$field); + } else if ($contentExpected === 'A_TOKEN') { + // A token is composed by 15 characters from + // ISecureRandom::CHAR_HUMAN_READABLE. + Assert::assertRegExp('/^[abcdefgijkmnopqrstwxyzABCDEFGHJKLMNPQRSTWXYZ23456789]{15}$/', (string)$returnedShare->$field, "Field '$field' is not a token"); + } else if (strpos($contentExpected, 'REGEXP ') === 0) { + Assert::assertRegExp(substr($contentExpected, strlen('REGEXP ')), (string)$returnedShare->$field, "Field '$field' does not match"); + } else { + Assert::assertEquals($contentExpected, (string)$returnedShare->$field, "Field '$field' does not match"); + } + } + + /** * @Then As :user remove all shares from the file named :fileName */ public function asRemoveAllSharesFromTheFileNamed($user, $fileName) { @@ -545,11 +654,11 @@ trait Sharing { /** * @When /^getting sharees for$/ - * @param \Behat\Gherkin\Node\TableNode $body + * @param TableNode $body */ public function whenGettingShareesFor($body) { $url = '/apps/files_sharing/api/v1/sharees'; - if ($body instanceof \Behat\Gherkin\Node\TableNode) { + if ($body instanceof TableNode) { $parameters = []; foreach ($body->getRowsHash() as $key => $value) { $parameters[] = $key . '=' . $value; @@ -566,7 +675,7 @@ trait Sharing { * @Then /^"([^"]*)" sharees returned (are|is empty)$/ * @param string $shareeType * @param string $isEmpty - * @param \Behat\Gherkin\Node\TableNode|null $shareesList + * @param TableNode|null $shareesList */ public function thenListOfSharees($shareeType, $isEmpty, $shareesList = null) { if ($isEmpty !== 'is empty') { diff --git a/build/integration/sharing_features/sharing-v1-part2.feature b/build/integration/sharing_features/sharing-v1-part2.feature index 3316f3d94ba..c3f2c8e915e 100644 --- a/build/integration/sharing_features/sharing-v1-part2.feature +++ b/build/integration/sharing_features/sharing-v1-part2.feature @@ -20,6 +20,69 @@ Feature: sharing And User "user2" should be included in the response And User "user3" should not be included in the response + Scenario: getting all shares of a file with a received share after revoking the resharing rights + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And file "textfile0.txt" of user "user1" is shared with user "user0" + And Updating last share with + | permissions | 1 | + And file "textfile0.txt" of user "user1" is shared with user "user2" + When As an "user0" + And sending "GET" to "/apps/files_sharing/api/v1/shares?reshares=true&path=/textfile0 (2).txt" + Then the list of returned shares has 1 shares + And share 0 is returned with + | share_type | 0 | + | uid_owner | user1 | + | displayname_owner | user1 | + | path | /textfile0 (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/textfile0 (2).txt | + | file_target | /textfile0.txt | + | share_with | user2 | + | share_with_displayname | user2 | + + Scenario: getting all shares of a file with a received share also reshared after revoking the resharing rights + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And user "user3" exists + And file "textfile0.txt" of user "user1" is shared with user "user0" + And save the last share data as "textfile0.txt from user1" + And file "textfile0 (2).txt" of user "user0" is shared with user "user3" + And restore the last share data from "textfile0.txt from user1" + And Updating last share with + | permissions | 1 | + And file "textfile0.txt" of user "user1" is shared with user "user2" + When As an "user0" + And sending "GET" to "/apps/files_sharing/api/v1/shares?reshares=true&path=/textfile0 (2).txt" + Then the list of returned shares has 2 shares + And share 0 is returned with + | share_type | 0 | + | uid_owner | user0 | + | displayname_owner | user0 | + | uid_file_owner | user1 | + | displayname_file_owner | user1 | + | path | /textfile0 (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/textfile0 (2).txt | + | file_target | /textfile0 (2).txt | + | share_with | user3 | + | share_with_displayname | user3 | + And share 1 is returned with + | share_type | 0 | + | uid_owner | user1 | + | displayname_owner | user1 | + | path | /textfile0 (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/textfile0 (2).txt | + | file_target | /textfile0.txt | + | share_with | user2 | + | share_with_displayname | user2 | + Scenario: Reshared files can be still accessed if a user in the middle removes it. Given user "user0" exists And user "user1" exists @@ -115,6 +178,253 @@ Feature: sharing | displayname_owner | user0 | | mimetype | text/plain | + Scenario: getting all shares including subfiles in a directory + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And file "PARENT/CHILD" of user "user0" is shared with user "user1" + And file "PARENT/parent.txt" of user "user0" is shared with user "user2" + When As an "user0" + And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=PARENT" + Then the list of returned shares has 2 shares + And share 0 is returned with + | share_type | 0 | + | uid_owner | user0 | + | displayname_owner | user0 | + | path | /PARENT/CHILD | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | home::user0 | + | file_target | /CHILD | + | share_with | user1 | + | share_with_displayname | user1 | + | permissions | 31 | + And share 1 is returned with + | share_type | 0 | + | uid_owner | user0 | + | displayname_owner | user0 | + | path | /PARENT/parent.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::user0 | + | file_target | /parent.txt | + | share_with | user2 | + | share_with_displayname | user2 | + + Scenario: getting all shares including subfiles in a directory with received shares + Given user "user0" exists + And user "user1" exists + And file "textfile0.txt" of user "user0" is shared with user "user1" + And file "textfile0.txt" of user "user1" is shared with user "user0" + When As an "user0" + And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=/" + Then the list of returned shares has 1 shares + And share 0 is returned with + | share_type | 0 | + | uid_owner | user0 | + | displayname_owner | user0 | + | path | /textfile0.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::user0 | + | file_target | /textfile0 (2).txt | + | share_with | user1 | + | share_with_displayname | user1 | + + Scenario: getting all shares including subfiles in a directory with shares in subdirectories + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And file "PARENT/CHILD" of user "user0" is shared with user "user1" + And file "PARENT/CHILD/child.txt" of user "user0" is shared with user "user2" + When As an "user0" + And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=PARENT" + Then the list of returned shares has 1 shares + And share 0 is returned with + | share_type | 0 | + | uid_owner | user0 | + | displayname_owner | user0 | + | path | /PARENT/CHILD | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | home::user0 | + | file_target | /CHILD | + | share_with | user1 | + | share_with_displayname | user1 | + | permissions | 31 | + + Scenario: getting all shares including subfiles in a shared directory with reshares + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And user "user3" exists + And file "PARENT" of user "user0" is shared with user "user1" + And file "PARENT (2)/CHILD" of user "user1" is shared with user "user2" + And file "CHILD" of user "user2" is shared with user "user3" + When As an "user0" + And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=PARENT" + Then the list of returned shares has 2 shares + And share 0 is returned with + | share_type | 0 | + | uid_owner | user1 | + | displayname_owner | user1 | + | uid_file_owner | user0 | + | displayname_file_owner | user0 | + | path | /PARENT/CHILD | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | home::user0 | + | file_target | /CHILD | + | share_with | user2 | + | share_with_displayname | user2 | + | permissions | 31 | + And share 1 is returned with + | share_type | 0 | + | uid_owner | user2 | + | displayname_owner | user2 | + | uid_file_owner | user0 | + | displayname_file_owner | user0 | + | path | /PARENT/CHILD | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | home::user0 | + | file_target | /CHILD | + | share_with | user3 | + | share_with_displayname | user3 | + | permissions | 31 | + + Scenario: getting all shares including subfiles in a directory by a resharer + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And user "user3" exists + And file "PARENT" of user "user0" is shared with user "user1" + And file "PARENT (2)/CHILD" of user "user1" is shared with user "user2" + And file "CHILD" of user "user2" is shared with user "user3" + When As an "user1" + And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=PARENT (2)" + Then the list of returned shares has 2 shares + And share 0 is returned with + | share_type | 0 | + | uid_owner | user1 | + | displayname_owner | user1 | + | uid_file_owner | user0 | + | displayname_file_owner | user0 | + | path | /PARENT (2)/CHILD | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | shared::/PARENT (2) | + | file_target | /CHILD | + | share_with | user2 | + | share_with_displayname | user2 | + | permissions | 31 | + And share 1 is returned with + | share_type | 0 | + | uid_owner | user2 | + | displayname_owner | user2 | + | uid_file_owner | user0 | + | displayname_file_owner | user0 | + | path | /PARENT (2)/CHILD | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | shared::/PARENT (2) | + | file_target | /CHILD | + | share_with | user3 | + | share_with_displayname | user3 | + | permissions | 31 | + + Scenario: getting all shares including subfiles in a directory by a resharer after revoking the resharing rights + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And user "user3" exists + And file "PARENT" of user "user0" is shared with user "user1" + And save the last share data as "parent folder" + And file "PARENT (2)/CHILD" of user "user1" is shared with user "user2" + And file "CHILD" of user "user2" is shared with user "user3" + And As an "user0" + And restore the last share data from "parent folder" + And Updating last share with + | permissions | 1 | + When As an "user1" + And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=PARENT (2)" + Then the list of returned shares has 1 shares + And share 0 is returned with + | share_type | 0 | + | uid_owner | user1 | + | displayname_owner | user1 | + | uid_file_owner | user0 | + | displayname_file_owner | user0 | + | path | /PARENT (2)/CHILD | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | shared::/PARENT (2) | + | file_target | /CHILD | + | share_with | user2 | + | share_with_displayname | user2 | + | permissions | 31 | + + Scenario: getting all shares including subfiles in a directory after moving a received share not reshareable also shared with another user + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And file "textfile0.txt" of user "user1" is shared with user "user0" + And Updating last share with + | permissions | 1 | + And file "textfile0.txt" of user "user1" is shared with user "user2" + And User "user0" moved file "/textfile0 (2).txt" to "/FOLDER/textfile0.txt" + When As an "user0" + And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=/FOLDER" + Then the list of returned shares has 1 shares + And share 0 is returned with + | share_type | 0 | + | uid_owner | user1 | + | displayname_owner | user1 | + | path | /FOLDER/textfile0.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/FOLDER/textfile0.txt | + | file_target | /textfile0.txt | + | share_with | user2 | + | share_with_displayname | user2 | + + Scenario: getting all shares including subfiles in a directory after moving a share and a received share not reshareable also shared with another user + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And file "textfile0.txt" of user "user0" is shared with user "user1" + And file "textfile0.txt" of user "user1" is shared with user "user0" + And Updating last share with + | permissions | 1 | + And file "textfile0.txt" of user "user1" is shared with user "user2" + And User "user0" moved file "/textfile0.txt" to "/FOLDER/textfile0.txt" + And User "user0" moved file "/textfile0 (2).txt" to "/FOLDER/textfile0 (2).txt" + When As an "user0" + And sending "GET" to "/apps/files_sharing/api/v1/shares?subfiles=true&path=/FOLDER" + Then the list of returned shares has 2 shares + And share 0 is returned with + | share_type | 0 | + | uid_owner | user0 | + | displayname_owner | user0 | + | path | /FOLDER/textfile0.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::user0 | + | file_target | /textfile0 (2).txt | + | share_with | user1 | + | share_with_displayname | user1 | + And share 1 is returned with + | share_type | 0 | + | uid_owner | user1 | + | displayname_owner | user1 | + | path | /FOLDER/textfile0 (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/FOLDER/textfile0 (2).txt | + | file_target | /textfile0.txt | + | share_with | user2 | + | share_with_displayname | user2 | + Scenario: keep group permissions in sync Given As an "admin" Given user "user0" exists diff --git a/build/integration/sharing_features/sharing-v1.feature b/build/integration/sharing_features/sharing-v1.feature index 81c96b8be5c..b655a835bd7 100644 --- a/build/integration/sharing_features/sharing-v1.feature +++ b/build/integration/sharing_features/sharing-v1.feature @@ -305,7 +305,7 @@ Feature: sharing And User "user2" should be included in the response And User "user3" should not be included in the response - Scenario: getting all shares of a file with a user with resharing rights + Scenario: getting all shares of a file with a user with resharing rights but not yourself Given user "user0" exists And user "user1" exists And user "user2" exists @@ -316,7 +316,7 @@ Feature: sharing When sending "GET" to "/apps/files_sharing/api/v1/shares?path=textfile0 (2).txt&reshares=true" Then the OCS status code should be "100" And the HTTP status code should be "200" - And User "user1" should be included in the response + And User "user1" should not be included in the response And User "user2" should be included in the response And User "user3" should not be included in the response |