From ac5bc22817a846b5f6b6df9ebf1e0684fbe21de8 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 4 Oct 2024 23:23:18 +0100 Subject: [PATCH] feat: ping endpoint --- app/config/collections.php | 22 ++++++++ app/controllers/general.php | 46 ++++++++++++++++ .../Utopia/Response/Model/Project.php | 12 ++++ tests/e2e/General/PingTest.php | 55 +++++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 tests/e2e/General/PingTest.php diff --git a/app/config/collections.php b/app/config/collections.php index 1eb286cf8f..4a19915b1b 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -4541,6 +4541,28 @@ $consoleCollections = array_merge([ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('pingCount'), + 'type' => Database::VAR_INTEGER, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => 0, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('pingedAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ] ], 'indexes' => [ [ diff --git a/app/controllers/general.php b/app/controllers/general.php index 04554a940e..7395a479a4 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -25,10 +25,12 @@ use Utopia\App; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; +use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Database\Validator\UID; use Utopia\Domains\Domain; use Utopia\DSN\DSN; use Utopia\Locale\Locale; @@ -1048,6 +1050,50 @@ App::get('/.well-known/acme-challenge/*') include_once __DIR__ . '/shared/api.php'; include_once __DIR__ . '/shared/api/auth.php'; +App::get('/v1/ping') + ->groups(['api', 'general']) + ->desc('Test the connection between the Appwrite and the SDK.') + ->label('scope', 'public') + ->label('event', 'projects.[projectId].ping') + ->param('projectId', '', new UID(), 'Project unique ID.') + ->inject('response') + ->inject('console') + ->inject('dbForConsole') + ->inject('queueForEvents') + ->action(function (string $projectId, Response $response, Document $project, Database $dbForConsole, Event $queueForEvents) { + if (empty($projectId) || $projectId === 'console') { + throw new AppwriteException(AppwriteException::PROJECT_NOT_FOUND); + } + + Console::log('Ping' . json_encode(['projectId' => $projectId], JSON_PRETTY_PRINT)); + + $project = Authorization::skip(function () use ($dbForConsole, $projectId) { + return $dbForConsole->getDocument('projects', $projectId); + }); + + if ($project->isEmpty()) { + Console::log('Ping' . json_encode($project, JSON_PRETTY_PRINT)); + throw new AppwriteException(AppwriteException::PROJECT_NOT_FOUND); + } + + $pingCount = $project->getAttribute('pingCount', 0) + 1; + $pingedAt = DateTime::now(); + + $project + ->setAttribute('pingCount', $pingCount) + ->setAttribute('pingedAt', $pingedAt); + + Authorization::skip(function () use ($dbForConsole, $project) { + $dbForConsole->updateDocument('projects', $project->getId(), $project); + }); + + $queueForEvents + ->setParam('projectId', $projectId) + ->setPayload($response->output($project, Response::MODEL_PROJECT)); + + $response->text('Pong!'); + }); + App::wildcard() ->groups(['api']) ->label('scope', 'global') diff --git a/src/Appwrite/Utopia/Response/Model/Project.php b/src/Appwrite/Utopia/Response/Model/Project.php index 80214aaa73..e1d0105587 100644 --- a/src/Appwrite/Utopia/Response/Model/Project.php +++ b/src/Appwrite/Utopia/Response/Model/Project.php @@ -234,6 +234,18 @@ class Project extends Model 'default' => '', 'example' => 'tls', ]) + ->addRule('pingCount', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Number of times the ping was received for this project.', + 'default' => 0, + 'example' => 1, + ]) + ->addRule('pingedAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Last ping datetime in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]) ; $services = Config::getParam('services', []); diff --git a/tests/e2e/General/PingTest.php b/tests/e2e/General/PingTest.php new file mode 100644 index 0000000000..c1199841fb --- /dev/null +++ b/tests/e2e/General/PingTest.php @@ -0,0 +1,55 @@ +client->call(Client::METHOD_GET, '/ping', [], [ + 'projectId' => $this->getProject()['$id'], + ]); + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Pong!', $response['body']); + + // With user session + $response = $this->client->call(Client::METHOD_GET, '/ping', $this->getHeaders(), [ + 'projectId' => $this->getProject()['$id'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Pong!', $response['body']); + + // With API key + $response = $this->client->call(Client::METHOD_GET, '/ping', [ + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'projectId' => $this->getProject()['$id'], + ]); + + /** + * Test for FAILURE + */ + // Fake project ID + $response = $this->client->call(Client::METHOD_GET, '/ping', \array_merge([ + 'origin' => 'http://localhost', + ]), [ + 'projectId' => 'fake-project-id', + ]); + + $this->assertEquals(404, $response['headers']['status-code']); + $this->assertNotContains('Pong!', $response['body']); + } +}