diff --git a/tests/acceptance/TestHelpers/CollaborationHelper.php b/tests/acceptance/TestHelpers/CollaborationHelper.php index cb9b6776858..d6d73c34b18 100644 --- a/tests/acceptance/TestHelpers/CollaborationHelper.php +++ b/tests/acceptance/TestHelpers/CollaborationHelper.php @@ -36,6 +36,7 @@ class CollaborationHelper { * @param string $password * @param string $baseUrl * @param string|null $viewMode + * @param array|null $headers * * @return ResponseInterface * @throws GuzzleException @@ -47,6 +48,7 @@ public static function sendPOSTRequestToAppOpen( string $password, string $baseUrl, ?string $viewMode = null, + ?array $headers = null, ): ResponseInterface { $url = $baseUrl . "/app/open?app_name=$app&file_id=$fileId"; if ($viewMode) { @@ -57,7 +59,7 @@ public static function sendPOSTRequestToAppOpen( $url, $username, $password, - ['Content-Type' => 'application/json'], + $headers ?? ['Content-Type' => 'application/json'], ); } diff --git a/tests/acceptance/bootstrap/CollaborationContext.php b/tests/acceptance/bootstrap/CollaborationContext.php index db801aec654..9a2cc7fcf83 100644 --- a/tests/acceptance/bootstrap/CollaborationContext.php +++ b/tests/acceptance/bootstrap/CollaborationContext.php @@ -25,6 +25,7 @@ use Behat\Gherkin\Node\TableNode; use GuzzleHttp\Exception\GuzzleException; use PHPUnit\Framework\Assert; +use Psr\Http\Message\ResponseInterface; use TestHelpers\HttpRequestHelper; use TestHelpers\WebDavHelper; use TestHelpers\CollaborationHelper; @@ -309,6 +310,7 @@ public function userHasSentTheFollowingAppOpenRequest(string $user, TableNode $p $this->featureContext->getActualUsername($user), $this->featureContext->getPasswordForUser($user), $this->featureContext->getBaseUrl(), + $rows['viewMode'] ?? null, ); $this->featureContext->theHTTPStatusCodeShouldBe(200, '', $appResponse); $this->setLastAppOpenData($appResponse->getBody()->getContents()); @@ -324,7 +326,61 @@ public function userHasSentTheFollowingAppOpenRequest(string $user, TableNode $p * @throws GuzzleException */ public function userGetsTheInformationOfTheLastOpenedFileUsingWopiEndpoint(string $user): void { - $response = json_decode($this->getLastAppOpenData()); + [$wopiSrc, $accessToken] = $this->getWopiSrcAndAccessTokenFromLastAppOpenData(); + + $this->featureContext->setResponse( + HttpRequestHelper::get( + $wopiSrc . "?access_token=$accessToken", + ), + ); + } + + /** + * @When user :user sends a lock request with lock id :lockId to the last opened file using wopi endpoint + * + * @param string $user + * @param string $lockId + * + * @return void + * @throws GuzzleException + */ + public function userSendsALockRequestWithLockIdToTheLastOpenedFileUsingWopiEndpoint( + string $user, + string $lockId, + ): void { + $this->featureContext->setResponse( + $this->sendLockRequestToLastOpenedFile($lockId), + ); + } + + /** + * Send a WOPI LOCK request using the last opened file's endpoint. + * + * @param string $lockId + * + * @return ResponseInterface + * @throws GuzzleException + */ + private function sendLockRequestToLastOpenedFile(string $lockId): ResponseInterface { + [$wopiSrc, $accessToken] = $this->getWopiSrcAndAccessTokenFromLastAppOpenData(); + return HttpRequestHelper::post( + $wopiSrc . "?access_token=$accessToken", + null, + null, + [ + 'X-WOPI-Override' => 'LOCK', + 'X-WOPI-Lock' => $lockId, + ], + ); + } + + /** + * Extract the WOPISrc and the access token from the last app-open response. + * + * @return array{0: string, 1: string} the WOPISrc URL and the access token + */ + private function getWopiSrcAndAccessTokenFromLastAppOpenData(): array { + $response = \json_decode($this->getLastAppOpenData()); $accessToken = $response->form_parameters->access_token; // Extract the WOPISrc from the app_url @@ -332,10 +388,48 @@ public function userGetsTheInformationOfTheLastOpenedFileUsingWopiEndpoint(strin parse_str($parsedUrl['query'], $queryParams); $wopiSrc = $queryParams['WOPISrc']; + return [$wopiSrc, $accessToken]; + } + + /** + * @Given the public has sent the following app-open request: + * + * @param TableNode $properties + * + * @return void + * @throws GuzzleException + */ + public function thePublicHasSentTheFollowingAppOpenRequest(TableNode $properties): void { + $rows = $properties->getRowsHash(); + $token = $this->featureContext->shareNgGetLastCreatedLinkShareToken(); + $password = $this->featureContext->getActualPassword("%public%"); + + $fileId = $this->spacesContext->getFileId($rows['owner'], $rows['space'], $rows['resource']); + + $appResponse = CollaborationHelper::sendPOSTRequestToAppOpen( + $fileId, + $rows['app'], + 'public', + $password, + $this->featureContext->getBaseUrl(), + $rows['view_mode'] ?? null, + ['Public-Token' => $token], + ); + $this->featureContext->theHTTPStatusCodeShouldBe(200, '', $appResponse); + $this->setLastAppOpenData($appResponse->getBody()->getContents()); + } + + /** + * @When the public sends a lock request with lock id :lockId to the last opened file using wopi endpoint + * + * @param string $lockId + * + * @return void + * @throws GuzzleException + */ + public function thePublicSendsALockRequestWithLockIdToTheLastOpenedFileUsingWopiEndpoint(string $lockId): void { $this->featureContext->setResponse( - HttpRequestHelper::get( - $wopiSrc . "?access_token=$accessToken", - ), + $this->sendLockRequestToLastOpenedFile($lockId), ); } diff --git a/tests/acceptance/features/apiCollaboration/wopi.feature b/tests/acceptance/features/apiCollaboration/wopi.feature index 860fe81f4e3..a9b853810a0 100644 --- a/tests/acceptance/features/apiCollaboration/wopi.feature +++ b/tests/acceptance/features/apiCollaboration/wopi.feature @@ -1135,3 +1135,88 @@ Feature: collaboration (wopi) | app-endpoint | template | target | | /app/open?file_id=<>&app_name=Collabora&view_mode=write&template_id=<> | template.ott | template.odt | | /app/open?file_id=<>&app_name=OnlyOffice&view_mode=write&template_id=<> | template.dotx | template.docx | + + + Scenario Outline: lock request on file opened with different view modes + Given user "Alice" has uploaded file "filesForUpload/simple.odt" to "simple.odt" + And user "Alice" has sent the following app-open request: + | resource | simple.odt | + | space | Personal | + | app | FakeOffice | + | viewMode | | + When user "Alice" sends a lock request with lock id "abcdef123" to the last opened file using wopi endpoint + Then the HTTP status code should be "200" + Examples: + | view-mode | + | view | + | read | + | write | + + + Scenario Outline: lock request with different lock id on file opened with different view modes + Given user "Alice" has uploaded file "filesForUpload/simple.odt" to "simple.odt" + And user "Alice" has sent the following app-open request: + | resource | simple.odt | + | space | Personal | + | app | FakeOffice | + | viewMode | | + When user "Alice" sends a lock request with lock id "abcdef123" to the last opened file using wopi endpoint + Then the HTTP status code should be "200" + When user "Alice" sends a lock request with lock id "different-lock-id" to the last opened file using wopi endpoint + Then the HTTP status code should be "" + Examples: + | view-mode | http-status-code | + | view | 200 | + | read | 200 | + | write | 409 | + + + Scenario: sharee with viewer permissions role sends lock request on shared file + Given user "Alice" has uploaded file "filesForUpload/simple.odt" to "simple.odt" + And user "Alice" has sent the following resource share invitation: + | resource | simple.odt | + | space | Personal | + | sharee | Brian | + | shareType | user | + | permissionsRole | Viewer | + And user "Brian" has sent the following app-open request: + | resource | simple.odt | + | space | Shares | + | app | FakeOffice | + When user "Brian" sends a lock request with lock id "abcdef123" to the last opened file using wopi endpoint + Then the HTTP status code should be "200" + + + Scenario: space viewer sends lock request on shared file + Given using spaces DAV path + And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API + And user "Alice" has created a space "new-space" with the default quota using the Graph API + And user "Alice" has created a folder "testFolder" in space "new-space" + And user "Alice" creates a file "simple.odt" inside folder "testFolder" in space "new-space" using wopi endpoint + And user "Alice" has sent the following space share invitation: + | space | new-space | + | sharee | Brian | + | shareType | user | + | permissionsRole | Space Viewer | + And user "Brian" has sent the following app-open request: + | resource | testFolder/simple.odt | + | space | new-space | + | app | FakeOffice | + When user "Brian" sends a lock request with lock id "abcdef123" to the last opened file using wopi endpoint + Then the HTTP status code should be "200" + + + Scenario: public link viewer sends lock request on shared file + Given user "Alice" has uploaded file "filesForUpload/simple.odt" to "simple.odt" + And user "Alice" has created the following resource link share: + | resource | simple.odt | + | space | Personal | + | permissionsRole | View | + | password | %public% | + And the public has sent the following app-open request: + | owner | Alice | + | resource | simple.odt | + | space | Personal | + | app | FakeOffice | + When the public sends a lock request with lock id "abcdef123" to the last opened file using wopi endpoint + Then the HTTP status code should be "200"