diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index 988f061ed5..765688e1ee 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -538,7 +538,7 @@ App::get('/v1/health/queue/databases') ->inject('response') ->action(function (string $name, int|string $threshold, Database $queueForDatabase, Response $response) { $threshold = \intval($threshold); - $size = $queueForDatabase->getSize(); + $size = $queueForDatabase->setQueue($name)->getSize(); if ($size >= $threshold) { throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}."); diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index a551ba3a5a..3eaf0fac04 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -246,10 +246,11 @@ App::init() $role = $apiKey->getRole(); $scopes = $apiKey->getScopes(); - // Disable authorization checks for API keys - Authorization::setDefaultStatus(false); if ($apiKey->getRole() === Auth::USER_ROLE_APPS) { + // Disable authorization checks for API keys + Authorization::setDefaultStatus(false); + $user = new Document([ '$id' => '', 'status' => true, diff --git a/app/http.php b/app/http.php index 09e233a216..dcc39e36d6 100644 --- a/app/http.php +++ b/app/http.php @@ -10,6 +10,7 @@ use Swoole\Http\Response as SwooleResponse; use Swoole\Http\Server; use Swoole\Process; use Swoole\Table; +use Swoole\Timer; use Utopia\App; use Utopia\Audit\Audit; use Utopia\CLI\Console; @@ -156,11 +157,16 @@ $http->on(Constant::EVENT_WORKER_START, function ($server, $workerId) { Console::success('Worker ' . ++$workerId . ' started successfully'); }); -$http->on(Constant::EVENT_BEFORE_RELOAD, function ($server, $workerId) { +$http->on(Constant::EVENT_WORKER_STOP, function ($server, $workerId) { + Timer::clearAll(); + Console::success('Worker ' . ++$workerId . ' stopped successfully'); +}); + +$http->on(Constant::EVENT_BEFORE_RELOAD, function ($server) { Console::success('Starting reload...'); }); -$http->on(Constant::EVENT_AFTER_RELOAD, function ($server, $workerId) { +$http->on(Constant::EVENT_AFTER_RELOAD, function ($server) { Console::success('Reload completed...'); }); @@ -551,7 +557,7 @@ $http->on(Constant::EVENT_TASK, function () use ($register, $domains) { /** @var Utopia\Database\Database $dbForPlatform */ $dbForPlatform = $app->getResource('dbForPlatform'); - Console::loop(function () use ($dbForPlatform, $domains, &$lastSyncUpdate) { + Timer::tick(DOMAIN_SYNC_TIMER * 1000, function () use ($dbForPlatform, $domains, &$lastSyncUpdate) { try { $time = DateTime::now(); $limit = 1000; @@ -590,8 +596,6 @@ $http->on(Constant::EVENT_TASK, function () use ($register, $domains) { } catch (Throwable $th) { Console::error($th->getMessage()); } - }, DOMAIN_SYNC_TIMER, 0, function ($error) { - Console::error($error); }); }); diff --git a/composer.lock b/composer.lock index a35a21ee89..e454de0313 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": "ce433cef8711249299b58cc36419d912", + "content-hash": "7553e976312b0423cc31544abb91caec", "packages": [ { "name": "adhocore/jwt", @@ -962,83 +962,6 @@ }, "time": "2025-08-20T17:20:16+00:00" }, - { - "name": "mongodb/mongodb", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/mongodb/mongo-php-library.git", - "reference": "3bbe7ba9578724c7e1f47fcd17c881c0995baaad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/3bbe7ba9578724c7e1f47fcd17c881c0995baaad", - "reference": "3bbe7ba9578724c7e1f47fcd17c881c0995baaad", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.0", - "ext-mongodb": "^2.1", - "php": "^8.1", - "psr/log": "^1.1.4|^2|^3", - "symfony/polyfill-php85": "^1.32" - }, - "replace": { - "mongodb/builder": "*" - }, - "require-dev": { - "doctrine/coding-standard": "^12.0", - "phpunit/phpunit": "^10.5.35", - "rector/rector": "^1.2", - "squizlabs/php_codesniffer": "^3.7", - "vimeo/psalm": "6.5.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "MongoDB\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Andreas Braun", - "email": "andreas.braun@mongodb.com" - }, - { - "name": "Jeremy Mikola", - "email": "jmikola@gmail.com" - }, - { - "name": "Jérôme Tamarelle", - "email": "jerome.tamarelle@mongodb.com" - } - ], - "description": "MongoDB driver library", - "homepage": "https://jira.mongodb.org/browse/PHPLIB", - "keywords": [ - "database", - "driver", - "mongodb", - "persistence" - ], - "support": { - "issues": "https://github.com/mongodb/mongo-php-library/issues", - "source": "https://github.com/mongodb/mongo-php-library/tree/2.1.0" - }, - "time": "2025-05-23T10:48:05+00:00" - }, { "name": "mustangostang/spyc", "version": "0.6.3", @@ -3097,86 +3020,6 @@ ], "time": "2025-07-08T02:45:35+00:00" }, - { - "name": "symfony/polyfill-php85", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php85\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.5+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.33.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2025-06-23T16:12:55+00:00" - }, { "name": "symfony/service-contracts", "version": "v3.6.0", @@ -3795,16 +3638,16 @@ }, { "name": "utopia-php/database", - "version": "dev-feat-mongo-tmp-pulls", + "version": "1.4.8", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "c967e720efb4b5ad6f14b8313c85faac3d7bdb16" + "reference": "dbecdf89fde33a5f81ec19f4f97fe0c3715dc83a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/c967e720efb4b5ad6f14b8313c85faac3d7bdb16", - "reference": "c967e720efb4b5ad6f14b8313c85faac3d7bdb16", + "url": "https://api.github.com/repos/utopia-php/database/zipball/dbecdf89fde33a5f81ec19f4f97fe0c3715dc83a", + "reference": "dbecdf89fde33a5f81ec19f4f97fe0c3715dc83a", "shasum": "" }, "require": { @@ -3813,7 +3656,6 @@ "php": ">=8.1", "utopia-php/cache": "0.13.*", "utopia-php/framework": "0.33.*", - "utopia-php/mongo": "dev-feat-create-UUID as 0.5.3", "utopia-php/pools": "0.8.*" }, "require-dev": { @@ -3846,9 +3688,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/feat-mongo-tmp-pulls" + "source": "https://github.com/utopia-php/database/tree/1.4.8" }, - "time": "2025-09-11T09:50:34+00:00" + "time": "2025-09-12T03:35:59+00:00" }, { "name": "utopia-php/detector", @@ -4402,67 +4244,6 @@ }, "time": "2025-09-10T06:17:20+00:00" }, - { - "name": "utopia-php/mongo", - "version": "dev-feat-create-UUID", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/mongo.git", - "reference": "682c2e0b8474acfca1953eaca321f6f9bb0245f0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/mongo/zipball/682c2e0b8474acfca1953eaca321f6f9bb0245f0", - "reference": "682c2e0b8474acfca1953eaca321f6f9bb0245f0", - "shasum": "" - }, - "require": { - "ext-mongodb": "2.1.1", - "mongodb/mongodb": "2.1.0", - "php": ">=8.0", - "ramsey/uuid": "^4.9.0" - }, - "require-dev": { - "fakerphp/faker": "^1.14", - "laravel/pint": "1.2.*", - "phpstan/phpstan": "2.1.*", - "phpunit/phpunit": "^9.4", - "swoole/ide-helper": "4.8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Mongo\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Wess", - "email": "wess@appwrite.io" - } - ], - "description": "A simple library to manage Mongo database", - "keywords": [ - "database", - "mongo", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/mongo/issues", - "source": "https://github.com/utopia-php/mongo/tree/feat-create-UUID" - }, - "time": "2025-09-11T10:51:49+00:00" - }, { "name": "utopia-php/orchestration", "version": "0.9.1", @@ -4670,16 +4451,16 @@ }, { "name": "utopia-php/queue", - "version": "0.11.0", + "version": "0.11.1", "source": { "type": "git", "url": "https://github.com/utopia-php/queue.git", - "reference": "06b5ced0eaed2ecc6aab6d8e1b4d96bff37a1ce5" + "reference": "498bbbef418b1db71b51e1bb62f5d1d752ddd8d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/06b5ced0eaed2ecc6aab6d8e1b4d96bff37a1ce5", - "reference": "06b5ced0eaed2ecc6aab6d8e1b4d96bff37a1ce5", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/498bbbef418b1db71b51e1bb62f5d1d752ddd8d6", + "reference": "498bbbef418b1db71b51e1bb62f5d1d752ddd8d6", "shasum": "" }, "require": { @@ -4730,9 +4511,9 @@ ], "support": { "issues": "https://github.com/utopia-php/queue/issues", - "source": "https://github.com/utopia-php/queue/tree/0.11.0" + "source": "https://github.com/utopia-php/queue/tree/0.11.1" }, - "time": "2025-05-30T09:52:38+00:00" + "time": "2025-05-30T11:50:34+00:00" }, { "name": "utopia-php/registry", @@ -8729,19 +8510,10 @@ "time": "2024-03-07T20:33:40+00:00" } ], - "aliases": [ - { - "package": "utopia-php/database", - "version": "dev-feat-mongo-tmp-pulls", - "alias": "1.4.6", - "alias_normalized": "1.4.6.0" - } - ], - "minimum-stability": "dev", - "stability-flags": { - "utopia-php/database": 20 - }, - "prefer-stable": true, + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, "prefer-lowest": false, "platform": { "php": ">=8.3.0", @@ -8764,5 +8536,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } diff --git a/package.json b/package.json index 6e32c7d515..1e2b1be430 100644 --- a/package.json +++ b/package.json @@ -4,5 +4,9 @@ "repository": { "type": "git", "url": "git+https://github.com/appwrite/appwrite.git" - } -} \ No newline at end of file + }, + "files": [ + "docs/examples", + "app/config/specs" + ] +} diff --git a/src/Appwrite/Event/Database.php b/src/Appwrite/Event/Database.php index 70051f9055..8e7f6b7625 100644 --- a/src/Appwrite/Event/Database.php +++ b/src/Appwrite/Event/Database.php @@ -161,17 +161,20 @@ class Database extends Event return $this->document; } - public function getQueue(): string + public function setProject(Document $project): self { - try { - $dsn = new DSN($this->getProject()->getAttribute('database')); - } catch (\InvalidArgumentException) { - // TODO: Temporary until all projects are using shared tables - $dsn = new DSN('mysql://' . $this->getProject()->getAttribute('database')); + $database = $project->getAttribute('database'); + if (!empty($database)) { + try { + $dsn = new DSN($database); + } catch (\InvalidArgumentException) { + // TODO: Temporary until all projects are using shared tables + $dsn = new DSN("mysql://$database"); + } + $this->queue = $dsn->getHost(); } - $this->queue = $dsn->getHost(); - return $this->queue; + return parent::setProject($project); } /** diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php index 4770d727a0..c9de9d5217 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php @@ -77,8 +77,8 @@ class Get extends Action str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_COLLECTIONS), str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_DOCUMENTS), str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_STORAGE), - str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASES_OPERATIONS_READS), - str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASES_OPERATIONS_WRITES) + str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_READS), + str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES) ]; Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { diff --git a/src/Appwrite/Utopia/Request/Filters/V16.php b/src/Appwrite/Utopia/Request/Filters/V16.php index 51b05359b3..55db1f4756 100644 --- a/src/Appwrite/Utopia/Request/Filters/V16.php +++ b/src/Appwrite/Utopia/Request/Filters/V16.php @@ -11,8 +11,6 @@ class V16 extends Filter { switch ($model) { case 'functions.create': - $content['commands'] = $this->getCommands($content['runtime'] ?? ''); - break; case 'functions.update': $content['commands'] = $this->getCommands($content['runtime'] ?? ''); break; diff --git a/src/Appwrite/Utopia/Request/Filters/V17.php b/src/Appwrite/Utopia/Request/Filters/V17.php index 83ec62a168..2cdf3973b2 100644 --- a/src/Appwrite/Utopia/Request/Filters/V17.php +++ b/src/Appwrite/Utopia/Request/Filters/V17.php @@ -2,6 +2,7 @@ namespace Appwrite\Utopia\Request\Filters; +use Appwrite\Extend\Exception; use Appwrite\Utopia\Request\Filter; use Utopia\Database\Query; @@ -67,9 +68,9 @@ class V17 extends Filter foreach ($content['queries'] as $query) { try { $query = $this->parseQuery($query); - $parsed[] = json_encode(array_filter($query->toArray())); + $parsed[] = \json_encode(\array_filter($query->toArray())); } catch (\Throwable $th) { - throw new \Exception("Invalid query: {$query}", previous: $th); + throw new Exception(Exception::GENERAL_QUERY_INVALID, $th->getMessage()); } } @@ -83,6 +84,7 @@ class V17 extends Filter { // Init empty vars we fill later $method = ''; + $attribute = null; $params = []; // Separate method from filter @@ -92,7 +94,7 @@ class V17 extends Filter throw new \Exception('Invalid query'); } - $method = mb_substr($filter, 0, $paramsStart); + $method = \mb_substr($filter, 0, $paramsStart); // Separate params from filter $paramsEnd = \strlen($filter) - 1; // -1 to ignore ) @@ -103,14 +105,13 @@ class V17 extends Filter throw new \Exception('Invalid query method'); } - $currentParam = ""; // We build param here before pushing when it's ended + $currentParam = ''; // We build param here before pushing when it's ended $currentArrayParam = []; // We build array param here before pushing when it's ended $stack = []; // State for stack of parentheses $stackCount = 0; // Length of stack array. Kept as variable to improve performance $stringStackState = null; // State for string support - // Loop thorough all characters for ($i = $parametersStart; $i < $paramsEnd; $i++) { $char = $filter[$i]; @@ -135,20 +136,25 @@ class V17 extends Filter ($filter[$i - 1] !== static::CHAR_BACKSLASH || $filter[$i - 2] === static::CHAR_BACKSLASH) // Must not be escaped; ) { if ($isStringStack) { - // Dont mix-up string symbols. Only allow the same as on start + // Don't mix up string symbols. Only allow the same as on start if ($char === $stringStackState) { // End of string $stringStackState = null; } - - // Either way, add symbol to builder - static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam); } else { // Start of string $stringStackState = $char; - static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam); } + // Either way, add symbol to builder + static::appendSymbol( + $isStringStack, + $char, + $i, + $filter, + $currentParam, + ); + continue; } @@ -174,12 +180,12 @@ class V17 extends Filter continue; } elseif ($char === static::CHAR_COMMA) { // Params separation support - // If in array stack, dont merge yet, just mark it in array param builder + // If in array stack, don't merge yet, just mark it in array param builder if ($isArrayStack) { $currentArrayParam[] = $currentParam; $currentParam = ""; } else { - // Append from parap builder. Either value, or array + // Append from param builder. Either value, or array if (empty($currentArrayParam)) { if (strlen($currentParam)) { $params[] = $currentParam; @@ -193,23 +199,28 @@ class V17 extends Filter } // Value, not relevant to syntax - static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam); + static::appendSymbol( + $isStringStack, + $char, + $i, + $filter, + $currentParam, + ); } - if (strlen($currentParam)) { + if (\strlen($currentParam)) { $params[] = $currentParam; - $currentParam = ""; + $currentParam = ''; } $parsedParams = []; foreach ($params as $param) { - // If array, parse each child separatelly + // If array, parse each child separately if (\is_array($param)) { foreach ($param as $element) { $arr[] = self::parseValue($element); } - $parsedParams[] = $arr ?? []; } else { $parsedParams[] = self::parseValue($param); @@ -295,8 +306,13 @@ class V17 extends Filter * @param string $currentParam * @return void */ - private function appendSymbol(bool $isStringStack, string $char, int $index, string $filter, string &$currentParam): void - { + private function appendSymbol( + bool $isStringStack, + string $char, + int $index, + string $filter, + string &$currentParam + ): void { // Ignore spaces and commas outside of string $canBeIgnored = false; diff --git a/src/Appwrite/Utopia/Request/Filters/V20.php b/src/Appwrite/Utopia/Request/Filters/V20.php index c8622f8b7a..3783a61947 100644 --- a/src/Appwrite/Utopia/Request/Filters/V20.php +++ b/src/Appwrite/Utopia/Request/Filters/V20.php @@ -2,8 +2,10 @@ namespace Appwrite\Utopia\Request\Filters; +use Appwrite\Extend\Exception; use Appwrite\Utopia\Request\Filter; use Utopia\Database\Database; +use Utopia\Database\Exception\NotFound; use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; @@ -54,8 +56,8 @@ class V20 extends Filter try { $parsed = Query::parseQueries($content['queries']); - } catch (QueryException) { - return $content; + } catch (QueryException $e) { + throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } $selections = Query::groupByType($parsed)['selections'] ?? []; @@ -136,17 +138,28 @@ class V20 extends Filter return []; } - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - if ($database->isEmpty()) { - return []; + try { + $database = Authorization::skip(fn () => $dbForProject->getDocument( + 'databases', + $databaseId + )); + if ($database->isEmpty()) { + return []; + } + } catch (NotFound) { + throw new Exception(Exception::DATABASE_NOT_FOUND); } - $collection = Authorization::skip(fn () => $dbForProject->getDocument( - 'database_' . $database->getSequence(), - $collectionId - )); - if ($collection->isEmpty()) { - return []; + try { + $collection = Authorization::skip(fn () => $dbForProject->getDocument( + 'database_' . $database->getSequence(), + $collectionId + )); + if ($collection->isEmpty()) { + return []; + } + } catch (NotFound) { + throw new Exception(Exception::COLLECTION_NOT_FOUND); } $attributes = $collection->getAttribute('attributes', []); diff --git a/tests/e2e/Services/Databases/Legacy/DatabasesBase.php b/tests/e2e/Services/Databases/Legacy/DatabasesBase.php index 1fc05915f1..2cc363fc23 100644 --- a/tests/e2e/Services/Databases/Legacy/DatabasesBase.php +++ b/tests/e2e/Services/Databases/Legacy/DatabasesBase.php @@ -6010,12 +6010,12 @@ trait DatabasesBase 'documentId' => ID::unique(), 'data' => [ 'name' => 'Upserted Location', - 'location' => [34.0522, -118.2437] // Los Angeles coordinates + 'location' => [34.0522, -80] // Los Angeles coordinates ] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals([34.0522, -118.2437], $response['body']['location']); + $this->assertEquals([34.0522, -80], $response['body']['location']); // Test 5: Create document without permissions (should fail) $response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', [ @@ -6145,12 +6145,12 @@ trait DatabasesBase 'documentId' => ID::unique(), 'data' => [ 'distance' => 200, - 'route' => [[34.0522, -118.2437], [34.0736, -118.2400]] // LA route + 'route' => [[34.0522, -80], [34.0736, -90]] // LA route ] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals([[34.0522, -118.2437], [34.0736, -118.2400]], $response['body']['route']); + $this->assertEquals([[34.0522, -80], [34.0736, -90]], $response['body']['route']); // Test 5: Delete document $response = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId, array_merge([ @@ -6282,12 +6282,12 @@ trait DatabasesBase 'documentId' => ID::unique(), 'data' => [ 'active' => false, - 'area' => [[[34.0522, -118.2437], [34.0736, -118.2437], [34.0736, -118.2400], [34.0522, -118.2400], [34.0522, -118.2437]]] // LA area + 'area' => [[[34.0522, -80], [34.0736, -80], [34.0736, -90], [34.0522, -90], [34.0522, -80]]] // LA area ] ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals([[[34.0522, -118.2437], [34.0736, -118.2437], [34.0736, -118.2400], [34.0522, -118.2400], [34.0522, -118.2437]]], $response['body']['area']); + $this->assertEquals([[[34.0522, -80], [34.0736, -80], [34.0736, -90], [34.0522, -90], [34.0522, -80]]], $response['body']['area']); // Test 5: Create document without required polygon attribute (should fail) $response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([ @@ -6722,7 +6722,7 @@ trait DatabasesBase '$id' => 'doc1', 'name' => 'Test Document 1', 'pointAttr' => [6.0, 6.0], - 'lineAttr' => [[1.0, 1.0], [2.0, 2.0]], + 'lineAttr' => [[1.0, 1.0], [1.1,1.1] , [2.0, 2.0]], 'polyAttr' => [[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]]] ], [ @@ -6804,6 +6804,7 @@ trait DatabasesBase $this->assertCount(1, $response['body']['documents']); $this->assertEquals('doc1', $response['body']['documents'][0]['$id']); + // Test 4.2: notContains on polygon (point outside all polygons) $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([ 'content-type' => 'application/json', diff --git a/tests/e2e/Services/Databases/Legacy/DatabasesCustomServerTest.php b/tests/e2e/Services/Databases/Legacy/DatabasesCustomServerTest.php index a4ad6f33df..e8c1d89db4 100644 --- a/tests/e2e/Services/Databases/Legacy/DatabasesCustomServerTest.php +++ b/tests/e2e/Services/Databases/Legacy/DatabasesCustomServerTest.php @@ -6710,7 +6710,7 @@ class DatabasesCustomServerTest extends Scope 'path' => [ [0, 0], [50, 50], - [100, 100] + [80, 80] ] // New LINE STRING ], ]); @@ -6724,7 +6724,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals([ [0, 0], [50, 50], - [100, 100] + [80, 80] ], $document['path']); } diff --git a/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php b/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php index 21d24c9d38..ad517a94fc 100644 --- a/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php +++ b/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php @@ -414,7 +414,6 @@ trait DatabasesBase Query::cursorAfter(new Document(['$id' => 'title']))->toString() ], ]); - $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(2, \count($response['body']['columns'])); $response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $data['moviesId'] . '/columns', array_merge([ diff --git a/tests/e2e/Services/Databases/TablesDB/DatabasesCustomServerTest.php b/tests/e2e/Services/Databases/TablesDB/DatabasesCustomServerTest.php index 0583850036..91a5517d3b 100644 --- a/tests/e2e/Services/Databases/TablesDB/DatabasesCustomServerTest.php +++ b/tests/e2e/Services/Databases/TablesDB/DatabasesCustomServerTest.php @@ -6413,7 +6413,7 @@ class DatabasesCustomServerTest extends Scope ]); // Coordinates are not validated strictly; creation should succeed - $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(400, $response['headers']['status-code']); // Test 4b: Invalid polygon (insufficient points - should fail) $response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ @@ -6684,7 +6684,7 @@ class DatabasesCustomServerTest extends Scope 'path' => [ [0, 0], [50, 50], - [100, 100] + [80, 80] ] // New LINE STRING ], ]); @@ -6698,7 +6698,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals([ [0, 0], [50, 50], - [100, 100] + [80, 80] ], $row['path']); }