diff --git a/tests/acceptance/features/bootstrap/SharingNgContext.php b/tests/acceptance/features/bootstrap/SharingNgContext.php index f1268ec76a..35ca8439df 100644 --- a/tests/acceptance/features/bootstrap/SharingNgContext.php +++ b/tests/acceptance/features/bootstrap/SharingNgContext.php @@ -26,6 +26,7 @@ use Psr\Http\Message\ResponseInterface; use TestHelpers\GraphHelper; use TestHelpers\OcisHelper; use TestHelpers\WebDavHelper; +use TestHelpers\HttpRequestHelper; use Behat\Gherkin\Node\TableNode; use PHPUnit\Framework\Assert; @@ -1240,6 +1241,78 @@ class SharingNgContext implements Context { $this->featureContext->setResponse($response); } + /** + * @param string $user + * @param string $resource + * + * @return void + * @throws GuzzleException + */ + public function isShareSynced(string $user, string $resource): bool { + $resource = \trim($resource, '/'); + $response = GraphHelper::getSharesSharedWithMe( + $this->featureContext->getBaseUrl(), + $this->featureContext->getStepLineRef(), + $user, + $this->featureContext->getPasswordForUser($user) + ); + + $shares = $this->featureContext->getJsonDecodedResponse($response)["value"]; + $syncStatus = false; + foreach ($shares as $share) { + if ($share["name"] === $resource) { + $syncStatus = $share["@client.synchronize"]; + break; + } + } + Assert::assertIsBool($syncStatus, "'@client.synchronize' must be a boolean value"); + return $syncStatus; + } + + /** + * @param string $user + * @param string $resource + * @param string $status + * + * @return void + * @throws Exception|GuzzleException + */ + public function waitAndCheckShareSyncStatus(string $user, string $resource, string $status): 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); + + if ($shareSynced === $expected) { + return; + } + + $tryAgain = !$shareSynced && $retried < HttpRequestHelper::numRetriesOnHttpTooEarly(); + if ($tryAgain) { + $retried += 1; + echo "[INFO] Wait for share sync status..."; + // wait 500ms and try again + \usleep(500 * 1000); + } + } while ($tryAgain); + Assert::fail("[Timeout] Sync for share '$resource' was expected to be '$status' but was not"); + } + + /** + * @Then /^user "([^"]*)" has a share "([^"]*)" synced$/ + * + * @param string $user + * @param string $resource + * + * @return void + * @throws Exception|GuzzleException + */ + public function userHasShareSynced(string $user, string $resource): void { + $this->waitAndCheckShareSyncStatus($user, $resource, "enabled"); + } + /** * @Then /^user "([^"]*)" should have sync (enabled|disabled) for share "([^"]*)"$/ * @@ -1251,28 +1324,7 @@ class SharingNgContext implements Context { * @throws GuzzleException */ public function userShouldHaveSyncEnabledOrDisabledForShare(string $user, string $status, string $resource):void { - $response = GraphHelper::getSharesSharedWithMe( - $this->featureContext->getBaseUrl(), - $this->featureContext->getStepLineRef(), - $user, - $this->featureContext->getPasswordForUser($user) - ); - $responseBody = $this->featureContext->getJsonDecodedResponse($response); - $expectedValue = $status === "enabled" ? "true" : "false"; - $actualValue = ""; - foreach ($responseBody["value"] as $value) { - if ($value["remoteItem"]["name"] === $resource) { - // var_export converts values to their string representations - // e.g.: true -> 'true' - $actualValue = var_export($value["@client.synchronize"], true); - break; - } - } - Assert::assertSame( - $actualValue, - $expectedValue, - "Expected property '@client.synchronize' to be '$expectedValue' but found '$actualValue'" - ); + $this->waitAndCheckShareSyncStatus($user, $resource, $status); } /** diff --git a/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature b/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature index b530f7ef0d..63d8cafdcf 100644 --- a/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature +++ b/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature @@ -245,7 +245,8 @@ Feature: sharing And user "Brian" has been added to group "grp2" And user "Alice" has created folder "/PARENT" When user "Alice" shares folder "/PARENT" with group "grp1" using the sharing API - Then user "Brian" should see the following elements + Then user "Brian" should have sync enabled for share "PARENT" + And user "Brian" should see the following elements | /Shares/PARENT/ | diff --git a/tests/acceptance/features/coreApiShareManagementToShares/moveReceivedShare.feature b/tests/acceptance/features/coreApiShareManagementToShares/moveReceivedShare.feature index 21bd5d8fc0..af64b596e0 100644 --- a/tests/acceptance/features/coreApiShareManagementToShares/moveReceivedShare.feature +++ b/tests/acceptance/features/coreApiShareManagementToShares/moveReceivedShare.feature @@ -180,6 +180,7 @@ Feature: sharing | sharee | grp1 | | shareType | group | | permissionsRole | Viewer | + And user "Carol" has a share "/TMP" synced When user "Carol" moves folder "/Shares/TMP" to "/Shares/new" using the WebDAV API And the administrator deletes user "Carol" using the provisioning API Then the HTTP status code of responses on each endpoint should be "201, 204" respectively