diff --git a/app/controllers/general.php b/app/controllers/general.php index 3f0886c445..b031ba3442 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -25,6 +25,7 @@ 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 Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\DateTime; @@ -107,8 +108,7 @@ function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleReques $headers = [ 'Content-Type: application/json', 'Content-Length: ' . \strlen($body), - 'X-Appwrite-Project: ' . $projectId, - 'Host: ' . $host, + 'X-Appwrite-Project: ' . $projectId ]; $ch = \curl_init(); @@ -310,6 +310,9 @@ App::init() case version_compare($responseFormat, '0.15.3', '<='): Response::setFilter(new ResponseV15()); break; + case version_compare($responseFormat, '1.4.0', '<'): + Response::setFilter(new ResponseV16()); + break; default: Response::setFilter(null); } diff --git a/src/Appwrite/Utopia/Response/Filters/V16.php b/src/Appwrite/Utopia/Response/Filters/V16.php new file mode 100644 index 0000000000..6943bd8f4d --- /dev/null +++ b/src/Appwrite/Utopia/Response/Filters/V16.php @@ -0,0 +1,109 @@ +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; + } + + return $parsedResponse; + } + + protected function parseDeployment(array $content) + { + $content['buildStderr'] = ''; + $content['buildStdout'] = $content['buildLogs']; + unset($content['buildLogs']); + return $content; + } + + protected function parseExecution(array $content) + { + if (isset($content['responseStatusCode'])) { + $content['statusCode'] = $content['responseStatusCode']; + unset($content['responseStatusCode']); + } + + if (isset($content['responseBody'])) { + $content['response'] = $content['responseBody']; + unset($content['responseBody']); + } + + if (isset($content['logs'])) { + $content['stdout'] = $content['logs']; + unset($content['logs']); + } + + if (isset($content['errors'])) { + $content['stderr'] = $content['errors']; + unset($content['errors']); + } + + return $content; + } + + protected function parseFunction(array $content) + { + $content['schedulePrevious'] = ''; + $content['scheduleNext'] = ''; + + if (!empty($content['schedule'])) { + $cron = new CronExpression($content['schedule']); + $content['schedulePrevious'] = DateTime::formatTz(DateTime::format($cron->getPreviousRunDate())); + $content['scheduleNext'] = DateTime::formatTz(DateTime::format($cron->getNextRunDate())); + } + + return $content; + } + + protected function parseProject(array $content) + { + foreach ($content['providers'] ?? [] as $i => $provider) { + $content['providers'][$i]['name'] = \ucfirst($provider['key']); + unset($content['providers'][$i]['key']); + } + + $content['domains'] = []; + return $content; + } + + protected function parseVariable(array $content) + { + if (isset($content['resourceId'])) { + $content['functionId'] = $content['resourceId']; + unset($content['resourceId']); + } + + return $content; + } +} diff --git a/tests/unit/Utopia/Response/Filters/V16Test.php b/tests/unit/Utopia/Response/Filters/V16Test.php new file mode 100644 index 0000000000..fba3b69535 --- /dev/null +++ b/tests/unit/Utopia/Response/Filters/V16Test.php @@ -0,0 +1,228 @@ +filter = new V16(); + } + + public function tearDown(): void + { + } + + public function deploymentProvider(): array + { + return [ + 'buildStdout and buildStderr' => [ + [ + 'buildLogs' => 'Compiling source files...', + ], + [ + 'buildStdout' => 'Compiling source files...', + 'buildStderr' => '', + ], + ], + ]; + } + + /** + * @dataProvider deploymentProvider + */ + public function testDeployment(array $content, array $expected): void + { + $model = Response::MODEL_DEPLOYMENT; + + $result = $this->filter->parse($content, $model); + + $this->assertEquals($expected, $result); + } + + public function executionProvider(): array + { + return [ + 'statusCode' => [ + [ + 'responseStatusCode' => 200, + ], + [ + 'statusCode' => 200, + ], + ], + 'response' => [ + [ + 'responseBody' => 'Sample response.', + ], + [ + 'response' => 'Sample response.', + ], + ], + 'stdout' => [ + [ + 'logs' => 'Sample log.', + ], + [ + 'stdout' => 'Sample log.', + ], + ], + 'stderr' => [ + [ + 'errors' => 'Sample error.', + ], + [ + 'stderr' => 'Sample error.', + ], + ], + ]; + } + + /** + * @dataProvider executionProvider + */ + public function testExecution(array $content, array $expected): void + { + $model = Response::MODEL_EXECUTION; + + $result = $this->filter->parse($content, $model); + + $this->assertEquals($expected, $result); + } + + public function functionProvider(): array + { + return [ + 'empty schedule' => [ + [ + 'schedule' => '', + ], + [ + 'schedule' => '', + 'schedulePrevious' => '', + 'scheduleNext' => '', + ], + ], + ]; + } + + /** + * @dataProvider functionProvider + */ + public function testFunction(array $content, array $expected): void + { + $model = Response::MODEL_FUNCTION; + + $result = $this->filter->parse($content, $model); + + $this->assertEquals($expected, $result); + } + + public function testFunctionSchedulePreviousScheduleNext(): void + { + $model = Response::MODEL_FUNCTION; + + $content = [ + 'schedule' => '0 * * * *', + ]; + + $cron = new CronExpression($content['schedule']); + + $expected = [ + 'schedule' => '0 * * * *', + 'scheduleNext' => DateTime::formatTz(DateTime::format($cron->getNextRunDate())), + 'schedulePrevious' => DateTime::formatTz(DateTime::format($cron->getPreviousRunDate())), + ]; + + $result = $this->filter->parse($content, $model); + + $this->assertEquals($expected, $result); + } + + public function projectProvider(): array + { + return [ + 'providers' => [ + [ + 'providers' => [ + [ + 'key' => 'github', + 'name' => 'GitHub', + 'appId' => 'client_id', + 'secret' => 'client_secret', + 'enabled' => true, + ], + ], + ], + [ + 'providers' => [ + [ + 'name' => 'Github', + 'appId' => 'client_id', + 'secret' => 'client_secret', + 'enabled' => true, + ], + ], + 'domains' => [], + ], + ], + 'domains' => [ + [ + ], + [ + 'domains' => [], + ], + ], + ]; + } + + /** + * @dataProvider projectProvider + */ + public function testProject(array $content, array $expected): void + { + $model = Response::MODEL_PROJECT; + + $result = $this->filter->parse($content, $model); + + $this->assertEquals($expected, $result); + } + + public function variableProvider(): array + { + return [ + 'functionId' => [ + [ + 'resourceId' => '5e5ea5c16897e', + ], + [ + 'functionId' => '5e5ea5c16897e', + ], + ], + ]; + } + + /** + * @dataProvider variableProvider + */ + public function testVariable(array $content, array $expected): void + { + $model = Response::MODEL_VARIABLE; + + $result = $this->filter->parse($content, $model); + + $this->assertEquals($expected, $result); + } +}