From 5e4eda2126e6f494f01a5267230ffd36e99a7d50 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Thu, 7 Mar 2024 14:48:36 +0100 Subject: [PATCH 1/6] feat: cascading response models --- app/controllers/general.php | 76 +-- src/Appwrite/Utopia/Request.php | 45 +- src/Appwrite/Utopia/Request/Filters/V12.php | 171 ------ src/Appwrite/Utopia/Request/Filters/V13.php | 38 -- src/Appwrite/Utopia/Request/Filters/V14.php | 34 -- src/Appwrite/Utopia/Request/Filters/V15.php | 275 --------- src/Appwrite/Utopia/Response.php | 32 +- src/Appwrite/Utopia/Response/Filter.php | 21 + src/Appwrite/Utopia/Response/Filters/V11.php | 401 ------------- src/Appwrite/Utopia/Response/Filters/V12.php | 269 --------- src/Appwrite/Utopia/Response/Filters/V13.php | 103 ---- src/Appwrite/Utopia/Response/Filters/V14.php | 176 ------ src/Appwrite/Utopia/Response/Filters/V15.php | 591 ------------------- src/Appwrite/Utopia/Response/Filters/V16.php | 34 +- src/Appwrite/Utopia/Response/Filters/V17.php | 34 +- 15 files changed, 117 insertions(+), 2183 deletions(-) delete mode 100644 src/Appwrite/Utopia/Request/Filters/V12.php delete mode 100644 src/Appwrite/Utopia/Request/Filters/V13.php delete mode 100644 src/Appwrite/Utopia/Request/Filters/V14.php delete mode 100644 src/Appwrite/Utopia/Request/Filters/V15.php delete mode 100644 src/Appwrite/Utopia/Response/Filters/V11.php delete mode 100644 src/Appwrite/Utopia/Response/Filters/V12.php delete mode 100644 src/Appwrite/Utopia/Response/Filters/V13.php delete mode 100644 src/Appwrite/Utopia/Response/Filters/V14.php delete mode 100644 src/Appwrite/Utopia/Response/Filters/V15.php diff --git a/app/controllers/general.php b/app/controllers/general.php index fab710023..ebbe9b096 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -8,18 +8,9 @@ use Appwrite\Event\Usage; use Appwrite\Extend\Exception as AppwriteException; use Appwrite\Network\Validator\Origin; use Appwrite\Utopia\Request; -use Appwrite\Utopia\Request\Filters\V12 as RequestV12; -use Appwrite\Utopia\Request\Filters\V13 as RequestV13; -use Appwrite\Utopia\Request\Filters\V14 as RequestV14; -use Appwrite\Utopia\Request\Filters\V15 as RequestV15; use Appwrite\Utopia\Request\Filters\V16 as RequestV16; use Appwrite\Utopia\Request\Filters\V17 as RequestV17; use Appwrite\Utopia\Response; -use Appwrite\Utopia\Response\Filters\V11 as ResponseV11; -use Appwrite\Utopia\Response\Filters\V12 as ResponseV12; -use Appwrite\Utopia\Response\Filters\V13 as ResponseV13; -use Appwrite\Utopia\Response\Filters\V14 as ResponseV14; -use Appwrite\Utopia\Response\Filters\V15 as ResponseV15; use Appwrite\Utopia\Response\Filters\V16 as ResponseV16; use Appwrite\Utopia\Response\Filters\V17 as ResponseV17; use Appwrite\Utopia\View; @@ -400,37 +391,21 @@ App::init() */ $route = $utopia->getRoute(); Request::setRoute($route); + Request::resetFilters(); if ($route === null) { return $response->setStatusCode(404)->send('Not Found'); } - $requestFormat = $request->getHeader('x-appwrite-response-format', App::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', '')); + $requestFormat = $request->getHeader('x-appwrite-response-format', App::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', null)); + if ($requestFormat) { - switch ($requestFormat) { - case version_compare($requestFormat, '0.12.0', '<'): - Request::setFilter(new RequestV12()); - break; - case version_compare($requestFormat, '0.13.0', '<'): - Request::setFilter(new RequestV13()); - break; - case version_compare($requestFormat, '0.14.0', '<'): - Request::setFilter(new RequestV14()); - break; - case version_compare($requestFormat, '0.15.3', '<'): - Request::setFilter(new RequestV15()); - break; - case version_compare($requestFormat, '1.4.0', '<'): - Request::setFilter(new RequestV16()); - break; - case version_compare($requestFormat, '1.5.0', '<'): - Request::setFilter(new RequestV17()); - break; - default: - Request::setFilter(null); + if (version_compare($requestFormat, '1.4.0', '<')) { + Request::addFilter(new RequestV16()); + } + if (version_compare($requestFormat, '1.5.0', '<')) { + Request::addFilter(new RequestV17()); } - } else { - Request::setFilter(null); } $domain = $request->getHostname(); @@ -539,35 +514,16 @@ App::init() /* * Response format */ - $responseFormat = $request->getHeader('x-appwrite-response-format', App::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', '')); + Response::resetFilters(); + + $responseFormat = $request->getHeader('x-appwrite-response-format', App::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', null)); if ($responseFormat) { - switch ($responseFormat) { - case version_compare($responseFormat, '0.11.2', '<='): - Response::setFilter(new ResponseV11()); - break; - case version_compare($responseFormat, '0.12.4', '<='): - Response::setFilter(new ResponseV12()); - break; - case version_compare($responseFormat, '0.13.4', '<='): - Response::setFilter(new ResponseV13()); - break; - case version_compare($responseFormat, '0.14.0', '<='): - Response::setFilter(new ResponseV14()); - break; - case version_compare($responseFormat, '0.15.3', '<='): - Response::setFilter(new ResponseV15()); - break; - case version_compare($responseFormat, '1.4.0', '<'): - Response::setFilter(new ResponseV16()); - break; - case version_compare($responseFormat, '1.5.0', '<'): - Response::setFilter(new ResponseV17()); - break; - default: - Response::setFilter(null); + if (version_compare($responseFormat, '1.4.0', '<')) { + Response::addFilter(new ResponseV16()); + } + if (version_compare($responseFormat, '1.5.0', '<')) { + Response::addFilter(new ResponseV17()); } - } else { - Response::setFilter(null); } /* diff --git a/src/Appwrite/Utopia/Request.php b/src/Appwrite/Utopia/Request.php index 9ad2f6cb7..af9b13661 100644 --- a/src/Appwrite/Utopia/Request.php +++ b/src/Appwrite/Utopia/Request.php @@ -9,7 +9,11 @@ use Utopia\Swoole\Request as UtopiaRequest; class Request extends UtopiaRequest { - private static ?Filter $filter = null; + /** + * @var array + */ + private static array $filters = []; + private static ?Route $route = null; public function __construct(SwooleRequest $request) @@ -24,35 +28,50 @@ class Request extends UtopiaRequest { $parameters = parent::getParams(); - if (self::hasFilter() && self::hasRoute()) { + if (self::hasFilters() && self::hasRoute()) { $method = self::getRoute()->getLabel('sdk.method', 'unknown'); $endpointIdentifier = self::getRoute()->getLabel('sdk.namespace', 'unknown') . '.' . $method; - $parameters = self::getFilter()->parse($parameters, $endpointIdentifier); + + $parameters = array_reduce( + self::getFilters(), + fn (array $carry, Filter $filter) => $filter->parse($carry, $endpointIdentifier), + $parameters + ); } return $parameters; } /** - * Function to set a response filter + * Function to add a response filter, the order of filters are first in - first out. * - * @param Filter|null $filter Filter the response filter to set + * @param Filter $filter the response filter to set * * @return void */ - public static function setFilter(?Filter $filter): void + public static function addFilter(Filter $filter): void { - self::$filter = $filter; + self::$filters[] = $filter; } /** * Return the currently set filter * - * @return Filter|null + * @return array */ - public static function getFilter(): ?Filter + public static function getFilters(): array { - return self::$filter; + return self::$filters; + } + + /** + * Reset filters + * + * @return void + */ + public static function resetFilters(): void + { + self::$filters = []; } /** @@ -60,9 +79,9 @@ class Request extends UtopiaRequest * * @return bool */ - public static function hasFilter(): bool + public static function hasFilters(): bool { - return self::$filter != null; + return !empty(self::$filters); } /** @@ -94,7 +113,7 @@ class Request extends UtopiaRequest */ public static function hasRoute(): bool { - return self::$route != null; + return self::$route !== null; } /** diff --git a/src/Appwrite/Utopia/Request/Filters/V12.php b/src/Appwrite/Utopia/Request/Filters/V12.php deleted file mode 100644 index 37a5232a1..000000000 --- a/src/Appwrite/Utopia/Request/Filters/V12.php +++ /dev/null @@ -1,171 +0,0 @@ - Custom IDs - case "account.create": - case "account.createMagicURLSession": - case "users.create": - $content = $this->addId($content, 'userId'); - break; - case "functions.create": - $content = $this->addId($content, 'functionId'); - break; - case "teams.create": - $content = $this->addId($content, 'teamId'); - break; - - // Status integer -> boolean - case "users.updateStatus": - $content = $this->convertStatus($content); - break; - - // Deprecating order type - case "functions.listExecutions": - $content = $this->removeOrderType($content); - break; - - // The rest (more complex) formats - case "database.createDocument": - $content = $this->addId($content, 'documentId'); - $content = $this->removeParentProperties($content); - break; - case "database.listDocuments": - $content = $this->removeOrderCast($content); - $content = $this->convertOrder($content); - $content = $this->convertQueries($content); - break; - case "database.createCollection": - $content = $this->addId($content, 'collectionId'); - $content = $this->removeRules($content); - $content = $this->addCollectionPermissionLevel($content); - break; - case "database.updateCollection": - $content = $this->removeRules($content); - $content = $this->addCollectionPermissionLevel($content); - break; - } - - return $content; - } - - // New parameters - - protected function addId(array $content, string $key): array - { - $content[$key] = 'unique()'; - return $content; - } - - protected function addCollectionPermissionLevel(array $content): array - { - $content['permission'] = 'document'; - return $content; - } - - // Deprecated parameters - - protected function removeRules(array $content): array - { - unset($content['rules']); - return $content; - } - - protected function removeOrderType(array $content): array - { - unset($content['orderType']); - return $content; - } - - protected function removeOrderCast(array $content): array - { - unset($content['orderCast']); - return $content; - } - - protected function removeParentProperties(array $content): array - { - if (isset($content['parentDocument'])) { - unset($content['parentDocument']); - } - if (isset($content['parentProperty'])) { - unset($content['parentProperty']); - } - if (isset($content['parentPropertyType'])) { - unset($content['parentPropertyType']); - } - return $content; - } - - // Modified parameters - - protected function convertStatus(array $content): array - { - if (isset($content['status'])) { - $content['status'] = $content['status'] === 2 ? false : true; - } - return $content; - } - - protected function convertOrder(array $content): array - { - if (isset($content['orderField'])) { - $content['orderAttributes'] = [ $content['orderField'] ]; - unset($content['orderField']); - } - - if (isset($content['orderType'])) { - $content['orderTypes'] = [ $content['orderType'] ]; - unset($content['orderType']); - } - - return $content; - } - - protected function convertQueries(array $content): array - { - $queries = []; - - if (!empty($content['filters'])) { - foreach ($content['filters'] as $filter) { - $operators = ['=' => 'equal', '!=' => 'notEqual', '>' => 'greater', '<' => 'lesser', '<=' => 'lesserEqual', '>=' => 'greaterEqual']; - foreach ($operators as $operator => $operatorVerbose) { - if (\str_contains($filter, $operator)) { - $usedOperator = $operator; - break; - } - } - - if (isset($usedOperator)) { - [ $attributeKey, $filterValue ] = \explode($usedOperator, $filter); - - if ($filterValue === 'true' || $filterValue === 'false') { - // Let's keep it at true and false string, but without "" around - // No action needed - } else { - $filterValue = \is_numeric($filterValue) ? $filterValue : '"' . $filterValue . '"'; - } - - $query = $attributeKey . '.' . $operators[$usedOperator] . '(' . $filterValue . ')'; - \array_push($queries, $query); - } - } - } - - // We cannot migrate search properly - unset($content['search']); - - unset($content['filters']); - $content['queries'] = $queries; - - return $content; - } -} diff --git a/src/Appwrite/Utopia/Request/Filters/V13.php b/src/Appwrite/Utopia/Request/Filters/V13.php deleted file mode 100644 index e1122fdd7..000000000 --- a/src/Appwrite/Utopia/Request/Filters/V13.php +++ /dev/null @@ -1,38 +0,0 @@ -convertStringToNum($content, "min"); - $content = $this->convertStringToNum($content, "max"); - $content = $this->convertStringToNum($content, "default"); - break; - case "functions.createExecution": - $content = $this->convertExecution($content); - } - - return $content; - } - - private function convertStringToNum($content, $value) - { - $content[$value] = is_null($content[$value]) ? null : (int)$content[$value]; - return $content; - } - - private function convertExecution($content) - { - $content['async'] = true; - return $content; - } -} diff --git a/src/Appwrite/Utopia/Request/Filters/V14.php b/src/Appwrite/Utopia/Request/Filters/V14.php deleted file mode 100644 index f42a35102..000000000 --- a/src/Appwrite/Utopia/Request/Filters/V14.php +++ /dev/null @@ -1,34 +0,0 @@ -convertEvents($content); - break; - } - - return $content; - } - - private function convertEvents($content) - { - $migration = new MigrationV13(); - - $events = $content['events'] ?? []; - $content['events'] = $migration->migrateEvents($events); - - return $content; - } -} diff --git a/src/Appwrite/Utopia/Request/Filters/V15.php b/src/Appwrite/Utopia/Request/Filters/V15.php deleted file mode 100644 index 52e9c4a72..000000000 --- a/src/Appwrite/Utopia/Request/Filters/V15.php +++ /dev/null @@ -1,275 +0,0 @@ -convertLimitAndOffset($content); - break; - case 'account.initials': - unset($content['color']); - break; - case 'databases.list': - case 'databases.listCollections': - case 'functions.list': - case 'functions.listDeployments': - case 'projects.list': - case 'storage.listBuckets': - case 'storage.listFiles': - case 'teams.list': - case 'teams.listMemberships': - case 'users.list': - $content = $this->convertLimitAndOffset($content); - $content = $this->convertCursor($content); - $content = $this->convertOrderType($content); - break; - case 'databases.createCollection': - case 'databases.updateCollection': - $content = $this->convertCollectionPermission($content); - $content = $this->convertReadWrite($content); - break; - case 'databases.createDocument': - case 'databases.updateDocument': - case 'storage.createFile': - case 'storage.updateFile': - $content = $this->convertReadWrite($content); - break; - case 'databases.listDocuments': - $content = $this->convertFilters($content); - $content = $this->convertLimitAndOffset($content); - $content = $this->convertCursor($content); - $content = $this->convertOrders($content); - break; - case 'functions.create': - case 'functions.update': - $content = $this->convertExecute($content); - break; - case 'functions.listExecutions': - $content = $this->convertLimitAndOffset($content); - $content = $this->convertCursor($content); - break; - case 'projects.createKey': - case 'projects.updateKey': - $content = $this->convertExpire($content); - break; - case 'storage.createBucket': - case 'storage.updateBucket': - $content = $this->convertBucketPermission($content); - $content = $this->convertReadWrite($content); - break; - } - - return $content; - } - - protected function convertLimitAndOffset($content) - { - if (isset($content['limit'])) { - $content['queries'][] = 'limit(' . $content['limit'] . ')'; - } - - if (isset($content['offset'])) { - $content['queries'][] = 'offset(' . $content['offset'] . ')'; - } - - unset($content['limit']); - unset($content['offset']); - - return $content; - } - - protected function convertCursor($content) - { - if (isset($content['cursor'])) { - $cursorDirection = $content['cursorDirection'] ?? Database::CURSOR_AFTER; - - if ($cursorDirection === Database::CURSOR_BEFORE) { - $content['queries'][] = 'cursorBefore("' . $content["cursor"] . '")'; - } else { - $content['queries'][] = 'cursorAfter("' . $content["cursor"] . '")'; - } - } - - unset($content['cursor']); - unset($content['cursorDirection']); - - return $content; - } - - protected function convertOrderType($content) - { - if (isset($content['orderType'])) { - if ($content['orderType'] === Database::ORDER_DESC) { - $content['queries'][] = 'orderDesc("")'; - } else { - $content['queries'][] = 'orderAsc("")'; - } - } - unset($content['orderType']); - - return $content; - } - - protected function convertOrders($content) - { - if (isset($content['orderTypes'])) { - foreach ($content['orderTypes'] as $i => $type) { - $attribute = $content['orderAttributes'][$i] ?? ''; - - if ($type === Database::ORDER_DESC) { - $content['queries'][] = 'orderDesc("' . $attribute . '")'; - } else { - $content['queries'][] = 'orderAsc("' . $attribute . '")'; - } - } - } - - unset($content['orderAttributes']); - unset($content['orderTypes']); - - return $content; - } - - protected function convertCollectionPermission($content) - { - if (isset($content['permission'])) { - $content['documentSecurity'] = $content['permission'] === 'document'; - } - - unset($content['permission']); - - return $content; - } - - protected function convertReadWrite($content) - { - if (isset($content['read'])) { - foreach ($content['read'] as $read) { - if ($read === 'role:all') { - $content['permissions'][] = Permission::read(Role::any()); - } elseif ($read === 'role:guest') { - $content['permissions'][] = Permission::read(Role::guests()); - } elseif ($read === 'role:member') { - $content['permissions'][] = Permission::read(Role::users()); - } elseif (str_contains($read, ':')) { - $content['permissions'][] = Permission::read(Role::parse($read)); - } - } - } - - if (isset($content['write'])) { - foreach ($content['write'] as $write) { - if ($write === 'role:all' || $write === 'role:member') { - $content['permissions'][] = Permission::write(Role::users()); - } elseif ($write === 'role:guest') { - // don't add because, historically, - // role:guest for write did nothing - } elseif (str_contains($write, ':')) { - $content['permissions'][] = Permission::write(Role::parse($write)); - } - } - } - - unset($content['read']); - unset($content['write']); - - return $content; - } - - protected function convertFilters($content) - { - if (!isset($content['queries'])) { - return $content; - } - - $operations = [ - 'equal' => Query::TYPE_EQUAL, - 'notEqual' => Query::TYPE_NOT_EQUAL, - 'lesser' => Query::TYPE_LESSER, - 'lesserEqual' => Query::TYPE_LESSER_EQUAL, - 'greater' => Query::TYPE_GREATER, - 'greaterEqual' => Query::TYPE_GREATER_EQUAL, - 'search' => Query::TYPE_SEARCH, - ]; - foreach ($content['queries'] as $i => $query) { - foreach ($operations as $oldOperation => $newOperation) { - $middle = ".$oldOperation("; - if (str_contains($query, $middle)) { - $parts = explode($middle, $query); - if (count($parts) > 1) { - $attribute = $parts[0]; - $value = rtrim($parts[1], ")"); - $content['queries'][$i] = $newOperation . '("' . $attribute . '", [' . $value . '])'; - } - } - } - } - return $content; - } - - protected function convertExecute($content) - { - if (!isset($content['execute'])) { - return $content; - } - - $execute = []; - foreach ($content['execute'] as $role) { - if ($role === 'role:all' || $role === 'role:member') { - $execute[] = Role::users()->toString(); - } elseif ($role === 'role:guest') { - // don't add because, historically, - // role:guest for write did nothing - } elseif (str_contains($role, ':')) { - $execute[] = $role; - } - } - $content['execute'] = $execute; - - return $content; - } - - protected function convertExpire($content) - { - if (!isset($content['expire'])) { - return $content; - } - - $expire = (int) $content['expire']; - - if ($expire === 0) { - $content['expire'] = null; - } else { - $content['expire'] = date(\DateTime::RFC3339_EXTENDED, $expire); - } - - return $content; - } - - protected function convertBucketPermission($content) - { - if (isset($content['permission'])) { - $content['fileSecurity'] = $content['permission'] === 'file'; - } - - unset($content['permission']); - - return $content; - } -} diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 22043b9f2..c570ccfb2 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -299,9 +299,9 @@ class Response extends SwooleResponse public const MODEL_MOCK = 'mock'; /** - * @var Filter + * @var array */ - private static $filter = null; + private static $filters = []; /** * @var array @@ -526,8 +526,8 @@ class Response extends SwooleResponse $output = $this->output(clone $document, $model); // If filter is set, parse the output - if (self::hasFilter()) { - $output = self::getFilter()->parse($output, $model); + foreach (self::$filters as $filter) { + $output = $filter->parse($output, $model); } switch ($this->getContentType()) { @@ -682,15 +682,15 @@ class Response extends SwooleResponse } /** - * Function to set a response filter + * Function to add a response filter, the order of filters are first in - first out. * * @param $filter the response filter to set * * @return void */ - public static function setFilter(?Filter $filter) + public static function addFilter(Filter $filter): void { - self::$filter = $filter; + self::$filters[] = $filter; } /** @@ -698,9 +698,19 @@ class Response extends SwooleResponse * * @return Filter */ - public static function getFilter(): ?Filter + public static function getFilters(): array { - return self::$filter; + return self::$filters; + } + + /** + * Reset filters + * + * @return void + */ + public static function resetFilters(): void + { + self::$filters = []; } /** @@ -708,9 +718,9 @@ class Response extends SwooleResponse * * @return bool */ - public static function hasFilter(): bool + public static function hasFilters(): bool { - return self::$filter != null; + return !empty(self::$filters); } /** diff --git a/src/Appwrite/Utopia/Response/Filter.php b/src/Appwrite/Utopia/Response/Filter.php index 9110abd07..bd82467f8 100644 --- a/src/Appwrite/Utopia/Response/Filter.php +++ b/src/Appwrite/Utopia/Response/Filter.php @@ -13,4 +13,25 @@ abstract class Filter * @return array */ abstract public function parse(array $content, string $model): array; + + + /** + * Handle list + * + * @param array $content + * @param string $key + * @param callable $callback + * + * @return array + */ + protected function handleList(array $content, string $key, callable $callback): array + { + if (array_key_exists($key, $content) && \is_array($content[$key])) { + foreach ($content[$key] as $i => $item) { + $content[$key][$i] = $callback($item); + } + } + + return $content; + } } diff --git a/src/Appwrite/Utopia/Response/Filters/V11.php b/src/Appwrite/Utopia/Response/Filters/V11.php deleted file mode 100644 index 9d6459915..000000000 --- a/src/Appwrite/Utopia/Response/Filters/V11.php +++ /dev/null @@ -1,401 +0,0 @@ -parsePermissions($content); - break; - case Response::MODEL_DOCUMENT_LIST: - $parsedResponse = $this->parseDocumentList($content); - break; - - case Response::MODEL_FILE: - $parsedResponse = $this->parsePermissions($content); - break; - case Response::MODEL_FILE_LIST: - $parsedResponse = $this->parseFileList($content); - break; - - case Response::MODEL_EXECUTION: - $parsedResponse = $this->parseExecutionPermissions($content); - break; - case Response::MODEL_EXECUTION_LIST: - $parsedResponse = $this->parseExecutionsList($content); - break; - - case Response::MODEL_FUNCTION: - $parsedResponse = $this->parseFunctionPermissions($content); - break; - case Response::MODEL_FUNCTION_LIST: - $parsedResponse = $this->parseFunctionsList($content); - break; - - // Convert status from boolean to int - case Response::MODEL_USER: - $parsedResponse = $this->parseStatus($content); - break; - case Response::MODEL_USER_LIST: - $parsedResponse = $this->parseUserList($content); - break; - - // Convert all Health responses back to original - case Response::MODEL_HEALTH_STATUS: - $parsedResponse = $this->parseHealthStatus($content); - break; - case Response::MODEL_HEALTH_VERSION: - $parsedResponse = $this->parseHealthVersion($content); - break; - case Response::MODEL_HEALTH_TIME: - $parsedResponse = $this->parseHealthTime($content); - break; - case Response::MODEL_HEALTH_QUEUE: - $parsedResponse = $this->parseHealthQueue($content); - break; - case Response::MODEL_HEALTH_ANTIVIRUS: - $parsedResponse = $this->parseHealthAntivirus($content); - break; - - // Complex filters - case Response::MODEL_COLLECTION: - $parsedResponse = $this->parseCollection($content); - break; - case Response::MODEL_COLLECTION_LIST: - $parsedResponse = $this->parseCollectionList($content); - break; - - case Response::MODEL_LOG: - $parsedResponse = $this->parseLog($content); - break; - case Response::MODEL_LOG_LIST: - $parsedResponse = $this->parseLogList($content); - break; - - case Response::MODEL_PROJECT: - $parsedResponse = $this->parseProject($content); - break; - case Response::MODEL_PROJECT_LIST: - $parsedResponse = $this->parseProjectList($content); - break; - } - - return $parsedResponse; - } - - protected function parseDocumentList(array $content) - { - $documents = $content['documents']; - $parsedResponse = []; - foreach ($documents as $document) { - $parsedResponse[] = $this->parsePermissions($document); - } - $content['documents'] = $parsedResponse; - return $content; - } - - protected function parseFileList(array $content) - { - $files = $content['files']; - $parsedResponse = []; - foreach ($files as $file) { - $parsedResponse[] = $this->parsePermissions($file); - } - $content['files'] = $parsedResponse; - return $content; - } - - protected function parseExecutionsList(array $content) - { - $executions = $content['executions']; - $parsedResponse = []; - foreach ($executions as $execution) { - $parsedResponse[] = $this->parseExecutionPermissions($execution); - } - $content['executions'] = $parsedResponse; - return $content; - } - - protected function parseFunctionsList(array $content) - { - $functions = $content['functions']; - $parsedResponse = []; - foreach ($functions as $function) { - $parsedResponse[] = $this->parseFunctionPermissions($function); - } - $content['functions'] = $parsedResponse; - return $content; - } - - protected function parseUserList(array $content) - { - $users = $content['users']; - $parsedResponse = []; - foreach ($users as $user) { - $parsedResponse[] = $this->parseStatus($user); - } - $content['users'] = $parsedResponse; - return $content; - } - - protected function parseCollection(array $content) - { - $parsedResponse = []; - $parsedResponse = $this->parsePermissions($content); - $parsedResponse = $this->removeRule($content, 'enabled'); - $parsedResponse = $this->removeRule($content, 'permission'); - $parsedResponse = $this->removeRule($content, 'indexes'); - $parsedResponse = $this->removeRule($content, 'enabled'); - $parsedResponse = $this->addDate($content, 'dateCreated'); - $parsedResponse = $this->addDate($content, 'dateUpdated'); - $parsedResponse = $this->parseAttributes($content); - return $parsedResponse; - } - - protected function parseCollectionList(array $content) - { - $collections = $content['collections']; - $parsedResponse = []; - foreach ($collections as $collection) { - $parsedResponse[] = $this->parseCollection($collection); - } - $content['collections'] = $parsedResponse; - return $content; - } - - protected function parseLog(array $content) - { - $parsedResponse = []; - $parsedResponse = $this->removeRule($content, 'userId'); - $parsedResponse = $this->removeRule($content, 'userEmail'); - $parsedResponse = $this->removeRule($content, 'userName'); - $parsedResponse = $this->removeRule($content, 'mode'); - $parsedResponse = $this->removeRule($content, 'sum'); - return $parsedResponse; - } - - protected function parseLogList(array $content) - { - $logs = $content['logs']; - $parsedResponse = []; - foreach ($logs as $log) { - $parsedResponse[] = $this->parseLog($log); - } - $content['logs'] = $parsedResponse; - return $content; - } - - protected function parseProject(array $content) - { - $parsedResponse = []; - $parsedResponse = $this->addTasks($content); - $parsedResponse = $this->parseAuthLimit($content); - $parsedResponse = $this->parseOAuths($content); - $parsedResponse = $this->parseAuthsStatus($content); - $parsedResponse = $this->removeServicesStatus($content); - return $parsedResponse; - } - - protected function parseProjectList(array $content) - { - $projects = $content['projects']; - $parsedResponse = []; - foreach ($projects as $project) { - $parsedResponse[] = $this->parseProject($project); - } - $content['projects'] = $parsedResponse; - return $content; - } - - protected function parseHealthAntivirus(array $content) - { - if ($content['status'] === 'pass') { - $content['status'] = 'online'; - } - - if ($content['status'] === 'fail') { - $content['status'] = 'offline'; - } - - return $content; - } - - protected function parseHealthTime(array $content) - { - $content['remote'] = $content['remoteTime']; - unset($content['remoteTime']); - - $content['local'] = $content['localTime']; - unset($content['localTime']); - - return $content; - } - - protected function parseHealthVersion(array $content) - { - // Did not change - - return $content; - } - - - protected function parseHealthQueue(array $content) - { - // Did not change - - return $content; - } - - protected function parseHealthStatus(array $content) - { - $content['status'] = 'OK'; // Is always returning pass, was always returning OK - unset($content['ping']); - - return $content; - } - - protected function parseStatus(array $content) - { - $content['status'] = $content['status'] === true ? - $content['emailVerification'] === true ? 1 : 0 - : 2; - - return $content; - } - - protected function parseAttributes(array $content) - { - $content['rules'] = \array_map(function ($attribute) use ($content) { - return [ - '$id' => $attribute['key'], - '$collection' => ID::custom($content['$id']), - 'type' => $attribute['type'], - 'key' => $attribute['key'], - 'label' => $attribute['key'], - 'default' => $attribute['default'], - 'array' => $attribute['array'], - 'required' => $attribute['required'], - 'list' => $attribute['elements'], - ]; - }, $content['attributes']); - unset($content['attributes']); - - return $content; - } - - protected function parseAuthLimit(array $content) - { - $content['usersAuthLimit'] = $content['authLimit']; - unset($content['authLimit']); - - return $content; - } - - protected function parseOAuths(array $content) - { - $regexPattern = "/provider([a-zA-Z0-9]+)(Appid|Secret)/"; - - foreach ($content as $key => $value) { - \preg_match_all($regexPattern, $key, $regexGroups); - if (\count($regexGroups[1]) > 0 && \count($regexGroups[2]) > 0) { - $providerName = $regexGroups[1][0]; - $valueKey = $regexGroups[2][0]; - $content['usersOauth2' . $providerName . $valueKey] = $value; - unset($content['provider' . $providerName . $valueKey]); - } - } - - return $content; - } - - protected function parseAuthsStatus(array $content) - { - $regexPattern = "/auth([a-zA-Z0-9]+)/"; - - foreach ($content as $key => $value) { - \preg_match_all($regexPattern, $key, $regexGroups); - if (\count($regexGroups[1]) > 0) { - $providerName = $regexGroups[1][0]; - - $content[$providerName] = $value; - unset($content['auth' . $providerName]); - } - } - - return $content; - } - - protected function removeServicesStatus(array $content) - { - // Such a key is part of new response, but is not part of old one. We simply remove it, older version never - // expected it anyway. - foreach ($content as $key => $value) { - if (\str_starts_with($key, 'serviceStatusFor')) { - unset($content[$key]); - } - } - - return $content; - } - - protected function removeRule(array $content, $key) - { - // Such a key is part of new response, but is not part of old one. We simply remove it, older version never - // expected it anyway. - unset($content[$key]); - - return $content; - } - - protected function addDate(array $content, $key) - { - // We simply don't have the date available in the content anymore. - // We set it to valid integer that indicates the value is not right - $content[$key] = 0; - - return $content; - } - - protected function addTasks(array $content) - { - // We simply don't have the date available in the content anymore. - // We set it to valid array - $content['tasks'] = []; - - return $content; - } - - protected function parsePermissions(array $content) - { - $content['$permissions'] = [ 'read' => $content['$read'], 'write' => $content['$write'] ]; - unset($content['$read']); - unset($content['$write']); - return $content; - } - - protected function parseFunctionPermissions(array $content) - { - $content['$permissions'] = [ 'execute' => $content['execute'] ]; - unset($content['execute']); - - return $content; - } - - protected function parseExecutionPermissions(array $content) - { - $content['$permissions'] = [ 'read' => $content['$read'] ]; - unset($content['$read']); - - return $content; - } -} diff --git a/src/Appwrite/Utopia/Response/Filters/V12.php b/src/Appwrite/Utopia/Response/Filters/V12.php deleted file mode 100644 index 79d22ad04..000000000 --- a/src/Appwrite/Utopia/Response/Filters/V12.php +++ /dev/null @@ -1,269 +0,0 @@ -parseError($content); - break; - - case Response::MODEL_SESSION: - $parsedResponse = $this->parseSession($content); - break; - case Response::MODEL_SESSION_LIST: - $parsedResponse = $this->parseSessionList($content); - break; - - case Response::MODEL_FILE: - $parsedResponse = $this->parseFile($content); - break; - case Response::MODEL_FILE_LIST: - $parsedResponse = $this->parseFileList($content); - break; - - case Response::MODEL_FUNCTION: - $parsedResponse = $this->parseFunction($content); - break; - case Response::MODEL_FUNCTION_LIST: - $parsedResponse = $this->parseFunctionList($content); - break; - - case Response::MODEL_DEPLOYMENT: - $parsedResponse = $this->parseDeployment($content); - break; - case Response::MODEL_DEPLOYMENT_LIST: - $parsedResponse = $this->parseDeploymentList($content); - break; - - case Response::MODEL_EXECUTION: - $parsedResponse = $this->parseExecution($content); - break; - case Response::MODEL_EXECUTION_LIST: - $parsedResponse = $this->parseExecutionList($content); - break; - - case Response::MODEL_USAGE_BUCKETS: - $parsedResponse = $this->parseUsageBuckets($content); - break; - - case Response::MODEL_USAGE_STORAGE: - $parsedResponse = $this->parseUsageStorage($content); - break; - - case Response::MODEL_TEAM: - $parsedResponse = $this->parseTeam($content); - break; - case Response::MODEL_TEAM_LIST: - $parsedResponse = $this->parseTeamList($content); - break; - - case Response::MODEL_DOCUMENT_LIST: - case Response::MODEL_COLLECTION_LIST: - case Response::MODEL_INDEX_LIST: - case Response::MODEL_USER_LIST: - case Response::MODEL_LOG_LIST: - case Response::MODEL_BUCKET_LIST: - case Response::MODEL_MEMBERSHIP_LIST: - case Response::MODEL_RUNTIME_LIST: - case Response::MODEL_BUILD_LIST: - case Response::MODEL_PROJECT_LIST: - case Response::MODEL_WEBHOOK_LIST: - case Response::MODEL_KEY_LIST: - case Response::MODEL_PLATFORM_LIST: - case Response::MODEL_DOMAIN_LIST: - case Response::MODEL_COUNTRY_LIST: - case Response::MODEL_CONTINENT_LIST: - case Response::MODEL_LANGUAGE_LIST: - case Response::MODEL_CURRENCY_LIST: - case Response::MODEL_PHONE_LIST: - case Response::MODEL_METRIC_LIST: - case Response::MODEL_ATTRIBUTE_LIST: - $parsedResponse = $this->parseList($content); - break; - } - - return $parsedResponse; - } - - protected function parseError(array $content) - { - unset($content['type']); - return $content; - } - - protected function parseSession(array $content) - { - $content['providerToken'] = $content['providerAccessToken']; - unset($content['providerAccessToken']); - - unset($content['providerAccessTokenExpiry']); - - unset($content['providerRefreshToken']); - - return $content; - } - - protected function parseSessionList(array $content) - { - $sessions = $content['sessions']; - $parsedResponse = []; - foreach ($sessions as $document) { - $parsedResponse[] = $this->parseSession($document); - } - $content['sessions'] = $parsedResponse; - $content['sum'] = $content['total']; - unset($content['total']); - return $content; - } - - protected function parseFile(array $content) - { - unset($content['bucketId']); - unset($content['chunksTotal']); - unset($content['chunksUploaded']); - - return $content; - } - - protected function parseFileList(array $content) - { - $files = $content['files']; - $parsedResponse = []; - foreach ($files as $document) { - $parsedResponse[] = $this->parseFile($document); - } - $content['files'] = $parsedResponse; - $content['sum'] = $content['total']; - unset($content['total']); - return $content; - } - - protected function parseFunction(array $content) - { - $content['tag'] = $content['deployment']; - unset($content['deployment']); - return $content; - } - - protected function parseFunctionList(array $content) - { - $functions = $content['functions']; - $parsedResponse = []; - foreach ($functions as $document) { - $parsedResponse[] = $this->parseFunction($document); - } - $content['functions'] = $parsedResponse; - $content['sum'] = $content['total']; - unset($content['total']); - return $content; - } - - protected function parseDeployment(array $content) - { - $content['functionId'] = $content['resourceId']; - $content['command'] = $content['entrypoint']; - return $content; - } - - protected function parseDeploymentList(array $content) - { - $deployments = $content['deployments']; - $parsedResponse = []; - foreach ($deployments as $document) { - $parsedResponse[] = $this->parseDeployment($document); - } - $content['deployments'] = $parsedResponse; - $content['sum'] = $content['total']; - unset($content['total']); - return $content; - } - - protected function parseUsageBuckets(array $content) - { - unset($content['filesStorage']); - return $content; - } - - protected function parseUsageStorage(array $content) - { - $content['storage'] = $content['filesStorage']; - unset($content['filesStorage']); - - $content['files'] = $content['tagsStorage']; - unset($content['tagsStorage']); - - unset($content['filesCount']); - unset($content['bucketsCount']); - unset($content['bucketsCreate']); - unset($content['bucketsRead']); - unset($content['bucketsUpdate']); - unset($content['bucketsDelete']); - unset($content['filesCount']); - unset($content['bucketsDelete']); - unset($content['filesCreate']); - unset($content['filesRead']); - unset($content['filesUpdate']); - unset($content['filesDelete']); - - return $content; - } - - protected function parseExecution($content) - { - $content['exitCode'] = $content['statusCode']; - unset($content['statusCode']); - - return $content; - } - - protected function parseExecutionList($content) - { - $executions = $content['executions']; - $parsedResponse = []; - foreach ($executions as $document) { - $parsedResponse[] = $this->parseExecution($document); - } - $content['executions'] = $parsedResponse; - $content['sum'] = $content['total']; - unset($content['total']); - return $content; - } - - protected function parseTeam($content) - { - $content['sum'] = $content['total']; - unset($content['total']); - return $content; - } - - protected function parseTeamList($content) - { - $teams = $content['teams']; - $parsedResponse = []; - foreach ($teams as $document) { - $parsedResponse[] = $this->parseTeam($document); - } - $content['teams'] = $parsedResponse; - $content['sum'] = $content['total']; - unset($content['total']); - return $content; - } - - protected function parseList($content) - { - $content['sum'] = $content['total']; - unset($content['total']); - return $content; - } -} diff --git a/src/Appwrite/Utopia/Response/Filters/V13.php b/src/Appwrite/Utopia/Response/Filters/V13.php deleted file mode 100644 index 04f978291..000000000 --- a/src/Appwrite/Utopia/Response/Filters/V13.php +++ /dev/null @@ -1,103 +0,0 @@ -parseProject($content); - break; - - case Response::MODEL_PROJECT_LIST: - $parsedResponse = $this->parseProjectList($content); - break; - - case Response::MODEL_MEMBERSHIP: - $parsedResponse = $this->parseMembership($content); - break; - case Response::MODEL_MEMBERSHIP_LIST: - $parsedResponse = $this->parseMembershipList($content); - break; - - case Response::MODEL_EXECUTION: - $parsedResponse = $this->parseExecution($content); - break; - case Response::MODEL_EXECUTION_LIST: - $parsedResponse = $this->parseExecutionList($content); - break; - } - - return $parsedResponse; - } - - protected function parseExecution($content) - { - $content['stdout'] = $content['response']; - unset($content['response']); - - return $content; - } - - protected function parseExecutionList($content) - { - $executions = $content['executions']; - $parsedResponse = []; - foreach ($executions as $document) { - $parsedResponse[] = $this->parseExecution($document); - } - $content['executions'] = $parsedResponse; - return $content; - } - - protected function parseProject($content) - { - $content['providers'] = $content['oAuthProviders']; - unset($content['oAuthProviders']); - - return $content; - } - - protected function parseProjectList($content) - { - $projects = $content['projects']; - $parsedResponse = []; - foreach ($projects as $document) { - $parsedResponse[] = $this->parseProject($document); - } - $content['projects'] = $parsedResponse; - return $content; - } - - protected function parseMembership($content) - { - $content['name'] = $content['userName']; - unset($content['userName']); - - $content['email'] = $content['userEmail']; - unset($content['userEmail']); - - unset($content['teamName']); - - return $content; - } - - protected function parseMembershipList($content) - { - $memberships = $content['memberships']; - $parsedResponse = []; - foreach ($memberships as $document) { - $parsedResponse[] = $this->parseMembership($document); - } - $content['memberships'] = $parsedResponse; - return $content; - } -} diff --git a/src/Appwrite/Utopia/Response/Filters/V14.php b/src/Appwrite/Utopia/Response/Filters/V14.php deleted file mode 100644 index 200823f37..000000000 --- a/src/Appwrite/Utopia/Response/Filters/V14.php +++ /dev/null @@ -1,176 +0,0 @@ -parseRemoveAttributes($content, ['$createdAt']); - - break; - case Response::MODEL_SESSION_LIST: - $parsedResponse = $this->parseRemoveAttributesList($content, 'domains', ['$createdAt']); - - break; - case Response::MODEL_DOCUMENT: - case Response::MODEL_DOMAIN: - case Response::MODEL_FUNCTION: - case Response::MODEL_TEAM: - case Response::MODEL_MEMBERSHIP: - case Response::MODEL_PLATFORM: - case Response::MODEL_PROJECT: - case Response::MODEL_USER: - case Response::MODEL_WEBHOOK: - $parsedResponse = $this->parseRemoveAttributes($content, ['$createdAt', '$updatedAt']); - - break; - case Response::MODEL_DOCUMENT_LIST: - $parsedResponse = $this->parseRemoveAttributesList($content, 'documents', ['$createdAt', '$updatedAt']); - - break; - case Response::MODEL_DOMAIN_LIST: - $parsedResponse = $this->parseRemoveAttributesList($content, 'domains', ['$createdAt', '$updatedAt']); - - break; - case Response::MODEL_FUNCTION_LIST: - $parsedResponse = $this->parseRemoveAttributesList($content, 'functions', ['$createdAt', '$updatedAt']); - - break; - case Response::MODEL_TEAM_LIST: - $parsedResponse = $this->parseRemoveAttributesList($content, 'teams', ['$createdAt', '$updatedAt']); - - break; - case Response::MODEL_MEMBERSHIP_LIST: - $parsedResponse = $this->parseRemoveAttributesList($content, 'memberships', ['$createdAt', '$updatedAt']); - - break; - case Response::MODEL_PLATFORM_LIST: - $parsedResponse = $this->parseRemoveAttributesList($content, 'platforms', ['$createdAt', '$updatedAt']); - - break; - case Response::MODEL_PROJECT_LIST: - $parsedResponse = $this->parseRemoveAttributesList($content, 'projects', ['$createdAt', '$updatedAt']); - - break; - case Response::MODEL_USER_LIST: - $parsedResponse = $this->parseRemoveAttributesList($content, 'users', ['$createdAt', '$updatedAt']); - - break; - case Response::MODEL_WEBHOOK_LIST: - $parsedResponse = $this->parseRemoveAttributesList($content, 'webhooks', ['$createdAt', '$updatedAt']); - - break; - case Response::MODEL_TEAM: - case Response::MODEL_EXECUTION: - case Response::MODEL_FILE: - $parsedResponse = $this->parseCreatedAt($content); - break; - - case Response::MODEL_TEAM_LIST: - $parsedResponse = $this->parseCreatedAtList($content, 'teams'); - break; - - case Response::MODEL_EXECUTION_LIST: - $parsedResponse = $this->parseCreatedAtList($content, 'executions'); - break; - - case Response::MODEL_FILE_LIST: - $parsedResponse = $this->parseCreatedAtList($content, 'files'); - break; - - case Response::MODEL_FUNCTION: - case Response::MODEL_DEPLOYMENT: - case Response::MODEL_BUCKET: - $parsedResponse = $this->parseCreatedAtAndUpdatedAt($content); - break; - - case Response::MODEL_FUNCTION_LIST: - $parsedResponse = $this->parseCreatedAtAndUpdatedAtList($content, 'functions'); - break; - - case Response::MODEL_DEPLOYMENT_LIST: - $parsedResponse = $this->parseCreatedAtAndUpdatedAtList($content, 'deployments'); - break; - - case Response::MODEL_BUCKET_LIST: - $parsedResponse = $this->parseCreatedAtAndUpdatedAtList($content, 'buckets'); - break; - } - - return $parsedResponse; - } - - protected function parseRemoveAttributes(array $content, array $attributes) - { - foreach ($attributes as $attribute) { - unset($content[$attribute]); - } - - return $content; - } - - protected function parseRemoveAttributesList(array $content, string $property, array $attributes) - { - $documents = $content[$property]; - $parsedResponse = []; - foreach ($documents as $document) { - $parsedResponse[] = $this->parseRemoveAttributes($document, $attributes); - } - $content[$property] = $parsedResponse; - - return $content; - } - - protected function parseCreatedAt(array $content) - { - $content['dateCreated'] = $content['$createdAt']; - unset($content['$createdAt']); - unset($content['$updatedAt']); - - return $content; - } - - protected function parseCreatedAtList(array $content, string $property) - { - $documents = $content[$property]; - $parsedResponse = []; - foreach ($documents as $document) { - $parsedResponse[] = $this->parseCreatedAt($document); - } - $content[$property] = $parsedResponse; - - return $content; - } - - protected function parseCreatedAtAndUpdatedAt(array $content) - { - $content['dateCreated'] = $content['$createdAt']; - $content['dateUpdated'] = $content['$updatedAt']; - unset($content['$createdAt']); - unset($content['$updatedAt']); - - return $content; - } - - protected function parseCreatedAtAndUpdatedAtList(array $content, string $property) - { - $documents = $content[$property]; - $parsedResponse = []; - foreach ($documents as $document) { - $parsedResponse[] = $this->parseCreatedAtAndUpdatedAt($document); - } - $content[$property] = $parsedResponse; - - return $content; - } -} diff --git a/src/Appwrite/Utopia/Response/Filters/V15.php b/src/Appwrite/Utopia/Response/Filters/V15.php deleted file mode 100644 index 232feec20..000000000 --- a/src/Appwrite/Utopia/Response/Filters/V15.php +++ /dev/null @@ -1,591 +0,0 @@ -parseUser($parsedResponse); - break; - case Response::MODEL_USER_LIST: - $listKey = 'users'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseUser($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_METRIC: - $parsedResponse = $this->parseMetric($parsedResponse); - break; - case Response::MODEL_BUILD: - $parsedResponse = $this->parseBuild($parsedResponse); - break; - case Response::MODEL_BUILD_LIST: - $listKey = 'builds'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseBuild($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_BUCKET: - $parsedResponse = $this->parseBucket($parsedResponse); - break; - case Response::MODEL_BUCKET_LIST: - $listKey = 'buckets'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseBucket($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_COLLECTION: - $parsedResponse = $this->parseCollection($parsedResponse); - break; - case Response::MODEL_COLLECTION_LIST: - $listKey = 'collections'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseCollection($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_DATABASE: - case Response::MODEL_DEPLOYMENT: - case Response::MODEL_DOMAIN: - case Response::MODEL_PLATFORM: - case Response::MODEL_PROJECT: - case Response::MODEL_TEAM: - case Response::MODEL_WEBHOOK: - $parsedResponse = $this->parseCreatedAtUpdatedAt($parsedResponse); - break; - case Response::MODEL_DATABASE_LIST: - case Response::MODEL_DEPLOYMENT_LIST: - case Response::MODEL_DOMAIN_LIST: - case Response::MODEL_PLATFORM_LIST: - case Response::MODEL_PROJECT_LIST: - case Response::MODEL_TEAM_LIST: - case Response::MODEL_WEBHOOK_LIST: - $listKey = ''; - switch ($model) { - case Response::MODEL_DATABASE_LIST: - $listKey = 'databases'; - break; - case Response::MODEL_DEPLOYMENT_LIST: - $listKey = 'deployments'; - break; - case Response::MODEL_DOMAIN_LIST: - $listKey = 'domains'; - break; - case Response::MODEL_PLATFORM_LIST: - $listKey = 'platforms'; - break; - case Response::MODEL_PROJECT_LIST: - $listKey = 'projects'; - break; - case Response::MODEL_TEAM_LIST: - $listKey = 'teams'; - break; - case Response::MODEL_WEBHOOK_LIST: - $listKey = 'webhooks'; - break; - } - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseCreatedAtUpdatedAt($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_DOCUMENT: - $parsedResponse = $this->parseDocument($parsedResponse); - break; - case Response::MODEL_FILE: - $parsedResponse = $this->parsePermissionsCreatedAtUpdatedAt($parsedResponse); - break; - case Response::MODEL_DOCUMENT_LIST: - $listKey = 'documents'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseDocument($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_FILE_LIST: - $listKey = 'files'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parsePermissionsCreatedAtUpdatedAt($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_EXECUTION: - $parsedResponse = $this->parseExecution($parsedResponse); - break; - case Response::MODEL_EXECUTION_LIST: - $listKey = 'executions'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseExecution($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_FUNCTION: - $parsedResponse = $this->parseFunction($parsedResponse); - break; - case Response::MODEL_FUNCTION_LIST: - $listKey = 'functions'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseFunction($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_KEY: - $parsedResponse = $this->parseKey($parsedResponse); - break; - case Response::MODEL_KEY_LIST: - $listKey = 'keys'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseKey($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_LOG: - $parsedResponse = $this->parseLog($parsedResponse); - break; - case Response::MODEL_LOG_LIST: - $listKey = 'logs'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseLog($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_MEMBERSHIP: - $parsedResponse = $this->parseMembership($parsedResponse); - break; - case Response::MODEL_MEMBERSHIP_LIST: - $listKey = 'memberships'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseMembership($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_SESSION: - $parsedResponse = $this->parseSession($parsedResponse); - break; - case Response::MODEL_SESSION_LIST: - $listKey = 'sessions'; - $parsedResponse[$listKey] = array_map(fn ($content) => $this->parseSession($content), $parsedResponse[$listKey]); - break; - case Response::MODEL_TOKEN: - $parsedResponse = $this->parseDatetimeAttributes($parsedResponse, ['$createdAt', 'expire']); - break; - case Response::MODEL_USAGE_DATABASES: - $parsedResponse = $this->parseUsageDatabases($parsedResponse); - break; - case Response::MODEL_USAGE_DATABASE: - $parsedResponse = $this->parseUsageDatabase($parsedResponse); - break; - case Response::MODEL_USAGE_COLLECTION: - $parsedResponse = $this->parseUsageCollection($parsedResponse); - break; - case Response::MODEL_USAGE_USERS: - $parsedResponse = $this->parseUsageUsers($parsedResponse); - break; - case Response::MODEL_USAGE_BUCKETS: - $parsedResponse = $this->parseUsageBuckets($parsedResponse); - break; - case Response::MODEL_USAGE_FUNCTIONS: - $parsedResponse = $this->parseUsageFuncs($parsedResponse); - break; - case Response::MODEL_USAGE_PROJECT: - $parsedResponse = $this->parseUsageProject($parsedResponse); - break; - case Response::MODEL_USAGE_STORAGE: - $parsedResponse = $this->parseUsageStorage($parsedResponse); - break; - } - - return $parsedResponse; - } - - protected function parseBuild(array $content) - { - $content = $this->parseDatetimeAttributes($content, ['startTime', 'endTime']); - - return $content; - } - - protected function parseBucket(array $content) - { - if (isset($content['fileSecurity'])) { - if ($content['fileSecurity']) { - $content['permission'] = 'file'; - } else { - $content['permission'] = 'bucket'; - } - } - - unset($content['fileSecurity']); - unset($content['compression']); - - $content = $this->parsePermissions($content); - $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt']); - - return $content; - } - - protected function parseDatetimeAttributes(array $content, array $attributes): array - { - foreach ($attributes as $attribute) { - if (array_key_exists($attribute, $content)) { - if (empty($content[$attribute])) { - $content[$attribute] = 0; - continue; - } - $content[$attribute] = strtotime($content[$attribute]); - } - } - return $content; - } - - protected function parseUser(array $content): array - { - unset($content['password']); - unset($content['hash']); - unset($content['hashOptions']); - - $content = $this->parseDatetimeAttributes($content, ['registration', 'passwordUpdate', '$createdAt', '$updatedAt']); - return $content; - } - - protected function parseMetric(array $content) - { - $content = $this->parseDatetimeAttributes($content, ['date']); - return $content; - } - - protected function parsePermissions(array $content) - { - if (!isset($content['$permissions'])) { - return $content; - } - - $read = []; - $write = []; - - // downgrade the permissions - foreach ($content['$permissions'] as $permission) { - $permission = Permission::parse($permission); - $permission_value = $permission->getRole(); - if ($permission->getIdentifier()) { - $permission_value .= ':' . $permission->getIdentifier(); - } - if ($permission->getDimension()) { - $permission_value .= '/' . $permission->getDimension(); - } - - // Old type permissions meant that 'write' is equivalent to 'create', 'update' and 'delete' - switch ($permission->getPermission()) { - case Database::PERMISSION_UPDATE: - case Database::PERMISSION_DELETE: - case Database::PERMISSION_WRITE: - case Database::PERMISSION_CREATE: - $write[$this->parseRole($permission_value)] = true; - break; - case Database::PERMISSION_READ: - $read[$this->parseRole($permission_value)] = true; - break; - } - } - - $content['$read'] = array_keys($read); - $content['$write'] = array_keys($write); - - unset($content['$permissions']); - - return $content; - } - - protected function parseRole(string $role) - { - switch ($role) { - case Role::any()->toString(): - return 'role:all'; - case Role::users()->toString(): - return 'role:member'; - case Role::guests()->toString(): - return 'role:guest'; - default: - return $role; - } - - return $role; - } - - protected function parseCollection(array $content) - { - if (isset($content['documentSecurity'])) { - if ($content['documentSecurity']) { - $content['permission'] = 'document'; - } else { - $content['permission'] = 'collection'; - } - } - - unset($content['documentSecurity']); - $content = $this->parsePermissions($content); - $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt']); - return $content; - } - - protected function parsePermissionsCreatedAtUpdatedAt(array $content) - { - $content = $this->parsePermissions($content); - $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt']); - return $content; - } - - protected function parseDocument(array $content) - { - if (isset($content['$collectionId'])) { - $content['$collection'] = $content['$collectionId']; - unset($content['$collectionId']); - } - - unset($content['$databaseId']); - - $content = $this->parsePermissionsCreatedAtUpdatedAt($content); - return $content; - } - - private function parseExecution($content) - { - unset($content['stdout']); - - if (isset($content['$permissions'])) { - $read = []; - foreach ($content['$permissions'] as $role) { - $read[] = $this->parseRole($role); - } - $content['$read'] = $read; - unset($content['$permissions']); - } - - if (isset($content['duration'])) { - $content['time'] = $content['duration']; - unset($content['duration']); - } - - $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt']); - - return $content; - } - - private function parseCreatedAtUpdatedAt($content) - { - $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt']); - return $content; - } - - private function parseFunction($content) - { - if (isset($content['execute'])) { - foreach ($content['execute'] as $i => $role) { - $content['execute'][$i] = $this->parseRole($role); - } - } - - if (isset($content['vars'])) { - $vars = []; - foreach ($content['vars'] as $i => $var) { - $vars[$var['key']] = $var['value']; - } - $content['vars'] = $vars; - } - - if (isset($content['enabled'])) { - $content['status'] = $content['enabled'] ? 'enabled' : 'disabled'; - unset($content['enabled']); - } - - $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt', 'scheduleNext', 'schedulePrevious']); - - return $content; - } - - private function parseKey($content) - { - $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt', 'expire']); - return $content; - } - - private function parseLog($content) - { - $content = $this->parseDatetimeAttributes($content, ['time']); - return $content; - } - - private function parseMembership($content) - { - $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt', 'invited', 'joined']); - return $content; - } - - private function parseSession($content) - { - $content = $this->parseDatetimeAttributes($content, ['$createdAt', 'expire', 'providerAccessTokenExpiry']); - return $content; - } - - private function parseUsage($content, $keys) - { - foreach ($keys as $key) { - $data = []; - foreach ($content[$key] as $metric) { - $data[] = $this->parseMetric($metric); - } - $content[$key] = $data; - } - - return $content; - } - - private function parseUsageDatabases($content) - { - $keys = [ - 'databasesCount', - 'documentsCount', - 'collectionsCount', - 'databasesCreate', - 'databasesRead', - 'databasesUpdate', - 'databasesDelete', - 'documentsCreate', - 'documentsRead', - 'documentsUpdate', - 'documentsDelete', - 'collectionsCreate', - 'collectionsRead', - 'collectionsUpdate', - 'collectionsDelete', - ]; - - $content = $this->parseUsage($content, $keys); - - return $content; - } - - private function parseUsageDatabase($content) - { - $keys = [ - 'documentsCount', - 'collectionsCount', - 'documentsCreate', - 'documentsRead', - 'documentsUpdate', - 'documentsDelete', - 'collectionsCreate', - 'collectionsRead', - 'collectionsUpdate', - 'collectionsDelete', - ]; - - $content = $this->parseUsage($content, $keys); - - return $content; - } - - private function parseUsageCollection($content) - { - $keys = [ - 'documentsCount', - 'documentsCreate', - 'documentsRead', - 'documentsUpdate', - 'documentsDelete', - ]; - - $content = $this->parseUsage($content, $keys); - - return $content; - } - - private function parseUsageUsers($content) - { - $keys = [ - 'usersCount', - 'usersCreate', - 'usersRead', - 'usersUpdate', - 'usersDelete', - 'sessionsCreate', - 'sessionsProviderCreate', - 'sessionsDelete', - ]; - - $content = $this->parseUsage($content, $keys); - - return $content; - } - - private function parseUsageBuckets($content) - { - $keys = [ - 'filesCount', - 'filesStorage', - 'filesCreate', - 'filesRead', - 'filesUpdate', - 'filesDelete', - ]; - - $content = $this->parseUsage($content, $keys); - - return $content; - } - - private function parseUsageFuncs($content) - { - $mapping = [ - 'executionsTotal' => 'functionsExecutions', - 'executionsFailure' => 'functionsFailures', - 'executionsTime' => 'functionsCompute', - ]; - - foreach ($mapping as $new => $old) { - if (isset($content[$new])) { - $data = []; - foreach ($content[$new] as $metric) { - $data[] = $this->parseMetric($metric); - } - $content[$old] = $data; - unset($content[$new]); - } - } - - unset($content['functionExecutions']); - unset($content['functionFailure']); - unset($content['executionsTime']); - unset($content['buildsTotal']); - unset($content['executionsSuccess']); - unset($content['buildsFailure']); - unset($content['buildsSuccess']); - unset($content['buildsTime']); - - return $content; - } - - private function parseUsageProject($content) - { - $content['functions'] = $content['executions']; - unset($content['executions']); - - $keys = [ - 'collections', - 'documents', - 'functions', - 'network', - 'requests', - 'storage', - 'users', - ]; - - $content = $this->parseUsage($content, $keys); - - return $content; - } - - private function parseUsageStorage($content) - { - $content['filesStorage'] = $content['storage']; - unset($content['storage']); - - $keys = [ - 'bucketsCount', - 'bucketsCreate', - 'bucketsDelete', - 'bucketsRead', - 'bucketsUpdate', - 'filesCount', - 'filesCreate', - 'filesDelete', - 'filesRead', - 'filesStorage', - 'filesUpdate', - ]; - - $content = $this->parseUsage($content, $keys); - - return $content; - } -} diff --git a/src/Appwrite/Utopia/Response/Filters/V16.php b/src/Appwrite/Utopia/Response/Filters/V16.php index 609f118f6..0d04ac8b9 100644 --- a/src/Appwrite/Utopia/Response/Filters/V16.php +++ b/src/Appwrite/Utopia/Response/Filters/V16.php @@ -14,27 +14,19 @@ class V16 extends Filter { $parsedResponse = $content; - switch ($model) { - case Response::MODEL_DEPLOYMENT: - $parsedResponse = $this->parseDeployment($parsedResponse); - break; - case Response::MODEL_PROXY_RULE: - // We won't be supporting the domain endpoints for older SDKs - // since these APIs are internal. As such, no filtering required - break; - case Response::MODEL_EXECUTION: - $parsedResponse = $this->parseExecution($parsedResponse); - break; - case Response::MODEL_FUNCTION: - $parsedResponse = $this->parseFunction($parsedResponse); - break; - case Response::MODEL_PROJECT: - $parsedResponse = $this->parseProject($parsedResponse); - break; - case Response::MODEL_VARIABLE: - $parsedResponse = $this->parseVariable($parsedResponse); - break; - } + $parsedResponse = match($model) { + Response::MODEL_DEPLOYMENT => $this->parseDeployment($parsedResponse), + Response::MODEL_DEPLOYMENT_LIST => $this->handleList($content, 'deployments', fn ($item) => $this->parseDeployment($item)), + Response::MODEL_EXECUTION => $this->parseExecution($parsedResponse), + Response::MODEL_EXECUTION_LIST => $this->handleList($content, 'executions', fn ($item) => $this->parseExecution($item)), + Response::MODEL_FUNCTION => $this->parseFunction($parsedResponse), + Response::MODEL_FUNCTION_LIST => $this->handleList($content, 'functions', fn ($item) => $this->parseFunction($item)), + Response::MODEL_PROJECT => $this->parseProject($parsedResponse), + Response::MODEL_PROJECT_LIST => $this->handleList($content, 'projects', fn ($item) => $this->parseProject($item)), + Response::MODEL_VARIABLE => $this->parseVariable($parsedResponse), + Response::MODEL_VARIABLE_LIST => $this->handleList($content, 'variables', fn ($item) => $this->parseVariable($item)), + default => $parsedResponse, + }; return $parsedResponse; } diff --git a/src/Appwrite/Utopia/Response/Filters/V17.php b/src/Appwrite/Utopia/Response/Filters/V17.php index 75fff719c..75821de16 100644 --- a/src/Appwrite/Utopia/Response/Filters/V17.php +++ b/src/Appwrite/Utopia/Response/Filters/V17.php @@ -12,26 +12,20 @@ class V17 extends Filter { $parsedResponse = $content; - switch ($model) { - case Response::MODEL_PROJECT: - $parsedResponse = $this->parseProject($parsedResponse); - break; - case Response::MODEL_USER: - $parsedResponse = $this->parseUser($parsedResponse); - break; - case Response::MODEL_TOKEN: - $parsedResponse = $this->parseToken($parsedResponse); - break; - case Response::MODEL_MEMBERSHIP: - $parsedResponse = $this->parseMembership($parsedResponse); - break; - case Response::MODEL_SESSION: - $parsedResponse = $this->parseSession($parsedResponse); - break; - case Response::MODEL_WEBHOOK: - $parsedResponse = $this->parseWebhook($parsedResponse); - break; - } + $parsedResponse = match($model) { + Response::MODEL_PROJECT => $this->parseProject($parsedResponse), + Response::MODEL_PROJECT_LIST => $this->handleList($content, 'projects', fn ($item) => $this->parseProject($item)), + Response::MODEL_USER => $this->parseUser($parsedResponse), + Response::MODEL_USER_LIST => $this->handleList($content, 'users', fn ($item) => $this->parseUser($item)), + Response::MODEL_MEMBERSHIP => $this->parseMembership($parsedResponse), + Response::MODEL_MEMBERSHIP_LIST => $this->handleList($content, 'memberships', fn ($item) => $this->parseMembership($item)), + Response::MODEL_SESSION => $this->parseSession($parsedResponse), + Response::MODEL_SESSION_LIST => $this->handleList($content, 'sessions', fn ($item) => $this->parseSession($item)), + Response::MODEL_WEBHOOK => $this->parseWebhook($parsedResponse), + Response::MODEL_WEBHOOK_LIST => $this->handleList($content, 'webhooks', fn ($item) => $this->parseWebhook($item)), + Response::MODEL_TOKEN => $this->parseToken($parsedResponse), + default => $parsedResponse, + }; return $parsedResponse; } From d721843ea8b744f4fc7e26539987bebd3dc96e5a Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Thu, 7 Mar 2024 15:03:43 +0100 Subject: [PATCH 2/6] test: response filters --- tests/unit/Utopia/Request/Filters/V15Test.php | 742 ------- .../unit/Utopia/Response/Filters/V15Test.php | 1920 ----------------- tests/unit/Utopia/ResponseTest.php | 15 +- 3 files changed, 8 insertions(+), 2669 deletions(-) delete mode 100644 tests/unit/Utopia/Request/Filters/V15Test.php delete mode 100644 tests/unit/Utopia/Response/Filters/V15Test.php diff --git a/tests/unit/Utopia/Request/Filters/V15Test.php b/tests/unit/Utopia/Request/Filters/V15Test.php deleted file mode 100644 index 70bf71d4c..000000000 --- a/tests/unit/Utopia/Request/Filters/V15Test.php +++ /dev/null @@ -1,742 +0,0 @@ -filter = new V15(); - } - - public function tearDown(): void - { - } - - public function limitOffsetProvider(): array - { - return [ - 'basic test' => [ - ['limit' => '12', 'offset' => '0'], - ['queries' => ['limit(12)', 'offset(0)']] - ], - ]; - } - - /** - * @dataProvider limitOffsetProvider - */ - public function testListAccountLogs(array $content, array $expected): void - { - $model = 'account.listLogs'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function testGetAccountInitials(): void - { - $model = 'account.initials'; - - $content = ['color' => 'deadbeef']; - $expected = []; - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function limitOffsetCursorOrderTypeProvider(): array - { - return [ - 'basic test' => [ - [ - 'limit' => '12', - 'offset' => '0', - 'cursor' => 'abcd', - 'cursorDirection' => 'before', - 'orderType' => 'asc', - ], - [ - 'queries' => [ - 'limit(12)', - 'offset(0)', - 'cursorBefore("abcd")', - 'orderAsc("")' - ] - ], - ], - ]; - } - - public function cursorProvider(): array - { - return [ - 'cursorDirection after' => [ - [ - 'cursor' => 'abcd', - 'cursorDirection' => 'after', - ], - [ - 'queries' => [ - 'cursorAfter("abcd")', - ] - ], - ], - 'cursorDirection invalid' => [ - [ - 'cursor' => 'abcd', - 'cursorDirection' => 'invalid', - ], - [ - 'queries' => [ - 'cursorAfter("abcd")', - ] - ], - ], - ]; - } - - public function orderTypeProvider(): array - { - return [ - 'orderType desc' => [ - [ - 'orderType' => 'DESC', - ], - [ - 'queries' => [ - 'orderDesc("")', - ] - ], - ], - 'orderType invalid' => [ - [ - 'orderType' => 'invalid', - ], - [ - 'queries' => [ - 'orderAsc("")', - ] - ], - ], - ]; - } - - /** - * @dataProvider limitOffsetCursorOrderTypeProvider - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - * @dataProvider orderTypeProvider - */ - public function testListDatabases(array $content, array $expected): void - { - $model = 'databases.list'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetProvider - */ - public function testListDatabaseLogs(array $content, array $expected): void - { - $model = 'databases.listLogs'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function collectionPermissionProvider(): array - { - return [ - 'permission collection' => [ - ['permission' => 'collection'], - ['documentSecurity' => false], - ], - 'permission document' => [ - ['permission' => 'document'], - ['documentSecurity' => true], - ], - 'permission empty' => [ - [], - [], - ], - 'permission invalid' => [ - ['permission' => 'invalid'], - ['documentSecurity' => false], - ], - ]; - } - - public function readWriteProvider(): array - { - return [ - 'read all types' => [ - [ - 'read' => [ - 'role:all', - 'role:guest', - 'role:member', - 'user:a', - 'team:b', - 'team:c/member', - 'member:z', - ], - ], - [ - 'permissions' => [ - 'read("any")', - 'read("guests")', - 'read("users")', - 'read("user:a")', - 'read("team:b")', - 'read("team:c/member")', - 'read("member:z")', - ], - ], - ], - 'read invalid' => [ - ['read' => ['invalid', 'invalid:a']], - ['permissions' => ['read("invalid:a")']], - ], - 'write all types' => [ - [ - 'write' => [ - 'role:all', - 'role:guest', - 'role:member', - 'user:a', - 'team:b', - 'team:c/member', - 'member:z', - ], - ], - [ - 'permissions' => [ - 'write("users")', - 'write("users")', - 'write("user:a")', - 'write("team:b")', - 'write("team:c/member")', - 'write("member:z")', - ], - ], - ], - 'write invalid' => [ - ['write' => ['invalid', 'invalid:a']], - ['permissions' => ['write("invalid:a")']], - ] - ]; - } - - /** - * @dataProvider collectionPermissionProvider - * @dataProvider readWriteProvider - */ - public function testCreateCollection(array $content, array $expected): void - { - $model = 'databases.createCollection'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetCursorOrderTypeProvider - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - * @dataProvider orderTypeProvider - */ - public function testListCollections(array $content, array $expected): void - { - $model = 'databases.listCollections'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetProvider - */ - public function testListCollectionLogs(array $content, array $expected): void - { - $model = 'databases.listCollectionLogs'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider collectionPermissionProvider - * @dataProvider readWriteProvider - */ - public function testUpdateCollection(array $content, array $expected): void - { - $model = 'databases.updateCollection'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider readWriteProvider - */ - public function testCreateDocument(array $content, array $expected): void - { - $model = 'databases.createDocument'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function ordersProvider(): array - { - return [ - 'basic test' => [ - [ - 'orderAttributes' => ['lastName', 'firstName'], - 'orderTypes' => ['DESC', 'ASC'], - ], - [ - 'queries' => [ - 'orderDesc("lastName")', - 'orderAsc("firstName")', - ] - ], - ], - 'orderType only' => [ - [ - 'orderTypes' => ['DESC'], - ], - [ - 'queries' => [ - 'orderDesc("")', - ] - ], - ], - 'orderType invalid' => [ - [ - 'orderAttributes' => ['lastName'], - 'orderTypes' => ['invalid'], - ], - [ - 'queries' => [ - 'orderAsc("lastName")', - ] - ], - ], - ]; - } - - public function filtersProvider(): array - { - return [ - 'all filters' => [ - [ - 'queries' => [ - 'lastName.equal("Smith", "Jackson")', - 'firstName.notEqual("John")', - 'age.lesser(50)', - 'age.lesserEqual(51)', - 'age.greater(20)', - 'age.greaterEqual(21)', - 'address.search("pla")', - ], - ], - [ - 'queries' => [ - 'equal("lastName", ["Smith", "Jackson"])', - 'notEqual("firstName", ["John"])', - 'lessThan("age", [50])', - 'lessThanEqual("age", [51])', - 'greaterThan("age", [20])', - 'greaterThanEqual("age", [21])', - 'search("address", ["pla"])', - ] - ], - ], - ]; - } - - /** - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - * @dataProvider ordersProvider - * @dataProvider filtersProvider - */ - public function testListDocuments(array $content, array $expected): void - { - $model = 'databases.listDocuments'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetProvider - */ - public function testListDocumentLogs(array $content, array $expected): void - { - $model = 'databases.listDocumentLogs'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider readWriteProvider - */ - public function testUpdateDocument(array $content, array $expected): void - { - $model = 'databases.updateDocument'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function executeProvider(): array - { - return [ - 'all roles' => [ - [ - 'execute' => [ - 'role:all', - 'role:guest', - 'role:member', - 'user:a', - 'team:b', - 'team:c/member', - 'member:z', - ], - ], - [ - 'execute' => [ - 'users', - 'users', - 'user:a', - 'team:b', - 'team:c/member', - 'member:z', - ] - ], - ], - ]; - } - - /** - * @dataProvider executeProvider - */ - public function testCreateFunction(array $content, array $expected): void - { - $model = 'functions.create'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetCursorOrderTypeProvider - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - * @dataProvider orderTypeProvider - */ - public function testListFunctions(array $content, array $expected): void - { - $model = 'functions.list'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider executeProvider - */ - public function testUpdateFunction(array $content, array $expected): void - { - $model = 'functions.update'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetCursorOrderTypeProvider - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - * @dataProvider orderTypeProvider - */ - public function testListDeployments(array $content, array $expected): void - { - $model = 'functions.listDeployments'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - */ - public function testListExecutions(array $content, array $expected): void - { - $model = 'functions.listExecutions'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetCursorOrderTypeProvider - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - * @dataProvider orderTypeProvider - */ - public function testListProjects(array $content, array $expected): void - { - $model = 'projects.list'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function expireProvider(): array - { - return [ - 'empty' => [ - [], - [], - ], - 'zero' => [ - ['expire' => '0'], - ['expire' => null], - ], - 'value' => [ - ['expire' => '1602743880'], - ['expire' => Model::TYPE_DATETIME_EXAMPLE], - ], - ]; - } - - /** - * @dataProvider expireProvider - */ - public function testCreateKey(array $content, array $expected) - { - $model = 'projects.createKey'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider expireProvider - */ - public function testUpdateKey(array $content, array $expected) - { - $model = 'projects.updateKey'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function bucketPermissionProvider(): array - { - return [ - 'permission bucket' => [ - ['permission' => 'bucket'], - ['fileSecurity' => false], - ], - 'permission document' => [ - ['permission' => 'file'], - ['fileSecurity' => true], - ], - 'permission empty' => [ - [], - [], - ], - 'permission invalid' => [ - ['permission' => 'invalid'], - ['fileSecurity' => false], - ], - ]; - } - - /** - * @dataProvider bucketPermissionProvider - * @dataProvider readWriteProvider - */ - public function testCreateBucket(array $content, array $expected) - { - $model = 'storage.createBucket'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetCursorOrderTypeProvider - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - * @dataProvider orderTypeProvider - */ - public function testListBuckets(array $content, array $expected): void - { - $model = 'storage.listBuckets'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider bucketPermissionProvider - * @dataProvider readWriteProvider - */ - public function testUpdateBucket(array $content, array $expected) - { - $model = 'storage.updateBucket'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider readWriteProvider - */ - public function testCreateFile(array $content, array $expected) - { - $model = 'storage.createFile'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetCursorOrderTypeProvider - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - * @dataProvider orderTypeProvider - */ - public function testListFiles(array $content, array $expected): void - { - $model = 'storage.listFiles'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider readWriteProvider - */ - public function testUpdateFile(array $content, array $expected) - { - $model = 'storage.updateFile'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetCursorOrderTypeProvider - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - * @dataProvider orderTypeProvider - */ - public function testListTeams(array $content, array $expected): void - { - $model = 'teams.list'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetCursorOrderTypeProvider - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - * @dataProvider orderTypeProvider - */ - public function testListTeamMemberships(array $content, array $expected): void - { - $model = 'teams.listMemberships'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetProvider - */ - public function testListTeamLogs(array $content, array $expected): void - { - $model = 'teams.listLogs'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetCursorOrderTypeProvider - * @dataProvider limitOffsetProvider - * @dataProvider cursorProvider - * @dataProvider orderTypeProvider - */ - public function testListUsers(array $content, array $expected): void - { - $model = 'users.list'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider limitOffsetProvider - */ - public function testListUserLogs(array $content, array $expected): void - { - $model = 'users.listLogs'; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } -} diff --git a/tests/unit/Utopia/Response/Filters/V15Test.php b/tests/unit/Utopia/Response/Filters/V15Test.php deleted file mode 100644 index d65ffebc6..000000000 --- a/tests/unit/Utopia/Response/Filters/V15Test.php +++ /dev/null @@ -1,1920 +0,0 @@ -filter = new V15(); - } - - public function tearDown(): void - { - } - - public function createdAtUpdatedAtProvider(): array - { - return [ - 'basic datetimes' => [ - [ - '$createdAt' => '2020-06-24T06:47:30.000Z', - '$updatedAt' => '2020-06-24T06:47:30.000Z', - ], - [ - '$createdAt' => 1592981250, - '$updatedAt' => 1592981250, - ], - ], - 'null datetime' => [ - [ - '$createdAt' => null, - '$updatedAt' => null, - ], - [ - '$createdAt' => 0, - '$updatedAt' => 0, - ], - ], - 'empty datetime' => [ - [ - '$createdAt' => '', - '$updatedAt' => '', - ], - [ - '$createdAt' => 0, - '$updatedAt' => 0, - ], - ], - ]; - } - - public function permissionsProvider(): array - { - return [ - 'basic permissions' => [ - [ - '$permissions' => [ - Permission::read(Role::any()), - Permission::write(Role::user('608f9da25e7e1')), - ], - ], - [ - '$read' => ['role:all'], - '$write' => ['user:608f9da25e7e1'], - ], - ], - 'all roles' => [ - [ - '$permissions' => [ - Permission::read(Role::any()), - Permission::read(Role::guests()), - Permission::read(Role::users()), - Permission::read(Role::user('asdf')), - Permission::read(Role::team('qwer')), - Permission::read(Role::team('qwer', 'uiop')), - Permission::read(Role::member('zxcv')), - ], - ], - [ - '$read' => [ - 'role:all', - 'role:guest', - 'role:member', - 'user:asdf', - 'team:qwer', - 'team:qwer/uiop', - 'member:zxcv', - ], - '$write' => [], - ], - ], - 'create conversion' => [ - [ - '$permissions' => [Permission::create(Role::user('a'))], - ], - [ - '$read' => [], - '$write' => ['user:a'], - ], - ], - 'update conversion' => [ - [ - '$permissions' => [Permission::update(Role::user('a'))], - ], - [ - '$read' => [], - '$write' => ['user:a'], - ], - ], - 'delete conversion' => [ - [ - '$permissions' => [Permission::delete(Role::user('a'))], - ], - [ - '$read' => [], - '$write' => ['user:a'], - ], - ], - 'write conversion' => [ - [ - '$permissions' => [Permission::write(Role::user('a'))], - ], - [ - '$read' => [], - '$write' => ['user:a'], - ], - ], - ]; - } - - public function testAccount(): void - { - $model = Response::MODEL_ACCOUNT; - - $content = [ - '$id' => '6264711f995c5b012b48', - '$createdAt' => '2020-06-24T06:47:30.000Z', - '$updatedAt' => '2020-06-24T06:47:30.000Z', - 'name' => 'John Doe', - 'registration' => '2020-06-24T06:47:30.000Z', - 'status' => true, - 'passwordUpdate' => '2020-06-24T06:47:30.000Z', - 'email' => 'john@appwrite.io', - 'phone' => '+4930901820', - 'emailVerification' => true, - 'phoneVerification' => true, - 'prefs' => new \stdClass(), - ]; - - $expected = [ - '$id' => '6264711f995c5b012b48', - '$createdAt' => 1592981250, - '$updatedAt' => 1592981250, - 'name' => 'John Doe', - 'registration' => 1592981250, - 'status' => true, - 'passwordUpdate' => 1592981250, - 'email' => 'john@appwrite.io', - 'phone' => '+4930901820', - 'emailVerification' => true, - 'phoneVerification' => true, - 'prefs' => new \stdClass(), - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function bucketProvider(): array - { - return [ - 'basic bucket' => [ - [ - '$id' => '5e5ea5c16897e', - '$createdAt' => '2020-06-24T06:47:30.000Z', - '$updatedAt' => '2020-06-24T06:47:30.000Z', - 'fileSecurity' => true, - '$permissions' => [ - Permission::read(Role::any()), - Permission::write(Role::user('608f9da25e7e1')), - ], - 'name' => 'Documents', - 'enabled' => false, - 'maximumFileSize' => 100, - 'allowedFileExtensions' => [ - 'jpg', - 'png' - ], - 'encryption' => false, - 'antivirus' => false, - ], - [ - '$id' => '5e5ea5c16897e', - '$createdAt' => 1592981250, - '$updatedAt' => 1592981250, - '$read' => ['role:all'], - '$write' => ['user:608f9da25e7e1'], - 'permission' => 'file', - 'name' => 'Documents', - 'enabled' => false, - 'maximumFileSize' => 100, - 'allowedFileExtensions' => [ - 'jpg', - 'png' - ], - 'encryption' => false, - 'antivirus' => false, - ], - ], - 'false fileSecurity' => [ - ['fileSecurity' => false], - ['permission' => 'bucket'], - ], - ]; - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider permissionsProvider - * @dataProvider bucketProvider - */ - public function testBucket(array $content, array $expected): void - { - $model = Response::MODEL_BUCKET; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider permissionsProvider - * @dataProvider bucketProvider - */ - public function testBucketList(array $content, array $expected): void - { - $model = Response::MODEL_BUCKET_LIST; - - $content = [ - 'buckets' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'buckets' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function buildProvider(): array - { - return [ - 'build start and end time' => [ - [ - 'startTime' => '2020-06-24T06:47:30.000Z', - 'endTime' => '2020-06-24T06:47:30.000Z', - ], - [ - 'startTime' => 1592981250, - 'endTime' => 1592981250, - ] - ] - ]; - } - - /** - * @dataProvider buildProvider - */ - public function testBuild(): void - { - $model = Response::MODEL_BUILD; - - $content = [ - 'startTime' => '2020-06-24T06:47:30.000Z', - 'endTime' => '2020-06-24T06:47:30.000Z', - ]; - - $expected = [ - 'startTime' => 1592981250, - 'endTime' => 1592981250, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider buildProvider - */ - public function testBuildList(array $content, array $expected): void - { - $model = Response::MODEL_BUILD_LIST; - - $content = [ - 'builds' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'builds' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function collectionProvider(): array - { - return [ - 'basic collection' => [ - [ - '$id' => '5e5ea5c16897e', - '$createdAt' => '2020-06-24T06:47:30.000Z', - '$updatedAt' => '2020-06-24T06:47:30.000Z', - '$permissions' => [ - Permission::read(Role::any()), - Permission::write(Role::user('608f9da25e7e1')), - ], - 'documentSecurity' => true, - 'databaseId' => '5e5ea5c16897e', - 'name' => 'My Collection', - 'enabled' => false, - 'attributes' => [ - 'key' => 'isEnabled', - 'type' => 'boolean', - 'status' => 'available', - 'required' => true, - 'array' => false, - 'default' => false - ], - 'indexes' => [ - 'key' => 'index1', - 'type' => 'primary', - 'status' => 'available', - 'attributes' => [], - 'orders' => [] - ], - ], - [ - '$id' => '5e5ea5c16897e', - '$createdAt' => 1592981250, - '$updatedAt' => 1592981250, - '$read' => [ - 'role:all' - ], - '$write' => [ - 'user:608f9da25e7e1' - ], - 'databaseId' => '5e5ea5c16897e', - 'name' => 'My Collection', - 'enabled' => false, - 'permission' => 'document', - 'attributes' => [ - 'key' => 'isEnabled', - 'type' => 'boolean', - 'status' => 'available', - 'required' => true, - 'array' => false, - 'default' => false - ], - 'indexes' => [ - 'key' => 'index1', - 'type' => 'primary', - 'status' => 'available', - 'attributes' => [], - 'orders' => [] - ], - ], - ], - 'false documentSecurity' => [ - ['documentSecurity' => false], - ['permission' => 'collection'], - ], - - ]; - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider permissionsProvider - * @dataProvider collectionProvider - */ - public function testCollection(array $content, array $expected): void - { - $model = Response::MODEL_COLLECTION; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider permissionsProvider - * @dataProvider collectionProvider - */ - public function testCollectionList(array $content, array $expected): void - { - $model = Response::MODEL_COLLECTION_LIST; - - $content = [ - 'collections' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'collections' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testDatabase(array $content, array $expected): void - { - $model = Response::MODEL_DATABASE; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testDatabaseList(array $content, array $expected): void - { - $model = Response::MODEL_DATABASE_LIST; - - $content = [ - 'databases' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'databases' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testDeployment(array $content, array $expected): void - { - $model = Response::MODEL_DEPLOYMENT; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testDeploymentList(array $content, array $expected): void - { - $model = Response::MODEL_DEPLOYMENT_LIST; - - $content = [ - 'deployments' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'deployments' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function documentProvider(): array - { - return [ - 'basic document' => [ - [ - '$id' => '5e5ea5c16897e', - '$collectionId' => '5e5ea5c15117e', - '$databaseId' => '5e5ea5c15117e', - '$createdAt' => '2020-06-24T06:47:30.000Z', - '$updatedAt' => '2020-06-24T06:47:30.000Z', - '$permissions' => [Permission::read(Role::any())] - ], - [ - '$id' => '5e5ea5c16897e', - '$collection' => '5e5ea5c15117e', - '$createdAt' => 1592981250, - '$updatedAt' => 1592981250, - '$read' => ['role:all'], - '$write' => [], - ], - ], - ]; - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider permissionsProvider - * @dataProvider documentProvider - */ - public function testDocument(array $content, array $expected): void - { - $model = Response::MODEL_DOCUMENT; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider permissionsProvider - */ - public function testDocumentList(array $content, array $expected): void - { - $model = Response::MODEL_DOCUMENT_LIST; - - $content = [ - 'documents' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'documents' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testDomain(array $content, array $expected): void - { - $model = Response::MODEL_DOMAIN; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testDomainList(array $content, array $expected): void - { - $model = Response::MODEL_DOMAIN_LIST; - - $content = [ - 'domains' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'domains' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function executionProvider(): array - { - return [ - 'basic execution' => [ - [ - '$id' => '5e5ea5c16897e', - '$createdAt' => '2020-06-24T06:47:30.000Z', - '$updatedAt' => '2020-06-24T06:47:30.000Z', - '$permissions' => [ - "any" - ], - 'functionId' => '5e5ea6g16897e', - 'trigger' => 'http', - 'status' => 'processing', - 'statusCode' => 0, - 'response' => '', - 'stdout' => '', - 'stderr' => '', - 'duration' => 0.4 - ], - [ - '$id' => '5e5ea5c16897e', - '$createdAt' => 1592981250, - '$updatedAt' => 1592981250, - '$read' => [ - "role:all" - ], - 'functionId' => '5e5ea6g16897e', - 'trigger' => 'http', - 'status' => 'processing', - 'statusCode' => 0, - 'response' => '', - 'stderr' => '', - 'time' => 0.4 - ], - ], - ]; - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider executionProvider - */ - public function testExecution(array $content, array $expected): void - { - $model = Response::MODEL_EXECUTION; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider executionProvider - */ - public function testExecutionList(array $content, array $expected): void - { - $model = Response::MODEL_EXECUTION_LIST; - - $content = [ - 'executions' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'executions' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider permissionsProvider - */ - public function testFile(array $content, array $expected): void - { - $model = Response::MODEL_FILE; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider permissionsProvider - */ - public function testFileList(array $content, array $expected): void - { - $model = Response::MODEL_FILE_LIST; - - $content = [ - 'files' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'files' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function functionProvider(): array - { - return [ - 'basic function' => [ - [ - '$id' => '5e5ea5c16897e', - '$createdAt' => '2020-06-24T06:47:30.000Z', - '$updatedAt' => '2020-06-24T06:47:30.000Z', - 'execute' => [ - Role::users()->toString(), - ], - 'name' => 'My Function', - 'enabled' => true, - 'runtime' => 'python-3.8', - 'deployment' => '5e5ea5c16897e', - 'vars' => [ - [ - '$id' => '631bd31717e034f14aa8', - '$createdAt' => '2020-06-24T06:47:30.000Z', - '$updatedAt' => '2020-06-24T06:47:30.000Z', - 'key' => 'key', - 'value' => 'value', - 'functionId' => '5e5ea5c16897e', - ] - ], - 'events' => [ - 'account.create' - ], - 'schedule' => '5 4 * * *', - 'scheduleNext' => '2020-06-24T06:48:12.000Z', - 'schedulePrevious' => '2020-06-24T06:47:17.000Z', - 'timeout' => 1592981237 - ], - [ - '$id' => '5e5ea5c16897e', - '$createdAt' => 1592981250, - '$updatedAt' => 1592981250, - 'execute' => [ - 'role:member' - ], - 'name' => 'My Function', - 'status' => 'enabled', - 'runtime' => 'python-3.8', - 'deployment' => '5e5ea5c16897e', - 'vars' => [ - 'key' => 'value' - ], - 'events' => [ - 'account.create' - ], - 'schedule' => '5 4 * * *', - 'scheduleNext' => 1592981292, - 'schedulePrevious' => 1592981237, - 'timeout' => 1592981237 - ], - ], - 'enabled false' => [ - ['enabled' => false], - ['status' => 'disabled'], - ], - ]; - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider functionProvider - */ - public function testFunc(array $content, array $expected): void - { - $model = Response::MODEL_FUNCTION; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider functionProvider - */ - public function testFuncList(array $content, array $expected): void - { - $model = Response::MODEL_FUNCTION_LIST; - - $content = [ - 'functions' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'functions' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function keyProvider(): array - { - return [ - 'basic key' => [ - ['expire' => '2020-06-24T06:47:30.000Z'], - ['expire' => 1592981250], - ], - ]; - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider keyProvider - */ - public function testKey(array $content, array $expected): void - { - $model = Response::MODEL_KEY; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider keyProvider - */ - public function testKeyList(array $content, array $expected): void - { - $model = Response::MODEL_KEY_LIST; - - $content = [ - 'keys' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'keys' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function logProvider(): array - { - return [ - 'basic log' => [ - [ - 'event' => 'account.sessions.create', - 'userId' => '610fc2f985ee0', - 'userEmail' => 'john@appwrite.io', - 'userName' => 'John Doe', - 'mode' => 'admin', - 'ip' => '127.0.0.1', - 'time' => '2020-06-24T06:47:30.000Z', - 'osCode' => 'Mac', - 'osName' => 'Mac', - 'osVersion' => 'Mac', - 'clientType' => 'browser', - 'clientCode' => 'CM', - 'clientName' => 'Chrome Mobile iOS', - 'clientVersion' => '84.0', - 'clientEngine' => 'WebKit', - 'clientEngineVersion' => '605.1.15', - 'deviceName' => 'smartphone', - 'deviceBrand' => 'Google', - 'deviceModel' => 'Nexus 5', - 'countryCode' => 'US', - 'countryName' => 'United States' - ], - [ - 'event' => 'account.sessions.create', - 'userId' => '610fc2f985ee0', - 'userEmail' => 'john@appwrite.io', - 'userName' => 'John Doe', - 'mode' => 'admin', - 'ip' => '127.0.0.1', - 'time' => 1592981250, - 'osCode' => 'Mac', - 'osName' => 'Mac', - 'osVersion' => 'Mac', - 'clientType' => 'browser', - 'clientCode' => 'CM', - 'clientName' => 'Chrome Mobile iOS', - 'clientVersion' => '84.0', - 'clientEngine' => 'WebKit', - 'clientEngineVersion' => '605.1.15', - 'deviceName' => 'smartphone', - 'deviceBrand' => 'Google', - 'deviceModel' => 'Nexus 5', - 'countryCode' => 'US', - 'countryName' => 'United States' - ] - ], - ]; - } - - /** - * @dataProvider logProvider - */ - public function testLog(array $content, array $expected): void - { - $model = Response::MODEL_LOG; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider logProvider - */ - public function testLogList(array $content, array $expected): void - { - $model = Response::MODEL_LOG_LIST; - - $content = [ - 'logs' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'logs' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function membershipProvider(): array - { - return [ - 'basic membership' => [ - [ - 'invited' => '2020-06-24T06:47:30.000Z', - 'joined' => '2020-06-24T06:47:30.000Z', - ], - [ - 'invited' => 1592981250, - 'joined' => 1592981250, - ], - ], - ]; - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider membershipProvider - */ - public function testMembership(array $content, array $expected): void - { - $model = Response::MODEL_MEMBERSHIP; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider membershipProvider - */ - public function testMembershipList(array $content, array $expected): void - { - $model = Response::MODEL_MEMBERSHIP_LIST; - - $content = [ - 'memberships' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'memberships' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function metricProvider(): array - { - return [ - 'basic metric' => [ - [ - 'date' => '2020-06-24T06:47:30.000Z', - ], - [ - 'date' => 1592981250, - ], - ], - ]; - } - - /** - * @dataProvider metricProvider - */ - public function testMetric(array $content, array $expected): void - { - $model = Response::MODEL_METRIC; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testPlatform(array $content, array $expected): void - { - $model = Response::MODEL_PLATFORM; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testPlatformList(array $content, array $expected): void - { - $model = Response::MODEL_PLATFORM_LIST; - - $content = [ - 'platforms' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'platforms' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testProject(array $content, array $expected): void - { - $model = Response::MODEL_PROJECT; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testProjectList(array $content, array $expected): void - { - $model = Response::MODEL_PROJECT_LIST; - - $content = [ - 'projects' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'projects' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function sessionProvider(): array - { - return [ - 'basic session' => [ - [ - '$createdAt' => '2020-06-24T06:47:30.000Z', - 'expire' => '2020-06-24T06:47:30.000Z', - 'providerAccessTokenExpiry' => '2020-06-24T06:47:30.000Z', - ], - [ - '$createdAt' => 1592981250, - 'expire' => 1592981250, - 'providerAccessTokenExpiry' => 1592981250, - ], - ], - 'empty values' => [ - [ - 'providerAccessTokenExpiry' => '', - ], - [ - 'providerAccessTokenExpiry' => 0, - ], - ], - ]; - } - - /** - * @dataProvider sessionProvider - */ - public function testSession(array $content, array $expected): void - { - $model = Response::MODEL_SESSION; - - $result = $this->filter->parse($content, $model); - - $this->assertSame($expected, $result); - } - - /** - * @dataProvider sessionProvider - */ - public function testSessionList(array $content, array $expected): void - { - $model = Response::MODEL_SESSION_LIST; - - $content = [ - 'sessions' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'sessions' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testTeam(array $content, array $expected): void - { - $model = Response::MODEL_TEAM; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testTeamList(array $content, array $expected): void - { - $model = Response::MODEL_TEAM_LIST; - - $content = [ - 'teams' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'teams' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function tokenProvider(): array - { - return [ - 'basic token' => [ - [ - '$createdAt' => '2020-06-24T06:47:30.000Z', - 'expire' => '2020-06-24T06:47:30.000Z', - ], - [ - '$createdAt' => 1592981250, - 'expire' => 1592981250, - ], - ], - ]; - } - - /** - * @dataProvider tokenProvider - */ - public function testToken(array $content, array $expected): void - { - $model = Response::MODEL_TOKEN; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function usageDatabasesProvider(): array - { - return [ - 'basic usage databases' => [ - [ - 'databasesCount' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsCount' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'collectionsCount' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'databasesCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'databasesRead' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'databasesUpdate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'databasesDelete' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsRead' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsUpdate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsDelete' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'collectionsCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'collectionsRead' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'collectionsUpdate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'collectionsDelete' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - ], - [ - 'databasesCount' => [ - ['date' => 1592981250], - ], - 'documentsCount' => [ - ['date' => 1592981250], - ], - 'collectionsCount' => [ - ['date' => 1592981250], - ], - 'databasesCreate' => [ - ['date' => 1592981250], - ], - 'databasesRead' => [ - ['date' => 1592981250], - ], - 'databasesUpdate' => [ - ['date' => 1592981250], - ], - 'databasesDelete' => [ - ['date' => 1592981250], - ], - 'documentsCreate' => [ - ['date' => 1592981250], - ], - 'documentsRead' => [ - ['date' => 1592981250], - ], - 'documentsUpdate' => [ - ['date' => 1592981250], - ], - 'documentsDelete' => [ - ['date' => 1592981250], - ], - 'collectionsCreate' => [ - ['date' => 1592981250], - ], - 'collectionsRead' => [ - ['date' => 1592981250], - ], - 'collectionsUpdate' => [ - ['date' => 1592981250], - ], - 'collectionsDelete' => [ - ['date' => 1592981250], - ], - ], - ], - ]; - } - - /** - * @dataProvider usageDatabasesProvider - */ - public function testUsageDatabases(array $content, array $expected): void - { - $model = Response::MODEL_USAGE_DATABASES; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function usageDatabaseProvider(): array - { - return [ - 'basic usage database' => [ - [ - 'documentsCount' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'collectionsCount' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsRead' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsUpdate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsDelete' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'collectionsCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'collectionsRead' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'collectionsUpdate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'collectionsDelete' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - ], - [ - 'documentsCount' => [ - ['date' => 1592981250], - ], - 'collectionsCount' => [ - ['date' => 1592981250], - ], - 'documentsCreate' => [ - ['date' => 1592981250], - ], - 'documentsRead' => [ - ['date' => 1592981250], - ], - 'documentsUpdate' => [ - ['date' => 1592981250], - ], - 'documentsDelete' => [ - ['date' => 1592981250], - ], - 'collectionsCreate' => [ - ['date' => 1592981250], - ], - 'collectionsRead' => [ - ['date' => 1592981250], - ], - 'collectionsUpdate' => [ - ['date' => 1592981250], - ], - 'collectionsDelete' => [ - ['date' => 1592981250], - ], - ], - ], - ]; - } - - /** - * @dataProvider usageDatabaseProvider - */ - public function testUsageDatabase(array $content, array $expected): void - { - $model = Response::MODEL_USAGE_DATABASE; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function usageCollectionProvider(): array - { - return [ - 'basic usage collection' => [ - [ - 'documentsCount' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsRead' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsUpdate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documentsDelete' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - ], - [ - 'documentsCount' => [ - ['date' => 1592981250], - ], - 'documentsCreate' => [ - ['date' => 1592981250], - ], - 'documentsRead' => [ - ['date' => 1592981250], - ], - 'documentsUpdate' => [ - ['date' => 1592981250], - ], - 'documentsDelete' => [ - ['date' => 1592981250], - ], - ], - ], - ]; - } - - /** - * @dataProvider usageCollectionProvider - */ - public function testUsageCollection(array $content, array $expected): void - { - $model = Response::MODEL_USAGE_COLLECTION; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function usageUsersProvider(): array - { - return [ - 'basic usage users' => [ - [ - 'usersCount' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'usersCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'usersRead' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'usersUpdate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'usersDelete' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'sessionsCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'sessionsProviderCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'sessionsDelete' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - ], - [ - 'usersCount' => [ - ['date' => 1592981250], - ], - 'usersCreate' => [ - ['date' => 1592981250], - ], - 'usersRead' => [ - ['date' => 1592981250], - ], - 'usersUpdate' => [ - ['date' => 1592981250], - ], - 'usersDelete' => [ - ['date' => 1592981250], - ], - 'sessionsCreate' => [ - ['date' => 1592981250], - ], - 'sessionsProviderCreate' => [ - ['date' => 1592981250], - ], - 'sessionsDelete' => [ - ['date' => 1592981250], - ], - ], - ], - ]; - } - - /** - * @dataProvider usageUsersProvider - */ - public function testUsageUsers(array $content, array $expected): void - { - $model = Response::MODEL_USAGE_USERS; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function usageBucketsProvider(): array - { - return [ - 'basic usage buckets' => [ - [ - 'filesCount' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'filesStorage' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'filesCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'filesRead' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'filesUpdate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'filesDelete' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - ], - [ - 'filesCount' => [ - ['date' => 1592981250], - ], - 'filesStorage' => [ - ['date' => 1592981250], - ], - 'filesCreate' => [ - ['date' => 1592981250], - ], - 'filesRead' => [ - ['date' => 1592981250], - ], - 'filesUpdate' => [ - ['date' => 1592981250], - ], - 'filesDelete' => [ - ['date' => 1592981250], - ], - ], - ], - ]; - } - - /** - * @dataProvider usageBucketsProvider - */ - public function testUsageBuckets(array $content, array $expected): void - { - $model = Response::MODEL_USAGE_BUCKETS; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function usageFunctionsProvider(): array - { - return [ - 'basic usage functions' => [ - [ - 'executionsTotal' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'executionsFailure' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'executionsSuccess' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'executionsTime' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'buildsTotal' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'buildsFailure' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'buildsSuccess' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'buildsTime' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - ], - [ - 'functionsExecutions' => [ - ['date' => 1592981250], - ], - 'functionsFailures' => [ - ['date' => 1592981250], - ], - 'functionsCompute' => [ - ['date' => 1592981250], - ], - ], - ], - ]; - } - - /** - * @dataProvider usageFunctionsProvider - */ - public function testUsageFunctions(array $content, array $expected): void - { - $model = Response::MODEL_USAGE_FUNCTIONS; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function usageProjectProvider(): array - { - return [ - 'basic usage project' => [ - [ - 'collections' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'documents' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'executions' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'network' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'requests' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'storage' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'users' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - ], - [ - 'collections' => [ - ['date' => 1592981250], - ], - 'documents' => [ - ['date' => 1592981250], - ], - 'functions' => [ - ['date' => 1592981250], - ], - 'network' => [ - ['date' => 1592981250], - ], - 'requests' => [ - ['date' => 1592981250], - ], - 'storage' => [ - ['date' => 1592981250], - ], - 'users' => [ - ['date' => 1592981250], - ], - ], - ], - ]; - } - - /** - * @dataProvider usageProjectProvider - */ - public function testUsageProject(array $content, array $expected): void - { - $model = Response::MODEL_USAGE_PROJECT; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function usageStorageProvider(): array - { - return [ - 'basic usage storage' => [ - [ - 'bucketsCount' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'bucketsCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'bucketsDelete' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'bucketsRead' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'bucketsUpdate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'filesCount' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'filesCreate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'filesDelete' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'filesRead' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'storage' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - 'filesUpdate' => [ - ['date' => '2020-06-24T06:47:30.000Z'], - ], - ], - [ - 'bucketsCount' => [ - ['date' => 1592981250], - ], - 'bucketsCreate' => [ - ['date' => 1592981250], - ], - 'bucketsDelete' => [ - ['date' => 1592981250], - ], - 'bucketsRead' => [ - ['date' => 1592981250], - ], - 'bucketsUpdate' => [ - ['date' => 1592981250], - ], - 'filesCount' => [ - ['date' => 1592981250], - ], - 'filesCreate' => [ - ['date' => 1592981250], - ], - 'filesDelete' => [ - ['date' => 1592981250], - ], - 'filesRead' => [ - ['date' => 1592981250], - ], - 'filesStorage' => [ - ['date' => 1592981250], - ], - 'filesUpdate' => [ - ['date' => 1592981250], - ], - ], - ], - ]; - } - - /** - * @dataProvider usageStorageProvider - */ - public function testUsageStorage(array $content, array $expected): void - { - $model = Response::MODEL_USAGE_STORAGE; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - public function userProvider(): array - { - return [ - 'basic user' => [ - [ - '$id' => '5e5ea5c16897e', - '$createdAt' => '2020-06-24T06:47:30.000Z', - '$updatedAt' => '2020-06-24T06:47:30.000Z', - 'name' => 'John Doe', - 'password' => '$argon2id$v=19$m=2048,t=4,p=3$aUZjLnliVWRINmFNTWMudg$5S+x+7uA31xFnrHFT47yFwcJeaP0w92L/4LdgrVRXxE', - 'hash' => 'argon2', - 'hashOptions' => [ - 'memoryCost' => 65536, - 'timeCost' => 4, - 'threads' => 3, - ], - 'registration' => '2020-06-24T06:47:30.000Z', - 'status' => true, - 'passwordUpdate' => '2020-06-24T06:47:30.000Z', - 'email' => 'john@appwrite.io', - 'phone' => '+4930901820', - 'emailVerification' => true, - 'phoneVerification' => true, - 'prefs' => new \stdClass(), - ], - [ - '$id' => '5e5ea5c16897e', - '$createdAt' => 1592981250, - '$updatedAt' => 1592981250, - 'name' => 'John Doe', - 'registration' => 1592981250, - 'status' => true, - 'passwordUpdate' => 1592981250, - 'email' => 'john@appwrite.io', - 'phone' => '+4930901820', - 'emailVerification' => true, - 'phoneVerification' => true, - 'prefs' => new \stdClass(), - ], - ], - ]; - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider userProvider - */ - public function testUser(array $content, array $expected): void - { - $model = Response::MODEL_USER; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - * @dataProvider userProvider - */ - public function testUserList(array $content, array $expected): void - { - $model = Response::MODEL_USER_LIST; - - $content = [ - 'users' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'users' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testWebhook(array $content, array $expected): void - { - $model = Response::MODEL_WEBHOOK; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } - - /** - * @dataProvider createdAtUpdatedAtProvider - */ - public function testWebhookList(array $content, array $expected): void - { - $model = Response::MODEL_WEBHOOK_LIST; - - $content = [ - 'webhooks' => [$content], - 'total' => 1, - ]; - - $expected = [ - 'webhooks' => [$expected], - 'total' => 1, - ]; - - $result = $this->filter->parse($content, $model); - - $this->assertEquals($expected, $result); - } -} diff --git a/tests/unit/Utopia/ResponseTest.php b/tests/unit/Utopia/ResponseTest.php index e62103650..374285fb3 100644 --- a/tests/unit/Utopia/ResponseTest.php +++ b/tests/unit/Utopia/ResponseTest.php @@ -4,6 +4,7 @@ namespace Tests\Unit\Utopia; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Filters\V11; +use Appwrite\Utopia\Response\Filters\V16; use Exception; use PHPUnit\Framework\TestCase; use Swoole\Http\Response as SwooleResponse; @@ -21,16 +22,16 @@ class ResponseTest extends TestCase $this->response->setModel(new Nested()); } - public function testSetFilter(): void + public function testSetFilters(): void { - $this->assertEquals($this->response->hasFilter(), false); - $this->assertEquals($this->response->getFilter(), null); + $this->assertEquals($this->response->hasFilters(), false); + $this->assertEquals($this->response->getFilters(), []); - $filter = new V11(); - $this->response->setFilter($filter); + $filter = new V16(); + $this->response->addFilter($filter); - $this->assertEquals($this->response->hasFilter(), true); - $this->assertEquals($this->response->getFilter(), $filter); + $this->assertEquals($this->response->hasFilters(), true); + $this->assertEquals($this->response->getFilters(), [$filter]); } public function testResponseModel(): void From bcebe02eef1df118557ffa2457e1d2dfe3102050 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Thu, 7 Mar 2024 15:05:14 +0100 Subject: [PATCH 3/6] chore: run formatter --- tests/unit/Utopia/ResponseTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/Utopia/ResponseTest.php b/tests/unit/Utopia/ResponseTest.php index 374285fb3..70e61c13b 100644 --- a/tests/unit/Utopia/ResponseTest.php +++ b/tests/unit/Utopia/ResponseTest.php @@ -3,7 +3,6 @@ namespace Tests\Unit\Utopia; use Appwrite\Utopia\Response; -use Appwrite\Utopia\Response\Filters\V11; use Appwrite\Utopia\Response\Filters\V16; use Exception; use PHPUnit\Framework\TestCase; From eacf7541a9c5c0c0738c4cd6ea914fa38ad1bb5f Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Thu, 7 Mar 2024 15:41:20 +0100 Subject: [PATCH 4/6] fix: convert filter to non-statics --- app/controllers/general.php | 12 ++++-------- src/Appwrite/Utopia/Request.php | 29 +++++++++++++---------------- src/Appwrite/Utopia/Response.php | 20 ++++++++++---------- 3 files changed, 27 insertions(+), 34 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index ebbe9b096..1602316dd 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -391,20 +391,18 @@ App::init() */ $route = $utopia->getRoute(); Request::setRoute($route); - Request::resetFilters(); if ($route === null) { return $response->setStatusCode(404)->send('Not Found'); } $requestFormat = $request->getHeader('x-appwrite-response-format', App::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', null)); - if ($requestFormat) { if (version_compare($requestFormat, '1.4.0', '<')) { - Request::addFilter(new RequestV16()); + $request->addFilter(new RequestV16()); } if (version_compare($requestFormat, '1.5.0', '<')) { - Request::addFilter(new RequestV17()); + $request->addFilter(new RequestV17()); } } @@ -514,15 +512,13 @@ App::init() /* * Response format */ - Response::resetFilters(); - $responseFormat = $request->getHeader('x-appwrite-response-format', App::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', null)); if ($responseFormat) { if (version_compare($responseFormat, '1.4.0', '<')) { - Response::addFilter(new ResponseV16()); + $response->addFilter(new ResponseV16()); } if (version_compare($responseFormat, '1.5.0', '<')) { - Response::addFilter(new ResponseV17()); + $response->addFilter(new ResponseV17()); } } diff --git a/src/Appwrite/Utopia/Request.php b/src/Appwrite/Utopia/Request.php index af9b13661..3f0a196d5 100644 --- a/src/Appwrite/Utopia/Request.php +++ b/src/Appwrite/Utopia/Request.php @@ -12,8 +12,7 @@ class Request extends UtopiaRequest /** * @var array */ - private static array $filters = []; - + private array $filters = []; private static ?Route $route = null; public function __construct(SwooleRequest $request) @@ -28,15 +27,13 @@ class Request extends UtopiaRequest { $parameters = parent::getParams(); - if (self::hasFilters() && self::hasRoute()) { + if ($this->hasFilters() && self::hasRoute()) { $method = self::getRoute()->getLabel('sdk.method', 'unknown'); $endpointIdentifier = self::getRoute()->getLabel('sdk.namespace', 'unknown') . '.' . $method; - $parameters = array_reduce( - self::getFilters(), - fn (array $carry, Filter $filter) => $filter->parse($carry, $endpointIdentifier), - $parameters - ); + foreach ($this->getFilters() as $filter) { + $parameters = $filter->parse($parameters, $endpointIdentifier); + } } return $parameters; @@ -49,9 +46,9 @@ class Request extends UtopiaRequest * * @return void */ - public static function addFilter(Filter $filter): void + public function addFilter(Filter $filter): void { - self::$filters[] = $filter; + $this->filters[] = $filter; } /** @@ -59,9 +56,9 @@ class Request extends UtopiaRequest * * @return array */ - public static function getFilters(): array + public function getFilters(): array { - return self::$filters; + return $this->filters; } /** @@ -69,9 +66,9 @@ class Request extends UtopiaRequest * * @return void */ - public static function resetFilters(): void + public function resetFilters(): void { - self::$filters = []; + $this->filters = []; } /** @@ -79,9 +76,9 @@ class Request extends UtopiaRequest * * @return bool */ - public static function hasFilters(): bool + public function hasFilters(): bool { - return !empty(self::$filters); + return !empty($this->filters); } /** diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index c570ccfb2..1c66875ec 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -301,7 +301,7 @@ class Response extends SwooleResponse /** * @var array */ - private static $filters = []; + protected array $filters = []; /** * @var array @@ -526,7 +526,7 @@ class Response extends SwooleResponse $output = $this->output(clone $document, $model); // If filter is set, parse the output - foreach (self::$filters as $filter) { + foreach ($this->filters as $filter) { $output = $filter->parse($output, $model); } @@ -688,9 +688,9 @@ class Response extends SwooleResponse * * @return void */ - public static function addFilter(Filter $filter): void + public function addFilter(Filter $filter): void { - self::$filters[] = $filter; + $this->filters[] = $filter; } /** @@ -698,9 +698,9 @@ class Response extends SwooleResponse * * @return Filter */ - public static function getFilters(): array + public function getFilters(): array { - return self::$filters; + return $this->filters; } /** @@ -708,9 +708,9 @@ class Response extends SwooleResponse * * @return void */ - public static function resetFilters(): void + public function resetFilters(): void { - self::$filters = []; + $this->filters = []; } /** @@ -718,9 +718,9 @@ class Response extends SwooleResponse * * @return bool */ - public static function hasFilters(): bool + public function hasFilters(): bool { - return !empty(self::$filters); + return !empty($this->filters); } /** From c3fc9e65675324f0a8e03b81d90d8d1c9c230a94 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Thu, 7 Mar 2024 16:20:34 +0100 Subject: [PATCH 5/6] tests: add request/response filter tests --- src/Appwrite/Utopia/Response.php | 15 ++++-- tests/unit/Utopia/Request/Filters/First.php | 19 +++++++ tests/unit/Utopia/Request/Filters/Second.php | 18 +++++++ tests/unit/Utopia/RequestTest.php | 53 +++++++++++++++++++ tests/unit/Utopia/Response/Filters/First.php | 19 +++++++ tests/unit/Utopia/Response/Filters/Second.php | 18 +++++++ tests/unit/Utopia/ResponseTest.php | 31 ++++++++--- 7 files changed, 160 insertions(+), 13 deletions(-) create mode 100644 tests/unit/Utopia/Request/Filters/First.php create mode 100644 tests/unit/Utopia/Request/Filters/Second.php create mode 100644 tests/unit/Utopia/RequestTest.php create mode 100644 tests/unit/Utopia/Response/Filters/First.php create mode 100644 tests/unit/Utopia/Response/Filters/Second.php diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 1c66875ec..6601a3607 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -511,6 +511,15 @@ class Response extends SwooleResponse return $this->models; } + public function applyFilters(array $data, string $model): array + { + foreach ($this->filters as $filter) { + $data = $filter->parse($data, $model); + } + + return $data; + } + /** * Validate response objects and outputs * the response according to given format type @@ -524,11 +533,7 @@ class Response extends SwooleResponse public function dynamic(Document $document, string $model): void { $output = $this->output(clone $document, $model); - - // If filter is set, parse the output - foreach ($this->filters as $filter) { - $output = $filter->parse($output, $model); - } + $output = $this->applyFilters($output, $model); switch ($this->getContentType()) { case self::CONTENT_TYPE_JSON: diff --git a/tests/unit/Utopia/Request/Filters/First.php b/tests/unit/Utopia/Request/Filters/First.php new file mode 100644 index 000000000..7e00abfc5 --- /dev/null +++ b/tests/unit/Utopia/Request/Filters/First.php @@ -0,0 +1,19 @@ +request = new Request(new SwooleRequest()); + } + + public function testFilters(): void + { + $this->assertFalse($this->request->hasFilters()); + $this->assertIsArray($this->request->getFilters()); + $this->assertEmpty($this->request->getFilters()); + + $this->request->addFilter(new First()); + $this->request->addFilter(new Second()); + + $this->assertTrue($this->request->hasFilters()); + $this->assertCount(2, $this->request->getFilters()); + + $route = new Route(Request::METHOD_GET, '/test'); + $route->label('sdk.method', 'method'); + $route->label('sdk.namespace', 'namespace'); + // set test header to prevent header populaten inside the request class + $this->request->addHeader('EXAMPLE', 'VALUE'); + $this->request->setRoute($route); + $this->request->setQueryString([ + 'initial' => true, + 'first' => false + ]); + $output = $this->request->getParams(); + + $this->assertArrayHasKey('initial', $output); + $this->assertTrue($output['initial']); + $this->assertArrayHasKey('first', $output); + $this->assertTrue($output['first']); + $this->assertArrayHasKey('second', $output); + $this->assertTrue($output['second']); + $this->assertArrayNotHasKey('deleted', $output); + } +} diff --git a/tests/unit/Utopia/Response/Filters/First.php b/tests/unit/Utopia/Response/Filters/First.php new file mode 100644 index 000000000..bf29b4f61 --- /dev/null +++ b/tests/unit/Utopia/Response/Filters/First.php @@ -0,0 +1,19 @@ +response->setModel(new Nested()); } - public function testSetFilters(): void + public function testFilters(): void { - $this->assertEquals($this->response->hasFilters(), false); - $this->assertEquals($this->response->getFilters(), []); + $this->assertFalse($this->response->hasFilters()); + $this->assertIsArray($this->response->getFilters()); + $this->assertEmpty($this->response->getFilters()); - $filter = new V16(); - $this->response->addFilter($filter); + $this->response->addFilter(new First()); + $this->response->addFilter(new Second()); - $this->assertEquals($this->response->hasFilters(), true); - $this->assertEquals($this->response->getFilters(), [$filter]); + $this->assertTrue($this->response->hasFilters()); + $this->assertCount(2, $this->response->getFilters()); + + $output = $this->response->applyFilters([ + 'initial' => true, + 'first' => false + ], 'test'); + + $this->assertArrayHasKey('initial', $output); + $this->assertTrue($output['initial']); + $this->assertArrayHasKey('first', $output); + $this->assertTrue($output['first']); + $this->assertArrayHasKey('second', $output); + $this->assertTrue($output['second']); + $this->assertArrayNotHasKey('deleted', $output); } public function testResponseModel(): void From 07000eabec17c7e7f23c39ad465079ffafd9d6c0 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Thu, 7 Mar 2024 16:49:44 +0100 Subject: [PATCH 6/6] test: remove deprecated filter tests --- .../Services/Teams/TeamsConsoleClientTest.php | 50 ------------------- 1 file changed, 50 deletions(-) diff --git a/tests/e2e/Services/Teams/TeamsConsoleClientTest.php b/tests/e2e/Services/Teams/TeamsConsoleClientTest.php index d7293c351..61d0f6a02 100644 --- a/tests/e2e/Services/Teams/TeamsConsoleClientTest.php +++ b/tests/e2e/Services/Teams/TeamsConsoleClientTest.php @@ -6,7 +6,6 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectConsole; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Utopia\Database\Helpers\ID; class TeamsConsoleClientTest extends Scope { @@ -15,55 +14,6 @@ class TeamsConsoleClientTest extends Scope use ProjectConsole; use SideClient; - public function testRequestHeader() - { - /** - * Test without header - */ - $response = $this->client->call(Client::METHOD_POST, '/teams', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => 'console' - ], $this->getHeaders()), [ - 'name' => 'Latest version Team', - 'teamId' => ID::unique() - ]); - - $this->assertEquals(201, $response['headers']['status-code']); - $team1Id = $response['body']['$id']; - - /** - * Test with header - */ - $response = $this->client->call(Client::METHOD_POST, '/teams', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => 'console', - 'x-appwrite-response-format' => '0.11.0' - ], $this->getHeaders()), [ - 'name' => 'Latest version Team' - // Notice "teamId' is not defined - ]); - - $this->assertEquals(201, $response['headers']['status-code']); - $team2Id = $response['body']['$id']; - - /** - * Cleanup, so I don't invalidate some listTeams requests by mistake - */ - $response = $this->client->call(Client::METHOD_DELETE, '/teams/' . $team1Id, \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => 'console', - ], $this->getHeaders())); - - $this->assertEquals(204, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_DELETE, '/teams/' . $team2Id, \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => 'console', - ], $this->getHeaders())); - - $this->assertEquals(204, $response['headers']['status-code']); - } - /** * @depends testCreateTeam */