diff --git a/.env b/.env index f6095351de..ce43bfd853 100644 --- a/.env +++ b/.env @@ -34,3 +34,4 @@ _APP_FUNCTIONS_CPUS=1 _APP_FUNCTIONS_MEMORY=128 _APP_FUNCTIONS_MEMORY_SWAP=128 _APP_MAINTENANCE_INTERVAL=86400 +_APP_SYSTEM_RESPONSE_FORMAT= \ No newline at end of file diff --git a/app/config/variables.php b/app/config/variables.php index d7c180ea11..80dd6fdb82 100644 --- a/app/config/variables.php +++ b/app/config/variables.php @@ -351,4 +351,10 @@ return [ ], ], ], + [ + 'name' => '_APP_SYSTEM_RESPONSE_FORMAT', + 'default' => '', + 'required' => false, + 'question' => '', + ], ]; \ No newline at end of file diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 06dc87a42b..90c232b21c 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -449,6 +449,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId') } } + // TODO : Response filter implementation $response->noContent(); }); @@ -492,6 +493,7 @@ App::delete('/v1/users/:userId/sessions') ->setParam('payload', $response->output($user, Response::MODEL_USER)) ; + // TODO : Response filter implementation $response->noContent(); }); @@ -553,5 +555,6 @@ App::delete('/v1/users/:userId') ->setParam('payload', $response->output($user, Response::MODEL_USER)) ; + // TODO : Response filter implementation $response->noContent(); }); diff --git a/app/controllers/general.php b/app/controllers/general.php index d77b3d5607..55f196e266 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -16,6 +16,8 @@ use Appwrite\Database\Validator\Authorization; use Appwrite\Network\Validator\Origin; use Appwrite\Storage\Device\Local; use Appwrite\Storage\Storage; +use Appwrite\Utopia\Response\Filter; +use Appwrite\Utopia\Response\Filter\V06; use Utopia\CLI\Console; Config::setParam('domainVerification', false); @@ -94,6 +96,22 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo Storage::setDevice('files', new Local(APP_STORAGE_UPLOADS.'/app-'.$project->getId())); Storage::setDevice('functions', new Local(APP_STORAGE_FUNCTIONS.'/app-'.$project->getId())); + /* + * Response format + */ + $responseFormat = $request->getHeader('x-appwrite-response-format', App::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', '')); + if ($responseFormat) { + switch($responseFormat) { + case version_compare ($responseFormat , '0.6.2', '<=') : + Response::setFilter(new V06()); + break; + default: + throw new Exception('No filter available for response format : '.$responseFormat, 400); + } + } else { + Response::setFilter(null); + } + /* * Security Headers * diff --git a/app/http.php b/app/http.php index 2197201d85..b3d7dcaac7 100644 --- a/app/http.php +++ b/app/http.php @@ -48,6 +48,7 @@ $http->on('AfterReload', function($serv, $workerId) { }); $http->on('start', function (Server $http) use ($payloadSize) { + Console::success('Server started succefully (max payload is '.number_format($payloadSize).' bytes)'); Console::info("Master pid {$http->master_pid}, manager pid {$http->manager_pid}"); diff --git a/docker-compose.yml b/docker-compose.yml index 0d1abc0ad9..2acd6d3ed2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -105,6 +105,7 @@ services: - _APP_STORAGE_LIMIT - _APP_FUNCTIONS_TIMEOUT - _APP_FUNCTIONS_CONTAINERS + - _APP_SYSTEM_RESPONSE_FORMAT - _APP_FUNCTIONS_CPUS - _APP_FUNCTIONS_MEMORY - _APP_FUNCTIONS_MEMORY_SWAP diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index a854416c3f..ce22df225e 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -6,6 +6,8 @@ use Exception; use Utopia\Swoole\Response as SwooleResponse; use Swoole\Http\Response as SwooleHTTPResponse; use Appwrite\Database\Document; +use Appwrite\Utopia\Response\Filter; +use Appwrite\Utopia\Response\Filter\V06; use Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response\Model\None; use Appwrite\Utopia\Response\Model\Any; @@ -112,6 +114,11 @@ class Response extends SwooleResponse const MODEL_DOMAIN = 'domain'; const MODEL_DOMAIN_LIST = 'domainList'; + /** + * @var Filter + */ + private static $filter = null; + /** * @var array */ @@ -243,7 +250,15 @@ class Response extends SwooleResponse */ public function dynamic(Document $document, string $model): void { - $this->json($this->output($document, $model)); + $output = $this->output($document, $model); + + // If filter is set, parse the item + if(self::isFilter()){ + $item = self::getFilter()->parse($output, $model); + } + + $this->json($output); + } /** @@ -329,4 +344,37 @@ class Response extends SwooleResponse { return $this->payload; } + + + /** + * Function to set a response filter + * + * @param $filter the response filter to set + * + * @return void + */ + public static function setFilter(?Filter $filter) + { + self::$filter = $filter; + } + + /** + * Return the currently set filter + * + * @return Filter + */ + public static function getFilter(): ?Filter + { + return self::$filter; + } + + /** + * Check if a filter has been set + * + * @return bool + */ + public static function isFilter(): bool + { + return self::$filter != null; + } } diff --git a/src/Appwrite/Utopia/Response/Filter.php b/src/Appwrite/Utopia/Response/Filter.php new file mode 100644 index 0000000000..6974c4ba89 --- /dev/null +++ b/src/Appwrite/Utopia/Response/Filter.php @@ -0,0 +1,17 @@ +parseCollection($content); + break; + + case Response::MODEL_COLLECTION_LIST: + $parsedResponse = $this->parseCollectionList($content); + break; + + case Response::MODEL_FILE : + $parsedResponse = $this->parseFile($content); + break; + + case Response::MODEL_FILE_LIST : + $parsedResponse = $content; + break; + + case Response::MODEL_USER : + $parsedResponse = $this->parseUser($content); + break; + + case Response::MODEL_USER_LIST: + $parsedResponse = $this->parseUserList($content); + break; + + case Response::MODEL_TEAM: + $parsedResponse = $this->parseTeam($content); + break; + + case Response::MODEL_TEAM_LIST: + $parsedResponse = $this->parseTeamList($content); + break; + + case Response::MODEL_MEMBERSHIP: + $parsedResponse = $content; + break; + + case Response::MODEL_MEMBERSHIP_LIST: + $parsedResponse = $content['memberships']; + break; + + case Response::MODEL_SESSION : + $parsedResponse = $this->parseSession($content); + break; + + case Response::MODEL_SESSION_LIST : + $parsedResponse = $this->parseSessionList($content); + break; + + case Response::MODEL_LOG_LIST : + $parsedResponse = $this->parseLogList($content); + break; + + case Response::MODEL_TOKEN: + $parsedResponse = $this->parseToken($content); + break; + + case Response::MODEL_LOCALE: + $parsedResponse = $this->parseLocale($content); + break; + + case Response::MODEL_COUNTRY_LIST: + $parsedResponse = $this->parseCountryList($content); + break; + + case Response::MODEL_PHONE_LIST: + $parsedResponse = $this->parsePhoneList($content); + break; + + case Response::MODEL_CONTINENT_LIST: + $parsedResponse = $this->parseContinentList($content); + break; + + case Response::MODEL_CURRENCY_LIST: + $parsedResponse = $this->parseCurrencyList($content); + break; + + case Response::MODEL_ANY : + $parsedResponse = $content; + break; + + default: + throw new Exception('Recevied invalid model : '.$model); + } + + return $parsedResponse; + } + + private function parseCollectionList(array $content) + { + foreach($content['collections'] as $key => $collection){ + $content['collections'][$key] = $this->parseCollection($collection); + } + return $content; + } + + private function parseCollection(array $content) + { + $content['$collection'] = Database::SYSTEM_COLLECTION_COLLECTIONS; + $content['structure'] = true; + return $content; + } + + private function parseFile(array $content) + { + $content['$collection'] = Database::SYSTEM_COLLECTION_FILES; + $content['algorithm'] = 'gzip'; + $content['comment'] = ''; + $content['fileOpenSSLCipher'] = OpenSSL::CIPHER_AES_128_GCM; + $content['fileOpenSSLIV'] = ''; + $content['fileOpenSSLTag'] = ''; + $content['fileOpenSSLVersion'] = ''; + $content['folderId'] = ''; + $content['path'] = ''; + $content['sizeActual'] = $content['sizeOriginal']; + $content['token'] = ''; + return $content; + } + + private function parseCurrencyList(array $content) + { + $content['locations'] = []; + $currencies = $content['currencies']; + $parsedResponse = []; + foreach($currencies as $currency) { + $currency['locations'] = []; + $parsedResponse[] = $currency; + } + $content['currencies'] = $parsedResponse; + return $content; + } + + private function parseContinentList(array $content) + { + $continents = $content['continents']; + $parsedResponse = []; + foreach($continents as $continent) { + $parsedResponse[$continent['code']] = $continent['name']; + } + $content['continents'] = $parsedResponse; + return $content; + } + + private function parsePhoneList(array $content) + { + $phones = $content['phones']; + $parsedResponse = []; + foreach($phones as $phone) { + $parsedResponse[$phone['countryCode']] = $phone['code']; + } + $content['phones'] = $parsedResponse; + return $content; + } + + private function parseCountryList(array $content) + { + $countries = $content['countries']; + $parsedResponse = []; + foreach($countries as $country) { + $parsedResponse[$country['code']] = $country['name']; + } + $content['countries'] = $parsedResponse; + return $content; + } + + private function parseLocale(array $content) + { + $content['ip'] = $content['ip'] ?? ''; + $content['countryCode'] = $content['countryCode'] ?? '--'; + $content['country'] = $content['country'] ?? Locale::getText('locale.country.unknown'); + $content['continent'] = $content['continent'] ?? Locale::getText('locale.country.unknown'); + $content['continentCode'] = $content['continentCode'] ?? '--'; + $content['eu'] = $content['eu'] ?? false; + $content['currency'] = $content['currency'] ?? null; + return $content; + } + + private function parseToken(array $content) + { + $content['type'] = Auth::TOKEN_TYPE_RECOVERY; + return $content; + } + + private function parseTeam(array $content) + { + $content['$collection'] = Database::SYSTEM_COLLECTION_TEAMS; + $content['$permissions'] = []; + return $content; + } + + private function parseTeamList(array $content) + { + $teams = $content['teams']; + $parsedResponse = []; + foreach($teams as $team) { + $parsedResponse[] = $this->parseTeam($team); + } + $content['teams'] = $parsedResponse; + return $content; + } + + private function parseLogList(array $content) + { + $logs = $content['logs']; + $parsedResponse = []; + foreach($logs as $log) { + $parsedResponse[] = [ + 'brand' => $log['deviceBrand'], + 'device' => $log['deviceName'], + 'event' => $log['event'], + 'ip' => $log['ip'], + 'model' => $log['deviceModel'], + 'time' => $log['time'], + 'geo' => [ + 'isoCode' => empty($log['countryCode']) ? '---' : $log['countryCode'] , + 'country' => empty($log['countryName'] ) ? Locale::getText('locale.country.unknown') : $log['countryName'] + ], + 'OS' => [ + 'name' => $log['osName'], + 'platform' => '', + 'short_name' => $log['osCode'], + 'version' => $log['osVersion'] + ], + 'client' => [ + 'engine' => $log['clientEngine'], + 'name' => $log['clientName'], + 'short_name' => $log['clientCode'], + 'type' => $log['clientType'], + 'version' => $log['clientVersion'] + ] + ]; + } + $content['logs'] = $parsedResponse; + return $content; + } + + private function parseSessionList(array $content) + { + $sessions = $content['sessions']; + $parsedResponse = []; + foreach($sessions as $session) { + $parsedResponse[] = [ + '$id' => $session['$id'], + 'brand' => $session['deviceBrand'], + 'current' => $session['current'], + 'device' => $session['deviceName'], + 'ip' => $session['ip'], + 'model' => $session['deviceModel'], + 'geo' => [ + 'isoCode' => empty($session['countryCode']) ? '---' : $session['countryCode'] , + 'country' => empty($session['countryName'] ) ? Locale::getText('locale.country.unknown') : $session['countryName'] + ], + 'OS' => [ + 'name' => $session['osName'], + 'platform' => '', + 'short_name' => $session['osCode'], + 'version' => $session['osVersion'] + ], + 'client' => [ + 'engine' => $session['clientEngine'], + 'name' => $session['clientName'], + 'short_name' => $session['clientCode'], + 'type' => $session['clientType'], + 'version' => $session['clientVersion'] + ] + ]; + } + $content['sessions'] = $parsedResponse; + return $content; + } + + private function parseSession(array $content) + { + $content['type'] = Auth::TOKEN_TYPE_LOGIN; + return $content; + } + + private function parseUserList(array $content) + { + $users = $content['users']; + $parsedResponse = []; + foreach($users as $user) { + $parsedResponse[] = $this->parseUser($user); + } + $content['users'] = $parsedResponse; + return $content; + } + + private function parseUser(array $content) + { + foreach (Config::getParam('providers', []) as $key => $provider) { + if (!$provider['enabled']) { + continue; + } + $content['oauth2'.ucfirst($key)] = ''; + $content['oauth2'.ucfirst($key).'AccessToken'] = ''; + } + $content['status'] = empty($content['status']) ? 0 : $content['status']; + $content['roles'] = Authorization::getRoles() ?? []; + return $content; + } +} \ No newline at end of file diff --git a/src/Appwrite/Utopia/Response/Model/User.php b/src/Appwrite/Utopia/Response/Model/User.php index 79c34db5ef..e11d49ed8f 100644 --- a/src/Appwrite/Utopia/Response/Model/User.php +++ b/src/Appwrite/Utopia/Response/Model/User.php @@ -27,7 +27,7 @@ class User extends Model ]) ->addRule('status', [ 'type' => self::TYPE_INTEGER, - 'description' => 'User status. 0 for Unavtivated, 1 for active and 2 is blocked.', + 'description' => 'User status. 0 for Unactivated, 1 for active and 2 is blocked.', 'example' => 0, ]) ->addRule('email', [ diff --git a/tests/unit/Utopia/Filters/V06Test.php b/tests/unit/Utopia/Filters/V06Test.php new file mode 100644 index 0000000000..59c688ea0d --- /dev/null +++ b/tests/unit/Utopia/Filters/V06Test.php @@ -0,0 +1,520 @@ +filter = new V06(); + } + + public function testParseUser() + { + $content = [ + '$id' => '5e5ea5c16897e', + 'name' => 'John Doe', + 'registration' => 1592981250, + 'status' => 0, + 'email' => 'john@appwrite.io', + 'emailVerification' => false, + 'prefs' => [ + 'theme' => 'pink', + 'timezone' => 'UTC' + ] + ]; + + Config::load('providers', __DIR__.'/../../../../app/config/providers.php'); + + $model = Response::MODEL_USER; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['$id'], '5e5ea5c16897e'); + $this->assertEquals($parsedResponse['name'], 'John Doe'); + $this->assertEquals($parsedResponse['registration'], 1592981250); + $this->assertEquals($parsedResponse['status'], 0); + $this->assertEquals($parsedResponse['email'], 'john@appwrite.io'); + $this->assertEquals($parsedResponse['emailVerification'], false); + $this->assertEquals($parsedResponse['prefs'], ['theme' => 'pink', 'timezone' => 'UTC']); + $this->assertEquals($parsedResponse['status'], 0); + $this->assertEquals($parsedResponse['roles'], Authorization::getRoles() ?? []); + } + + public function testParseUserList() + { + $content = [ + 'sum' => 1, + 'users' => [ + 0 => [ + '$id' => '5e5ea5c16897e', + 'name' => 'John Doe', + 'registration' => 1592981250, + 'status' => 0, + 'email' => 'john@appwrite.io', + 'emailVerification' => false, + 'prefs' => [ + 'theme' => 'pink', + 'timezone' => 'UTC' + ] + ] + ] + ]; + + Config::load('providers', __DIR__.'/../../../../app/config/providers.php'); + + $model = Response::MODEL_USER_LIST; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['sum'], 1); + $this->assertEquals($parsedResponse['users'][0]['$id'], '5e5ea5c16897e'); + $this->assertEquals($parsedResponse['users'][0]['name'], 'John Doe'); + $this->assertEquals($parsedResponse['users'][0]['registration'], 1592981250); + $this->assertEquals($parsedResponse['users'][0]['status'], 0); + $this->assertEquals($parsedResponse['users'][0]['email'], 'john@appwrite.io'); + $this->assertEquals($parsedResponse['users'][0]['emailVerification'], false); + $this->assertEquals($parsedResponse['users'][0]['prefs'], ['theme' => 'pink', 'timezone' => 'UTC']); + $this->assertEquals($parsedResponse['users'][0]['status'], 0); + $this->assertEquals($parsedResponse['users'][0]['roles'], Authorization::getRoles() ?? []); + } + + public function testParseSession() + { + $content = [ + '$id' => '5e5ea5c16897e', + 'userId' => '5e5bb8c16897e', + 'expire' => 1592981250, + 'ip' => '127.0.0.1', + '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', + 'current' => true + ]; + + $model = Response::MODEL_SESSION; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['$id'], '5e5ea5c16897e'); + $this->assertEquals($parsedResponse['userId'], '5e5bb8c16897e'); + $this->assertEquals($parsedResponse['expire'], 1592981250); + $this->assertEquals($parsedResponse['ip'], '127.0.0.1'); + $this->assertEquals($parsedResponse['osCode'], 'Mac'); + $this->assertEquals($parsedResponse['osName'], 'Mac'); + $this->assertEquals($parsedResponse['osVersion'], 'Mac'); + $this->assertEquals($parsedResponse['clientType'], 'browser'); + $this->assertEquals($parsedResponse['clientCode'], 'CM'); + $this->assertEquals($parsedResponse['clientName'], 'Chrome Mobile iOS'); + $this->assertEquals($parsedResponse['clientVersion'], '84.0'); + $this->assertEquals($parsedResponse['clientEngine'], 'WebKit'); + $this->assertEquals($parsedResponse['clientEngineVersion'], '605.1.15'); + $this->assertEquals($parsedResponse['deviceName'], 'smartphone'); + $this->assertEquals($parsedResponse['deviceBrand'], 'Google'); + $this->assertEquals($parsedResponse['deviceModel'], 'Nexus 5'); + $this->assertEquals($parsedResponse['countryCode'], 'US'); + $this->assertEquals($parsedResponse['countryName'], 'United States'); + $this->assertEquals($parsedResponse['current'], true); + $this->assertEquals($parsedResponse['type'], Auth::TOKEN_TYPE_LOGIN); + } + + public function testParseSessionList() + { + $content = [ + 'sum' => 1, + 'sessions' => [ + 0 => [ + '$id' => '5e5ea5c16897e', + 'userId' => '5e5bb8c16897e', + 'expire' => 1592981250, + 'ip' => '127.0.0.1', + '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', + 'current' => true + ] + ] + ]; + + $model = Response::MODEL_SESSION_LIST; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['sum'], 1); + $this->assertEquals($parsedResponse['sessions'][0]['$id'], '5e5ea5c16897e'); + $this->assertEquals($parsedResponse['sessions'][0]['brand'], 'Google'); + $this->assertEquals($parsedResponse['sessions'][0]['current'], true); + $this->assertEquals($parsedResponse['sessions'][0]['device'], 'smartphone'); + $this->assertEquals($parsedResponse['sessions'][0]['ip'], '127.0.0.1'); + $this->assertEquals($parsedResponse['sessions'][0]['model'], 'Nexus 5'); + + $this->assertEquals($parsedResponse['sessions'][0]['OS']['name'], 'Mac'); + $this->assertEquals($parsedResponse['sessions'][0]['OS']['platform'], ''); + $this->assertEquals($parsedResponse['sessions'][0]['OS']['short_name'], 'Mac'); + $this->assertEquals($parsedResponse['sessions'][0]['OS']['version'], 'Mac'); + + $this->assertEquals($parsedResponse['sessions'][0]['client']['engine'], 'WebKit'); + $this->assertEquals($parsedResponse['sessions'][0]['client']['name'], 'Chrome Mobile iOS'); + $this->assertEquals($parsedResponse['sessions'][0]['client']['short_name'], 'CM'); + $this->assertEquals($parsedResponse['sessions'][0]['client']['type'], 'browser'); + $this->assertEquals($parsedResponse['sessions'][0]['client']['version'], '84.0'); + + $this->assertEquals($parsedResponse['sessions'][0]['geo']['isoCode'], 'US'); + $this->assertEquals($parsedResponse['sessions'][0]['geo']['country'], 'United States'); + } + + public function testParseLogList() + { + $content = [ + 'sum' => 1, + 'logs' => [ + 0 => [ + 'event' => 'account.sessions.create', + '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' + ] + ] + ]; + + $model = Response::MODEL_LOG_LIST; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['sum'], 1); + $this->assertEquals($parsedResponse['logs'][0]['brand'], 'Google'); + $this->assertEquals($parsedResponse['logs'][0]['device'], 'smartphone'); + $this->assertEquals($parsedResponse['logs'][0]['event'], 'account.sessions.create'); + $this->assertEquals($parsedResponse['logs'][0]['ip'], '127.0.0.1'); + $this->assertEquals($parsedResponse['logs'][0]['model'], 'Nexus 5'); + $this->assertEquals($parsedResponse['logs'][0]['time'], 1592981250); + + $this->assertEquals($parsedResponse['logs'][0]['OS']['name'], 'Mac'); + $this->assertEquals($parsedResponse['logs'][0]['OS']['platform'], ''); + $this->assertEquals($parsedResponse['logs'][0]['OS']['short_name'], 'Mac'); + $this->assertEquals($parsedResponse['logs'][0]['OS']['version'], 'Mac'); + + $this->assertEquals($parsedResponse['logs'][0]['client']['engine'], 'WebKit'); + $this->assertEquals($parsedResponse['logs'][0]['client']['name'], 'Chrome Mobile iOS'); + $this->assertEquals($parsedResponse['logs'][0]['client']['short_name'], 'CM'); + $this->assertEquals($parsedResponse['logs'][0]['client']['type'], 'browser'); + $this->assertEquals($parsedResponse['logs'][0]['client']['version'], '84.0'); + + $this->assertEquals($parsedResponse['logs'][0]['geo']['isoCode'], 'US'); + $this->assertEquals($parsedResponse['logs'][0]['geo']['country'], 'United States'); + } + + public function testParseTeam() + { + $content = [ + '$id' => '5ff45ef261829', + 'name' => 'test', + 'dateCreated' => 1592981250, + 'sum' => 7 + ]; + + $model = Response::MODEL_TEAM; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['$id'], '5ff45ef261829'); + $this->assertEquals($parsedResponse['name'], 'test'); + $this->assertEquals($parsedResponse['dateCreated'], 1592981250); + $this->assertEquals($parsedResponse['sum'], 7); + $this->assertEquals($parsedResponse['$collection'], 'teams'); + $this->assertEquals($parsedResponse['$permissions'], []); + } + + public function testParseTeamList() + { + $content = [ + 'sum' => 1, + 'teams' => [ + 0 => [ + '$id' => '5ff45ef261829', + 'name' => 'test', + 'dateCreated' => 1592981250, + 'sum' => 7 + ] + ] + ]; + + $model = Response::MODEL_TEAM_LIST; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['sum'], 1); + $this->assertEquals($parsedResponse['teams'][0]['$id'], '5ff45ef261829'); + $this->assertEquals($parsedResponse['teams'][0]['name'], 'test'); + $this->assertEquals($parsedResponse['teams'][0]['dateCreated'], 1592981250); + $this->assertEquals($parsedResponse['teams'][0]['sum'], 7); + $this->assertEquals($parsedResponse['teams'][0]['$collection'], 'teams'); + $this->assertEquals($parsedResponse['teams'][0]['$permissions'], []); + + } + + public function testParseToken() + { + $content = [ + '$id' => 'bb8ea5c16897e', + 'userId' => '5e5ea5c168bb8', + 'secret' => '', + 'expire' => 1592981250 + ]; + + $model = Response::MODEL_TOKEN; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['$id'], 'bb8ea5c16897e'); + $this->assertEquals($parsedResponse['userId'], '5e5ea5c168bb8'); + $this->assertEquals($parsedResponse['expire'], 1592981250); + $this->assertEquals($parsedResponse['secret'], ''); + $this->assertEquals($parsedResponse['type'], Auth::TOKEN_TYPE_RECOVERY); + } + + public function testParseLocale() + { + $content = [ + 'ip' => '127.0.0.1', + 'countryCode' => 'US', + 'country' => 'United States', + 'continentCode' => 'NA', + 'continent' => 'North America', + 'eu' => false, + 'currency' => 'USD' + ]; + + $model = Response::MODEL_LOCALE; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['ip'], '127.0.0.1'); + $this->assertEquals($parsedResponse['countryCode'], 'US'); + $this->assertEquals($parsedResponse['country'], 'United States'); + $this->assertEquals($parsedResponse['continentCode'], 'NA'); + $this->assertEquals($parsedResponse['continent'], 'North America'); + $this->assertEquals($parsedResponse['eu'], false); + $this->assertEquals($parsedResponse['currency'], 'USD'); + } + + public function testParseCountryList() + { + $content = [ + 'sum' => 1, + 'countries' => [ + 0 => [ + 'name' => 'United States', + 'code' => 'US' + ] + ] + ]; + + $model = Response::MODEL_COUNTRY_LIST; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['sum'], 1); + $this->assertEquals($parsedResponse['countries']['US'], 'United States'); + } + + public function testParsePhoneList() + { + $content = [ + 'sum' => 1, + 'phones' => [ + 0 => [ + 'code' => '+1', + 'countryCode' => 'US', + 'countryName' => 'United States' + ] + ] + ]; + + $model = Response::MODEL_PHONE_LIST; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['sum'], 1); + $this->assertEquals($parsedResponse['phones']['US'], '+1'); + } + + public function testParseContinentList() + { + $content = [ + 'sum' => 1, + 'continents' => [ + 0 => [ + 'name' => 'Europe', + 'code' => 'EU', + ] + ] + ]; + + $model = Response::MODEL_CONTINENT_LIST; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['sum'], 1); + $this->assertEquals($parsedResponse['continents']['EU'], 'Europe'); + } + + public function testParseCurrencyList() + { + $content = [ + 'sum' => 1, + 'currencies' => [ + 0 => [ + 'symbol' => '$', + 'name' => 'US dollar', + 'symbolNative' => '$', + 'decimalDigits' => 2, + 'rounding' => 0, + 'code' => 'USD', + 'namePlural' => 'US Dollars' + ] + ] + ]; + + $model = Response::MODEL_CURRENCY_LIST; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['sum'], 1); + $this->assertEquals($parsedResponse['currencies'][0]['symbol'], '$'); + $this->assertEquals($parsedResponse['currencies'][0]['name'], 'US dollar'); + $this->assertEquals($parsedResponse['currencies'][0]['symbolNative'], '$'); + $this->assertEquals($parsedResponse['currencies'][0]['decimalDigits'], 2); + $this->assertEquals($parsedResponse['currencies'][0]['rounding'], 0); + $this->assertEquals($parsedResponse['currencies'][0]['code'], 'USD'); + $this->assertEquals($parsedResponse['currencies'][0]['namePlural'], 'US Dollars'); + $this->assertEquals($parsedResponse['currencies'][0]['locations'], []); + } + + public function testParseFile() + { + $content = [ + '$id' => '5e5ea5c16897e', + '$permissions' => ['read' => ['*'], 'write' => ['*']], + 'name' => 'Pink.png', + 'dateCreated' => 1592981250, + 'signature' => '5d529fd02b544198ae075bd57c1762bb', + 'mimeType' => 'image/png', + 'sizeOriginal' => 17890 + ]; + + $model = Response::MODEL_FILE; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['$id'], '5e5ea5c16897e'); + $this->assertEquals($parsedResponse['$permissions'], ['read' => ['*'], 'write' => ['*']]); + $this->assertEquals($parsedResponse['name'], 'Pink.png'); + $this->assertEquals($parsedResponse['dateCreated'], 1592981250); + $this->assertEquals($parsedResponse['signature'], '5d529fd02b544198ae075bd57c1762bb'); + $this->assertEquals($parsedResponse['mimeType'], 'image/png'); + $this->assertEquals($parsedResponse['sizeOriginal'], 17890); + $this->assertEquals($parsedResponse['$collection'], Database::SYSTEM_COLLECTION_FILES); + $this->assertEquals($parsedResponse['algorithm'], 'gzip'); + $this->assertEquals($parsedResponse['comment'], ''); + $this->assertEquals($parsedResponse['fileOpenSSLCipher'], OpenSSL::CIPHER_AES_128_GCM); + $this->assertEquals($parsedResponse['fileOpenSSLIV'], ''); + $this->assertEquals($parsedResponse['fileOpenSSLTag'], ''); + $this->assertEquals($parsedResponse['fileOpenSSLVersion'], ''); + $this->assertEquals($parsedResponse['folderId'], ''); + $this->assertEquals($parsedResponse['path'], ''); + $this->assertEquals($parsedResponse['sizeActual'], $content['sizeOriginal']); + $this->assertEquals($parsedResponse['token'], ''); + } + + public function testParseCollection() + { + $content = [ + '$id' => '5e5ea5c16897e', + '$permissions' => ['read' => ['*'], 'write' => ['*']], + 'name' => 'Movies', + 'dateCreated' => 1592981250, + 'dateUpdated' => '5d529fd02b544198ae075bd57c1762bb', + 'rules' => [] + ]; + + $model = Response::MODEL_COLLECTION; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['$id'], '5e5ea5c16897e'); + $this->assertEquals($parsedResponse['$permissions'], ['read' => ['*'], 'write' => ['*']]); + $this->assertEquals($parsedResponse['name'], 'Movies'); + $this->assertEquals($parsedResponse['dateCreated'], 1592981250); + $this->assertEquals($parsedResponse['dateUpdated'], '5d529fd02b544198ae075bd57c1762bb'); + $this->assertEquals($parsedResponse['rules'], []); + $this->assertEquals($parsedResponse['$collection'], Database::SYSTEM_COLLECTION_COLLECTIONS); + $this->assertEquals($parsedResponse['structure'], true); + } + + public function testParseCollectionList() + { + + $content = [ + 'sum' => 1, + 'collections' => [ + 0 => [ + '$id' => '5e5ea5c16897e', + '$permissions' => ['read' => ['*'], 'write' => ['*']], + 'name' => 'Movies', + 'dateCreated' => 1592981250, + 'dateUpdated' => '5d529fd02b544198ae075bd57c1762bb', + 'rules' => [] + ] + ] + ]; + + $model = Response::MODEL_COLLECTION_LIST; + $parsedResponse = $this->filter->parse($content, $model); + + $this->assertEquals($parsedResponse['sum'], 1); + $this->assertEquals($parsedResponse['collections'][0]['$id'], '5e5ea5c16897e'); + $this->assertEquals($parsedResponse['collections'][0]['$permissions'], ['read' => ['*'], 'write' => ['*']]); + $this->assertEquals($parsedResponse['collections'][0]['name'], 'Movies'); + $this->assertEquals($parsedResponse['collections'][0]['dateCreated'], 1592981250); + $this->assertEquals($parsedResponse['collections'][0]['dateUpdated'], '5d529fd02b544198ae075bd57c1762bb'); + $this->assertEquals($parsedResponse['collections'][0]['rules'], []); + $this->assertEquals($parsedResponse['collections'][0]['$collection'], Database::SYSTEM_COLLECTION_COLLECTIONS); + $this->assertEquals($parsedResponse['collections'][0]['structure'], true); + } +} \ No newline at end of file diff --git a/tests/unit/Utopia/ResponseTest.php b/tests/unit/Utopia/ResponseTest.php new file mode 100644 index 0000000000..20df14058a --- /dev/null +++ b/tests/unit/Utopia/ResponseTest.php @@ -0,0 +1,34 @@ +object = new Response(new SwooleResponse()); + } + + public function testSetFilter() + { + $this->assertEquals($this->object->isFilter(), false); + $this->assertEquals($this->object->getFilter(), null); + + $filter = new V06(); + $this->object->setFilter($filter); + + $this->assertEquals($this->object->isFilter(), true); + $this->assertEquals($this->object->getFilter(), $filter); + } +} \ No newline at end of file