diff --git a/libs/sandboxes-service-api-client/src/Apps/App.php b/libs/sandboxes-service-api-client/src/Apps/App.php index e9bacbedc..3b3b7675c 100644 --- a/libs/sandboxes-service-api-client/src/Apps/App.php +++ b/libs/sandboxes-service-api-client/src/Apps/App.php @@ -61,6 +61,7 @@ class App private string $id; private string $projectId; private string $componentId; + private ?string $type = null; private ?string $branchId = null; private string $configId; private string $configVersion; @@ -83,6 +84,7 @@ public static function fromArray(array $in): self $app->setId((string) $in['id']); $app->setProjectId((string) $in['projectId']); $app->setComponentId((string) $in['componentId']); + $app->setType(isset($in['type']) ? (string) $in['type'] : null); $app->setBranchId(isset($in['branchId']) ? $in['branchId'] : null); $app->setConfigId((string) $in['configId']); $app->setConfigVersion((string) $in['configVersion']); @@ -102,6 +104,7 @@ public function toArray(): array 'id' => $this->id, 'projectId' => $this->projectId, 'componentId' => $this->componentId, + 'type' => $this->type, 'branchId' => $this->branchId, 'configId' => $this->configId, 'configVersion' => $this->configVersion, @@ -147,6 +150,17 @@ public function setComponentId(string $componentId): self return $this; } + public function getType(): ?string + { + return $this->type; + } + + public function setType(?string $type): self + { + $this->type = $type; + return $this; + } + public function getBranchId(): ?string { return $this->branchId; diff --git a/libs/sandboxes-service-api-client/src/Apps/AppsApiClient.php b/libs/sandboxes-service-api-client/src/Apps/AppsApiClient.php index 1c4efce9f..8b514ca4f 100644 --- a/libs/sandboxes-service-api-client/src/Apps/AppsApiClient.php +++ b/libs/sandboxes-service-api-client/src/Apps/AppsApiClient.php @@ -19,12 +19,18 @@ public function __construct(ApiClientConfiguration $configuration) } /** - * @param int|null $offset - * @param int|null $limit + * @param int|null $offset + * @param int|null $limit + * @param list $types Filter by app type (e.g. 'python', 'r', 'streamlit') + * @param bool $listAll When true, lists all apps in the project regardless of token ownership * @return array */ - public function listApps(?int $offset = null, ?int $limit = null): array - { + public function listApps( + ?int $offset = null, + ?int $limit = null, + array $types = [], + bool $listAll = false, + ): array { $queryParams = []; if ($offset !== null) { $queryParams['offset'] = (string) $offset; @@ -32,6 +38,12 @@ public function listApps(?int $offset = null, ?int $limit = null): array if ($limit !== null) { $queryParams['limit'] = (string) $limit; } + foreach ($types as $type) { + $queryParams['type'][] = $type; + } + if ($listAll) { + $queryParams['listAll'] = '1'; + } $uri = '/apps'; if (!empty($queryParams)) { diff --git a/libs/sandboxes-service-api-client/tests/Apps/AppTest.php b/libs/sandboxes-service-api-client/tests/Apps/AppTest.php index 9bdd51977..c4249f494 100644 --- a/libs/sandboxes-service-api-client/tests/Apps/AppTest.php +++ b/libs/sandboxes-service-api-client/tests/Apps/AppTest.php @@ -71,6 +71,7 @@ public function testToArray(): void 'id' => 'app-id', 'projectId' => 'project-id', 'componentId' => 'keboola.data-apps', + 'type' => null, 'branchId' => 'branch-id', 'configId' => 'config-id', 'configVersion' => '5', diff --git a/libs/sandboxes-service-api-client/tests/Apps/AppsApiClientTest.php b/libs/sandboxes-service-api-client/tests/Apps/AppsApiClientTest.php index fc60d98f4..5a479304a 100644 --- a/libs/sandboxes-service-api-client/tests/Apps/AppsApiClientTest.php +++ b/libs/sandboxes-service-api-client/tests/Apps/AppsApiClientTest.php @@ -326,6 +326,94 @@ public function testListAppsWithOnlyLimit(): void ); } + public function testListAppsWithListAll(): void + { + $responseBody = []; + + $requestHandler = self::createRequestHandler($requestsHistory, [ + new Response( + 200, + ['Content-Type' => 'application/json'], + Json::encodeArray($responseBody), + ), + ]); + + $client = new AppsApiClient( + new ApiClientConfiguration( + baseUrl: 'https://data-apps.keboola.com', + storageToken: 'my-token', + userAgent: 'Keboola Sandboxes Service API PHP Client', + requestHandler: $requestHandler(...), + ), + ); + $result = $client->listApps(listAll: true); + + self::assertEquals([], $result); + + self::assertCount(1, $requestsHistory); + self::assertRequestEquals( + 'GET', + 'https://data-apps.keboola.com/apps?listAll=1', + [ + 'X-StorageApi-Token' => 'my-token', + ], + '', + $requestsHistory[0]['request'], + ); + } + + public function testListAppsWithTypes(): void + { + $responseBody = [ + [ + 'id' => 'app-id-1', + 'projectId' => 'project-id', + 'componentId' => 'keboola.jupyter-sandbox', + 'type' => 'python', + 'branchId' => null, + 'configId' => 'config-id-1', + 'configVersion' => '1', + 'state' => 'running', + 'desiredState' => 'running', + 'lastRequestTimestamp' => '2024-02-01T08:00:00+01:00', + 'url' => null, + 'autoSuspendAfterSeconds' => 3600, + 'provisioningStrategy' => 'operator', + ], + ]; + + $requestHandler = self::createRequestHandler($requestsHistory, [ + new Response( + 200, + ['Content-Type' => 'application/json'], + Json::encodeArray($responseBody), + ), + ]); + + $client = new AppsApiClient( + new ApiClientConfiguration( + baseUrl: 'https://data-apps.keboola.com', + storageToken: 'my-token', + userAgent: 'Keboola Sandboxes Service API PHP Client', + requestHandler: $requestHandler(...), + ), + ); + $result = $client->listApps(types: ['python', 'r']); + + self::assertEquals([App::fromArray($responseBody[0])], $result); + + self::assertCount(1, $requestsHistory); + self::assertRequestEquals( + 'GET', + 'https://data-apps.keboola.com/apps?type%5B0%5D=python&type%5B1%5D=r', + [ + 'X-StorageApi-Token' => 'my-token', + ], + '', + $requestsHistory[0]['request'], + ); + } + public function testCreateApp(): void { $responseBody = [