diff --git a/tests/acceptance/bootstrap/CollaborationContext.php b/tests/acceptance/bootstrap/CollaborationContext.php index db801aec654..cee5b472f0e 100644 --- a/tests/acceptance/bootstrap/CollaborationContext.php +++ b/tests/acceptance/bootstrap/CollaborationContext.php @@ -137,7 +137,17 @@ public function userCreatesFileInsideFolderInSpaceUsingWopiEndpoint( string $folder, string $space, ): void { - $parentContainerId = $this->spacesContext->getResourceId($user, $space, $folder); + // getResourceId does a single PROPFIND; after a share invite the xattr grant + // may not be visible yet, so retry until oc:fileid is non-empty. + $retried = 0; + do { + $parentContainerId = $this->spacesContext->getResourceId($user, $space, $folder); + $tryAgain = empty($parentContainerId) && $retried < HttpRequestHelper::maxHTTPRequestRetries(); + if ($tryAgain) { + $retried += 1; + \usleep(500 * 1000); + } + } while ($tryAgain); $this->featureContext->setResponse( CollaborationHelper::createFile( $this->featureContext->getBaseUrl(), diff --git a/tests/acceptance/bootstrap/SharingNgContext.php b/tests/acceptance/bootstrap/SharingNgContext.php index d7f4c4b89f0..d94500db5e5 100644 --- a/tests/acceptance/bootstrap/SharingNgContext.php +++ b/tests/acceptance/bootstrap/SharingNgContext.php @@ -1739,6 +1739,49 @@ public function userHasShareSynced(string $user, string $resource): void { $this->waitAndCheckShareSyncStatus($user, $resource, "enabled"); } + /** + * @Given /^user "([^"]*)" has a share "([^"]*)" accessible via WebDAV$/ + * + * Waits until the share mount point is reachable via WebDAV PROPFIND (HTTP 207). + * This is a storage-layer readiness check that complements userHasShareSynced, + * which only checks the JSON share-manager state. The xattr grant written by + * AddGrant may still be propagating when the share-manager state already reads + * ACCEPTED, so resolveAcceptedShare's Stat call can fail transiently without + * this extra gate. + * + * @param string $user + * @param string $resource + * + * @return void + * @throws GuzzleException + */ + public function userHasShareAccessibleViaWebDAV(string $user, string $resource): void { + $resource = \trim($resource, '/'); + $davPath = WebDavHelper::getDavPath(WebDavHelper::DAV_VERSION_NEW, $user); + $baseUrl = $this->featureContext->getBaseUrl(); + $password = $this->featureContext->getPasswordForUser($user); + + $retried = 0; + do { + $response = HttpRequestHelper::sendRequest( + "$baseUrl/$davPath/Shares/$resource", + 'PROPFIND', + $user, + $password, + ['Depth' => '0'], + ); + if ($response->getStatusCode() === 207) { + return; + } + $tryAgain = $retried < HttpRequestHelper::maxHTTPRequestRetries(); + if ($tryAgain) { + $retried += 1; + \usleep(500 * 1000); + } + } while ($tryAgain); + Assert::fail("[Timeout] Share '$resource' for user '$user' not accessible via WebDAV after retries"); + } + /** * @Then /^user "([^"]*)" should have sync (enabled|disabled) for share "([^"]*)"$/ * diff --git a/tests/acceptance/features/coreApiShareManagementToShares/moveReceivedShare.feature b/tests/acceptance/features/coreApiShareManagementToShares/moveReceivedShare.feature index fead0e203cc..0a1956b574d 100644 --- a/tests/acceptance/features/coreApiShareManagementToShares/moveReceivedShare.feature +++ b/tests/acceptance/features/coreApiShareManagementToShares/moveReceivedShare.feature @@ -107,6 +107,7 @@ Feature: sharing | shareType | user | | permissionsRole | | And user "Carol" has a share "sharefile.txt" synced + And user "Carol" has a share "sharefile.txt" accessible via WebDAV When user "Carol" moves file "Shares/sharefile.txt" to "Shares/renamedsharefile.txt" using the WebDAV API Then the HTTP status code should be "201" And as "Carol" file "Shares/renamedsharefile.txt" should exist @@ -149,6 +150,7 @@ Feature: sharing | shareType | user | | permissionsRole | | And user "Carol" has a share "sharefile.txt" synced + And user "Carol" has a share "sharefile.txt" accessible via WebDAV When user "Carol" moves file "Shares/sharefile.txt" to "Shares/renamedsharefile.txt" using the WebDAV API Then the HTTP status code should be "201" And as "Carol" file "Shares/renamedsharefile.txt" should exist