From ca261fdff2c859bb7fed378a999ae4d7abdb14ca Mon Sep 17 00:00:00 2001 From: Prajwol Amatya <83579989+PrajwolAmatya@users.noreply.github.com> Date: Thu, 27 Aug 2026 11:24:45 +0545 Subject: [PATCH] [tests-only][full-ci]test: backport test to share resources from vault (#12839) test: add test to share resources from vault Signed-off-by: Prajwol Amatya --- tests/acceptance/TestHelpers/GraphHelper.php | 17 ++- .../acceptance/TestHelpers/SettingsHelper.php | 20 +-- tests/acceptance/bootstrap/FeatureContext.php | 12 +- .../acceptance/bootstrap/SharingNgContext.php | 62 +++++++- .../features/apiVault/vault.feature | 144 +++++++++++++++++- 5 files changed, 231 insertions(+), 24 deletions(-) diff --git a/tests/acceptance/TestHelpers/GraphHelper.php b/tests/acceptance/TestHelpers/GraphHelper.php index 0e76ba2d290..c8456269f75 100644 --- a/tests/acceptance/TestHelpers/GraphHelper.php +++ b/tests/acceptance/TestHelpers/GraphHelper.php @@ -1947,23 +1947,28 @@ class GraphHelper { /** * @param string $baseUrl - * @param string $user - * @param string $password + * @param string|null $user + * @param string|null $password + * @param array $headers + * @param boolean $isVault * * @return ResponseInterface * @throws GuzzleException */ public static function getSharesSharedWithMe( string $baseUrl, - string $user, - string $password, + ?string $user, + ?string $password, + array $headers = [], + bool $isVault = false, ): ResponseInterface { - $url = self::getBetaFullUrl($baseUrl, "me/drive/sharedWithMe"); + $url = self::getBetaFullUrl($baseUrl, "me/drive/sharedWithMe", $isVault); + $requestHeaders = array_merge(self::getRequestHeaders(), $headers); return HttpRequestHelper::get( $url, $user, $password, - self::getRequestHeaders(), + $requestHeaders, ); } diff --git a/tests/acceptance/TestHelpers/SettingsHelper.php b/tests/acceptance/TestHelpers/SettingsHelper.php index 0c3842c025c..2d42a6edbbc 100644 --- a/tests/acceptance/TestHelpers/SettingsHelper.php +++ b/tests/acceptance/TestHelpers/SettingsHelper.php @@ -226,8 +226,8 @@ class SettingsHelper { /** * @param string $baseUrl - * @param string $user - * @param string $password + * @param string|null $user + * @param string|null $password * @param array $headers * * @return ResponseInterface @@ -237,8 +237,8 @@ class SettingsHelper { */ public static function getValuesList( string $baseUrl, - string $user, - string $password, + ?string $user, + ?string $password, array $headers = [], ): ResponseInterface { $fullUrl = self::buildFullUrl($baseUrl, "values-list"); @@ -254,8 +254,9 @@ class SettingsHelper { /** * @param string $baseUrl - * @param string $user - * @param string $password + * @param string|null $user + * @param string|null $password + * @param array $headers * * @return bool * @@ -264,10 +265,11 @@ class SettingsHelper { */ public static function getAutoAcceptSharesDefaultValue( string $baseUrl, - string $user, - string $password, + ?string $user, + ?string $password, + array $headers = [], ): bool { - $response = self::getValuesList($baseUrl, $user, $password); + $response = self::getValuesList($baseUrl, $user, $password, $headers); Assert::assertEquals(201, $response->getStatusCode(), "Failed to get values list"); $valuesList = HttpRequestHelper::getJsonDecodedResponseBodyContent($response); diff --git a/tests/acceptance/bootstrap/FeatureContext.php b/tests/acceptance/bootstrap/FeatureContext.php index 08d749afa34..fb2c97eae8c 100644 --- a/tests/acceptance/bootstrap/FeatureContext.php +++ b/tests/acceptance/bootstrap/FeatureContext.php @@ -179,10 +179,20 @@ class FeatureContext extends BehatVariablesContext { if (\array_key_exists($user, $this->autoSyncSettings)) { return $this->autoSyncSettings[$user]; } + $headers = []; + if (\TestHelpers\KeycloakHelper::isTestingWithKeycloak()) { + $accessToken = $this->getOcisUserToken($user)['token']['accessToken']; + $headers['Authorization'] = 'Bearer ' . $accessToken; + $user = null; + $password = null; + } else { + $password = $this->getPasswordForUser($user); + } $autoSyncSetting = SettingsHelper::getAutoAcceptSharesDefaultValue( $this->baseUrl, $user, - $this->getPasswordForUser($user), + $password, + $headers, ); $this->autoSyncSettings[$user] = $autoSyncSetting; diff --git a/tests/acceptance/bootstrap/SharingNgContext.php b/tests/acceptance/bootstrap/SharingNgContext.php index d7f4c4b89f0..57a6202ebcb 100644 --- a/tests/acceptance/bootstrap/SharingNgContext.php +++ b/tests/acceptance/bootstrap/SharingNgContext.php @@ -1670,16 +1670,28 @@ class SharingNgContext implements Context { /** * @param string $user * @param string $resource + * @param boolean $isVault * * @return void * @throws GuzzleException */ - public function isShareSynced(string $user, string $resource): bool { + public function isShareSynced(string $user, string $resource, bool $isVault = false): bool { $resource = \trim($resource, '/'); + $headers = []; + if (KeycloakHelper::isTestingWithKeycloak()) { + $accessToken = $this->featureContext->getOcisUserToken($user)['token']['accessToken']; + $headers['Authorization'] = 'Bearer ' . $accessToken; + $user = null; + $password = null; + } else { + $password = $this->featureContext->getPasswordForUser($user); + } $response = GraphHelper::getSharesSharedWithMe( $this->featureContext->getBaseUrl(), $user, - $this->featureContext->getPasswordForUser($user), + $password, + $headers, + $isVault, ); $shares = $this->featureContext->getJsonDecodedResponse($response)["value"]; @@ -1698,17 +1710,23 @@ class SharingNgContext implements Context { * @param string $user * @param string $resource * @param string $status + * @param boolean $isVault * * @return void * @throws Exception|GuzzleException */ - public function waitAndCheckShareSyncStatus(string $user, string $resource, string $status): void { + public function waitAndCheckShareSyncStatus( + string $user, + string $resource, + string $status, + bool $isVault = false, + ): void { $expected = $status === "enabled"; // NOTE: Sharing is async so it might take some time for the share to be available. $retried = 0; do { - $shareSynced = $this->isShareSynced($user, $resource); + $shareSynced = $this->isShareSynced($user, $resource, $isVault); if ($shareSynced === $expected) { return; @@ -1727,7 +1745,6 @@ class SharingNgContext implements Context { /** * @Given /^user "([^"]*)" has a share "([^"]*)" synced$/ - * @Then user :user should have a share :resource synced * * @param string $user * @param string $resource @@ -1739,6 +1756,21 @@ class SharingNgContext implements Context { $this->waitAndCheckShareSyncStatus($user, $resource, "enabled"); } + /** + * @Then /^user "([^"]*)" should have a share(| in vault)? "([^"]*)" synced$/ + * + * @param string $user + * @param string $isVault + * @param string $resource + * + * @return void + * @throws Exception|GuzzleException + */ + public function userShouldHaveShareSynced(string $user, string $isVault, string $resource): void { + $isVault = trim($isVault) === "in vault"; + $this->waitAndCheckShareSyncStatus($user, $resource, "enabled", $isVault); + } + /** * @Then /^user "([^"]*)" should have sync (enabled|disabled) for share "([^"]*)"$/ * @@ -2210,6 +2242,7 @@ class SharingNgContext implements Context { * @param bool $shouldExist * @param bool $federatedShare * @param string $role compares share role if provided + * @param boolean $isVault * * @return void * @throws GuzzleException @@ -2224,9 +2257,19 @@ class SharingNgContext implements Context { bool $shouldExist = true, bool $federatedShare = false, string $role = '', + bool $isVault = false, ): void { $share = \ltrim($share, "/"); $wasOrNot = $shouldExist ? "was not" : "was"; + $headers = []; + if (KeycloakHelper::isTestingWithKeycloak()) { + $accessToken = $this->featureContext->getOcisUserToken($sharee)['token']['accessToken']; + $headers["Authorization"] = "Bearer " . $accessToken; + $sharee = null; + $password = null; + } else { + $password = $this->featureContext->getPasswordForUser($sharee); + } if (!$federatedShare) { if (\strtolower($space) === "personal") { $remoteDriveAlias = "personal/" . \strtolower($sharer); @@ -2238,8 +2281,11 @@ class SharingNgContext implements Context { $response = GraphHelper::getMySpaces( $this->featureContext->getBaseUrl(), $sharee, - $this->featureContext->getPasswordForUser($sharee), + $password, "", + [], + $headers, + $isVault, ); $driveList = HttpRequestHelper::getJsonDecodedResponseBodyContent($response)->value; $foundShareMountpoint = false; @@ -2263,6 +2309,8 @@ class SharingNgContext implements Context { $this->featureContext->getBaseUrl(), $sharee, $this->featureContext->getPasswordForUser($sharee), + $headers, + $isVault, ); $sharedWithMeList = HttpRequestHelper::getJsonDecodedResponseBodyContent($response)->value; $foundShareInSharedWithMe = false; @@ -2330,6 +2378,7 @@ class SharingNgContext implements Context { // set default space to personal if not provided $space = $shares[0]['space'] ?? 'personal'; foreach ($shares as $share) { + $isVault = isset($share['storage']) && $share['storage'] === 'vault'; $this->checkIfShareExists( $share["resource"], $sharee, @@ -2338,6 +2387,7 @@ class SharingNgContext implements Context { true, false, $share["permissionsRole"], + $isVault, ); } } diff --git a/tests/acceptance/features/apiVault/vault.feature b/tests/acceptance/features/apiVault/vault.feature index 38ff0d93967..8a713bd55ef 100644 --- a/tests/acceptance/features/apiVault/vault.feature +++ b/tests/acceptance/features/apiVault/vault.feature @@ -786,7 +786,7 @@ Feature: vault Then the HTTP status code should be "207" And the search result should contain "1" entries And the search result of user "Alice" should contain only these files: - | testDriveFile.txt | + | testDriveFile.txt | @tikaServiceNeeded Scenario: search result by content of file inside project space should be isolated between vault and drive @@ -805,7 +805,7 @@ Feature: vault Then the HTTP status code should be "207" And the search result should contain "1" entries And the search result of user "Alice" should contain only these files: - | testDriveFile.txt | + | testDriveFile.txt | Scenario: search results by resource tags should be isolated between vault and drive @@ -873,3 +873,143 @@ Feature: vault And the search result of user "Alice" should contain only these files: | testDriveFile.txt | | driveFolder | + + + Scenario Outline: folder share received from vault and drive personal space should be isolated + Given user "Brian" has been created with default attributes + And user "Alice" has logged in via web UI + And user "Brian" has logged in via web UI + And user "Alice" has created a folder "driveFolder" in space "Personal" + And user "Alice" has created a folder "vaultFolder" in space "Personal" in vault + And user "Alice" has sent the following resource share invitation: + | resource | driveFolder | + | space | Personal | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + When user "Alice" sends the following resource share invitation using the Graph API: + | resource | vaultFolder | + | space | Personal | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + | storage | vault | + Then the HTTP status code should be "200" + And user "Brian" should have a share in vault "vaultFolder" synced + And user "Brian" should have the following resource shares: + | resource | permissionsRole | sharer | space | storage | + | vaultFolder | | Alice | Personal | vault | + And user "Brian" should have the following resource shares: + | resource | permissionsRole | sharer | space | + | driveFolder | | Alice | Personal | + Examples: + | permissions-role | + | Viewer | + | Editor | + | Uploader | + + + Scenario Outline: file share received from vault and drive personal space should be isolated + Given user "Brian" has been created with default attributes + And user "Alice" has logged in via web UI + And user "Brian" has logged in via web UI + And user "Alice" has uploaded a file inside space "Personal" with content "some content" to "driveFile.txt" + And user "Alice" has uploaded a file inside space "Personal" with content "some content" to "vaultFile.txt" in vault + And user "Alice" has sent the following resource share invitation: + | resource | driveFile.txt | + | space | Personal | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + When user "Alice" sends the following resource share invitation using the Graph API: + | resource | vaultFile.txt | + | space | Personal | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + | storage | vault | + Then the HTTP status code should be "200" + And user "Brian" should have a share in vault "vaultFile.txt" synced + And user "Brian" should have the following resource shares: + | resource | permissionsRole | sharer | space | storage | + | vaultFile.txt | | Alice | Personal | vault | + And user "Brian" should have the following resource shares: + | resource | permissionsRole | sharer | space | + | driveFile.txt | | Alice | Personal | + Examples: + | permissions-role | + | Viewer | + | File Editor | + + + Scenario Outline: folder share received from vault and drive project space should be isolated + Given user "Brian" has been created with default attributes + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has logged in via web UI + And user "Brian" has logged in via web UI + And user "Alice" has created a space "new-space" with the default quota using the Graph API + And user "Alice" has created a space "new-space" in vault with the default quota using the Graph API + And user "Alice" has created a folder "driveFolder" in space "new-space" + And user "Alice" has created a folder "vaultFolder" in space "new-space" in vault + And user "Alice" has sent the following resource share invitation: + | resource | driveFolder | + | space | new-space | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + When user "Alice" sends the following resource share invitation using the Graph API: + | resource | vaultFolder | + | space | new-space | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + | storage | vault | + Then the HTTP status code should be "200" + And user "Brian" should have a share in vault "vaultFolder" synced + And user "Brian" should have the following resource shares: + | resource | permissionsRole | sharer | space | storage | + | vaultFolder | | Alice | new-space | vault | + And user "Brian" should have the following resource shares: + | resource | permissionsRole | sharer | space | + | driveFolder | | Alice | new-space | + Examples: + | permissions-role | + | Viewer | + | Editor | + | Uploader | + + + Scenario Outline: folder share received from vault and drive project space should be isolated + Given user "Brian" has been created with default attributes + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has logged in via web UI + And user "Brian" has logged in via web UI + And user "Alice" has created a space "new-space" with the default quota using the Graph API + And user "Alice" has created a space "new-space" in vault with the default quota using the Graph API + And user "Alice" has uploaded a file inside space "new-space" with content "some content" to "driveFile.txt" + And user "Alice" has uploaded a file inside space "new-space" with content "some content" to "vaultFile.txt" in vault + And user "Alice" has sent the following resource share invitation: + | resource | driveFile.txt | + | space | new-space | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + When user "Alice" sends the following resource share invitation using the Graph API: + | resource | vaultFile.txt | + | space | new-space | + | sharee | Brian | + | shareType | user | + | permissionsRole | | + | storage | vault | + Then the HTTP status code should be "200" + And user "Brian" should have a share in vault "vaultFile.txt" synced + And user "Brian" should have the following resource shares: + | resource | permissionsRole | sharer | space | storage | + | vaultFile.txt | | Alice | new-space | vault | + And user "Brian" should have the following resource shares: + | resource | permissionsRole | sharer | space | + | driveFile.txt | | Alice | new-space | + Examples: + | permissions-role | + | Viewer | + | File Editor |