From a7c4edba9533d2ece4611d694ac1c247846281ad Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sat, 14 Aug 2021 21:56:28 +0300 Subject: [PATCH 01/16] Updated collection structures to support fulltext search --- app/config/collections2.php | 106 ++++++++++++++++++++++++++---- app/controllers/api/account.php | 36 +++++----- app/controllers/api/database.php | 6 +- app/controllers/api/functions.php | 21 +++++- app/controllers/api/projects.php | 23 ++++--- app/controllers/api/storage.php | 12 +++- app/controllers/api/teams.php | 13 +++- app/controllers/api/users.php | 17 +++-- 8 files changed, 181 insertions(+), 53 deletions(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index ae9a4feeb..d75775232 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -221,13 +221,24 @@ $collections = [ 'array' => true, 'filters' => ['json'], ], + [ + '$id' => 'search', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], ], 'indexes' => [ [ - '$id' => '_fulltext_name', + '$id' => '_key_search', 'type' => Database::INDEX_FULLTEXT, - 'attributes' => ['name'], - 'lengths' => [1024], + 'attributes' => ['search'], + 'lengths' => [2048], 'orders' => [Database::ORDER_ASC], ], ], @@ -370,6 +381,17 @@ $collections = [ 'array' => true, 'filters' => ['json'], ], + [ + '$id' => 'search', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], ], 'indexes' => [ [ @@ -379,6 +401,13 @@ $collections = [ 'lengths' => [1024], 'orders' => [Database::ORDER_ASC], ], + [ + '$id' => '_key_search', + 'type' => Database::INDEX_FULLTEXT, + 'attributes' => ['search'], + 'lengths' => [2048], + 'orders' => [Database::ORDER_ASC], + ], ], ], @@ -668,13 +697,24 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => 'search', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], ], 'indexes' => [ [ - '$id' => '_fulltext_name', + '$id' => '_key_search', 'type' => Database::INDEX_FULLTEXT, - 'attributes' => ['name'], - 'lengths' => [1024], + 'attributes' => ['search'], + 'lengths' => [2048], 'orders' => [Database::ORDER_ASC], ], ], @@ -948,6 +988,17 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => 'search', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], ], 'indexes' => [ [ @@ -958,10 +1009,10 @@ $collections = [ 'orders' => [Database::ORDER_ASC], ], [ - '$id' => '_fulltext_name', + '$id' => '_key_search', 'type' => Database::INDEX_FULLTEXT, - 'attributes' => ['name'], - 'lengths' => [1024], + 'attributes' => ['search'], + 'lengths' => [2048], 'orders' => [Database::ORDER_ASC], ], ], @@ -1116,13 +1167,24 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => 'search', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], ], 'indexes' => [ [ - '$id' => '_fulltext_name', + '$id' => '_key_search', 'type' => Database::INDEX_FULLTEXT, - 'attributes' => ['name'], - 'lengths' => [1024], + 'attributes' => ['search'], + 'lengths' => [2048], 'orders' => [Database::ORDER_ASC], ], ], @@ -1189,6 +1251,17 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => 'search', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], ], 'indexes' => [ [ @@ -1198,6 +1271,13 @@ $collections = [ 'lengths' => [Database::LENGTH_KEY], 'orders' => [Database::ORDER_ASC], ], + [ + '$id' => '_key_search', + 'type' => Database::INDEX_FULLTEXT, + 'attributes' => ['search'], + 'lengths' => [2048], + 'orders' => [Database::ORDER_ASC], + ], ], ], @@ -1405,4 +1485,4 @@ $collections = [ ], ]; -return $collections; +return $collections; \ No newline at end of file diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index ef0880511..11649966d 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -103,6 +103,7 @@ App::post('/v1/account') 'sessions' => [], 'tokens' => [], 'memberships' => [], + 'search' => implode(' ', [$userId, $email, $name]), ])); } catch (Duplicate $th) { throw new Exception('Account already exists', 409); @@ -195,8 +196,8 @@ App::post('/v1/account/sessions') Authorization::setRole('user:' . $profile->getId()); $session = $dbForInternal->createDocument('sessions', $session - ->setAttribute('$read', ['user:' . $profile->getId()]) - ->setAttribute('$write', ['user:' . $profile->getId()]) + ->setAttribute('$read', ['user:' . $profile->getId()]) + ->setAttribute('$write', ['user:' . $profile->getId()]) ); $profile->setAttribute('sessions', $session, Document::SET_TYPE_APPEND); @@ -481,6 +482,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') 'sessions' => [], 'tokens' => [], 'memberships' => [], + 'search' => implode(' ', [$userId, $email, $name]), ])); } catch (Duplicate $th) { throw new Exception('Account already exists', 409); @@ -530,8 +532,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') Authorization::setRole('user:' . $user->getId()); $session = $dbForInternal->createDocument('sessions', $session - ->setAttribute('$read', ['user:' . $user->getId()]) - ->setAttribute('$write', ['user:' . $user->getId()]) + ->setAttribute('$read', ['user:' . $user->getId()]) + ->setAttribute('$write', ['user:' . $user->getId()]) ); $user = $dbForInternal->updateDocument('users', $user->getId(), $user); @@ -644,6 +646,7 @@ App::post('/v1/account/sessions/anonymous') 'sessions' => [], 'tokens' => [], 'memberships' => [], + 'search' => $userId, ])); Authorization::reset(); @@ -978,7 +981,10 @@ App::patch('/v1/account/name') /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ - $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('name', $name)); + $user = $dbForInternal->updateDocument('users', $user->getId(), $user + ->setAttribute('name', $name) + ->setAttribute('search', implode(' ', [$user->getId(), $name, $user->getAttribute('email')])) + ); $audits ->setParam('userId', $user->getId()) @@ -1073,9 +1079,10 @@ App::patch('/v1/account/email') } $user = $dbForInternal->updateDocument('users', $user->getId(), $user - ->setAttribute('password', $isAnonymousUser ? Auth::passwordHash($password) : $user->getAttribute('password', '')) - ->setAttribute('email', $email) - ->setAttribute('emailVerification', false) // After this user needs to confirm mail again + ->setAttribute('password', $isAnonymousUser ? Auth::passwordHash($password) : $user->getAttribute('password', '')) + ->setAttribute('email', $email) + ->setAttribute('emailVerification', false) // After this user needs to confirm mail again + ->setAttribute('search', implode(' ', [$user->getId(), $user->getAttribute('name'), $user->getAttribute('email')])) ); $audits @@ -1489,10 +1496,9 @@ App::put('/v1/account/recovery') ); /** - * We act like we're updating and validating - * the recovery token but actually we don't need it anymore. - */ - + * We act like we're updating and validating + * the recovery token but actually we don't need it anymore. + */ foreach ($tokens as $key => $token) { if ($recovery === $token->getId()) { $recovery = $token; @@ -1650,9 +1656,9 @@ App::put('/v1/account/verification') $profile = $dbForInternal->updateDocument('users', $profile->getId(), $profile->setAttribute('emailVerification', true)); /** - * We act like we're updating and validating - * the verification token but actually we don't need it anymore. - */ + * We act like we're updating and validating + * the verification token but actually we don't need it anymore. + */ foreach ($tokens as $key => $token) { if ($token->getId() === $verification) { $verification = $token; diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 1ebb857da..05f74c94f 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -189,7 +189,11 @@ App::get('/v1/database/collections') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForExternal */ - $queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : []; + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('name', Query::TYPE_SEARCH, [$search]); + } $response->dynamic(new Document([ 'collections' => $dbForExternal->find(Database::COLLECTIONS, $queries, $limit, $offset, ['_id'], [$orderType]), diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index a0bcb535b..9994c9eaa 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -53,8 +53,9 @@ App::post('/v1/functions') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ + $functionId = ($functionId == 'unique()') ? $dbForInternal->getId() : $functionId; $function = $dbForInternal->createDocument('functions', new Document([ - '$id' => $functionId == 'unique()' ? $dbForInternal->getId() : $functionId, + '$id' => $functionId, 'execute' => $execute, 'dateCreated' => time(), 'dateUpdated' => time(), @@ -68,6 +69,7 @@ App::post('/v1/functions') 'schedulePrevious' => 0, 'scheduleNext' => 0, 'timeout' => $timeout, + 'search' => implode(' ', [$functionId, $name, $runtime]), ])); $response->setStatusCode(Response::STATUS_CODE_CREATED); @@ -95,7 +97,11 @@ App::get('/v1/functions') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - $queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : []; + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } $response->dynamic(new Document([ 'functions' => $dbForInternal->find('functions', $queries, $limit, $offset, ['_id'], [$orderType]), @@ -296,6 +302,7 @@ App::put('/v1/functions/:functionId') 'schedule' => $schedule, 'scheduleNext' => (int)$next, 'timeout' => $timeout, + 'search' => implode(' ', [$functionId, $name, $function->getAttribute('runtime')]), ]))); if ($next && $schedule !== $original) { @@ -472,8 +479,9 @@ App::post('/v1/functions/:functionId/tags') throw new Exception('Failed moving file', 500); } + $tagId = $dbForInternal->getId(); $tag = $dbForInternal->createDocument('tags', new Document([ - '$id' => $dbForInternal->getId(), + '$id' => $tagId, '$read' => [], '$write' => [], 'functionId' => $function->getId(), @@ -481,6 +489,7 @@ App::post('/v1/functions/:functionId/tags') 'command' => $command, 'path' => $path, 'size' => $size, + 'search' => implode(' ', [$tagId, $command]), ])); $usage @@ -519,6 +528,12 @@ App::get('/v1/functions/:functionId/tags') throw new Exception('Function not found', 404); } + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } + $queries[] = new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]); $results = $dbForInternal->find('tags', $queries, $limit, $offset, ['_id'], [$orderType]); diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 493eb65dc..dfce1525d 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -5,9 +5,7 @@ use Appwrite\Database\Validator\CustomId; use Appwrite\Network\Validator\CNAME; use Appwrite\Network\Validator\Domain as DomainValidator; use Appwrite\Network\Validator\URL; -use Appwrite\Task\Validator\Cron; use Appwrite\Utopia\Response; -use Cron\CronExpression; use Utopia\App; use Utopia\Config\Config; use Utopia\Database\Document; @@ -78,8 +76,9 @@ App::post('/v1/projects') $auths[$method['key'] ?? ''] = true; } + $projectId = ($projectId == 'unique()') ? $dbForConsole->getId() : $projectId; $project = $dbForConsole->createDocument('projects', new Document([ - '$id' => $projectId == 'unique()' ? $dbForConsole->getId() : $projectId, + '$id' => $projectId, '$collection' => 'projects', '$read' => ['team:' . $teamId], '$write' => ['team:' . $teamId . '/owner', 'team:' . $teamId . '/developer'], @@ -95,12 +94,13 @@ App::post('/v1/projects') 'legalCity' => $legalCity, 'legalAddress' => $legalAddress, 'legalTaxId' => $legalTaxId, + 'auths' => $auths, 'services' => new stdClass(), 'platforms' => [], 'webhooks' => [], 'keys' => [], 'domains' => [], - 'auths' => $auths, + 'search' => implode(' ', [$projectId, $name]), ])); $collections = Config::getParam('collections2', []); /** @var array $collections */ @@ -171,7 +171,11 @@ App::get('/v1/projects') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForConsole */ - $queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : []; + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } $results = $dbForConsole->find('projects', $queries, $limit, $offset, ['_id'], [$orderType]); $sum = $dbForConsole->count('projects', $queries, APP_LIMIT_COUNT); @@ -445,6 +449,7 @@ App::patch('/v1/projects/:projectId') ->setAttribute('legalCity', $legalCity) ->setAttribute('legalAddress', $legalAddress) ->setAttribute('legalTaxId', $legalTaxId) + ->setAttribute('search', implode(' ', [$projectId, $name])) ); $response->dynamic($project, Response::MODEL_PROJECT); @@ -546,7 +551,7 @@ App::patch('/v1/projects/:projectId/auth/limit') $auths['limit'] = $limit; $dbForConsole->updateDocument('projects', $project->getId(), $project - ->setAttribute('auths', $auths) + ->setAttribute('auths', $auths) ); $response->dynamic($project, Response::MODEL_PROJECT); @@ -869,7 +874,7 @@ App::post('/v1/projects/:projectId/keys') ]); $project = $dbForConsole->updateDocument('projects', $project->getId(), $project - ->setAttribute('keys', $key, Document::SET_TYPE_APPEND) + ->setAttribute('keys', $key, Document::SET_TYPE_APPEND) ); $response->setStatusCode(Response::STATUS_CODE_CREATED); @@ -1053,7 +1058,7 @@ App::post('/v1/projects/:projectId/platforms') ]); $project = $dbForConsole->updateDocument('projects', $project->getId(), $project - ->setAttribute('platforms', $platform, Document::SET_TYPE_APPEND) + ->setAttribute('platforms', $platform, Document::SET_TYPE_APPEND) ); $response->setStatusCode(Response::STATUS_CODE_CREATED); @@ -1262,7 +1267,7 @@ App::post('/v1/projects/:projectId/domains') ]); $project = $dbForConsole->updateDocument('projects', $project->getId(), $project - ->setAttribute('domains', $domain, Document::SET_TYPE_APPEND) + ->setAttribute('domains', $domain, Document::SET_TYPE_APPEND) ); $response->setStatusCode(Response::STATUS_CODE_CREATED); diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 4f579a1b3..50e1f4d43 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -123,13 +123,14 @@ App::post('/v1/storage/files') $sizeActual = $device->getFileSize($path); + $fileId = ($fileId == 'unique()') ? $dbForInternal->getId() : $fileId; $file = $dbForInternal->createDocument('files', new Document([ - '$id' => $fileId == 'unique()' ? $dbForInternal->getId() : $fileId, + '$id' => $fileId, '$read' => (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? [], // By default set read permissions for user '$write' => (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? [], // By default set write permissions for user 'dateCreated' => \time(), 'bucketId' => '', - 'name' => $file['name'], + 'name' => $file['name'] ?? '', 'path' => $path, 'signature' => $device->getFileHash($path), 'mimeType' => $mimeType, @@ -141,6 +142,7 @@ App::post('/v1/storage/files') 'openSSLCipher' => OpenSSL::CIPHER_AES_128_GCM, 'openSSLTag' => \bin2hex($tag), 'openSSLIV' => \bin2hex($iv), + 'search' => implode(' ', [$fileId, $file['name'] ?? '',]), ])); $audits @@ -178,7 +180,11 @@ App::get('/v1/storage/files') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - $queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, $search)] : []; + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } $response->dynamic(new Document([ 'files' => $dbForInternal->find('files', $queries, $limit, $offset, ['_id'], [$orderType]), diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 01ce3c82f..5e9deedc6 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -57,6 +57,7 @@ App::post('/v1/teams') 'name' => $name, 'sum' => ($isPrivilegedUser || $isAppUser) ? 0 : 1, 'dateCreated' => \time(), + 'search' => implode(' ', [$teamId, $name]), ])); Authorization::reset(); @@ -106,7 +107,11 @@ App::get('/v1/teams') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - $queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : []; + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } $results = $dbForInternal->find('teams', $queries, $limit, $offset, ['_id'], [$orderType]); $sum = $dbForInternal->count('teams', $queries, APP_LIMIT_COUNT); @@ -170,7 +175,10 @@ App::put('/v1/teams/:teamId') throw new Exception('Team not found', 404); } - $team = $dbForInternal->updateDocument('teams', $team->getId(), $team->setAttribute('name', $name)); + $team = $dbForInternal->updateDocument('teams', $team->getId(),$team + ->setAttribute('name', $name) + ->setAttribute('search', implode(' ', [$teamId, $name])) + ); $response->dynamic($team, Response::MODEL_TEAM); }); @@ -314,6 +322,7 @@ App::post('/v1/teams/:teamId/memberships') 'sessions' => [], 'tokens' => [], 'memberships' => [], + 'search' => implode(' ', [$userId, $email, $name]), ])); } catch (Duplicate $th) { throw new Exception('Account already exists', 409); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index d57be233e..c2c7a9bb3 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -17,6 +17,7 @@ use Utopia\Database\Exception\Duplicate; use Utopia\Database\Validator\UID; use DeviceDetector\DeviceDetector; use Appwrite\Database\Validator\CustomId; +use Utopia\Database\Query; App::post('/v1/users') ->desc('Create User') @@ -60,6 +61,7 @@ App::post('/v1/users') 'sessions' => [], 'tokens' => [], 'memberships' => [], + 'search' => implode(' ', [$userId, $email, $name]), ])); } catch (Duplicate $th) { throw new Exception('Account already exists', 409); @@ -90,8 +92,14 @@ App::get('/v1/users') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - $results = $dbForInternal->find('users', [], $limit, $offset, ['_id'], [$orderType]); - $sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT); + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } + + $results = $dbForInternal->find('users', $queries, $limit, $offset, ['_id'], [$orderType]); + $sum = $dbForInternal->count('users', $queries, APP_LIMIT_COUNT); $response->dynamic(new Document([ 'users' => $results, @@ -519,11 +527,6 @@ App::delete('/v1/users/:userId') if (!$dbForInternal->deleteDocument('users', $userId)) { throw new Exception('Failed to remove user from DB', 500); } - - // $dbForInternal->createDocument('users', new Document([ - // '$id' => $userId, - // '$read' => ['role:all'], - // ])); $deletes ->setParam('type', DELETE_TYPE_DOCUMENT) From 89f55a17277361f14b84fac7f07659920c5e74eb Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Wed, 18 Aug 2021 16:42:03 +0300 Subject: [PATCH 02/16] Re-orgenized controller flow --- app/controllers/api/database.php | 12 ++++++------ app/controllers/api/functions.php | 28 ++++++++++++++-------------- app/controllers/api/projects.php | 12 ++++++------ app/controllers/api/storage.php | 12 ++++++------ app/controllers/api/teams.php | 12 ++++++------ 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 6cc933e6c..01f3e7df7 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -193,12 +193,6 @@ App::get('/v1/database/collections') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForExternal */ - $queries = []; - - if (!empty($search)) { - $queries[] = new Query('name', Query::TYPE_SEARCH, [$search]); - } - if (!empty($after)) { $afterCollection = $dbForExternal->getDocument('collections', $after); @@ -207,6 +201,12 @@ App::get('/v1/database/collections') } } + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('name', Query::TYPE_SEARCH, [$search]); + } + $response->dynamic(new Document([ 'collections' => $dbForExternal->find(Database::COLLECTIONS, $queries, $limit, $offset, [], [$orderType], $afterCollection ?? null), 'sum' => $dbForExternal->count(Database::COLLECTIONS, $queries, APP_LIMIT_COUNT), diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index f862bee85..f0f7f6133 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -98,12 +98,6 @@ App::get('/v1/functions') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - $queries = []; - - if (!empty($search)) { - $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); - } - if (!empty($after)) { $afterFunction = $dbForInternal->getDocument('functions', $after); @@ -111,6 +105,12 @@ App::get('/v1/functions') throw new Exception("Function '{$after}' for the 'after' value not found.", 400); } } + + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } $response->dynamic(new Document([ 'functions' => $dbForInternal->find('functions', $queries, $limit, $offset, [], [$orderType], $afterFunction ?? null), @@ -538,14 +538,6 @@ App::get('/v1/functions/:functionId/tags') throw new Exception('Function not found', 404); } - $queries = []; - - if (!empty($search)) { - $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); - } - - $queries[] = new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]); - if (!empty($after)) { $afterTag = $dbForInternal->getDocument('tags', $after); @@ -554,6 +546,14 @@ App::get('/v1/functions/:functionId/tags') } } + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } + + $queries[] = new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]); + $results = $dbForInternal->find('tags', $queries, $limit, $offset, [], [$orderType], $afterTag ?? null); $sum = $dbForInternal->count('tags', $queries, APP_LIMIT_COUNT); diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 0a2336920..df740eb42 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -171,12 +171,6 @@ App::get('/v1/projects') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForConsole */ - $queries = []; - - if (!empty($search)) { - $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); - } - if (!empty($after)) { $afterProject = $dbForConsole->getDocument('projects', $after); @@ -185,6 +179,12 @@ App::get('/v1/projects') } } + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } + $results = $dbForConsole->find('projects', $queries, $limit, $offset, [], [$orderType], $afterProject ?? null); $sum = $dbForConsole->count('projects', $queries, APP_LIMIT_COUNT); diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index d6735c138..b73e3facf 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -181,12 +181,6 @@ App::get('/v1/storage/files') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - $queries = []; - - if (!empty($search)) { - $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); - } - if (!empty($after)) { $afterFile = $dbForInternal->getDocument('files', $after); @@ -195,6 +189,12 @@ App::get('/v1/storage/files') } } + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } + $response->dynamic(new Document([ 'files' => $dbForInternal->find('files', $queries, $limit, $offset, [], [$orderType], $afterFile ?? null), 'sum' => $dbForInternal->count('files', $queries, APP_LIMIT_COUNT), diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 903668d52..75d6f91cb 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -108,12 +108,6 @@ App::get('/v1/teams') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - $queries = []; - - if (!empty($search)) { - $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); - } - if (!empty($after)) { $afterTeam = $dbForInternal->getDocument('teams', $after); @@ -122,6 +116,12 @@ App::get('/v1/teams') } } + $queries = []; + + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } + $results = $dbForInternal->find('teams', $queries, $limit, $offset, [], [$orderType], $afterTeam ?? null); $sum = $dbForInternal->count('teams', $queries, APP_LIMIT_COUNT); From 732c59a03de82ccebe5f4cb1b3a785cd8345abc7 Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Tue, 21 Sep 2021 10:22:13 +0200 Subject: [PATCH 03/16] Implemented search tests --- app/controllers/api/users.php | 4 +- composer.lock | 147 +++++++++--------- .../Functions/FunctionsCustomClientTest.php | 1 + .../Functions/FunctionsCustomServerTest.php | 74 +++++++++ .../Projects/ProjectsConsoleClientTest.php | 23 +++ tests/e2e/Services/Storage/StorageBase.php | 38 ++++- tests/e2e/Services/Teams/TeamsBase.php | 14 ++ tests/e2e/Services/Users/UsersBase.php | 80 +++++++++- 8 files changed, 294 insertions(+), 87 deletions(-) diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 4ca682b92..e4008e545 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -97,7 +97,7 @@ App::get('/v1/users') $afterUser = $dbForInternal->getDocument('users', $after); if ($afterUser->isEmpty()) { - throw new Exception('User for after not found', 400); + throw new Exception("User '{$after}' for the 'after' value not found.", 400); } } @@ -107,7 +107,7 @@ App::get('/v1/users') $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); } - $results = $dbForInternal->find('users', $queries, $limit, $offset, ['_id'], [$orderType]); + $results = $dbForInternal->find('users', $queries, $limit, $offset, [], [$orderType], $afterUser ?? null); $sum = $dbForInternal->count('users', $queries, APP_LIMIT_COUNT); $response->dynamic(new Document([ diff --git a/composer.lock b/composer.lock index db07f5df2..f1709a381 100644 --- a/composer.lock +++ b/composer.lock @@ -248,16 +248,16 @@ }, { "name": "chillerlan/php-settings-container", - "version": "2.1.1", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/chillerlan/php-settings-container.git", - "reference": "98ccc1b31b31a53bcb563465c4961879b2b93096" + "reference": "ec834493a88682dd69652a1eeaf462789ed0c5f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/98ccc1b31b31a53bcb563465c4961879b2b93096", - "reference": "98ccc1b31b31a53bcb563465c4961879b2b93096", + "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/ec834493a88682dd69652a1eeaf462789ed0c5f5", + "reference": "ec834493a88682dd69652a1eeaf462789ed0c5f5", "shasum": "" }, "require": { @@ -307,7 +307,7 @@ "type": "ko_fi" } ], - "time": "2021-01-06T15:57:03+00:00" + "time": "2021-09-06T15:17:01+00:00" }, { "name": "colinmollenhour/credis", @@ -355,16 +355,16 @@ }, { "name": "composer/package-versions-deprecated", - "version": "1.11.99.2", + "version": "1.11.99.4", "source": { "type": "git", "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "c6522afe5540d5fc46675043d3ed5a45a740b27c" + "reference": "b174585d1fe49ceed21928a945138948cb394600" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/c6522afe5540d5fc46675043d3ed5a45a740b27c", - "reference": "c6522afe5540d5fc46675043d3ed5a45a740b27c", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600", + "reference": "b174585d1fe49ceed21928a945138948cb394600", "shasum": "" }, "require": { @@ -408,7 +408,7 @@ "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", "support": { "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.2" + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.4" }, "funding": [ { @@ -424,7 +424,7 @@ "type": "tidelift" } ], - "time": "2021-05-24T07:46:03+00:00" + "time": "2021-09-13T08:41:34+00:00" }, { "name": "dragonmantank/cron-expression", @@ -1666,22 +1666,22 @@ }, { "name": "utopia-php/abuse", - "version": "0.6.2", + "version": "0.6.3", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "4cd9c16610f7398d2e1737663ef682fa721ae736" + "reference": "d63e928c2c50b367495a499a85ba9806ee274c5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4cd9c16610f7398d2e1737663ef682fa721ae736", - "reference": "4cd9c16610f7398d2e1737663ef682fa721ae736", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/d63e928c2c50b367495a499a85ba9806ee274c5e", + "reference": "d63e928c2c50b367495a499a85ba9806ee274c5e", "shasum": "" }, "require": { "ext-pdo": "*", "php": ">=7.4", - "utopia-php/database": "0.7.*" + "utopia-php/database": ">=0.6 <1.0" }, "require-dev": { "phpunit/phpunit": "^9.4", @@ -1713,9 +1713,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.6.2" + "source": "https://github.com/utopia-php/abuse/tree/0.6.3" }, - "time": "2021-08-13T07:52:34+00:00" + "time": "2021-08-16T18:38:31+00:00" }, { "name": "utopia-php/analytics", @@ -1774,22 +1774,22 @@ }, { "name": "utopia-php/audit", - "version": "0.6.2", + "version": "0.6.3", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "2ec39a53eb98a5f9d230550ad56c7c04de5d77df" + "reference": "d79b467fbc7d03e5e02f12cdeb08761507a60ca0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/2ec39a53eb98a5f9d230550ad56c7c04de5d77df", - "reference": "2ec39a53eb98a5f9d230550ad56c7c04de5d77df", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/d79b467fbc7d03e5e02f12cdeb08761507a60ca0", + "reference": "d79b467fbc7d03e5e02f12cdeb08761507a60ca0", "shasum": "" }, "require": { "ext-pdo": "*", "php": ">=7.4", - "utopia-php/database": "0.7.*" + "utopia-php/database": ">=0.6 <1.0" }, "require-dev": { "phpunit/phpunit": "^9.3", @@ -1821,9 +1821,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.6.2" + "source": "https://github.com/utopia-php/audit/tree/0.6.3" }, - "time": "2021-08-13T08:05:20+00:00" + "time": "2021-08-16T18:49:55+00:00" }, { "name": "utopia-php/cache", @@ -3389,16 +3389,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.12.0", + "version": "v4.13.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143" + "reference": "50953a2691a922aa1769461637869a0a2faa3f53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53", + "reference": "50953a2691a922aa1769461637869a0a2faa3f53", "shasum": "" }, "require": { @@ -3439,9 +3439,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0" }, - "time": "2021-07-21T10:44:31+00:00" + "time": "2021-09-20T12:20:58+00:00" }, { "name": "openlss/lib-array2xml", @@ -3718,16 +3718,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/30f38bffc6f24293dadd1823936372dfa9e86e2f", + "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f", "shasum": "" }, "require": { @@ -3735,7 +3735,8 @@ "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "ext-tokenizer": "*" + "ext-tokenizer": "*", + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -3761,39 +3762,39 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.0" }, - "time": "2020-09-17T18:55:26+00:00" + "time": "2021-09-17T15:28:14+00:00" }, { "name": "phpspec/prophecy", - "version": "1.13.0", + "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea" + "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea", - "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.1", + "php": "^7.2 || ~8.0, <8.2", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { - "phpspec/phpspec": "^6.0", + "phpspec/phpspec": "^6.0 || ^7.0", "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -3828,29 +3829,29 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.13.0" + "source": "https://github.com/phpspec/prophecy/tree/1.14.0" }, - "time": "2021-03-17T13:42:18+00:00" + "time": "2021-09-10T09:02:12+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.6", + "version": "9.2.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f6293e1b30a2354e8428e004689671b83871edde" + "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde", - "reference": "f6293e1b30a2354e8428e004689671b83871edde", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d4c798ed8d51506800b441f7a13ecb0f76f12218", + "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.10.2", + "nikic/php-parser": "^4.12.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -3899,7 +3900,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.6" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.7" }, "funding": [ { @@ -3907,7 +3908,7 @@ "type": "github" } ], - "time": "2021-03-28T07:26:59+00:00" + "time": "2021-09-17T05:39:03+00:00" }, { "name": "phpunit/php-file-iterator", @@ -5319,16 +5320,16 @@ }, { "name": "symfony/console", - "version": "v5.3.6", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "51b71afd6d2dc8f5063199357b9880cea8d8bfe2" + "reference": "8b1008344647462ae6ec57559da166c2bfa5e16a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/51b71afd6d2dc8f5063199357b9880cea8d8bfe2", - "reference": "51b71afd6d2dc8f5063199357b9880cea8d8bfe2", + "url": "https://api.github.com/repos/symfony/console/zipball/8b1008344647462ae6ec57559da166c2bfa5e16a", + "reference": "8b1008344647462ae6ec57559da166c2bfa5e16a", "shasum": "" }, "require": { @@ -5398,7 +5399,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.6" + "source": "https://github.com/symfony/console/tree/v5.3.7" }, "funding": [ { @@ -5414,7 +5415,7 @@ "type": "tidelift" } ], - "time": "2021-07-27T19:10:22+00:00" + "time": "2021-08-25T20:02:16+00:00" }, { "name": "symfony/deprecation-contracts", @@ -5888,16 +5889,16 @@ }, { "name": "symfony/string", - "version": "v5.3.3", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "bd53358e3eccec6a670b5f33ab680d8dbe1d4ae1" + "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/bd53358e3eccec6a670b5f33ab680d8dbe1d4ae1", - "reference": "bd53358e3eccec6a670b5f33ab680d8dbe1d4ae1", + "url": "https://api.github.com/repos/symfony/string/zipball/8d224396e28d30f81969f083a58763b8b9ceb0a5", + "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5", "shasum": "" }, "require": { @@ -5951,7 +5952,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.3.3" + "source": "https://github.com/symfony/string/tree/v5.3.7" }, "funding": [ { @@ -5967,7 +5968,7 @@ "type": "tidelift" } ], - "time": "2021-06-27T11:44:38+00:00" + "time": "2021-08-26T08:00:08+00:00" }, { "name": "theseer/tokenizer", @@ -6021,16 +6022,16 @@ }, { "name": "twig/twig", - "version": "v2.14.6", + "version": "v2.14.7", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "27e5cf2b05e3744accf39d4c68a3235d9966d260" + "reference": "8e202327ee1ed863629de9b18a5ec70ac614d88f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/27e5cf2b05e3744accf39d4c68a3235d9966d260", - "reference": "27e5cf2b05e3744accf39d4c68a3235d9966d260", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/8e202327ee1ed863629de9b18a5ec70ac614d88f", + "reference": "8e202327ee1ed863629de9b18a5ec70ac614d88f", "shasum": "" }, "require": { @@ -6040,7 +6041,7 @@ }, "require-dev": { "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9" + "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" }, "type": "library", "extra": { @@ -6084,7 +6085,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v2.14.6" + "source": "https://github.com/twigphp/Twig/tree/v2.14.7" }, "funding": [ { @@ -6096,7 +6097,7 @@ "type": "tidelift" } ], - "time": "2021-05-16T12:12:47+00:00" + "time": "2021-09-17T08:39:54+00:00" }, { "name": "vimeo/psalm", diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 86f6fde48..0d229aafc 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -7,6 +7,7 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; +use function var_dump; class FunctionsCustomClientTest extends Scope { diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index cb820b45c..e118df8a5 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -7,6 +7,8 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; +use function array_merge; +use function var_dump; class FunctionsCustomServerTest extends Scope { @@ -77,6 +79,39 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ + $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => $data['functionId'] + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertCount(1, $response['body']['functions']); + $this->assertEquals($response['body']['functions'][0]['name'], 'Test'); + + $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => 'Test' + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertCount(1, $response['body']['functions']); + $this->assertEquals($response['body']['functions'][0]['$id'], $data['functionId']); + + $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => 'php-8.0' + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertCount(1, $response['body']['functions']); + $this->assertEquals($response['body']['functions'][0]['$id'], $data['functionId']); + $response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ 'content-type' => 'application/json', @@ -283,6 +318,45 @@ class FunctionsCustomServerTest extends Scope $this->assertIsArray($function['body']['tags']); $this->assertCount(1, $function['body']['tags']); + $function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/tags', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders(), [ + 'search' => $data['functionId'] + ])); + + $this->assertEquals($function['headers']['status-code'], 200); + $this->assertEquals($function['body']['sum'], 1); + $this->assertIsArray($function['body']['tags']); + $this->assertCount(1, $function['body']['tags']); + $this->assertEquals($function['body']['tags'][0]['$id'], $data['tagId']); + + $function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/tags', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders(), [ + 'search' => 'Test' + ])); + + $this->assertEquals($function['headers']['status-code'], 200); + $this->assertEquals($function['body']['sum'], 1); + $this->assertIsArray($function['body']['tags']); + $this->assertCount(1, $function['body']['tags']); + $this->assertEquals($function['body']['tags'][0]['$id'], $data['tagId']); + + $function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/tags', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders(), [ + 'search' => 'php-8.0' + ])); + + $this->assertEquals($function['headers']['status-code'], 200); + $this->assertEquals($function['body']['sum'], 1); + $this->assertIsArray($function['body']['tags']); + $this->assertCount(1, $function['body']['tags']); + $this->assertEquals($function['body']['tags'][0]['$id'], $data['tagId']); + return $data; } diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 4d83efb41..6c0813cc2 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -7,6 +7,7 @@ use Tests\E2E\Scopes\ProjectConsole; use Tests\E2E\Scopes\SideClient; use Tests\E2E\Services\Projects\ProjectsBase; use Tests\E2E\Client; +use function array_merge; class ProjectsConsoleClientTest extends Scope { @@ -97,6 +98,28 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals($id, $response['body']['projects'][0]['$id']); $this->assertEquals('Project Test', $response['body']['projects'][0]['name']); + $response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders(), [ + 'search' => $id + ])); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertEquals('Project Test', $response['body']['projects'][0]['name']); + + $response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders(), [ + 'search' => 'Project Test' + ])); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertEquals($id, $response['body']['projects'][0]['$id']); + /** * Test after pagination */ diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index 57a5ee697..fde1fc9fb 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -5,6 +5,9 @@ namespace Tests\E2E\Services\Storage; use CURLFile; use Tests\E2E\Client; use Utopia\Image\Image; +use function array_merge; +use function realpath; +use function var_dump; trait StorageBase { @@ -163,7 +166,7 @@ trait StorageBase 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'fileId' => 'unique()', - 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'), + 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/file.png'), 'image/png', 'file.png'), 'read' => ['role:all'], 'write' => ['role:all'], ]); @@ -171,9 +174,9 @@ trait StorageBase $this->assertEquals($file['headers']['status-code'], 201); $this->assertNotEmpty($file['body']['$id']); $this->assertIsInt($file['body']['dateCreated']); - $this->assertEquals('logo.png', $file['body']['name']); - $this->assertEquals('image/png', $file['body']['mimeType']); - $this->assertEquals(47218, $file['body']['sizeOriginal']); + $this->assertEquals('file.png', $file['body']['name']); + $this->assertEquals('image/jpeg', $file['body']['mimeType']); + $this->assertEquals(16804, $file['body']['sizeOriginal']); $files = $this->client->call(Client::METHOD_GET, '/storage/files', array_merge([ 'content-type' => 'application/json', @@ -197,6 +200,33 @@ trait StorageBase $this->assertEquals($files['body']['files'][1]['$id'], $response['body']['files'][0]['$id']); $this->assertCount(1, $response['body']['files']); + $response = $this->client->call(Client::METHOD_GET, '/storage/files', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => $data['fileId'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertGreaterThan(0, $response['body']['sum']); + $this->assertIsInt($response['body']['sum']); + $this->assertCount(1, $response['body']['files']); + $this->assertEquals('logo.png', $response['body']['files'][0]['name']); + + + $response = $this->client->call(Client::METHOD_GET, '/storage/files', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => 'logo', + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertGreaterThan(0, $response['body']['sum']); + $this->assertIsInt($response['body']['sum']); + $this->assertGreaterThan(0, $response['body']['files']); + $this->assertEquals($data['fileId'], $response['body']['files'][0]['$id']); + /** * Test for FAILURE */ diff --git a/tests/e2e/Services/Teams/TeamsBase.php b/tests/e2e/Services/Teams/TeamsBase.php index 6c1ebbe36..fd1b064a7 100644 --- a/tests/e2e/Services/Teams/TeamsBase.php +++ b/tests/e2e/Services/Teams/TeamsBase.php @@ -3,6 +3,7 @@ namespace Tests\E2E\Services\Teams; use Tests\E2E\Client; +use function array_merge; trait TeamsBase { @@ -172,6 +173,19 @@ trait TeamsBase $this->assertCount(1, $response['body']['teams']); $this->assertEquals('Manchester United', $response['body']['teams'][0]['name']); + $response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => $data['teamUid'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertGreaterThan(0, $response['body']['sum']); + $this->assertIsInt($response['body']['sum']); + $this->assertCount(1, $response['body']['teams']); + $this->assertEquals('Arsenal', $response['body']['teams'][0]['name']); + $teams = $this->client->call(Client::METHOD_GET, '/teams', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index b35f355c9..e85e2a44a 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -3,6 +3,8 @@ namespace Tests\E2E\Services\Users; use Tests\E2E\Client; +use function array_merge; +use function var_dump; trait UsersBase { @@ -16,14 +18,14 @@ trait UsersBase 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'userId' => 'unique()', - 'email' => 'users.service@example.com', + 'email' => 'first.user@example.com', 'password' => 'password', - 'name' => 'Project User', + 'name' => 'First Name', ]); $this->assertEquals($user['headers']['status-code'], 201); - $this->assertEquals($user['body']['name'], 'Project User'); - $this->assertEquals($user['body']['email'], 'users.service@example.com'); + $this->assertEquals($user['body']['name'], 'First Name'); + $this->assertEquals($user['body']['email'], 'first.user@example.com'); $this->assertEquals($user['body']['status'], true); $this->assertGreaterThan(0, $user['body']['registration']); @@ -56,7 +58,7 @@ trait UsersBase public function testListUsers(array $data): void { /** - * Test for SUCCESS + * Test for SUCCESS listUsers */ $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ 'content-type' => 'application/json', @@ -82,8 +84,70 @@ trait UsersBase $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['users']); $this->assertCount(1, $response['body']['users']); - $this->assertEquals($response['body']['users'][0]['$id'], 'user1'); + + /** + * Test for SUCCESS searchUsers + */ + $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => 'First Name' + ]); + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertGreaterThan(0, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); + + $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => 'first.user' + ]); + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertGreaterThan(0, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); + + $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => 'first user name' + ]); + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertGreaterThan(0, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); + + $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => $data['userId'] + ]); + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertGreaterThan(0, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); + + $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => 'first user - first.user@example.com ' . $data['userId'] + ]); + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertGreaterThan(0, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); } /** @@ -100,8 +164,8 @@ trait UsersBase ], $this->getHeaders())); $this->assertEquals($user['headers']['status-code'], 200); - $this->assertEquals($user['body']['name'], 'Project User'); - $this->assertEquals($user['body']['email'], 'users.service@example.com'); + $this->assertEquals($user['body']['name'], 'First Name'); + $this->assertEquals($user['body']['email'], 'first.user@example.com'); $this->assertEquals($user['body']['status'], true); $this->assertGreaterThan(0, $user['body']['registration']); From 9d1b1a17d951a4ee050dbf99ce740622f50f6050 Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Tue, 21 Sep 2021 10:26:28 +0200 Subject: [PATCH 04/16] Removed PHPStorm-generated stuff --- tests/e2e/Services/Functions/FunctionsCustomClientTest.php | 1 - tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 -- tests/e2e/Services/Storage/StorageBase.php | 1 - tests/e2e/Services/Users/UsersBase.php | 2 -- 4 files changed, 6 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 0d229aafc..86f6fde48 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -7,7 +7,6 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use function var_dump; class FunctionsCustomClientTest extends Scope { diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index e118df8a5..62198293a 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -7,8 +7,6 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use function array_merge; -use function var_dump; class FunctionsCustomServerTest extends Scope { diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index fde1fc9fb..47a81444c 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -7,7 +7,6 @@ use Tests\E2E\Client; use Utopia\Image\Image; use function array_merge; use function realpath; -use function var_dump; trait StorageBase { diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index e85e2a44a..4bf344d95 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -3,8 +3,6 @@ namespace Tests\E2E\Services\Users; use Tests\E2E\Client; -use function array_merge; -use function var_dump; trait UsersBase { From fce5e3e96c54488a2250c8c801ba35cd1e1cf7ed Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Tue, 21 Sep 2021 10:27:31 +0200 Subject: [PATCH 05/16] Removed PHPStorm-generated stuff 2 --- tests/e2e/Services/Projects/ProjectsConsoleClientTest.php | 1 - tests/e2e/Services/Storage/StorageBase.php | 2 -- tests/e2e/Services/Teams/TeamsBase.php | 1 - 3 files changed, 4 deletions(-) diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 6c0813cc2..9edee076a 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -7,7 +7,6 @@ use Tests\E2E\Scopes\ProjectConsole; use Tests\E2E\Scopes\SideClient; use Tests\E2E\Services\Projects\ProjectsBase; use Tests\E2E\Client; -use function array_merge; class ProjectsConsoleClientTest extends Scope { diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index 47a81444c..8d9b2d9c8 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -5,8 +5,6 @@ namespace Tests\E2E\Services\Storage; use CURLFile; use Tests\E2E\Client; use Utopia\Image\Image; -use function array_merge; -use function realpath; trait StorageBase { diff --git a/tests/e2e/Services/Teams/TeamsBase.php b/tests/e2e/Services/Teams/TeamsBase.php index fd1b064a7..b594bbfa6 100644 --- a/tests/e2e/Services/Teams/TeamsBase.php +++ b/tests/e2e/Services/Teams/TeamsBase.php @@ -3,7 +3,6 @@ namespace Tests\E2E\Services\Teams; use Tests\E2E\Client; -use function array_merge; trait TeamsBase { From 4bbf0e93037e03edd072c29f0432a68f45485cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Thu, 23 Sep 2021 08:44:57 +0200 Subject: [PATCH 06/16] Remove unnecessary whitespace Co-authored-by: kodumbeats --- tests/e2e/Services/Storage/StorageBase.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index 8d9b2d9c8..c2f2483a5 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -210,7 +210,6 @@ trait StorageBase $this->assertCount(1, $response['body']['files']); $this->assertEquals('logo.png', $response['body']['files'][0]['name']); - $response = $this->client->call(Client::METHOD_GET, '/storage/files', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], From d43987fd7a569eb3470900be8f3ed26cce248758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Thu, 23 Sep 2021 08:49:45 +0200 Subject: [PATCH 07/16] Fix test assert bug Co-authored-by: kodumbeats --- tests/e2e/Services/Storage/StorageBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index c2f2483a5..2bd69ec1a 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -205,7 +205,7 @@ trait StorageBase ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertGreaterThan(0, $response['body']['sum']); + $this->assertEquals(1, $response['body']['sum']); $this->assertIsInt($response['body']['sum']); $this->assertCount(1, $response['body']['files']); $this->assertEquals('logo.png', $response['body']['files'][0]['name']); From 8f1847f87109c617dadd41f1bbe6a109199f329a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Thu, 23 Sep 2021 08:50:47 +0200 Subject: [PATCH 08/16] Test assert bug fix Co-authored-by: kodumbeats --- tests/e2e/Services/Storage/StorageBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index 2bd69ec1a..ecfc55d1a 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -218,7 +218,7 @@ trait StorageBase ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertGreaterThan(0, $response['body']['sum']); + $this->assertEquals(1, $response['body']['sum']); $this->assertIsInt($response['body']['sum']); $this->assertGreaterThan(0, $response['body']['files']); $this->assertEquals($data['fileId'], $response['body']['files'][0]['$id']); From 1f2f0c2443618366256522566d0645e4d5c98e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Thu, 23 Sep 2021 08:57:16 +0200 Subject: [PATCH 09/16] Apply suggestions from code review Co-authored-by: kodumbeats --- tests/e2e/Services/Storage/StorageBase.php | 2 +- tests/e2e/Services/Users/UsersBase.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index ecfc55d1a..ab1a08c68 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -220,7 +220,7 @@ trait StorageBase $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(1, $response['body']['sum']); $this->assertIsInt($response['body']['sum']); - $this->assertGreaterThan(0, $response['body']['files']); + $this->assertCount(1, $response['body']['files']); $this->assertEquals($data['fileId'], $response['body']['files'][0]['$id']); /** diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index 1fd4444b3..564b3e786 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -96,7 +96,7 @@ trait UsersBase $this->assertEquals($response['headers']['status-code'], 200); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['users']); - $this->assertGreaterThan(0, $response['body']['users']); + $this->assertCount(1, $response['body']['users']); $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ @@ -108,7 +108,7 @@ trait UsersBase $this->assertEquals($response['headers']['status-code'], 200); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['users']); - $this->assertGreaterThan(0, $response['body']['users']); + $this->assertCount(1, $response['body']['users']); $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ @@ -120,7 +120,7 @@ trait UsersBase $this->assertEquals($response['headers']['status-code'], 200); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['users']); - $this->assertGreaterThan(0, $response['body']['users']); + $this->assertCount(1, $response['body']['users']); $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ From c61b00995c643bc95a1fc968adcc40dbc21858cf Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Thu, 23 Sep 2021 09:01:10 +0200 Subject: [PATCH 10/16] Manual code review suggestion changes --- .../Functions/FunctionsCustomServerTest.php | 12 +++++++++-- .../Projects/ProjectsConsoleClientTest.php | 20 +++++++++++++------ tests/e2e/Services/Users/UsersBase.php | 4 ++-- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 62198293a..a0b0754b0 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -77,6 +77,10 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ + + /** + * Test search queries + */ $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -110,7 +114,9 @@ class FunctionsCustomServerTest extends Scope $this->assertCount(1, $response['body']['functions']); $this->assertEquals($response['body']['functions'][0]['$id'], $data['functionId']); - + /** + * Test pagination + */ $response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -155,7 +161,6 @@ class FunctionsCustomServerTest extends Scope $this->assertCount(1, $response['body']['functions']); $this->assertEquals($response['body']['functions'][0]['name'], 'Test 2'); - return $data; } @@ -316,6 +321,9 @@ class FunctionsCustomServerTest extends Scope $this->assertIsArray($function['body']['tags']); $this->assertCount(1, $function['body']['tags']); + /** + * Test search queries + */ $function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/tags', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 5de323cc4..56daab688 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -87,6 +87,7 @@ class ProjectsConsoleClientTest extends Scope /** * Test for SUCCESS */ + $response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -97,6 +98,9 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals($id, $response['body']['projects'][0]['$id']); $this->assertEquals('Project Test', $response['body']['projects'][0]['name']); + /** + * Test search queries + */ $response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -104,9 +108,11 @@ class ProjectsConsoleClientTest extends Scope 'search' => $id ])); - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertNotEmpty($response['body']); - $this->assertEquals('Project Test', $response['body']['projects'][0]['name']); + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertEquals($response['body']['sum'], 1); + $this->assertIsArray($response['body']['projects']); + $this->assertCount(1, $response['body']['projects']); + $this->assertEquals($response['body']['projects'][0]['name'], 'Project Test'); $response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([ 'content-type' => 'application/json', @@ -115,9 +121,11 @@ class ProjectsConsoleClientTest extends Scope 'search' => 'Project Test' ])); - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertNotEmpty($response['body']); - $this->assertEquals($id, $response['body']['projects'][0]['$id']); + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertEquals($response['body']['sum'], 1); + $this->assertIsArray($response['body']['projects']); + $this->assertCount(1, $response['body']['projects']); + $this->assertEquals($response['body']['projects'][0]['$id'], $data['projectId']); /** * Test after pagination diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index 564b3e786..7db500ddc 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -132,7 +132,7 @@ trait UsersBase $this->assertEquals($response['headers']['status-code'], 200); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['users']); - $this->assertGreaterThan(0, $response['body']['users']); + $this->assertCount(1, $response['body']['users']); $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ @@ -144,7 +144,7 @@ trait UsersBase $this->assertEquals($response['headers']['status-code'], 200); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['users']); - $this->assertGreaterThan(0, $response['body']['users']); + $this->assertCount(1, $response['body']['users']); $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); } From d0b70a9dee75d1a1f6026f325e1cce6374a2ab5e Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Mon, 27 Sep 2021 12:12:42 +0200 Subject: [PATCH 11/16] Re-added function execution search + added missing tests --- app/config/collections2.php | 18 +++++++++++ app/controllers/api/functions.php | 24 +++++++++----- .../Functions/FunctionsCustomServerTest.php | 32 +++++++++++++++++++ 3 files changed, 66 insertions(+), 8 deletions(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index ea99ae47d..da79e3684 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -1711,6 +1711,17 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => 'search', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], ], 'indexes' => [ [ @@ -1720,6 +1731,13 @@ $collections = [ 'lengths' => [Database::LENGTH_KEY], 'orders' => [Database::ORDER_ASC], ], + [ + '$id' => '_fulltext_search', + 'type' => Database::INDEX_FULLTEXT, + 'attributes' => ['search'], + 'lengths' => [1024], + 'orders' => [Database::ORDER_ASC], + ], ], ], diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 28ff911c1..00ed18123 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -680,8 +680,10 @@ App::post('/v1/functions/:functionId/executions') Authorization::disable(); + $executionId = $dbForInternal->getId(); + $execution = $dbForInternal->createDocument('executions', new Document([ - '$id' => $dbForInternal->getId(), + '$id' => $executionId, '$read' => (!$user->isEmpty()) ? ['user:' . $user->getId()] : [], '$write' => [], 'dateCreated' => time(), @@ -693,6 +695,7 @@ App::post('/v1/functions/:functionId/executions') 'stdout' => '', 'stderr' => '', 'time' => 0.0, + 'search' => implode(' ', [$functionId, $executionId]), ])); Authorization::reset(); @@ -747,10 +750,11 @@ App::get('/v1/functions/:functionId/executions') ->param('functionId', '', new UID(), 'Function unique ID.') ->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true) + ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) ->param('after', '', new UID(), 'ID of the execution used as the starting point for the query, excluding the execution itself. Should be used for efficient pagination when working with large sets of data.', true) ->inject('response') ->inject('dbForInternal') - ->action(function ($functionId, $limit, $offset, $after, $response, $dbForInternal) { + ->action(function ($functionId, $limit, $offset, $search, $after, $response, $dbForInternal) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ @@ -770,13 +774,17 @@ App::get('/v1/functions/:functionId/executions') } } - $results = $dbForInternal->find('executions', [ - new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]), - ], $limit, $offset, [], [Database::ORDER_DESC], $afterExecution ?? null); + $queries = [ + new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]) + ]; - $sum = $dbForInternal->count('executions', [ - new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]), - ], APP_LIMIT_COUNT); + if (!empty($search)) { + $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); + } + + $results = $dbForInternal->find('executions', $queries, $limit, $offset, [], [Database::ORDER_DESC], $afterExecution ?? null); + + $sum = $dbForInternal->count('executions', $queries, APP_LIMIT_COUNT); $response->dynamic(new Document([ 'executions' => $results, diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index a0b0754b0..aa6413388 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -7,6 +7,8 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; +use function array_merge; +use function var_dump; class FunctionsCustomServerTest extends Scope { @@ -474,6 +476,36 @@ class FunctionsCustomServerTest extends Scope $this->assertCount(1, $function['body']['executions']); $this->assertEquals($function['body']['executions'][0]['$id'], $data['executionId']); + /** + * Test search queries + */ + + $response = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/executions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => $data['executionId'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals(1, $response['body']['sum']); + $this->assertIsInt($response['body']['sum']); + $this->assertCount(1, $response['body']['executions']); + $this->assertEquals($data['functionId'], $response['body']['executions'][0]['functionId']); + + $response = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/executions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => $data['functionId'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals(1, $response['body']['sum']); + $this->assertIsInt($response['body']['sum']); + $this->assertCount(1, $response['body']['executions']); + $this->assertEquals($data['executionId'], $response['body']['executions'][0]['$id']); + return $data; } From 24f9c2518bf54f68c15329abb46f58f15fd31054 Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Mon, 27 Sep 2021 12:20:32 +0200 Subject: [PATCH 12/16] Removed imports --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index aa6413388..57b8ad921 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -7,8 +7,6 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use function array_merge; -use function var_dump; class FunctionsCustomServerTest extends Scope { From 7497540db0c9c7a48dbb618b2679e9d371e7067a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 4 Oct 2021 13:02:54 +0200 Subject: [PATCH 13/16] Update app/config/collections2.php Co-authored-by: kodumbeats --- app/config/collections2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index da79e3684..bab2414ae 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -1735,7 +1735,7 @@ $collections = [ '$id' => '_fulltext_search', 'type' => Database::INDEX_FULLTEXT, 'attributes' => ['search'], - 'lengths' => [1024], + 'lengths' => [16384], 'orders' => [Database::ORDER_ASC], ], ], From 3d6de5da4774f60719526f6ebe2a8306bb435158 Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Tue, 5 Oct 2021 12:02:54 -0400 Subject: [PATCH 14/16] Throw correct response code for duplicate user --- app/controllers/api/account.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index e01bb0731..ac7179972 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1140,7 +1140,7 @@ App::patch('/v1/account/email') $profile = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address if ($profile) { - throw new Exception('User already registered', 400); + throw new Exception('User already registered', 409); } try { From 4a054559a54ddc43601caeaf5a5af11e92646b5d Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 5 Oct 2021 23:15:43 +0200 Subject: [PATCH 15/16] fix search with cristiano --- app/controllers/api/users.php | 2 +- tests/e2e/Services/Users/UsersBase.php | 67 +++++++++++--------------- 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index a68857273..7adaa747c 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -111,7 +111,7 @@ App::get('/v1/users') throw new Exception("User '{$after}' for the 'after' value not found.", 400); } } - + $queries = []; if (!empty($search)) { diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index 7db500ddc..ee35e66fc 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -16,14 +16,14 @@ trait UsersBase 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'userId' => 'unique()', - 'email' => 'first.user@example.com', + 'email' => 'cristiano.ronaldo@manchester-united.co.uk', 'password' => 'password', - 'name' => 'First Name', + 'name' => 'Cristiano Ronaldo', ]); $this->assertEquals($user['headers']['status-code'], 201); - $this->assertEquals($user['body']['name'], 'First Name'); - $this->assertEquals($user['body']['email'], 'first.user@example.com'); + $this->assertEquals($user['body']['name'], 'Cristiano Ronaldo'); + $this->assertEquals($user['body']['email'], 'cristiano.ronaldo@manchester-united.co.uk'); $this->assertEquals($user['body']['status'], true); $this->assertGreaterThan(0, $user['body']['registration']); @@ -35,15 +35,15 @@ trait UsersBase 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'userId' => 'user1', - 'email' => 'users.service1@example.com', + 'email' => 'lionel.messi@psg.fr', 'password' => 'password', - 'name' => 'Project User', + 'name' => 'Lionel Messi', ]); $this->assertEquals($res['headers']['status-code'], 201); $this->assertEquals($res['body']['$id'], 'user1'); - $this->assertEquals($res['body']['name'], 'Project User'); - $this->assertEquals($res['body']['email'], 'users.service1@example.com'); + $this->assertEquals($res['body']['name'], 'Lionel Messi'); + $this->assertEquals($res['body']['email'], 'lionel.messi@psg.fr'); $this->assertEquals(true, $res['body']['status']); $this->assertGreaterThan(0, $res['body']['registration']); @@ -91,7 +91,7 @@ trait UsersBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'search' => 'First Name' + 'search' => 'Ronaldo' ]); $this->assertEquals($response['headers']['status-code'], 200); $this->assertNotEmpty($response['body']); @@ -103,7 +103,7 @@ trait UsersBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'search' => 'first.user' + 'search' => 'cristiano.ronaldo' ]); $this->assertEquals($response['headers']['status-code'], 200); $this->assertNotEmpty($response['body']); @@ -115,7 +115,7 @@ trait UsersBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'search' => 'first user name' + 'search' => 'manchester' ]); $this->assertEquals($response['headers']['status-code'], 200); $this->assertNotEmpty($response['body']); @@ -123,6 +123,20 @@ trait UsersBase $this->assertCount(1, $response['body']['users']); $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); + $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => 'manchester-united.co.uk' + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertIsArray($response['body']); + $this->assertIsArray($response['body']['users']); + $this->assertIsInt($response['body']['sum']); + $this->assertEquals(1, $response['body']['sum']); + $this->assertCount(1, $response['body']['users']); + $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -134,18 +148,6 @@ trait UsersBase $this->assertNotEmpty($response['body']['users']); $this->assertCount(1, $response['body']['users']); $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); - - $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'search' => 'first user - first.user@example.com ' . $data['userId'] - ]); - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertNotEmpty($response['body']); - $this->assertNotEmpty($response['body']['users']); - $this->assertCount(1, $response['body']['users']); - $this->assertEquals($response['body']['users'][0]['$id'], $data['userId']); } /** @@ -162,8 +164,8 @@ trait UsersBase ], $this->getHeaders())); $this->assertEquals($user['headers']['status-code'], 200); - $this->assertEquals($user['body']['name'], 'First Name'); - $this->assertEquals($user['body']['email'], 'first.user@example.com'); + $this->assertEquals($user['body']['name'], 'Cristiano Ronaldo'); + $this->assertEquals($user['body']['email'], 'cristiano.ronaldo@manchester-united.co.uk'); $this->assertEquals($user['body']['status'], true); $this->assertGreaterThan(0, $user['body']['registration']); @@ -194,21 +196,6 @@ trait UsersBase $this->assertIsInt($users['body']['sum']); $this->assertGreaterThan(0, $users['body']['sum']); - $users = $this->client->call(Client::METHOD_GET, '/users', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'search' => 'example.com' - ]); - - $this->assertEquals($users['headers']['status-code'], 200); - $this->assertIsArray($users['body']); - $this->assertIsArray($users['body']['users']); - $this->assertIsInt($users['body']['sum']); - $this->assertEquals(2, $users['body']['sum']); - $this->assertGreaterThan(0, $users['body']['sum']); - $this->assertCount(2, $users['body']['users']); - return $data; } From e0699932a03ad73b66b14e78459c5586d1313fe6 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 6 Oct 2021 14:56:44 +0200 Subject: [PATCH 16/16] fix(users): query to ignore deleted users --- app/controllers/api/users.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 28da6b0a9..99748d40d 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -113,7 +113,9 @@ App::get('/v1/users') } } - $queries = []; + $queries = [ + new Query('deleted', Query::TYPE_EQUAL, [false]) + ]; if (!empty($search)) { $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);