From 71206a98864fd95349c0e5024fb0428a9c4891d3 Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Sat, 10 Sep 2022 01:00:20 +0000 Subject: [PATCH] Update V15 response filter and add tests --- src/Appwrite/Utopia/Response/Filters/V15.php | 262 +++-- src/Appwrite/Utopia/Response/Model/Metric.php | 11 +- tests/unit/Utopia/Request/Filters/V15Test.php | 2 +- .../unit/Utopia/Response/Filters/V15Test.php | 912 ++++++++++++++++++ 4 files changed, 1089 insertions(+), 98 deletions(-) create mode 100644 tests/unit/Utopia/Response/Filters/V15Test.php diff --git a/src/Appwrite/Utopia/Response/Filters/V15.php b/src/Appwrite/Utopia/Response/Filters/V15.php index 57c8bce4ca..f28200d388 100644 --- a/src/Appwrite/Utopia/Response/Filters/V15.php +++ b/src/Appwrite/Utopia/Response/Filters/V15.php @@ -4,7 +4,9 @@ namespace Appwrite\Utopia\Response\Filters; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Filter; +use Utopia\Database\Database; use Utopia\Database\Permission; +use Utopia\Database\Role; class V15 extends Filter { @@ -14,26 +16,28 @@ class V15 extends Filter $parsedResponse = $content; switch ($model) { + case Response::MODEL_ACCOUNT: case Response::MODEL_USER: - $parsedResponse = $this->handleDatetimeAttributes($content, ['$createdAt', '$updatedAt', 'registration', 'passwordUpdate']); - $parsedResponse = $this->handleUser($parsedResponse); + $parsedResponse = $this->parseUser($parsedResponse); break; case Response::MODEL_METRIC: - $parsedResponse = $this->handleMetricAttributes($content); + $parsedResponse = $this->parseMetric($parsedResponse); break; case Response::MODEL_BUILD: - $parsedResponse = $this->handleDatetimeAttributes($content, ['startTime', 'endTime']); + $parsedResponse = $this->parseDatetimeAttributes($parsedResponse, ['startTime', 'endTime']); break; case Response::MODEL_BUCKET: - $parsedResponse = $this->handleBucketAttributes($content); + $parsedResponse = $this->parseBucket($parsedResponse); break; case Response::MODEL_COLLECTION: - $parsedResponse = $this->handleCollectionAttributes($content); + $parsedResponse = $this->parseCollection($parsedResponse); break; case Response::MODEL_DEPLOYMENT: case Response::MODEL_DOCUMENT: + $parsedResponse = $this->parseDatetimeAttributes($parsedResponse, ['$createdAt', '$updatedAt']); + break; case Response::MODEL_EXECUTION: - $parsedResponse = $this->handleExecutionAttributes($content); + $parsedResponse = $this->parseExecution($parsedResponse); break; case Response::MODEL_PLATFORM: case Response::MODEL_PROJECT: @@ -42,51 +46,62 @@ class V15 extends Filter case Response::MODEL_WEBHOOK: case Response::MODEL_DOMAIN: case Response::MODEL_DATABASE: - $parsedResponse = $this->handleDatetimeAttributes($content, ['$createdAt', '$updatedAt']); + $parsedResponse = $this->parseDatetimeAttributes($parsedResponse, ['$createdAt', '$updatedAt']); break; case Response::MODEL_FUNCTION: - $parsedResponse = $this->handleFunctionAttribtues($content); + $parsedResponse = $this->parseFunction($parsedResponse); break; case Response::MODEL_KEY: - $parsedResponse = $this->handleDatetimeAttributes($content, ['$createdAt', '$updatedAt', 'expire']); + $parsedResponse = $this->parseDatetimeAttributes($parsedResponse, ['$createdAt', '$updatedAt', 'expire']); break; case Response::MODEL_LOG: - $parsedResponse = $this->handleDatetimeAttributes($content, ['$createdAt', '$updatedAt', 'time']); + $parsedResponse = $this->parseDatetimeAttributes($parsedResponse, ['$createdAt', '$updatedAt', 'time']); break; case Response::MODEL_MEMBERSHIP: - $parsedResponse = $this->handleDatetimeAttributes($content, ['$createdAt', '$updatedAt', 'invited', 'joined']); + $parsedResponse = $this->parseDatetimeAttributes($parsedResponse, ['$createdAt', '$updatedAt', 'invited', 'joined']); break; case Response::MODEL_SESSION: - $parsedResponse = $this->handleDatetimeAttributes($content, ['$createdAt', 'expire', 'providerAccessTokenExpiry']); + $parsedResponse = $this->parseDatetimeAttributes($parsedResponse, ['$createdAt', 'expire', 'providerAccessTokenExpiry']); break; case Response::MODEL_TOKEN: - $parsedResponse = $this->handleDatetimeAttributes($content, ['$createdAt', 'expire']); + $parsedResponse = $this->parseDatetimeAttributes($parsedResponse, ['$createdAt', 'expire']); break; case Response::MODEL_USAGE_FUNCTIONS: - $parsedResponse = $this->handleModelUsageFuncAttributes($content); + $parsedResponse = $this->parseModelUsageFunc($parsedResponse); + break; + case Response::MODEL_USAGE_PROJECT: + $parsedResponse = $this->parseUsageProject($parsedResponse); + break; + case Response::MODEL_USAGE_STORAGE: + $parsedResponse = $this->parseUsageStorage($parsedResponse); + break; } // Downgrade Permissions for all models - $parsedResponse = $this->handleDowngradePermissions($parsedResponse); + $parsedResponse = $this->parsePermissions($parsedResponse); return $parsedResponse; } - protected function handleBucketAttributes(array $content) + protected function parseBucket(array $content) { - if ($content['fileSecurity']) { - $content['permssion'] = 'file'; - } else { - $content['permssion'] = 'bucket'; + if (isset($content['fileSecurity'])) { + if ($content['fileSecurity']) { + $content['permission'] = 'file'; + } else { + $content['permission'] = 'bucket'; + } } unset($content['fileSecurity']); unset($content['compression']); - $content = $this->handleDatetimeAttributes($content, ['$createdAt', '$updatedAt']); + $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt']); + + return $content; } - protected function handleDatetimeAttributes(array $content, array $attributes): array + protected function parseDatetimeAttributes(array $content, array $attributes): array { foreach ($attributes as $attribute) { if (isset($content[$attribute])) { @@ -96,117 +111,141 @@ class V15 extends Filter return $content; } - protected function handleUser(array $content): array + protected function parseUser(array $content): array { unset($content['password']); unset($content['hash']); unset($content['hashOptions']); - $content = $this->handleDatetimeAttributes($content, ['registration', 'passwordUpdate', '$createdAt', '$updatedAt']); + $content = $this->parseDatetimeAttributes($content, ['registration', 'passwordUpdate', '$createdAt', '$updatedAt']); return $content; } - protected function handleMetricAttributes(array $content) + protected function parseMetric(array $content) { - $content['timestamp'] = $content['date']; - unset($content['date']); + $content = $this->parseDatetimeAttributes($content, ['date']); + return $content; } - protected function handleDowngradePermissions(array $content) + protected function parsePermissions(array $content) { if (!isset($content['$permissions'])) { return $content; } - $content = array_merge($content, $this->downgradePermissions($content['permissions'])); - unset($content['permissions']); - return $content; - } - protected function downgradePermissionSelector(string $permSelector) - { - switch ($permSelector) { - case 'any': - return 'role:all'; - case 'users': - return 'role:user'; - case 'guests': - return 'role:guest'; - } - - return $permSelector; - } - - protected function downgradePermissions(array $model) - { - if (!isset($model['$permissions'])) { - return $model; - } - - $permissions = $model['$permissions']; - - $result = [ - '$read' => [], - '$write' => [] - ]; + $read = []; + $write = []; // downgrade the permissions - foreach ($permissions as $permission) { + foreach ($content['$permissions'] as $permission) { $permission = Permission::parse($permission); - // permission = "read('any')" = ["$read" => "role:all"] + $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 'update': - case 'delete': - case 'write': - case 'create': - if (!in_array($this->downgradePermissionSelector($permission_value), $result['write'])) { - $result['$write'][] = $this->downgradePermissionSelector($permission_value); - } + case Database::PERMISSION_UPDATE: + case Database::PERMISSION_DELETE: + case Database::PERMISSION_WRITE: + case Database::PERMISSION_CREATE: + $write[$this->parseRole($permission_value)] = true; break; - case 'read': - if (!in_array($this->downgradePermissionSelector($permission_value), $result['read'])) { - $result['$read'][] = $this->downgradePermissionSelector($permission_value); - } + case Database::PERMISSION_READ: + $read[$this->parseRole($permission_value)] = true; break; } } - unset($model['$permissions']); - return array_merge($model, $result); + $content['$read'] = array_keys($read); + $content['$write'] = array_keys($write); + + unset($content['$permissions']); + + return $content; } - protected function handleCollectionAttributes(array $content) + protected function parseRole(string $role) { - $content['permission'] = $content['documentSecurity']; + 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->handleDatetimeAttributes($content, ['$createdAt', '$updatedAt']); + $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt']); return $content; } - private function handleExecutionAttributes($content) + private function parseExecution($content) { unset($content['stdout']); - - $content = $this->handleDatetimeAttributes($content, ['$createdAt', '$updatedAt']); + $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt', 'startTime', 'endTime']); return $content; } - private function handleFunctionAttribtues($content) + private function parseFunction($content) { - $content['execute'] = array_map($this->downgradePermissionSelector, $content['execute']); + if (isset($content['execute'])) { + foreach ($content['execute'] as $i => $role) { + $content['execute'][$i] = $this->parseRole($role); + } + } - $content = $this->handleDatetimeAttributes($content, ['$createdAt', '$updatedAt', 'scheduleNext', 'schedulePrevious']); + if (isset($content['vars'])) { + $vars = []; + foreach ($content['vars'] as $i => $var) { + $vars[$var['key']] = $var['value']; + } + $content['vars'] = $vars; + } + + $content = $this->parseDatetimeAttributes($content, ['$createdAt', '$updatedAt', 'scheduleNext', 'schedulePrevious']); return $content; } - private function handleModelUsageFuncAttributes($content) + private function parseModelUsageFunc($content) { - $content['functiosnExecutions'] = $content['executionsTotal']; - $content['functionsFailures'] = $content['executionsFailure']; - $content['functionsCompute'] = $content['executionsTime']; + $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']); @@ -219,18 +258,59 @@ class V15 extends Filter return $content; } - private function handleUsageProjectAttributes($content) + private function parseUsageProject($content) { $content['functions'] = $content['executions']; unset($content['executions']); + $usage = [ + 'collections', + 'documents', + 'functions', + 'network', + 'requests', + 'storage', + 'users', + ]; + + foreach ($usage as $name) { + $data = []; + foreach ($content[$name] as $metric) { + $data[] = $this->parseMetric($metric); + } + $content[$name] = $data; + } + return $content; } - private function handleUsageStorageAttribtues($content) + private function parseUsageStorage($content) { $content['filesStorage'] = $content['storage']; - $content['tagsStorage'] = []; unset($content['storage']); + + $usage = [ + 'bucketsCount', + 'bucketsCreate', + 'bucketsDelete', + 'bucketsRead', + 'bucketsUpdate', + 'filesCount', + 'filesCreate', + 'filesDelete', + 'filesRead', + 'filesStorage', + 'filesUpdate', + ]; + + foreach ($usage as $name) { + $data = []; + foreach ($content[$name] as $metric) { + $data[] = $this->parseMetric($metric); + } + $content[$name] = $data; + } + + return $content; } } diff --git a/src/Appwrite/Utopia/Response/Model/Metric.php b/src/Appwrite/Utopia/Response/Model/Metric.php index 7fb1b98386..16cf7f7df2 100644 --- a/src/Appwrite/Utopia/Response/Model/Metric.php +++ b/src/Appwrite/Utopia/Response/Model/Metric.php @@ -17,12 +17,11 @@ class Metric extends Model 'example' => 1, ]) ->addRule('date', [ - 'type' => self::TYPE_INTEGER, - 'description' => 'The UNIX timestamp at which this metric was aggregated.', - 'default' => 0, - 'example' => 1592981250 - ]) - ; + 'type' => self::TYPE_DATETIME, + 'description' => 'The date at which this metric was aggregated in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE + ]); } /** diff --git a/tests/unit/Utopia/Request/Filters/V15Test.php b/tests/unit/Utopia/Request/Filters/V15Test.php index 28bdda3911..1617c2b0c5 100644 --- a/tests/unit/Utopia/Request/Filters/V15Test.php +++ b/tests/unit/Utopia/Request/Filters/V15Test.php @@ -1,6 +1,6 @@ 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); + } + + 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); + } + + 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 + */ + 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 testDeployment(array $content, array $expected): void + { + $model = Response::MODEL_DEPLOYMENT; + + $result = $this->filter->parse($content, $model); + + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider createdAtUpdatedAtProvider + * @dataProvider permissionsProvider + */ + public function testDocument(array $content, array $expected): void + { + $model = Response::MODEL_DOCUMENT; + + $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); + } + + public function executionProvider(): array + { + return [ + 'basic execution' => [ + ['stdout' => ''], + [], + ], + ]; + } + + /** + * @dataProvider createdAtUpdatedAtProvider + * @dataProvider permissionsProvider + * @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 permissionsProvider + */ + public function testFile(array $content, array $expected): void + { + $model = Response::MODEL_FILE; + + $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', + 'status' => 'enabled', + '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 + ], + ], + ]; + } + + /** + * @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); + } + + 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); + } + + public function logProvider(): array + { + return [ + 'basic log' => [ + ['time' => '2020-06-24T06:47:30.000Z'], + ['time' => 1592981250], + ], + ]; + } + + /** + * @dataProvider createdAtUpdatedAtProvider + * @dataProvider logProvider + */ + public function testLog(array $content, array $expected): void + { + $model = Response::MODEL_LOG; + + $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); + } + + 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 testProject(array $content, array $expected): void + { + $model = Response::MODEL_PROJECT; + + $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, + ], + ], + ]; + } + + /** + * @dataProvider sessionProvider + */ + public function testSession(array $content, array $expected): void + { + $model = Response::MODEL_SESSION; + + $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); + } + + 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 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); + } +}