mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
New services and protocols tests
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\E2E\Services\Project;
|
||||
|
||||
use Tests\E2E\Client;
|
||||
|
||||
trait ProtocolsBase
|
||||
{
|
||||
protected static array $protocols = ['rest', 'graphql', 'websocket'];
|
||||
|
||||
// Success flow
|
||||
|
||||
public function testDisableProtocol(): void
|
||||
{
|
||||
foreach (self::$protocols as $protocol) {
|
||||
$response = $this->updateProtocolStatus($protocol, false);
|
||||
|
||||
$this->assertSame(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertSame(false, $response['body']['protocolStatusFor' . ucfirst($protocol)]);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
foreach (self::$protocols as $protocol) {
|
||||
$this->updateProtocolStatus($protocol, true);
|
||||
}
|
||||
}
|
||||
|
||||
public function testEnableProtocol(): void
|
||||
{
|
||||
// Disable first
|
||||
foreach (self::$protocols as $protocol) {
|
||||
$this->updateProtocolStatus($protocol, false);
|
||||
}
|
||||
|
||||
// Re-enable
|
||||
foreach (self::$protocols as $protocol) {
|
||||
$response = $this->updateProtocolStatus($protocol, true);
|
||||
|
||||
$this->assertSame(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertSame(true, $response['body']['protocolStatusFor' . ucfirst($protocol)]);
|
||||
}
|
||||
}
|
||||
|
||||
public function testDisableProtocolIdempotent(): void
|
||||
{
|
||||
$first = $this->updateProtocolStatus('rest', false);
|
||||
$this->assertSame(200, $first['headers']['status-code']);
|
||||
$this->assertSame(false, $first['body']['protocolStatusForRest']);
|
||||
|
||||
$second = $this->updateProtocolStatus('rest', false);
|
||||
$this->assertSame(200, $second['headers']['status-code']);
|
||||
$this->assertSame(false, $second['body']['protocolStatusForRest']);
|
||||
|
||||
// Cleanup
|
||||
$this->updateProtocolStatus('rest', true);
|
||||
}
|
||||
|
||||
public function testEnableProtocolIdempotent(): void
|
||||
{
|
||||
$first = $this->updateProtocolStatus('rest', true);
|
||||
$this->assertSame(200, $first['headers']['status-code']);
|
||||
$this->assertSame(true, $first['body']['protocolStatusForRest']);
|
||||
|
||||
$second = $this->updateProtocolStatus('rest', true);
|
||||
$this->assertSame(200, $second['headers']['status-code']);
|
||||
$this->assertSame(true, $second['body']['protocolStatusForRest']);
|
||||
}
|
||||
|
||||
public function testDisabledRestBlocksClientRequest(): void
|
||||
{
|
||||
$this->updateProtocolStatus('rest', false);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/teams', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
]);
|
||||
|
||||
$this->assertSame(403, $response['headers']['status-code']);
|
||||
$this->assertSame('general_api_disabled', $response['body']['type']);
|
||||
|
||||
// Cleanup
|
||||
$this->updateProtocolStatus('rest', true);
|
||||
}
|
||||
|
||||
public function testEnabledRestAllowsClientRequest(): void
|
||||
{
|
||||
$this->updateProtocolStatus('rest', false);
|
||||
$this->updateProtocolStatus('rest', true);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertSame(200, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testDisabledGraphqlBlocksClientRequest(): void
|
||||
{
|
||||
$this->updateProtocolStatus('graphql', false);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, '/graphql', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'query' => '{ localeListCountries { total } }',
|
||||
]);
|
||||
|
||||
$this->assertSame(403, $response['headers']['status-code']);
|
||||
$this->assertSame('general_api_disabled', $response['body']['type']);
|
||||
|
||||
// Cleanup
|
||||
$this->updateProtocolStatus('graphql', true);
|
||||
}
|
||||
|
||||
public function testDisableOneProtocolDoesNotAffectOther(): void
|
||||
{
|
||||
$this->updateProtocolStatus('graphql', false);
|
||||
|
||||
// REST should still work
|
||||
$response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertSame(200, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->updateProtocolStatus('graphql', true);
|
||||
}
|
||||
|
||||
public function testResponseModel(): void
|
||||
{
|
||||
$response = $this->updateProtocolStatus('rest', false);
|
||||
|
||||
$this->assertSame(200, $response['headers']['status-code']);
|
||||
$this->assertArrayHasKey('$id', $response['body']);
|
||||
$this->assertArrayHasKey('name', $response['body']);
|
||||
$this->assertArrayHasKey('protocolStatusForRest', $response['body']);
|
||||
$this->assertArrayHasKey('protocolStatusForGraphql', $response['body']);
|
||||
$this->assertArrayHasKey('protocolStatusForWebsocket', $response['body']);
|
||||
|
||||
// Cleanup
|
||||
$this->updateProtocolStatus('rest', true);
|
||||
}
|
||||
|
||||
// Failure flow
|
||||
|
||||
public function testUpdateProtocolWithoutAuthentication(): void
|
||||
{
|
||||
$response = $this->updateProtocolStatus('rest', false, false);
|
||||
|
||||
$this->assertSame(401, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testUpdateProtocolInvalidProtocolId(): void
|
||||
{
|
||||
$response = $this->updateProtocolStatus('invalid', false);
|
||||
|
||||
$this->assertSame(400, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testUpdateProtocolEmptyProtocolId(): void
|
||||
{
|
||||
$response = $this->updateProtocolStatus('', false);
|
||||
|
||||
$this->assertSame(400, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
protected function updateProtocolStatus(string $protocolId, bool $enabled, bool $authenticated = true): mixed
|
||||
{
|
||||
$headers = [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
];
|
||||
|
||||
if ($authenticated) {
|
||||
$headers = array_merge($headers, $this->getHeaders());
|
||||
}
|
||||
|
||||
return $this->client->call(Client::METHOD_PUT, '/project/protocols/' . $protocolId . '/status', $headers, [
|
||||
'enabled' => $enabled,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\E2E\Services\Project;
|
||||
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideConsole;
|
||||
|
||||
class ProtocolsConsoleClientTest extends Scope
|
||||
{
|
||||
use ProtocolsBase;
|
||||
use ProjectCustom;
|
||||
use SideConsole;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\E2E\Services\Project;
|
||||
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideServer;
|
||||
|
||||
class ProtocolsCustomServerTest extends Scope
|
||||
{
|
||||
use ProtocolsBase;
|
||||
use ProjectCustom;
|
||||
use SideServer;
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\E2E\Services\Project;
|
||||
|
||||
use Tests\E2E\Client;
|
||||
|
||||
trait ServicesBase
|
||||
{
|
||||
/**
|
||||
* Optional services that can be toggled.
|
||||
*/
|
||||
protected static array $optionalServices = [
|
||||
'account',
|
||||
'avatars',
|
||||
'databases',
|
||||
'tablesdb',
|
||||
'locale',
|
||||
'health',
|
||||
'project',
|
||||
'storage',
|
||||
'teams',
|
||||
'users',
|
||||
'vcs',
|
||||
'sites',
|
||||
'functions',
|
||||
'proxy',
|
||||
'graphql',
|
||||
'migrations',
|
||||
'messaging',
|
||||
];
|
||||
|
||||
// Success flow
|
||||
|
||||
public function testDisableService(): void
|
||||
{
|
||||
foreach (self::$optionalServices as $service) {
|
||||
$response = $this->updateServiceStatus($service, false);
|
||||
|
||||
$this->assertSame(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertSame(false, $response['body']['serviceStatusFor' . ucfirst($service)]);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
foreach (self::$optionalServices as $service) {
|
||||
$this->updateServiceStatus($service, true);
|
||||
}
|
||||
}
|
||||
|
||||
public function testEnableService(): void
|
||||
{
|
||||
// Disable first
|
||||
foreach (self::$optionalServices as $service) {
|
||||
$this->updateServiceStatus($service, false);
|
||||
}
|
||||
|
||||
// Re-enable
|
||||
foreach (self::$optionalServices as $service) {
|
||||
$response = $this->updateServiceStatus($service, true);
|
||||
|
||||
$this->assertSame(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertSame(true, $response['body']['serviceStatusFor' . ucfirst($service)]);
|
||||
}
|
||||
}
|
||||
|
||||
public function testDisableServiceIdempotent(): void
|
||||
{
|
||||
$first = $this->updateServiceStatus('teams', false);
|
||||
$this->assertSame(200, $first['headers']['status-code']);
|
||||
$this->assertSame(false, $first['body']['serviceStatusForTeams']);
|
||||
|
||||
$second = $this->updateServiceStatus('teams', false);
|
||||
$this->assertSame(200, $second['headers']['status-code']);
|
||||
$this->assertSame(false, $second['body']['serviceStatusForTeams']);
|
||||
|
||||
// Cleanup
|
||||
$this->updateServiceStatus('teams', true);
|
||||
}
|
||||
|
||||
public function testEnableServiceIdempotent(): void
|
||||
{
|
||||
$first = $this->updateServiceStatus('teams', true);
|
||||
$this->assertSame(200, $first['headers']['status-code']);
|
||||
$this->assertSame(true, $first['body']['serviceStatusForTeams']);
|
||||
|
||||
$second = $this->updateServiceStatus('teams', true);
|
||||
$this->assertSame(200, $second['headers']['status-code']);
|
||||
$this->assertSame(true, $second['body']['serviceStatusForTeams']);
|
||||
}
|
||||
|
||||
public function testDisabledServiceBlocksClientRequest(): void
|
||||
{
|
||||
$this->updateServiceStatus('teams', false);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/teams', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
]);
|
||||
|
||||
$this->assertSame(403, $response['headers']['status-code']);
|
||||
$this->assertSame('general_service_disabled', $response['body']['type']);
|
||||
|
||||
// Cleanup
|
||||
$this->updateServiceStatus('teams', true);
|
||||
}
|
||||
|
||||
public function testEnabledServiceAllowsClientRequest(): void
|
||||
{
|
||||
$this->updateServiceStatus('teams', false);
|
||||
$this->updateServiceStatus('teams', true);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertSame(200, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testDisableOneServiceDoesNotAffectOther(): void
|
||||
{
|
||||
$this->updateServiceStatus('teams', false);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertSame(200, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->updateServiceStatus('teams', true);
|
||||
}
|
||||
|
||||
public function testResponseModel(): void
|
||||
{
|
||||
$response = $this->updateServiceStatus('teams', false);
|
||||
|
||||
$this->assertSame(200, $response['headers']['status-code']);
|
||||
$this->assertArrayHasKey('$id', $response['body']);
|
||||
$this->assertArrayHasKey('name', $response['body']);
|
||||
$this->assertArrayHasKey('serviceStatusForTeams', $response['body']);
|
||||
|
||||
// Cleanup
|
||||
$this->updateServiceStatus('teams', true);
|
||||
}
|
||||
|
||||
// Failure flow
|
||||
|
||||
public function testUpdateServiceWithoutAuthentication(): void
|
||||
{
|
||||
$response = $this->updateServiceStatus('teams', false, false);
|
||||
|
||||
$this->assertSame(401, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testUpdateServiceInvalidServiceId(): void
|
||||
{
|
||||
$response = $this->updateServiceStatus('invalid', false);
|
||||
|
||||
$this->assertSame(400, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testUpdateServiceEmptyServiceId(): void
|
||||
{
|
||||
$response = $this->updateServiceStatus('', false);
|
||||
|
||||
$this->assertSame(400, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
protected function updateServiceStatus(string $serviceId, bool $enabled, bool $authenticated = true): mixed
|
||||
{
|
||||
$headers = [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
];
|
||||
|
||||
if ($authenticated) {
|
||||
$headers = array_merge($headers, $this->getHeaders());
|
||||
}
|
||||
|
||||
return $this->client->call(Client::METHOD_PUT, '/project/services/' . $serviceId . '/status', $headers, [
|
||||
'enabled' => $enabled,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\E2E\Services\Project;
|
||||
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideConsole;
|
||||
|
||||
class ServicesConsoleClientTest extends Scope
|
||||
{
|
||||
use ServicesBase;
|
||||
use ProjectCustom;
|
||||
use SideConsole;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\E2E\Services\Project;
|
||||
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideServer;
|
||||
|
||||
class ServicesCustomServerTest extends Scope
|
||||
{
|
||||
use ServicesBase;
|
||||
use ProjectCustom;
|
||||
use SideServer;
|
||||
}
|
||||
Reference in New Issue
Block a user