2021-12-06 12:03:12 +00:00
< ? php
namespace Tests\E2E\Services\Realtime ;
use Tests\E2E\Client ;
use Tests\E2E\Scopes\ProjectCustom ;
2024-03-06 17:34:21 +00:00
use Tests\E2E\Scopes\Scope ;
2021-12-06 12:03:12 +00:00
use Tests\E2E\Scopes\SideConsole ;
2022-10-25 19:16:05 +00:00
use Tests\E2E\Services\Functions\FunctionsBase ;
2023-02-05 20:07:46 +00:00
use Utopia\Database\Helpers\ID ;
use Utopia\Database\Helpers\Permission ;
use Utopia\Database\Helpers\Role ;
2021-12-06 12:03:12 +00:00
class RealtimeConsoleClientTest extends Scope
{
2022-10-25 19:16:05 +00:00
use FunctionsBase ;
2021-12-06 12:03:12 +00:00
use RealtimeBase ;
use ProjectCustom ;
use SideConsole ;
2026-02-05 15:28:12 +00:00
/**
* Helper to create database + collection with a string attribute .
* Used by tests that need an existing collection setup .
*/
protected function createCollectionWithAttribute () : array
{
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'databaseId' => ID :: unique (),
'name' => 'Actors DB' ,
]);
$databaseId = $database [ 'body' ][ '$id' ];
$actors = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'collectionId' => ID :: unique (),
'name' => 'Actors' ,
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: create ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
],
]);
$actorsId = $actors [ 'body' ][ '$id' ];
// Create attribute and wait for it to be available
$this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $actorsId . '/attributes/string' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'key' => 'name' ,
'size' => 256 ,
'required' => true ,
]);
// Wait for attribute to be available
2026-02-09 07:42:15 +00:00
$this -> assertEventually ( function () use ( $databaseId , $actorsId ) {
$attribute = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $actorsId . '/attributes/name' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $attribute [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'available' , $attribute [ 'body' ][ 'status' ]);
2026-02-24 01:00:07 +00:00
}, 120000 , 500 );
2026-02-05 15:28:12 +00:00
return [ 'actorsId' => $actorsId , 'databaseId' => $databaseId ];
}
/**
2026-02-05 15:46:59 +00:00
* Helper to create database + table with a string column ( for TablesDB ) .
2026-02-05 15:28:12 +00:00
*/
protected function createTableWithAttribute () : array
{
2026-02-05 15:46:59 +00:00
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
2026-02-05 15:28:12 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'databaseId' => ID :: unique (),
'name' => 'Actors Tables DB' ,
]);
2026-02-09 08:26:16 +00:00
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ], 'Database creation failed: ' . json_encode ( $database [ 'body' ]));
2026-02-05 15:28:12 +00:00
$databaseId = $database [ 'body' ][ '$id' ];
$actors = $this -> client -> call ( Client :: METHOD_POST , '/tablesdb/' . $databaseId . '/tables' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'tableId' => ID :: unique (),
'name' => 'Actors' ,
]);
2026-02-09 08:26:16 +00:00
$this -> assertEquals ( 201 , $actors [ 'headers' ][ 'status-code' ], 'Table creation failed: ' . json_encode ( $actors [ 'body' ]));
2026-02-05 15:28:12 +00:00
$actorsId = $actors [ 'body' ][ '$id' ];
2026-02-05 15:46:59 +00:00
// Create column and wait for it to be available
2026-02-09 08:26:16 +00:00
$column = $this -> client -> call ( Client :: METHOD_POST , '/tablesdb/' . $databaseId . '/tables/' . $actorsId . '/columns/string' , array_merge ([
2026-02-05 15:28:12 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'key' => 'name' ,
'size' => 256 ,
'required' => true ,
]);
2026-02-09 08:26:16 +00:00
$this -> assertEquals ( 202 , $column [ 'headers' ][ 'status-code' ], 'Column creation failed: ' . json_encode ( $column [ 'body' ]));
2026-02-05 15:46:59 +00:00
// Wait for column to be available
2026-02-09 00:25:19 +00:00
$this -> assertEventually ( function () use ( $databaseId , $actorsId ) {
$column = $this -> client -> call ( Client :: METHOD_GET , '/tablesdb/' . $databaseId . '/tables/' . $actorsId . '/columns/name' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $column [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'available' , $column [ 'body' ][ 'status' ]);
2026-02-24 01:00:07 +00:00
}, 120000 , 500 );
2026-02-05 15:28:12 +00:00
return [ 'actorsId' => $actorsId , 'databaseId' => $databaseId ];
}
/**
* Helper to create collection with attribute and index .
*/
protected function createCollectionWithIndex () : array
{
$data = $this -> createCollectionWithAttribute ();
2026-02-09 08:26:16 +00:00
$indexResponse = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ 'actorsId' ] . '/indexes' , array_merge ([
2026-02-05 15:28:12 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'key' => 'key_name' ,
'type' => 'key' ,
'attributes' => [ 'name' ],
]);
2026-02-09 08:26:16 +00:00
$this -> assertEquals ( 202 , $indexResponse [ 'headers' ][ 'status-code' ], 'Index creation failed: ' . json_encode ( $indexResponse [ 'body' ]));
2026-02-05 15:28:12 +00:00
// Wait for index to be available
2026-02-09 07:42:15 +00:00
$this -> assertEventually ( function () use ( $data ) {
$index = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ 'actorsId' ] . '/indexes/key_name' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
2026-02-09 08:26:16 +00:00
$this -> assertEquals ( 200 , $index [ 'headers' ][ 'status-code' ], 'Index polling returned ' . $index [ 'headers' ][ 'status-code' ] . ': ' . json_encode ( $index [ 'body' ] ? ? '' ));
2026-02-09 07:42:15 +00:00
$this -> assertEquals ( 'available' , $index [ 'body' ][ 'status' ]);
2026-02-24 01:00:07 +00:00
}, 120000 , 500 );
2026-02-05 15:28:12 +00:00
return $data ;
}
/**
* Helper to create table with attribute and index .
*/
protected function createTableWithIndex () : array
{
$data = $this -> createTableWithAttribute ();
2026-02-09 08:26:16 +00:00
$indexResponse = $this -> client -> call ( Client :: METHOD_POST , '/tablesdb/' . $data [ 'databaseId' ] . '/tables/' . $data [ 'actorsId' ] . '/indexes' , array_merge ([
2026-02-05 15:28:12 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'key' => 'key_name' ,
'type' => 'key' ,
2026-02-09 09:11:18 +00:00
'columns' => [ 'name' ],
2026-02-05 15:28:12 +00:00
]);
2026-02-09 08:26:16 +00:00
$this -> assertEquals ( 202 , $indexResponse [ 'headers' ][ 'status-code' ], 'Index creation failed: ' . json_encode ( $indexResponse [ 'body' ]));
2026-02-05 15:28:12 +00:00
// Wait for index to be available
2026-02-09 00:25:19 +00:00
$this -> assertEventually ( function () use ( $data ) {
$index = $this -> client -> call ( Client :: METHOD_GET , '/tablesdb/' . $data [ 'databaseId' ] . '/tables/' . $data [ 'actorsId' ] . '/indexes/key_name' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
2026-02-09 08:26:16 +00:00
$this -> assertEquals ( 200 , $index [ 'headers' ][ 'status-code' ], 'Index polling returned ' . $index [ 'headers' ][ 'status-code' ] . ': ' . json_encode ( $index [ 'body' ] ? ? '' ));
2026-02-09 00:25:19 +00:00
$this -> assertEquals ( 'available' , $index [ 'body' ][ 'status' ]);
2026-02-24 01:00:07 +00:00
}, 120000 , 500 );
2026-02-05 15:28:12 +00:00
return $data ;
}
2024-09-30 14:32:50 +00:00
public function testManualAuthentication () : void
2022-07-06 10:53:30 +00:00
{
$user = $this -> getUser ();
$userId = $user [ '$id' ] ? ? '' ;
$session = $user [ 'session' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$client = $this -> getWebsocket ([ 'account' ], [
'origin' => 'http://localhost'
]);
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'connected' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertCount ( 1 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'account' , $response [ 'data' ][ 'channels' ]);
$client -> send ( \json_encode ([
'type' => 'authentication' ,
'data' => [
'session' => $session
]
]));
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'response' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertEquals ( 'authentication' , $response [ 'data' ][ 'to' ]);
$this -> assertTrue ( $response [ 'data' ][ 'success' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'user' ]);
$this -> assertEquals ( $userId , $response [ 'data' ][ 'user' ][ '$id' ]);
/**
* Test for FAILURE
*/
$client -> send ( \json_encode ([
'type' => 'authentication' ,
'data' => [
'session' => 'invalid_session'
]
]));
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'error' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertEquals ( 1003 , $response [ 'data' ][ 'code' ]);
$this -> assertEquals ( 'Session is not valid.' , $response [ 'data' ][ 'message' ]);
$client -> send ( \json_encode ([
'type' => 'authentication' ,
'data' => []
]));
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'error' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertEquals ( 1003 , $response [ 'data' ][ 'code' ]);
2026-05-13 13:22:14 +00:00
$this -> assertEquals ( 'Payload is not valid. Session is required' , $response [ 'data' ][ 'message' ]);
2022-07-06 10:53:30 +00:00
$client -> send ( \json_encode ([
'type' => 'unknown' ,
'data' => [
'session' => 'invalid_session'
]
]));
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'error' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertEquals ( 1003 , $response [ 'data' ][ 'code' ]);
$this -> assertEquals ( 'Message type is not valid.' , $response [ 'data' ][ 'message' ]);
$client -> send ( \json_encode ([
'test' => '123' ,
]));
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'error' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertEquals ( 1003 , $response [ 'data' ][ 'code' ]);
$this -> assertEquals ( 'Message format is not valid.' , $response [ 'data' ][ 'message' ]);
$client -> close ();
}
2026-02-05 15:46:59 +00:00
public function testAttributesCollectionsAPI () : void
2021-12-06 12:03:12 +00:00
{
2022-06-22 10:51:49 +00:00
/**
2026-02-18 01:42:41 +00:00
* Create database and collection BEFORE opening WebSocket
* to avoid their creation events interfering with attribute events .
2022-06-22 10:51:49 +00:00
*/
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2022-08-14 10:33:36 +00:00
'databaseId' => ID :: unique (),
2022-06-22 10:51:49 +00:00
'name' => 'Actors DB' ,
]);
$databaseId = $database [ 'body' ][ '$id' ];
2026-02-18 01:42:41 +00:00
2022-06-22 10:51:49 +00:00
$actors = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-12-06 12:03:12 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-05-09 09:41:14 +00:00
'collectionId' => ID :: unique (),
2021-12-06 12:03:12 +00:00
'name' => 'Actors' ,
2022-08-03 04:17:49 +00:00
'permissions' => [
2022-08-14 05:21:11 +00:00
Permission :: read ( Role :: any ()),
Permission :: create ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
2022-08-03 04:17:49 +00:00
],
2021-12-06 12:03:12 +00:00
]);
2022-04-18 16:21:45 +00:00
$actorsId = $actors [ 'body' ][ '$id' ];
2021-12-06 12:03:12 +00:00
2026-02-18 01:42:41 +00:00
$projectId = 'console' ;
$client = $this -> getWebsocket ([ 'console' ], [
'origin' => 'http://localhost' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
], $projectId );
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'connected' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertCount ( 1 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'user' ]);
/**
* Test Attributes
*/
2022-06-22 10:51:49 +00:00
$name = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $actorsId . '/attributes/string' , array_merge ([
2021-12-06 12:03:12 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2021-12-16 16:10:01 +00:00
'key' => 'name' ,
2021-12-06 12:03:12 +00:00
'size' => 256 ,
'required' => true ,
]);
2024-09-30 14:32:50 +00:00
$projectId = $this -> getProject ()[ '$id' ];
2022-04-18 16:21:45 +00:00
2025-05-09 09:41:14 +00:00
$this -> assertEquals ( 202 , $name [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'name' , $name [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'string' , $name [ 'body' ][ 'type' ]);
$this -> assertEquals ( 256 , $name [ 'body' ][ 'size' ]);
$this -> assertTrue ( $name [ 'body' ][ 'required' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .attributes.*.create " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .attributes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.attributes.*.create " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.attributes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases.* " , $response [ 'data' ][ 'events' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$this -> assertEquals ( 'processing' , $response [ 'data' ][ 'payload' ][ 'status' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .attributes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .attributes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.attributes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.attributes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases.* " , $response [ 'data' ][ 'events' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$this -> assertEquals ( 'available' , $response [ 'data' ][ 'payload' ][ 'status' ]);
$client -> close ();
}
2026-02-05 15:28:12 +00:00
public function testAttributesTablesAPI () : void
2025-05-09 09:41:14 +00:00
{
/**
2026-02-18 01:42:41 +00:00
* Create database and table BEFORE opening WebSocket
* to avoid their creation events interfering with column events .
2025-05-09 09:41:14 +00:00
*/
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'databaseId' => ID :: unique (),
'name' => 'Actors DB' ,
]);
$databaseId = $database [ 'body' ][ '$id' ];
2025-08-18 09:16:01 +00:00
$actors = $this -> client -> call ( Client :: METHOD_POST , '/tablesdb/' . $databaseId . '/tables' , array_merge ([
2025-05-09 09:41:14 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'tableId' => ID :: unique (),
'name' => 'Actors' ,
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: create ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
],
]);
$actorsId = $actors [ 'body' ][ '$id' ];
2026-02-18 01:42:41 +00:00
$projectId = 'console' ;
$client = $this -> getWebsocket ([ 'console' ], [
'origin' => 'http://localhost' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
], $projectId );
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'connected' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertCount ( 1 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'user' ]);
/**
* Test Attributes
*/
2025-08-18 09:16:01 +00:00
$name = $this -> client -> call ( Client :: METHOD_POST , '/tablesdb/' . $databaseId . '/tables/' . $actorsId . '/columns/string' , array_merge ([
2025-05-09 09:41:14 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'key' => 'name' ,
'size' => 256 ,
'required' => true ,
]);
$projectId = $this -> getProject ()[ '$id' ];
$this -> assertEquals ( 202 , $name [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'name' , $name [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'string' , $name [ 'body' ][ 'type' ]);
$this -> assertEquals ( 256 , $name [ 'body' ][ 'size' ]);
$this -> assertTrue ( $name [ 'body' ][ 'required' ]);
2021-12-06 12:03:12 +00:00
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
2024-09-30 14:32:50 +00:00
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
2021-12-06 12:03:12 +00:00
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
2024-09-30 14:32:50 +00:00
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
2025-04-27 05:06:21 +00:00
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .columns.*.create " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .columns.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.columns.*.create " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.columns.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.* " , $response [ 'data' ][ 'events' ]);
2022-06-22 10:51:49 +00:00
$this -> assertContains ( " databases. { $databaseId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases.* " , $response [ 'data' ][ 'events' ]);
2021-12-06 12:03:12 +00:00
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$this -> assertEquals ( 'processing' , $response [ 'data' ][ 'payload' ][ 'status' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
2024-09-30 14:32:50 +00:00
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
2021-12-06 12:03:12 +00:00
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
2024-09-30 14:32:50 +00:00
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
2025-04-27 05:06:21 +00:00
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .columns.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .columns.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.columns.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.columns.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.* " , $response [ 'data' ][ 'events' ]);
2022-06-22 10:51:49 +00:00
$this -> assertContains ( " databases. { $databaseId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases.* " , $response [ 'data' ][ 'events' ]);
2021-12-06 12:03:12 +00:00
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$this -> assertEquals ( 'available' , $response [ 'data' ][ 'payload' ][ 'status' ]);
$client -> close ();
2025-05-09 09:41:14 +00:00
}
2026-02-05 15:28:12 +00:00
public function testIndexesCollectionAPI () : void
2025-05-09 09:41:14 +00:00
{
2026-02-05 15:28:12 +00:00
$data = $this -> createCollectionWithAttribute ();
2025-05-09 09:41:14 +00:00
$projectId = 'console' ;
$actorsId = $data [ 'actorsId' ];
$databaseId = $data [ 'databaseId' ];
$client = $this -> getWebsocket ([ 'console' ], [
'origin' => 'http://localhost' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
], $projectId );
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'connected' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertCount ( 1 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'user' ]);
/**
* Test Indexes
*/
$index = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $actorsId . '/indexes' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'key' => 'key_name' ,
'type' => 'key' ,
'attributes' => [
'name' ,
],
]);
$this -> assertEquals ( 202 , $index [ 'headers' ][ 'status-code' ]);
$projectId = $this -> getProject ()[ '$id' ];
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .indexes.*.create " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.indexes.*.create " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.* " , $response [ 'data' ][ 'events' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$this -> assertEquals ( 'processing' , $response [ 'data' ][ 'payload' ][ 'status' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .indexes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.indexes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.* " , $response [ 'data' ][ 'events' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$this -> assertEquals ( 'available' , $response [ 'data' ][ 'payload' ][ 'status' ]);
$client -> close ();
2021-12-06 12:03:12 +00:00
}
2026-02-05 15:28:12 +00:00
public function testIndexesTablesAPI () : void
2021-12-06 12:03:12 +00:00
{
2026-02-05 15:28:12 +00:00
$data = $this -> createTableWithAttribute ();
2021-12-06 12:03:12 +00:00
$projectId = 'console' ;
2022-04-18 16:21:45 +00:00
$actorsId = $data [ 'actorsId' ];
2022-06-22 10:51:49 +00:00
$databaseId = $data [ 'databaseId' ];
2021-12-06 12:03:12 +00:00
$client = $this -> getWebsocket ([ 'console' ], [
'origin' => 'http://localhost' ,
2022-04-18 16:21:45 +00:00
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
2021-12-06 12:03:12 +00:00
], $projectId );
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'connected' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertCount ( 1 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'user' ]);
/**
* Test Indexes
*/
2025-08-18 09:16:01 +00:00
$index = $this -> client -> call ( Client :: METHOD_POST , '/tablesdb/' . $databaseId . '/tables/' . $actorsId . '/indexes' , array_merge ([
2021-12-06 12:03:12 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2021-12-16 16:10:01 +00:00
'key' => 'key_name' ,
2021-12-06 12:03:12 +00:00
'type' => 'key' ,
2025-05-06 05:59:56 +00:00
'columns' => [
2021-12-06 12:03:12 +00:00
'name' ,
],
]);
2025-05-09 09:41:14 +00:00
$this -> assertEquals ( 202 , $index [ 'headers' ][ 'status-code' ]);
2024-09-30 14:32:50 +00:00
$projectId = $this -> getProject ()[ '$id' ];
2021-12-06 12:03:12 +00:00
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
2024-09-30 14:32:50 +00:00
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
2021-12-06 12:03:12 +00:00
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
2024-09-30 14:32:50 +00:00
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
2025-04-27 05:06:21 +00:00
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .indexes.*.create " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.indexes.*.create " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.* " , $response [ 'data' ][ 'events' ]);
2021-12-06 12:03:12 +00:00
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$this -> assertEquals ( 'processing' , $response [ 'data' ][ 'payload' ][ 'status' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
2024-09-30 14:32:50 +00:00
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
2021-12-06 12:03:12 +00:00
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
2024-09-30 14:32:50 +00:00
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
2025-04-27 05:06:21 +00:00
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .indexes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.indexes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.* " , $response [ 'data' ][ 'events' ]);
2021-12-06 12:03:12 +00:00
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$this -> assertEquals ( 'available' , $response [ 'data' ][ 'payload' ][ 'status' ]);
$client -> close ();
}
2026-02-05 15:28:12 +00:00
public function testDeleteIndexCollectionsAPI () : void
2021-12-06 12:03:12 +00:00
{
2026-02-05 15:28:12 +00:00
$data = $this -> createCollectionWithIndex ();
2022-04-18 16:21:45 +00:00
$actorsId = $data [ 'actorsId' ];
2021-12-06 12:03:12 +00:00
$projectId = 'console' ;
2022-06-22 10:51:49 +00:00
$databaseId = $data [ 'databaseId' ];
2021-12-06 12:03:12 +00:00
$client = $this -> getWebsocket ([ 'console' ], [
'origin' => 'http://localhost' ,
2022-04-18 16:21:45 +00:00
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
2021-12-06 12:03:12 +00:00
], $projectId );
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'connected' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertCount ( 1 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'user' ]);
2024-09-30 14:32:50 +00:00
$projectId = $this -> getProject ()[ '$id' ];
2021-12-06 12:03:12 +00:00
/**
* Test Delete Index
*/
2023-10-18 15:42:23 +00:00
$indexKey = 'key_name' ;
2023-10-18 15:50:40 +00:00
$attribute = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $actorsId . '/indexes/' . $indexKey , array_merge ([
2021-12-06 12:03:12 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
2025-05-09 09:41:14 +00:00
$this -> assertEquals ( 204 , $attribute [ 'headers' ][ 'status-code' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .indexes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.indexes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.* " , $response [ 'data' ][ 'events' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
/** Delete index generates two events. One from the API and one from the database worker */
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .indexes.*.delete " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.indexes.*.delete " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.* " , $response [ 'data' ][ 'events' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$client -> close ();
}
2026-02-05 15:28:12 +00:00
public function testDeleteIndexTablesAPI () : void
2025-05-09 09:41:14 +00:00
{
2026-02-05 15:28:12 +00:00
$data = $this -> createTableWithIndex ();
2025-05-09 09:41:14 +00:00
$projectId = 'console' ;
$actorsId = $data [ 'actorsId' ];
$databaseId = $data [ 'databaseId' ];
$client = $this -> getWebsocket ([ 'console' ], [
'origin' => 'http://localhost' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
], $projectId );
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'connected' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertCount ( 1 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'user' ]);
$projectId = $this -> getProject ()[ '$id' ];
/**
* Test Delete Index
*/
$indexKey = 'key_name' ;
2025-08-18 09:16:01 +00:00
$attribute = $this -> client -> call ( Client :: METHOD_DELETE , '/tablesdb/' . $databaseId . '/tables/' . $actorsId . '/indexes/' . $indexKey , array_merge ([
2025-05-09 09:41:14 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 204 , $attribute [ 'headers' ][ 'status-code' ]);
2024-09-30 14:32:50 +00:00
2021-12-06 12:03:12 +00:00
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
2024-09-30 14:32:50 +00:00
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
2021-12-06 12:03:12 +00:00
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
2024-09-30 14:32:50 +00:00
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
2025-04-27 05:06:21 +00:00
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .indexes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.indexes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.* " , $response [ 'data' ][ 'events' ]);
2021-12-06 12:03:12 +00:00
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
2023-10-18 15:50:40 +00:00
/** Delete index generates two events. One from the API and one from the database worker */
2023-10-18 15:42:23 +00:00
$response = json_decode ( $client -> receive (), true );
2025-05-09 09:41:14 +00:00
2023-10-18 15:42:23 +00:00
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
2024-09-30 14:32:50 +00:00
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
2023-10-18 15:42:23 +00:00
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
2024-09-30 14:32:50 +00:00
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
2025-04-27 05:06:21 +00:00
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .indexes.*.delete " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.indexes.*.delete " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.indexes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.* " , $response [ 'data' ][ 'events' ]);
2023-10-18 15:42:23 +00:00
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
2021-12-06 12:03:12 +00:00
$client -> close ();
}
2026-02-05 15:28:12 +00:00
public function testDeleteAttributeCollectionsAPI () : void
2021-12-06 12:03:12 +00:00
{
2026-02-05 15:28:12 +00:00
$data = $this -> createCollectionWithAttribute ();
2021-12-06 12:03:12 +00:00
$projectId = 'console' ;
2025-05-09 09:41:14 +00:00
$actorsId = $data [ 'actorsId' ];
2022-06-22 10:51:49 +00:00
$databaseId = $data [ 'databaseId' ];
2021-12-06 12:03:12 +00:00
$client = $this -> getWebsocket ([ 'console' ], [
'origin' => 'http://localhost' ,
2022-04-18 16:21:45 +00:00
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
2021-12-06 12:03:12 +00:00
], $projectId );
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'connected' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertCount ( 1 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'user' ]);
2024-09-30 14:32:50 +00:00
$attributeKey = 'name' ;
$projectId = $this -> getProject ()[ '$id' ];
2021-12-06 12:03:12 +00:00
/**
* Test Delete Attribute
*/
2023-10-18 15:42:23 +00:00
$attribute = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $data [ 'actorsId' ] . '/attributes/' . $attributeKey , array_merge ([
2021-12-06 12:03:12 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
2025-05-09 09:41:14 +00:00
$this -> assertEquals ( 204 , $attribute [ 'headers' ][ 'status-code' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .attributes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .attributes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.attributes.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.attributes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.* " , $response [ 'data' ][ 'events' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .attributes.*.delete " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } .attributes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.attributes.*.delete " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.*.attributes.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .collections.* " , $response [ 'data' ][ 'events' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$client -> close ();
}
2026-02-05 15:28:12 +00:00
public function testDeleteAttributeTablesAPI () : void
2025-05-09 09:41:14 +00:00
{
2026-02-05 15:28:12 +00:00
$data = $this -> createTableWithAttribute ();
2025-05-09 09:41:14 +00:00
$projectId = 'console' ;
$actorsId = $data [ 'actorsId' ];
$databaseId = $data [ 'databaseId' ];
$client = $this -> getWebsocket ([ 'console' ], [
'origin' => 'http://localhost' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
], $projectId );
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'connected' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertCount ( 1 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'user' ]);
$attributeKey = 'name' ;
$projectId = $this -> getProject ()[ '$id' ];
/**
* Test Delete Attribute
*/
2025-08-18 09:16:01 +00:00
$attribute = $this -> client -> call ( Client :: METHOD_DELETE , '/tablesdb/' . $databaseId . '/tables/' . $data [ 'actorsId' ] . '/columns/' . $attributeKey , array_merge ([
2025-05-09 09:41:14 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 204 , $attribute [ 'headers' ][ 'status-code' ]);
2021-12-06 12:03:12 +00:00
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
2023-10-18 16:30:47 +00:00
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
2024-09-30 14:32:50 +00:00
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
2023-10-18 16:30:47 +00:00
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
2024-09-30 14:32:50 +00:00
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
2025-04-27 05:06:21 +00:00
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .columns.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .columns.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.columns.*.update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.columns.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.* " , $response [ 'data' ][ 'events' ]);
2023-10-18 16:30:47 +00:00
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
2021-12-06 12:03:12 +00:00
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
2024-09-30 14:32:50 +00:00
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
2021-12-06 12:03:12 +00:00
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
2024-09-30 14:32:50 +00:00
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
2025-04-27 05:06:21 +00:00
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .columns.*.delete " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } .columns.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables. { $actorsId } " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.columns.*.delete " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.*.columns.* " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( " databases. { $databaseId } .tables.* " , $response [ 'data' ][ 'events' ]);
2021-12-06 12:03:12 +00:00
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$client -> close ();
}
2022-10-25 19:16:05 +00:00
2024-10-07 13:00:19 +00:00
public function testPing ()
{
$client = $this -> getWebsocket ([ 'console' ], [
'origin' => 'http://localhost' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
], 'console' );
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertEquals ( 'connected' , $response [ 'type' ]);
$pong = $this -> client -> call ( Client :: METHOD_GET , '/ping' , [
'origin' => 'http://localhost' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]);
$this -> assertEquals ( 200 , $pong [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Pong!' , $pong [ 'body' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
2024-10-07 14:58:34 +00:00
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
2024-10-07 13:00:19 +00:00
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $this -> getProject ()[ '$id' ] } " , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $this -> getProject ()[ '$id' ] } .ping " , $response [ 'data' ][ 'events' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ]);
$this -> assertArrayHasKey ( 'pingCount' , $response [ 'data' ][ 'payload' ]);
$this -> assertArrayHasKey ( 'pingedAt' , $response [ 'data' ][ 'payload' ]);
$this -> assertEquals ( 1 , $response [ 'data' ][ 'payload' ][ 'pingCount' ]);
$client -> close ();
}
2022-10-25 19:16:05 +00:00
public function testCreateDeployment ()
{
$response1 = $this -> client -> call ( Client :: METHOD_POST , '/functions' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'functionId' => ID :: unique (),
'name' => 'Test' ,
2025-07-09 14:58:55 +00:00
'runtime' => 'node-22' ,
'entrypoint' => 'index.js' ,
2022-10-25 19:16:05 +00:00
'events' => [
'users.*.create' ,
'users.*.delete' ,
],
'schedule' => '0 0 1 1 *' ,
2023-03-01 12:00:36 +00:00
'timeout' => 10
2022-10-25 19:16:05 +00:00
]);
$this -> assertEquals ( 201 , $response1 [ 'headers' ][ 'status-code' ]);
2025-03-17 12:21:36 +00:00
$functionId = $response1 [ 'body' ][ '$id' ];
$this -> assertNotEmpty ( $functionId );
2022-10-25 19:16:05 +00:00
$projectId = 'console' ;
$client = $this -> getWebsocket ([ 'console' ], [
'origin' => 'http://localhost' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
], $projectId );
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'connected' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertCount ( 1 , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'user' ]);
/**
* Test Create Deployment
*/
2024-10-03 09:20:47 +00:00
$projectId = $this -> getProject ()[ '$id' ];
2022-10-25 19:16:05 +00:00
$deployment = $this -> client -> call ( Client :: METHOD_POST , '/functions/' . $functionId . '/deployments' , array_merge ([
'content-type' => 'multipart/form-data' ,
2024-10-03 09:20:47 +00:00
'x-appwrite-project' => $projectId ,
2022-10-25 19:16:05 +00:00
], $this -> getHeaders ()), [
2025-07-09 14:58:55 +00:00
'code' => $this -> packageFunction ( 'basic' ),
2023-03-01 12:00:36 +00:00
'activate' => true
2022-10-25 19:16:05 +00:00
]);
$this -> assertEquals ( 202 , $deployment [ 'headers' ][ 'status-code' ]);
2025-03-17 12:21:36 +00:00
$deploymentId = $deployment [ 'body' ][ '$id' ];
$this -> assertNotEmpty ( $deploymentId );
2022-10-25 19:16:05 +00:00
$response = json_decode ( $client -> receive (), true );
$this -> assertArrayHasKey ( 'type' , $response );
$this -> assertArrayHasKey ( 'data' , $response );
$this -> assertEquals ( 'event' , $response [ 'type' ]);
$this -> assertNotEmpty ( $response [ 'data' ]);
$this -> assertArrayHasKey ( 'timestamp' , $response [ 'data' ]);
2024-09-30 14:32:50 +00:00
$this -> assertCount ( 2 , $response [ 'data' ][ 'channels' ]);
2022-10-25 19:16:05 +00:00
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
2024-09-30 14:32:50 +00:00
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
2025-03-17 12:21:36 +00:00
$this -> assertEquals ( " waiting " , $response [ 'data' ][ 'payload' ][ 'status' ]);
$this -> assertContains ( " functions. { $functionId } .deployments. { $deploymentId } .create " , $response [ 'data' ][ 'events' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertContains ( " functions. { $functionId } .deployments. { $deploymentId } .update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertEquals ( " processing " , $response [ 'data' ][ 'payload' ][ 'status' ]);
$response = json_decode ( $client -> receive (), true );
$this -> assertContains ( " functions. { $functionId } .deployments. { $deploymentId } .update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertEquals ( " building " , $response [ 'data' ][ 'payload' ][ 'status' ]);
$previousBuildLogs = null ;
while ( true ) {
$response = json_decode ( $client -> receive (), true );
$this -> assertContains ( " functions. { $functionId } .deployments. { $deploymentId } .update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertArrayHasKey ( 'buildLogs' , $response [ 'data' ][ 'payload' ]);
2025-06-25 11:14:08 +00:00
if ( ! empty ( $response [ 'data' ][ 'payload' ][ 'buildSize' ])) {
2025-05-12 14:52:13 +00:00
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ][ 'buildStartedAt' ]);
2025-03-26 16:04:38 +00:00
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ][ 'buildPath' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ][ 'buildSize' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ][ 'totalSize' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ][ 'buildLogs' ]);
2025-03-17 12:21:36 +00:00
break ;
}
2025-05-18 10:51:07 +00:00
2025-04-27 05:06:21 +00:00
// Ignore comparison for first payload
2025-03-17 12:21:36 +00:00
if ( $previousBuildLogs !== null ) {
$this -> assertNotEquals ( $previousBuildLogs , $response [ 'data' ][ 'payload' ][ 'buildLogs' ]);
}
$previousBuildLogs = $response [ 'data' ][ 'payload' ][ 'buildLogs' ];
2025-03-26 16:04:38 +00:00
$this -> assertEquals ( 'building' , $response [ 'data' ][ 'payload' ][ 'status' ]);
2025-03-17 12:21:36 +00:00
}
2022-10-25 19:16:05 +00:00
2025-03-26 16:04:38 +00:00
$response = json_decode ( $client -> receive (), true );
$this -> assertContains ( " functions. { $functionId } .deployments. { $deploymentId } .update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertEquals ( " ready " , $response [ 'data' ][ 'payload' ][ 'status' ]);
2025-06-25 11:14:08 +00:00
$response = json_decode ( $client -> receive (), true );
$this -> assertContains ( " functions. { $functionId } .deployments. { $deploymentId } .update " , $response [ 'data' ][ 'events' ]);
$this -> assertContains ( 'console' , $response [ 'data' ][ 'channels' ]);
$this -> assertContains ( " projects. { $projectId } " , $response [ 'data' ][ 'channels' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ][ 'buildDuration' ]);
$this -> assertNotEmpty ( $response [ 'data' ][ 'payload' ][ 'buildEndedAt' ]);
2022-10-25 19:16:05 +00:00
$client -> close ();
}
2022-04-18 16:21:45 +00:00
}