diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29cc1d129e..eb58f7f8cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -445,19 +445,19 @@ jobs: ] include: - service: Databases - runner: blacksmith-4vcpu-ubuntu-2404 + runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g paratest_processes: 3 timeout_minutes: 30 - service: Sites - runner: blacksmith-4vcpu-ubuntu-2404 + runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g - service: Functions - runner: blacksmith-4vcpu-ubuntu-2404 + runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g - service: Avatars - runner: blacksmith-4vcpu-ubuntu-2404 + runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g - service: Realtime - runner: blacksmith-4vcpu-ubuntu-2404 + runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g - service: TablesDB - runner: blacksmith-4vcpu-ubuntu-2404 + runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g paratest_processes: 3 timeout_minutes: 30 - service: Migrations diff --git a/composer.json b/composer.json index 9a84be6111..55106d33d1 100644 --- a/composer.json +++ b/composer.json @@ -68,11 +68,11 @@ "utopia-php/dns": "1.6.*", "utopia-php/dsn": "0.2.1", "utopia-php/http": "0.34.*", - "utopia-php/fetch": "0.5.*", + "utopia-php/fetch": "^1.1", "utopia-php/validators": "0.2.*", "utopia-php/image": "0.8.*", "utopia-php/locale": "0.8.*", - "utopia-php/logger": "0.6.*", + "utopia-php/logger": "0.8.*", "utopia-php/messaging": "0.22.*", "utopia-php/migration": "1.*", "utopia-php/platform": "0.13.*", diff --git a/composer.lock b/composer.lock index d356362788..f7b443b135 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ec2ad489c60f0102f0dfab223b6d1fe4", + "content-hash": "4ef65b015dba97e91f6571b061787653", "packages": [ { "name": "adhocore/jwt", @@ -3411,21 +3411,21 @@ }, { "name": "utopia-php/agents", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/utopia-php/agents.git", - "reference": "052227953678a30ecc4b5467401fcb0b2386471e" + "reference": "0703f4cae02261e09a1bf0d39a4b1ce649cae634" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/agents/zipball/052227953678a30ecc4b5467401fcb0b2386471e", - "reference": "052227953678a30ecc4b5467401fcb0b2386471e", + "url": "https://api.github.com/repos/utopia-php/agents/zipball/0703f4cae02261e09a1bf0d39a4b1ce649cae634", + "reference": "0703f4cae02261e09a1bf0d39a4b1ce649cae634", "shasum": "" }, "require": { "php": ">=8.3", - "utopia-php/fetch": "0.5.*" + "utopia-php/fetch": "^1.1.0" }, "require-dev": { "laravel/pint": "^1.18", @@ -3458,9 +3458,9 @@ ], "support": { "issues": "https://github.com/utopia-php/agents/issues", - "source": "https://github.com/utopia-php/agents/tree/1.2.1" + "source": "https://github.com/utopia-php/agents/tree/1.2.2" }, - "time": "2026-02-24T06:03:55+00:00" + "time": "2026-05-08T10:38:23+00:00" }, { "name": "utopia-php/analytics", @@ -3510,22 +3510,22 @@ }, { "name": "utopia-php/audit", - "version": "2.2.2", + "version": "2.2.3", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "90886c202e7983999e6b6a8201004d5ab61d4b57" + "reference": "95e9961fa286d2fdb6bf3eaa198f21d51bf58d9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/90886c202e7983999e6b6a8201004d5ab61d4b57", - "reference": "90886c202e7983999e6b6a8201004d5ab61d4b57", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/95e9961fa286d2fdb6bf3eaa198f21d51bf58d9c", + "reference": "95e9961fa286d2fdb6bf3eaa198f21d51bf58d9c", "shasum": "" }, "require": { "php": ">=8.0", "utopia-php/database": "5.*", - "utopia-php/fetch": "0.5.*", + "utopia-php/fetch": "^1.1", "utopia-php/validators": "0.2.*" }, "require-dev": { @@ -3553,9 +3553,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/2.2.2" + "source": "https://github.com/utopia-php/audit/tree/2.2.3" }, - "time": "2026-05-04T06:48:58+00:00" + "time": "2026-05-08T10:38:23+00:00" }, { "name": "utopia-php/auth", @@ -4180,22 +4180,21 @@ }, { "name": "utopia-php/emails", - "version": "0.6.9", + "version": "0.6.10", "source": { "type": "git", "url": "https://github.com/utopia-php/emails.git", - "reference": "3a59fb392a03a88f5497e5fdb0ea84a252a4dfdf" + "reference": "2e397754ce68c2ba918564b9f31d9923c0a90429" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/emails/zipball/3a59fb392a03a88f5497e5fdb0ea84a252a4dfdf", - "reference": "3a59fb392a03a88f5497e5fdb0ea84a252a4dfdf", + "url": "https://api.github.com/repos/utopia-php/emails/zipball/2e397754ce68c2ba918564b9f31d9923c0a90429", + "reference": "2e397754ce68c2ba918564b9f31d9923c0a90429", "shasum": "" }, "require": { "php": ">=8.0", "utopia-php/domains": "^1.0", - "utopia-php/fetch": "^0.5", "utopia-php/validators": "0.*" }, "require-dev": { @@ -4203,7 +4202,8 @@ "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.3", "utopia-php/cli": "^0.22", - "utopia-php/console": "0.*" + "utopia-php/console": "0.*", + "utopia-php/fetch": "^1.1" }, "type": "library", "autoload": { @@ -4235,22 +4235,22 @@ ], "support": { "issues": "https://github.com/utopia-php/emails/issues", - "source": "https://github.com/utopia-php/emails/tree/0.6.9" + "source": "https://github.com/utopia-php/emails/tree/0.6.10" }, - "time": "2026-03-14T13:52:56+00:00" + "time": "2026-05-08T10:16:22+00:00" }, { "name": "utopia-php/fetch", - "version": "0.5.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/utopia-php/fetch.git", - "reference": "a96a010e1c273f3888765449687baf58cbc61fcd" + "reference": "64f2b3a789480f1deb102ce684dac4217d8e98d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/fetch/zipball/a96a010e1c273f3888765449687baf58cbc61fcd", - "reference": "a96a010e1c273f3888765449687baf58cbc61fcd", + "url": "https://api.github.com/repos/utopia-php/fetch/zipball/64f2b3a789480f1deb102ce684dac4217d8e98d5", + "reference": "64f2b3a789480f1deb102ce684dac4217d8e98d5", "shasum": "" }, "require": { @@ -4259,7 +4259,8 @@ "require-dev": { "laravel/pint": "^1.5.0", "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^9.5", + "swoole/ide-helper": "^6.0" }, "type": "library", "autoload": { @@ -4274,9 +4275,9 @@ "description": "A simple library that provides an interface for making HTTP Requests.", "support": { "issues": "https://github.com/utopia-php/fetch/issues", - "source": "https://github.com/utopia-php/fetch/tree/0.5.1" + "source": "https://github.com/utopia-php/fetch/tree/1.1.2" }, - "time": "2025-12-18T16:25:10+00:00" + "time": "2026-04-29T11:19:19+00:00" }, { "name": "utopia-php/http", @@ -4434,20 +4435,21 @@ }, { "name": "utopia-php/logger", - "version": "0.6.2", + "version": "0.8.0", "source": { "type": "git", "url": "https://github.com/utopia-php/logger.git", - "reference": "25b5bd2ad8bb51292f76332faa7034644fd0941d" + "reference": "132236c42222cd614cb882938a48f8729ef3118b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/25b5bd2ad8bb51292f76332faa7034644fd0941d", - "reference": "25b5bd2ad8bb51292f76332faa7034644fd0941d", + "url": "https://api.github.com/repos/utopia-php/logger/zipball/132236c42222cd614cb882938a48f8729ef3118b", + "reference": "132236c42222cd614cb882938a48f8729ef3118b", "shasum": "" }, "require": { - "php": ">=8.0" + "php": ">=8.1", + "utopia-php/fetch": "^1.1" }, "require-dev": { "laravel/pint": "1.2.*", @@ -4482,9 +4484,9 @@ ], "support": { "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.6.2" + "source": "https://github.com/utopia-php/logger/tree/0.8.0" }, - "time": "2024-10-14T16:02:49+00:00" + "time": "2026-05-05T06:04:27+00:00" }, { "name": "utopia-php/messaging", @@ -5254,23 +5256,23 @@ }, { "name": "utopia-php/vcs", - "version": "3.2.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "44a84ab52b42fc12f812b4d7331286b519d39db3" + "reference": "03ccd12b75d67d29094eb760b468fddde4b6b5e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/44a84ab52b42fc12f812b4d7331286b519d39db3", - "reference": "44a84ab52b42fc12f812b4d7331286b519d39db3", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/03ccd12b75d67d29094eb760b468fddde4b6b5e5", + "reference": "03ccd12b75d67d29094eb760b468fddde4b6b5e5", "shasum": "" }, "require": { "adhocore/jwt": "^1.1", "php": ">=8.0", "utopia-php/cache": "1.0.*", - "utopia-php/fetch": "0.5.*" + "utopia-php/fetch": "^1.1" }, "require-dev": { "laravel/pint": "1.*.*", @@ -5297,9 +5299,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/3.2.0" + "source": "https://github.com/utopia-php/vcs/tree/3.2.1" }, - "time": "2026-04-08T16:00:31+00:00" + "time": "2026-05-08T10:13:53+00:00" }, { "name": "utopia-php/websocket", diff --git a/docs/references/vcs/list-repository-branches.md b/docs/references/vcs/list-repository-branches.md index eea1795a3e..b614c2ad13 100644 --- a/docs/references/vcs/list-repository-branches.md +++ b/docs/references/vcs/list-repository-branches.md @@ -1 +1 @@ -Get a list of all branches from a GitHub repository in your installation. This endpoint returns the names of all branches in the repository and their total count. The GitHub installation must be properly configured and have access to the requested repository for this endpoint to work. +Get a list of branches from a GitHub repository in your installation. This endpoint supports filtering by a search term and pagination using query strings such as `Query.limit()`, `Query.offset()`, `Query.cursorAfter()`, and `Query.cursorBefore()`. It returns branch names along with the total number of matches. The GitHub installation must be properly configured and have access to the requested repository for this endpoint to work. diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php b/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php index 7d1cdc4980..c766f73929 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php @@ -109,9 +109,7 @@ class Screenshots extends Action throw new \Exception("Rule for deployment not found"); } - $client = new FetchClient(); - $client->setTimeout(\intval($site->getAttribute('timeout', '15')) * 1000); - $client->addHeader('content-type', FetchClient::CONTENT_TYPE_APPLICATION_JSON); + $timeout = \intval($site->getAttribute('timeout', '15')) * 1000; $bucket = $dbForPlatform->getDocument('buckets', 'screenshots'); @@ -162,8 +160,8 @@ class Screenshots extends Action ]); $screenshotError = null; - $screenshots = batch(\array_map(function ($key) use ($configs, $apiKey, $site, $client, &$screenshotError) { - return function () use ($key, $configs, $apiKey, $site, $client, &$screenshotError) { + $screenshots = batch(\array_map(function ($key) use ($configs, $apiKey, $site, $timeout, &$screenshotError) { + return function () use ($key, $configs, $apiKey, $site, $timeout, &$screenshotError) { try { $config = $configs[$key]; @@ -179,6 +177,10 @@ class Screenshots extends Action } $browserEndpoint = System::getEnv('_APP_BROWSER_HOST', 'http://appwrite-browser:3000/v1'); + $client = new FetchClient(); + $client->setTimeout($timeout); + $client->addHeader('content-type', FetchClient::CONTENT_TYPE_APPLICATION_JSON); + $fetchResponse = $client->fetch( url: $browserEndpoint . '/screenshots', method: 'POST', diff --git a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Preview/Get.php b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Preview/Get.php index cb0d8c76ef..cb511d5231 100644 --- a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Preview/Get.php +++ b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Preview/Get.php @@ -245,28 +245,43 @@ class Get extends Action throw new Exception(Exception::STORAGE_FILE_TYPE_UNSUPPORTED, $e->getMessage()); } - $image->crop((int) $width, (int) $height, $gravity); + if ($width > 0 || $height > 0 || $gravity !== Image::GRAVITY_CENTER) { + Span::add('storage.transform.crop.width', $width); + Span::add('storage.transform.crop.height', $height); + Span::add('storage.transform.crop.gravity', $gravity); + $image->crop($width, $height, $gravity); + } - if (!empty($opacity)) { + if ($opacity !== 1.0) { + Span::add('storage.transform.opacity', $opacity); $image->setOpacity($opacity); } if (!empty($background)) { + Span::add('storage.transform.background', $background); $image->setBackground('#' . $background); } - if (!empty($borderWidth)) { + if ($borderWidth > 0) { + Span::add('storage.transform.border.width', $borderWidth); + Span::add('storage.transform.border.color', $borderColor); $image->setBorder($borderWidth, '#' . $borderColor); } - if (!empty($borderRadius)) { + if ($borderRadius > 0) { + Span::add('storage.transform.borderRadius', $borderRadius); $image->setBorderRadius($borderRadius); } - if (!empty($rotation)) { + if ($rotation !== 0) { + Span::add('storage.transform.rotation', $rotation); $image->setRotation(($rotation + 360) % 360); } + if ($quality !== -1) { + Span::add('storage.transform.quality', $quality); + } + $data = $image->output($output, $quality); $renderingTime = \microtime(true) - $startTime - $downloadTime - $decryptionTime - $decompressionTime; diff --git a/src/Appwrite/Platform/Modules/VCS/Http/Installations/Repositories/Branches/XList.php b/src/Appwrite/Platform/Modules/VCS/Http/Installations/Repositories/Branches/XList.php index 8ead94b7cb..fda462159f 100644 --- a/src/Appwrite/Platform/Modules/VCS/Http/Installations/Repositories/Branches/XList.php +++ b/src/Appwrite/Platform/Modules/VCS/Http/Installations/Repositories/Branches/XList.php @@ -7,9 +7,12 @@ use Appwrite\Platform\Action; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; +use Appwrite\Utopia\Database\Validator\Queries\Branches; use Appwrite\Utopia\Response; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Exception\Query as QueryException; +use Utopia\Database\Query; use Utopia\Platform\Scope\HTTP; use Utopia\System\System; use Utopia\Validator\Text; @@ -49,6 +52,8 @@ class XList extends Action )) ->param('installationId', '', new Text(256), 'Installation Id') ->param('providerRepositoryId', '', new Text(256), 'Repository Id') + ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) + ->param('queries', [], new Branches(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit, offset, cursorAfter, and cursorBefore', true) ->inject('gitHub') ->inject('response') ->inject('dbForPlatform') @@ -58,10 +63,18 @@ class XList extends Action public function action( string $installationId, string $providerRepositoryId, + string $search, + array $queries, GitHub $github, Response $response, Database $dbForPlatform ) { + try { + $queries = Query::parseQueries($queries); + } catch (QueryException $e) { + throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); + } + $installation = $dbForPlatform->getDocument('installations', $installationId); if ($installation->isEmpty()) { @@ -85,11 +98,48 @@ class XList extends Action $branches = $github->listBranches($owner, $repositoryName); + if (!empty($search)) { + $branches = \array_values(\array_filter($branches, fn (string $branch) => \stripos($branch, $search) !== false)); + } + + $total = \count($branches); + [ + 'limit' => $limit, + 'offset' => $offset, + ] = Query::groupByType($queries); + $cursorQuery = \current(Query::getCursorQueries($queries, false)); + + $limit ??= APP_LIMIT_LIST_DEFAULT; + $offset ??= 0; + + if ($cursorQuery instanceof Query) { + $cursor = $cursorQuery->getValue(); + $cursorDirection = $cursorQuery->getMethod() === Query::TYPE_CURSOR_AFTER + ? Database::CURSOR_AFTER + : Database::CURSOR_BEFORE; + + $cursorIndex = \array_search($cursor, $branches, true); + if ($cursorIndex === false) { + throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Branch '{$cursor}' for the 'cursor' value not found."); + } + + $offset += $cursorDirection === Database::CURSOR_AFTER ? $cursorIndex + 1 : 0; + + if ($cursorDirection === Database::CURSOR_BEFORE) { + $start = \max(0, $cursorIndex - $limit); + $branches = \array_slice($branches, $start, $cursorIndex - $start); + } else { + $branches = \array_slice($branches, $offset, $limit); + } + } else { + $branches = \array_slice($branches, $offset, $limit); + } + $response->dynamic(new Document([ 'branches' => \array_map(function ($branch) { return new Document(['name' => $branch]); }, $branches), - 'total' => \count($branches), + 'total' => $total, ]), Response::MODEL_BRANCH_LIST); } } diff --git a/src/Appwrite/SDK/Specification/Format/OpenAPI3.php b/src/Appwrite/SDK/Specification/Format/OpenAPI3.php index 962bc8948a..c491a3211d 100644 --- a/src/Appwrite/SDK/Specification/Format/OpenAPI3.php +++ b/src/Appwrite/SDK/Specification/Format/OpenAPI3.php @@ -755,7 +755,18 @@ class OpenAPI3 extends Format $node['schema']['default'] = $param['default']; } - if (false !== \strpos($url, ':' . $name)) { // Param is in URL path + $pathAliases = [$name, ...($param['aliases'] ?? [])]; + $pathAliasMap = \array_flip($pathAliases); + $isPathParam = false; + + foreach (\explode('/', $url) as $segment) { + if ($segment !== '' && $segment[0] === ':' && isset($pathAliasMap[\substr($segment, 1)])) { + $isPathParam = true; + break; + } + } + + if ($isPathParam) { // Param is in URL path (directly or through alias) $node['in'] = 'path'; $temp['parameters'][] = $node; } elseif ($route->getMethod() == 'GET') { // Param is in query @@ -796,7 +807,14 @@ class OpenAPI3 extends Format } } - $url = \str_replace(':' . $name, '{' . $name . '}', $url); + $segments = \explode('/', $url); + foreach ($segments as &$segment) { + if ($segment !== '' && $segment[0] === ':' && isset($pathAliasMap[\substr($segment, 1)])) { + $segment = '{' . $name . '}'; + } + } + unset($segment); + $url = \implode('/', $segments); } if (!empty($bodyRequired)) { diff --git a/src/Appwrite/SDK/Specification/Format/Swagger2.php b/src/Appwrite/SDK/Specification/Format/Swagger2.php index d07d957577..1dbba73a94 100644 --- a/src/Appwrite/SDK/Specification/Format/Swagger2.php +++ b/src/Appwrite/SDK/Specification/Format/Swagger2.php @@ -722,7 +722,18 @@ class Swagger2 extends Format $node['default'] = $param['default']; } - if (\str_contains($url, ':' . $name)) { // Param is in URL path + $pathAliases = [$name, ...($param['aliases'] ?? [])]; + $pathAliasMap = \array_flip($pathAliases); + $isPathParam = false; + + foreach (\explode('/', $url) as $segment) { + if ($segment !== '' && $segment[0] === ':' && isset($pathAliasMap[\substr($segment, 1)])) { + $isPathParam = true; + break; + } + } + + if ($isPathParam) { // Param is in URL path (directly or through alias) $node['in'] = 'path'; $temp['parameters'][] = $node; } elseif ($route->getMethod() == 'GET') { // Param is in query @@ -767,7 +778,14 @@ class Swagger2 extends Format } } - $url = \str_replace(':' . $name, '{' . $name . '}', $url); + $segments = \explode('/', $url); + foreach ($segments as &$segment) { + if ($segment !== '' && $segment[0] === ':' && isset($pathAliasMap[\substr($segment, 1)])) { + $segment = '{' . $name . '}'; + } + } + unset($segment); + $url = \implode('/', $segments); } if (!empty($bodyRequired)) { diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Branches.php b/src/Appwrite/Utopia/Database/Validator/Queries/Branches.php new file mode 100644 index 0000000000..82ca911747 --- /dev/null +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Branches.php @@ -0,0 +1,20 @@ +getMethod(); + + if (!\in_array($method, [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE], true)) { + $this->message = 'Invalid query method: ' . $method; + return false; + } + + $cursor = $value->getValue(); + + $validator = new Text(256); + if (!$validator->isValid($cursor)) { + $this->message = 'Invalid cursor: ' . $validator->getDescription(); + return false; + } + + return true; + } + + public function getMethodType(): string + { + return self::METHOD_TYPE_CURSOR; + } +} diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index 854e7110f1..23007339de 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -513,6 +513,59 @@ class VCSConsoleClientTest extends Scope $this->assertEquals($repositoryBranches['body']['branches'][0]['name'], 'main'); $this->assertEquals($repositoryBranches['body']['branches'][1]['name'], 'test'); + $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId . '/branches', array_merge([ + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => 'tes', + ]); + + $this->assertEquals(200, $repositoryBranches['headers']['status-code']); + $this->assertEquals($repositoryBranches['body']['total'], 1); + $this->assertCount(1, $repositoryBranches['body']['branches']); + $this->assertEquals($repositoryBranches['body']['branches'][0]['name'], 'test'); + + $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId . '/branches', array_merge([ + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [ + Query::limit(1)->toString(), + Query::offset(1)->toString(), + ], + ]); + + $this->assertEquals(200, $repositoryBranches['headers']['status-code']); + $this->assertEquals($repositoryBranches['body']['total'], 2); + $this->assertCount(1, $repositoryBranches['body']['branches']); + $this->assertEquals($repositoryBranches['body']['branches'][0]['name'], 'test'); + + $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId . '/branches', array_merge([ + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [ + Query::limit(1)->toString(), + Query::cursorAfter(new \Utopia\Database\Document(['$id' => 'main']))->toString(), + ], + ]); + + $this->assertEquals(200, $repositoryBranches['headers']['status-code']); + $this->assertEquals($repositoryBranches['body']['total'], 2); + $this->assertCount(1, $repositoryBranches['body']['branches']); + $this->assertEquals($repositoryBranches['body']['branches'][0]['name'], 'test'); + + $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId . '/branches', array_merge([ + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [ + Query::limit(1)->toString(), + Query::cursorBefore(new \Utopia\Database\Document(['$id' => 'test']))->toString(), + ], + ]); + + $this->assertEquals(200, $repositoryBranches['headers']['status-code']); + $this->assertEquals($repositoryBranches['body']['total'], 2); + $this->assertCount(1, $repositoryBranches['body']['branches']); + $this->assertEquals($repositoryBranches['body']['branches'][0]['name'], 'main'); + /** * Test for FAILURE */ @@ -522,6 +575,16 @@ class VCSConsoleClientTest extends Scope ], $this->getHeaders())); $this->assertEquals(404, $repositoryBranches['headers']['status-code']); + + $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId . '/branches', array_merge([ + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [ + Query::cursorAfter(new \Utopia\Database\Document(['$id' => 'missing-branch']))->toString(), + ], + ]); + + $this->assertEquals(400, $repositoryBranches['headers']['status-code']); } public function testCreateFunctionUsingVCS(): void