diff --git a/.drone.star b/.drone.star index d01ac47c4..63091bf15 100644 --- a/.drone.star +++ b/.drone.star @@ -240,6 +240,7 @@ def testPipelines(ctx): if "skip" not in config["localApiTests"] or not config["localApiTests"]["skip"]: pipelines = [ localApiTests(ctx, "ocis", "apiAccountsHashDifficulty", "default"), + localApiTests(ctx, "ocis", "apiSpaces", "default"), ] if "skip" not in config["apiTests"] or not config["apiTests"]["skip"]: @@ -1512,6 +1513,7 @@ def notify(ctx): def ocisServer(storage, accounts_hash_difficulty = 4, volumes = []): environment = { "OCIS_URL": "https://ocis-server:9200", + "GRAPH_SPACES_WEBDAV_BASE": "https://ocis-server:9200/dav/spaces/", "STORAGE_HOME_DRIVER": "%s" % (storage), "STORAGE_USERS_DRIVER": "%s" % (storage), "STORAGE_USERS_DRIVER_LOCAL_ROOT": "/srv/app/tmp/ocis/local/root", diff --git a/tests/acceptance/config/behat.yml b/tests/acceptance/config/behat.yml index 131a0d0af..645583040 100644 --- a/tests/acceptance/config/behat.yml +++ b/tests/acceptance/config/behat.yml @@ -28,6 +28,25 @@ default: - PublicWebDavContext: - TrashbinContext: - WebDavPropertiesContext: + apiSpaces: + paths: + - '%paths.base%/../features/apiSpaces' + contexts: + - GraphApiContext: + - OccContext: + - FeatureContext: &common_feature_context_params + baseUrl: http://localhost:8080 + adminUsername: admin + adminPassword: admin + regularUserPassword: 123456 + ocPath: apps/testing/api/v1/occ + - CapabilitiesContext: + - ChecksumContext: + - FavoritesContext: + - FilesVersionsContext: + - PublicWebDavContext: + - TrashbinContext: + - WebDavPropertiesContext: extensions: jarnaiz\JUnitFormatter\JUnitFormatterExtension: diff --git a/tests/acceptance/features/apiSpaces/ListSpaces.feature b/tests/acceptance/features/apiSpaces/ListSpaces.feature new file mode 100644 index 000000000..d4dbdeb8f --- /dev/null +++ b/tests/acceptance/features/apiSpaces/ListSpaces.feature @@ -0,0 +1,14 @@ +@api @skipOnOcV10 +Feature: List and create spaces + As a user + I want to be able to work with personal and project spaces to collaborate with individuals and teams + + Note - this feature is run in CI with ACCOUNTS_HASH_DIFFICULTY set to the default for production + See https://github.com/owncloud/ocis/issues/1542 and https://github.com/owncloud/ocis/pull/839 + + Scenario: list own spaces + Given user "Alice" has been created with default attributes and without skeleton files + And user "Alice" lists all available spaces via the GraphApi + Then the HTTP status code should be "200" + And user "Alice" lists the content of the personal space root using the WebDav Api + And the HTTP status code should be "207" diff --git a/tests/acceptance/features/bootstrap/GraphApiContext.php b/tests/acceptance/features/bootstrap/GraphApiContext.php new file mode 100644 index 000000000..dcff78a26 --- /dev/null +++ b/tests/acceptance/features/bootstrap/GraphApiContext.php @@ -0,0 +1,213 @@ +personalDriveWebDavUrl; + } + + /** + * @param string $personalDriveWebDavUrl + */ + public function setPersonalDriveWebDavUrl(string $personalDriveWebDavUrl): void + { + $this->personalDriveWebDavUrl = $personalDriveWebDavUrl; + } + /** + * @BeforeScenario + * + * @param BeforeScenarioScope $scope + * + * @return void + * @throws Exception + */ + public function setUpScenario(BeforeScenarioScope $scope): void + { + // Get the environment + $environment = $scope->getEnvironment(); + // Get all the contexts you need in this context + $this->featureContext = $environment->getContext('FeatureContext'); + SetupHelper::init( + $this->featureContext->getAdminUsername(), + $this->featureContext->getAdminPassword(), + $this->featureContext->getBaseUrl(), + $this->featureContext->getOcPath() + ); + } + + /** + * Send Graph List Drives Request + * + * @param $baseUrl + * @param $user + * @param $password + * @param $arguments + * @param string $xRequestId + * @param array $body + * @param array $headers + * @return ResponseInterface + */ + public function listSpacesRequest( + $baseUrl, + $user, + $password, + $arguments, + string $xRequestId = '', + array $body = [], + array $headers = [] + ) { + $fullUrl = $baseUrl; + if (!str_ends_with($fullUrl, '/')) { + $fullUrl .= '/'; + } + $fullUrl .= "graph/v1.0/me/drives/" . $arguments; + + return HttpRequestHelper::get($fullUrl, $xRequestId, $user, $password, $headers, $body); + } + + /** + * Send Graph List Drives Request + * + * @param $baseUrl + * @param $user + * @param $password + * @param string $spaceName + * @param string $xRequestId + * @param array $headers + * @return ResponseInterface + */ + public function sendCreateSpaceRequest( + $baseUrl, + $user, + $password, + string $spaceName, + string $xRequestId = '', + array $headers = [] + ): ResponseInterface + { + $fullUrl = $baseUrl; + if (!str_ends_with($fullUrl, '/')) { + $fullUrl .= '/'; + } + $fullUrl .= "drives/" . $spaceName; + + return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, 'POST', $user, $password, $headers); + } + + /** + * Send Propfind Request to Url + * + * @param $fullUrl + * @param $user + * @param $password + * @param string $xRequestId + * @param array $headers + * @return ResponseInterface + */ + public function sendPropfindRequestToUrl( + $fullUrl, + $user, + $password, + string $xRequestId = '', + array $headers = [] + ): ResponseInterface + { + return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, 'PROPFIND', $user, $password, $headers); + } + + /** + * @When /^user "([^"]*)" lists all available spaces via the GraphApi$/ + * + * @param $user + * @return void + */ + public function theUserListsAllHisAvailableSpacesUsingTheGraphApi($user): void + { + $this->featureContext->setResponse( + $this->listSpacesRequest( + $this->featureContext->getBaseUrl(), + $user, + $this->featureContext->getPasswordForUser($user), + "", + "" + ) + ); + } + + /** + * Get the webDavUrl of the personal space has been found + * + * @return void + */ + public function theWebDavUrlOfThePersonalSpaceHasBeenFound(): void + { + $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); + $drives = []; + if (isset(\json_decode($rawBody, true)["value"])) { + $drives = \json_decode($rawBody, true)["value"]; + } + + Assert::assertArrayHasKey(0, $drives, "No drives were found on that endpoint"); + + foreach($drives as $drive) { + if (isset($drive["driveType"]) && $drive["driveType"] === "personal") { + $this->setPersonalDriveWebDavUrl($drive["root"]["webDavUrl"]); + + Assert::assertNotEmpty( + $drive["root"]["webDavUrl"], + "The personal space attributes contain no webDavUrl" + ); + } + } + } + + /** + * @When /^user "([^"]*)" lists the content of the personal space root using the WebDav Api$/ + * + * @param $user + * + * @return void + */ + public function theUserListsTheContentOfAPersonalSpaceRootUsingTheWebDAvApi($user): void + { + $this->theUserListsAllHisAvailableSpacesUsingTheGraphApi($user); + $this->theWebDavUrlOfThePersonalSpaceHasBeenFound(); + $this->featureContext->setResponse( + $this->sendPropfindRequestToUrl( + $this->getPersonalDriveWebDavUrl(), + $user, + $this->featureContext->getPasswordForUser($user), + "", + [], + [], + [] + ) + ); + } +}