2020-01-13 08:46:09 +00:00
< ? php
2025-06-19 05:22:15 +00:00
namespace Tests\E2E\Services\Databases\Legacy ;
2020-01-13 08:46:09 +00:00
2023-02-27 07:47:20 +00:00
use Appwrite\Extend\Exception as AppwriteException ;
2024-03-06 17:34:21 +00:00
use Tests\E2E\Client ;
2020-01-13 08:46:09 +00:00
use Tests\E2E\Scopes\ProjectCustom ;
use Tests\E2E\Scopes\Scope ;
use Tests\E2E\Scopes\SideServer ;
2024-04-23 03:20:25 +00:00
use Utopia\Database\Database ;
2023-12-20 10:55:09 +00:00
use Utopia\Database\Document ;
2024-04-23 03:20:25 +00:00
use Utopia\Database\Exception ;
2022-12-14 15:42:25 +00:00
use Utopia\Database\Helpers\ID ;
2022-12-14 16:04:06 +00:00
use Utopia\Database\Helpers\Permission ;
use Utopia\Database\Helpers\Role ;
2023-12-20 10:55:09 +00:00
use Utopia\Database\Query ;
2020-01-13 08:46:09 +00:00
2022-06-22 10:51:49 +00:00
class DatabasesCustomServerTest extends Scope
2020-01-13 08:46:09 +00:00
{
2022-06-22 10:51:49 +00:00
use DatabasesBase ;
2020-01-13 08:46:09 +00:00
use ProjectCustom ;
use SideServer ;
2020-12-05 05:31:59 +00:00
2022-06-22 10:51:49 +00:00
public function testListDatabases ()
{
$test1 = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'databaseId' => ID :: custom ( 'first' ),
2022-06-22 10:51:49 +00:00
'name' => 'Test 1' ,
]);
2023-05-18 13:25:22 +00:00
2022-06-22 10:51:49 +00:00
$this -> assertEquals ( 201 , $test1 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Test 1' , $test1 [ 'body' ][ 'name' ]);
$test2 = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'databaseId' => ID :: custom ( 'second' ),
2022-06-22 10:51:49 +00:00
'name' => 'Test 2' ,
]);
$this -> assertEquals ( 201 , $test2 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Test 2' , $test2 [ 'body' ][ 'name' ]);
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 2 , $databases [ 'body' ][ 'total' ]);
$this -> assertEquals ( $test1 [ 'body' ][ '$id' ], $databases [ 'body' ][ 'databases' ][ 0 ][ '$id' ]);
$this -> assertEquals ( $test2 [ 'body' ][ '$id' ], $databases [ 'body' ][ 'databases' ][ 1 ][ '$id' ]);
2025-10-20 15:18:17 +00:00
/**
2025-10-29 09:08:08 +00:00
* Test for SUCCESS with total = false
2025-10-20 15:18:17 +00:00
*/
$databasesWithIncludeTotalFalse = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-10-29 09:08:08 +00:00
'total' => false
2025-10-20 15:18:17 +00:00
]);
2025-10-20 15:38:14 +00:00
$this -> assertEquals ( 200 , $databasesWithIncludeTotalFalse [ 'headers' ][ 'status-code' ]);
2025-10-20 15:18:17 +00:00
$this -> assertIsArray ( $databasesWithIncludeTotalFalse [ 'body' ]);
$this -> assertIsArray ( $databasesWithIncludeTotalFalse [ 'body' ][ 'databases' ]);
$this -> assertIsInt ( $databasesWithIncludeTotalFalse [ 'body' ][ 'total' ]);
$this -> assertEquals ( 0 , $databasesWithIncludeTotalFalse [ 'body' ][ 'total' ]);
$this -> assertGreaterThan ( 0 , count ( $databasesWithIncludeTotalFalse [ 'body' ][ 'databases' ]));
2022-08-24 12:43:07 +00:00
$base = array_reverse ( $databases [ 'body' ][ 'databases' ]);
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: limit ( 1 ) -> toString (),
],
2022-08-24 12:43:07 +00:00
]);
$this -> assertEquals ( 200 , $databases [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 1 , $databases [ 'body' ][ 'databases' ]);
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: offset ( 1 ) -> toString (),
],
2022-08-24 12:43:07 +00:00
]);
$this -> assertEquals ( 200 , $databases [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 1 , $databases [ 'body' ][ 'databases' ]);
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: equal ( 'name' , [ 'Test 1' , 'Test 2' ]) -> toString (),
],
2022-08-24 12:43:07 +00:00
]);
$this -> assertEquals ( 200 , $databases [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 2 , $databases [ 'body' ][ 'databases' ]);
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: equal ( 'name' , [ 'Test 2' ]) -> toString (),
],
2022-08-24 12:43:07 +00:00
]);
$this -> assertEquals ( 200 , $databases [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 1 , $databases [ 'body' ][ 'databases' ]);
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: equal ( '$id' , [ 'first' ]) -> toString (),
],
2022-08-24 12:43:07 +00:00
]);
$this -> assertEquals ( 200 , $databases [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 1 , $databases [ 'body' ][ 'databases' ]);
2022-06-22 10:51:49 +00:00
/**
* Test for Order
*/
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: orderDesc () -> toString (),
],
2022-06-22 10:51:49 +00:00
]);
$this -> assertEquals ( 2 , $databases [ 'body' ][ 'total' ]);
$this -> assertEquals ( $base [ 0 ][ '$id' ], $databases [ 'body' ][ 'databases' ][ 0 ][ '$id' ]);
$this -> assertEquals ( $base [ 1 ][ '$id' ], $databases [ 'body' ][ 'databases' ][ 1 ][ '$id' ]);
/**
* Test for After
*/
$base = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: cursorAfter ( new Document ([ '$id' => $base [ 'body' ][ 'databases' ][ 0 ][ '$id' ]])) -> toString (),
],
2022-06-22 10:51:49 +00:00
]);
$this -> assertCount ( 1 , $databases [ 'body' ][ 'databases' ]);
$this -> assertEquals ( $base [ 'body' ][ 'databases' ][ 1 ][ '$id' ], $databases [ 'body' ][ 'databases' ][ 0 ][ '$id' ]);
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: cursorAfter ( new Document ([ '$id' => $base [ 'body' ][ 'databases' ][ 1 ][ '$id' ]])) -> toString (),
],
2022-06-22 10:51:49 +00:00
]);
$this -> assertCount ( 0 , $databases [ 'body' ][ 'databases' ]);
$this -> assertEmpty ( $databases [ 'body' ][ 'databases' ]);
/**
* Test for Before
*/
$base = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: cursorBefore ( new Document ([ '$id' => $base [ 'body' ][ 'databases' ][ 1 ][ '$id' ]])) -> toString (),
],
2022-06-22 10:51:49 +00:00
]);
$this -> assertCount ( 1 , $databases [ 'body' ][ 'databases' ]);
$this -> assertEquals ( $base [ 'body' ][ 'databases' ][ 0 ][ '$id' ], $databases [ 'body' ][ 'databases' ][ 0 ][ '$id' ]);
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: cursorBefore ( new Document ([ '$id' => $base [ 'body' ][ 'databases' ][ 0 ][ '$id' ]])) -> toString (),
],
2022-06-22 10:51:49 +00:00
]);
$this -> assertCount ( 0 , $databases [ 'body' ][ 'databases' ]);
$this -> assertEmpty ( $databases [ 'body' ][ 'databases' ]);
/**
* Test for Search
*/
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'search' => 'first'
]);
$this -> assertEquals ( 1 , $databases [ 'body' ][ 'total' ]);
$this -> assertEquals ( 'first' , $databases [ 'body' ][ 'databases' ][ 0 ][ '$id' ]);
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'search' => 'Test'
]);
$this -> assertEquals ( 2 , $databases [ 'body' ][ 'total' ]);
$this -> assertEquals ( 'Test 1' , $databases [ 'body' ][ 'databases' ][ 0 ][ 'name' ]);
$this -> assertEquals ( 'Test 2' , $databases [ 'body' ][ 'databases' ][ 1 ][ 'name' ]);
$databases = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'search' => 'Nonexistent'
]);
$this -> assertEquals ( 0 , $databases [ 'body' ][ 'total' ]);
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: cursorAfter ( new Document ([ '$id' => 'unknown' ])) -> toString (),
],
2022-06-22 10:51:49 +00:00
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
// This collection already exists
$response = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'name' => 'Test 1' ,
2022-08-14 10:33:36 +00:00
'databaseId' => ID :: custom ( 'first' ),
2022-06-22 10:51:49 +00:00
]);
$this -> assertEquals ( 409 , $response [ 'headers' ][ 'status-code' ]);
return [ 'databaseId' => $test1 [ 'body' ][ '$id' ]];
}
/**
* @ depends testListDatabases
*/
public function testGetDatabase ( array $data ) : array
{
$databaseId = $data [ 'databaseId' ];
/**
* Test for SUCCESS
*/
$database = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$this -> assertEquals ( 200 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $databaseId , $database [ 'body' ][ '$id' ]);
$this -> assertEquals ( 'Test 1' , $database [ 'body' ][ 'name' ]);
2023-05-18 13:25:22 +00:00
$this -> assertEquals ( true , $database [ 'body' ][ 'enabled' ]);
2022-06-22 10:51:49 +00:00
return [ 'databaseId' => $database [ 'body' ][ '$id' ]];
}
2023-05-22 14:40:09 +00:00
/**
* @ depends testListDatabases
*/
public function testUpdateDatabase ( array $data )
{
$databaseId = $data [ 'databaseId' ];
$database = $this -> client -> call ( Client :: METHOD_PUT , '/databases/' . $databaseId , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'name' => 'Test 1 Updated' ,
2023-05-23 08:00:39 +00:00
'enabled' => false ,
]);
2023-05-22 14:40:09 +00:00
$this -> assertEquals ( 200 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Test 1 Updated' , $database [ 'body' ][ 'name' ]);
$this -> assertFalse ( $database [ 'body' ][ 'enabled' ]);
// Now update the database without the passing the enabled parameter
$database = $this -> client -> call ( Client :: METHOD_PUT , '/databases/' . $databaseId , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2023-05-23 08:00:48 +00:00
], [
'name' => 'Test 1'
]);
2023-05-22 14:40:09 +00:00
$this -> assertEquals ( 200 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Test 1' , $database [ 'body' ][ 'name' ]);
$this -> assertTrue ( $database [ 'body' ][ 'enabled' ]);
}
2022-06-22 10:51:49 +00:00
/**
* @ depends testListDatabases
*/
public function testDeleteDatabase ( $data )
{
$databaseId = $data [ 'databaseId' ];
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], $this -> getHeaders ()));
$this -> assertEquals ( 204 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( " " , $response [ 'body' ]);
// Try to get the collection and check if it has been deleted
$response = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ]
], $this -> getHeaders ()));
$this -> assertEquals ( 404 , $response [ 'headers' ][ 'status-code' ]);
}
2023-05-22 14:40:09 +00:00
public function testListCollections () : array
2021-08-09 14:54:10 +00:00
{
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' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'databaseId' => ID :: unique (),
2022-06-22 10:51:49 +00:00
'name' => 'invalidDocumentDatabase' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'invalidDocumentDatabase' , $database [ 'body' ][ 'name' ]);
2023-05-19 12:48:26 +00:00
$this -> assertTrue ( $database [ 'body' ][ 'enabled' ]);
2022-06-22 10:51:49 +00:00
$databaseId = $database [ 'body' ][ '$id' ];
2021-08-09 14:54:10 +00:00
/**
* Test for SUCCESS
*/
2022-06-22 10:51:49 +00:00
$test1 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-08-09 14:54:10 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'name' => 'Test 1' ,
2022-08-14 10:33:36 +00:00
'collectionId' => ID :: custom ( 'first' ),
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
],
'documentSecurity' => true ,
2021-08-09 14:54:10 +00:00
]);
2022-06-22 10:51:49 +00:00
$test2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-08-09 14:54:10 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'name' => 'Test 2' ,
2022-08-14 10:33:36 +00:00
'collectionId' => ID :: custom ( 'second' ),
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
],
'documentSecurity' => true ,
2021-08-09 14:54:10 +00:00
]);
2022-06-22 10:51:49 +00:00
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-08-09 14:54:10 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
2022-02-27 09:57:09 +00:00
$this -> assertEquals ( 2 , $collections [ 'body' ][ 'total' ]);
2021-08-09 14:54:10 +00:00
$this -> assertEquals ( $test1 [ 'body' ][ '$id' ], $collections [ 'body' ][ 'collections' ][ 0 ][ '$id' ]);
2023-05-19 12:48:26 +00:00
$this -> assertEquals ( $test1 [ 'body' ][ 'enabled' ], $collections [ 'body' ][ 'collections' ][ 0 ][ 'enabled' ]);
2021-08-09 14:54:10 +00:00
$this -> assertEquals ( $test2 [ 'body' ][ '$id' ], $collections [ 'body' ][ 'collections' ][ 1 ][ '$id' ]);
2023-05-19 12:48:26 +00:00
$this -> assertEquals ( $test1 [ 'body' ][ 'enabled' ], $collections [ 'body' ][ 'collections' ][ 0 ][ 'enabled' ]);
2021-08-09 14:54:10 +00:00
2025-10-20 15:18:17 +00:00
/**
2025-10-29 09:08:08 +00:00
* Test for SUCCESS with total = false
2025-10-20 15:18:17 +00:00
*/
$collectionsWithIncludeTotalFalse = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-10-29 09:08:08 +00:00
'total' => false
2025-10-20 15:18:17 +00:00
]);
2025-10-20 15:38:14 +00:00
$this -> assertEquals ( 200 , $collectionsWithIncludeTotalFalse [ 'headers' ][ 'status-code' ]);
2025-10-20 15:18:17 +00:00
$this -> assertIsArray ( $collectionsWithIncludeTotalFalse [ 'body' ]);
$this -> assertIsArray ( $collectionsWithIncludeTotalFalse [ 'body' ][ 'collections' ]);
$this -> assertIsInt ( $collectionsWithIncludeTotalFalse [ 'body' ][ 'total' ]);
$this -> assertEquals ( 0 , $collectionsWithIncludeTotalFalse [ 'body' ][ 'total' ]);
$this -> assertGreaterThan ( 0 , count ( $collectionsWithIncludeTotalFalse [ 'body' ][ 'collections' ]));
2022-08-24 12:43:07 +00:00
$base = array_reverse ( $collections [ 'body' ][ 'collections' ]);
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: limit ( 1 ) -> toString (),
],
2022-08-24 12:43:07 +00:00
]);
$this -> assertEquals ( 200 , $collections [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 1 , $collections [ 'body' ][ 'collections' ]);
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: offset ( 1 ) -> toString (),
],
2022-08-24 12:43:07 +00:00
]);
$this -> assertEquals ( 200 , $collections [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 1 , $collections [ 'body' ][ 'collections' ]);
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: equal ( 'enabled' , [ true ]) -> toString (),
],
2022-08-24 12:43:07 +00:00
]);
$this -> assertEquals ( 200 , $collections [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 2 , $collections [ 'body' ][ 'collections' ]);
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: equal ( 'enabled' , [ false ]) -> toString (),
],
2022-08-24 12:43:07 +00:00
]);
$this -> assertEquals ( 200 , $collections [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 0 , $collections [ 'body' ][ 'collections' ]);
2021-08-09 14:54:10 +00:00
/**
* Test for Order
*/
2022-06-22 10:51:49 +00:00
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-08-09 14:54:10 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: orderDesc () -> toString (),
],
2021-08-09 14:54:10 +00:00
]);
2022-02-27 09:57:09 +00:00
$this -> assertEquals ( 2 , $collections [ 'body' ][ 'total' ]);
2021-08-09 14:54:10 +00:00
$this -> assertEquals ( $base [ 0 ][ '$id' ], $collections [ 'body' ][ 'collections' ][ 0 ][ '$id' ]);
$this -> assertEquals ( $base [ 1 ][ '$id' ], $collections [ 'body' ][ 'collections' ][ 1 ][ '$id' ]);
/**
* Test for After
*/
2022-06-22 10:51:49 +00:00
$base = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-08-09 14:54:10 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
2022-06-22 10:51:49 +00:00
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-08-09 14:54:10 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: cursorAfter ( new Document ([ '$id' => $base [ 'body' ][ 'collections' ][ 0 ][ '$id' ]])) -> toString (),
],
2021-08-09 14:54:10 +00:00
]);
$this -> assertCount ( 1 , $collections [ 'body' ][ 'collections' ]);
$this -> assertEquals ( $base [ 'body' ][ 'collections' ][ 1 ][ '$id' ], $collections [ 'body' ][ 'collections' ][ 0 ][ '$id' ]);
2022-06-22 10:51:49 +00:00
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-08-09 14:54:10 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: cursorAfter ( new Document ([ '$id' => $base [ 'body' ][ 'collections' ][ 1 ][ '$id' ]])) -> toString (),
],
2021-08-09 14:54:10 +00:00
]);
$this -> assertCount ( 0 , $collections [ 'body' ][ 'collections' ]);
$this -> assertEmpty ( $collections [ 'body' ][ 'collections' ]);
2021-10-05 10:30:33 +00:00
/**
* Test for Before
*/
2022-06-22 10:51:49 +00:00
$base = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-10-05 10:30:33 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
2022-06-22 10:51:49 +00:00
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-10-05 10:30:33 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: cursorBefore ( new Document ([ '$id' => $base [ 'body' ][ 'collections' ][ 1 ][ '$id' ]])) -> toString (),
],
2021-10-05 10:30:33 +00:00
]);
$this -> assertCount ( 1 , $collections [ 'body' ][ 'collections' ]);
$this -> assertEquals ( $base [ 'body' ][ 'collections' ][ 0 ][ '$id' ], $collections [ 'body' ][ 'collections' ][ 0 ][ '$id' ]);
2022-06-22 10:51:49 +00:00
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-10-05 10:30:33 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: cursorBefore ( new Document ([ '$id' => $base [ 'body' ][ 'collections' ][ 0 ][ '$id' ]])) -> toString (),
],
2021-10-05 10:30:33 +00:00
]);
$this -> assertCount ( 0 , $collections [ 'body' ][ 'collections' ]);
$this -> assertEmpty ( $collections [ 'body' ][ 'collections' ]);
2022-01-19 09:04:57 +00:00
/**
* Test for Search
*/
2022-06-22 10:51:49 +00:00
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2022-01-19 09:04:57 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'search' => 'first'
]);
2022-02-27 09:57:09 +00:00
$this -> assertEquals ( 1 , $collections [ 'body' ][ 'total' ]);
2022-01-19 09:04:57 +00:00
$this -> assertEquals ( 'first' , $collections [ 'body' ][ 'collections' ][ 0 ][ '$id' ]);
2022-06-22 10:51:49 +00:00
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2022-01-19 09:04:57 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'search' => 'Test'
]);
2022-05-23 14:54:50 +00:00
2022-02-27 09:57:09 +00:00
$this -> assertEquals ( 2 , $collections [ 'body' ][ 'total' ]);
2022-01-19 09:04:57 +00:00
$this -> assertEquals ( 'Test 1' , $collections [ 'body' ][ 'collections' ][ 0 ][ 'name' ]);
$this -> assertEquals ( 'Test 2' , $collections [ 'body' ][ 'collections' ][ 1 ][ 'name' ]);
2022-06-22 10:51:49 +00:00
$collections = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2022-01-19 09:04:57 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'search' => 'Nonexistent'
]);
2022-05-23 14:54:50 +00:00
2022-02-27 09:57:09 +00:00
$this -> assertEquals ( 0 , $collections [ 'body' ][ 'total' ]);
2022-01-19 09:04:57 +00:00
2021-10-05 10:30:33 +00:00
/**
* Test for FAILURE
*/
2022-06-22 10:51:49 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-10-05 10:30:33 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query :: cursorAfter ( new Document ([ '$id' => 'unknown' ])) -> toString (),
],
2021-10-05 10:30:33 +00:00
]);
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2022-01-12 19:51:13 +00:00
// This collection already exists
2022-06-22 10:51:49 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
2022-01-12 19:51:13 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'name' => 'Test 1' ,
2022-08-14 10:33:36 +00:00
'collectionId' => ID :: custom ( 'first' ),
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
],
'documentSecurity' => true ,
2022-01-12 19:51:13 +00:00
]);
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 409 , $response [ 'headers' ][ 'status-code' ]);
2023-05-29 08:34:41 +00:00
return [
'databaseId' => $databaseId ,
'collectionId' => $test1 [ 'body' ][ '$id' ],
];
2023-05-22 14:40:09 +00:00
}
/**
* @ depends testListCollections
*/
public function testGetCollection ( array $data ) : void
{
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
$collection = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $collection [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Test 1' , $collection [ 'body' ][ 'name' ]);
$this -> assertEquals ( 'first' , $collection [ 'body' ][ '$id' ]);
$this -> assertTrue ( $collection [ 'body' ][ 'enabled' ]);
}
/**
* @ depends testListCollections
*/
public function testUpdateCollection ( array $data )
{
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
$collection = $this -> client -> call ( Client :: METHOD_PUT , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'name' => 'Test 1 Updated' ,
'enabled' => false
]);
$this -> assertEquals ( 200 , $collection [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Test 1 Updated' , $collection [ 'body' ][ 'name' ]);
$this -> assertEquals ( 'first' , $collection [ 'body' ][ '$id' ]);
$this -> assertFalse ( $collection [ 'body' ][ 'enabled' ]);
2021-08-09 14:54:10 +00:00
}
2023-06-08 11:04:57 +00:00
/**
2024-08-16 06:18:52 +00:00
* @ depends testListCollections
2023-06-08 11:04:57 +00:00
*/
2023-06-22 04:29:09 +00:00
public function testCreateEncryptedAttribute ( array $data ) : void
2023-06-08 11:04:57 +00:00
{
$databaseId = $data [ 'databaseId' ];
/**
* Test for SUCCESS
*/
// Create collection
$actors = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Encrypted Actors Data' ,
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: create ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
],
'documentSecurity' => true ,
]);
$this -> assertEquals ( 201 , $actors [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $actors [ 'body' ][ 'name' ], 'Encrypted Actors Data' );
/**
* Test for creating encrypted attributes
*/
$attributesPath = '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ] . '/attributes' ;
$firstName = $this -> client -> call ( Client :: METHOD_POST , $attributesPath . '/string' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'firstName' ,
'size' => 256 ,
'required' => true ,
]);
2025-05-26 06:03:03 +00:00
2025-05-23 15:27:35 +00:00
// checking size test
$lastName = $this -> client -> call ( Client :: METHOD_POST , $attributesPath . '/string' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'lastName' ,
'size' => 149 ,
'required' => true ,
'encrypt' => true
]);
$this -> assertEquals ( " Size too small. Encrypted strings require a minimum size of " . APP_DATABASE_ENCRYPT_SIZE_MIN . " characters. " , $lastName [ 'body' ][ 'message' ]);
2023-06-08 11:04:57 +00:00
$lastName = $this -> client -> call ( Client :: METHOD_POST , $attributesPath . '/string' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'lastName' ,
'size' => 256 ,
'required' => true ,
2025-05-26 05:36:55 +00:00
'encrypt' => true
2023-06-08 11:04:57 +00:00
]);
2025-05-26 05:36:55 +00:00
$this -> assertTrue ( $lastName [ 'body' ][ 'encrypt' ]);
2025-05-26 06:03:03 +00:00
2025-05-26 05:36:55 +00:00
sleep ( 1 );
2025-05-26 06:03:03 +00:00
2025-05-26 05:36:55 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , $attributesPath . '/lastName' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
]));
2025-05-26 06:10:08 +00:00
2025-05-26 05:36:55 +00:00
$this -> assertTrue ( $response [ 'body' ][ 'encrypt' ]);
2023-06-08 11:04:57 +00:00
2023-06-23 10:29:23 +00:00
/**
* Check status of every attribute
*/
2023-06-08 11:04:57 +00:00
$this -> assertEquals ( 202 , $firstName [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'firstName' , $firstName [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'string' , $firstName [ 'body' ][ 'type' ]);
$this -> assertEquals ( 202 , $lastName [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'lastName' , $lastName [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'string' , $lastName [ 'body' ][ 'type' ]);
// Wait for database worker to finish creating attributes
2023-06-22 04:29:09 +00:00
sleep ( 2 );
2023-06-08 11:04:57 +00:00
// Creating document to ensure cache is purged on schema change
$document = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => ID :: unique (),
'data' => [
2023-06-21 10:45:00 +00:00
'firstName' => 'Jonah' ,
'lastName' => 'Jameson' ,
2023-06-08 11:04:57 +00:00
],
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
],
]);
// Check document to ensure cache is purged on schema change
$document = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ] . '/documents/' . $document [ 'body' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2023-06-22 04:29:09 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Jonah' , $document [ 'body' ][ 'firstName' ]);
$this -> assertEquals ( 'Jameson' , $document [ 'body' ][ 'lastName' ]);
2025-05-26 05:36:55 +00:00
$actors = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), []);
$attributes = $actors [ 'body' ][ 'attributes' ];
foreach ( $attributes as $attribute ) {
$this -> assertArrayHasKey ( 'encrypt' , $attribute );
if ( $attribute [ 'key' ] === 'firstName' ) {
$this -> assertFalse ( $attribute [ 'encrypt' ]);
}
if ( $attribute [ 'key' ] === 'lastName' ) {
$this -> assertTrue ( $attribute [ 'encrypt' ]);
}
}
2023-06-08 11:04:57 +00:00
}
2021-08-08 23:56:31 +00:00
public function testDeleteAttribute () : array
2020-12-05 05:31:59 +00:00
{
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' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'databaseId' => ID :: unique (),
2022-06-22 10:51:49 +00:00
'name' => 'invalidDocumentDatabase' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'invalidDocumentDatabase' , $database [ 'body' ][ 'name' ]);
$databaseId = $database [ 'body' ][ '$id' ];
2020-12-05 05:31:59 +00:00
/**
* Test for SUCCESS
*/
// Create collection
2022-06-22 10:51:49 +00:00
$actors = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
2020-12-05 05:31:59 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'collectionId' => ID :: unique (),
2021-06-15 14:24:51 +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
],
'documentSecurity' => true ,
2020-12-05 05:31:59 +00:00
]);
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 201 , $actors [ 'headers' ][ 'status-code' ]);
2020-12-05 05:31:59 +00:00
$this -> assertEquals ( $actors [ 'body' ][ 'name' ], 'Actors' );
2021-06-11 18:07:05 +00:00
2022-06-22 10:51:49 +00:00
$firstName = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ] . '/attributes/string' , array_merge ([
2021-06-11 18:07:05 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'firstName' ,
2021-06-11 18:07:05 +00:00
'size' => 256 ,
'required' => true ,
]);
2022-06-22 10:51:49 +00:00
$lastName = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ] . '/attributes/string' , array_merge ([
2021-06-11 18:07:05 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'lastName' ,
2021-06-11 18:07:05 +00:00
'size' => 256 ,
'required' => true ,
]);
2022-06-22 10:51:49 +00:00
$unneeded = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ] . '/attributes/string' , array_merge ([
2021-08-08 22:08:10 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'unneeded' ,
2021-08-08 22:08:10 +00:00
'size' => 256 ,
'required' => true ,
]);
// Wait for database worker to finish creating attributes
2021-08-23 04:06:53 +00:00
sleep ( 2 );
2021-08-08 22:08:10 +00:00
2021-11-23 17:39:01 +00:00
// Creating document to ensure cache is purged on schema change
2022-06-22 10:51:49 +00:00
$document = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ] . '/documents' , array_merge ([
2021-11-23 17:39:01 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'documentId' => ID :: unique (),
2021-11-23 17:39:01 +00:00
'data' => [
'firstName' => 'lorem' ,
'lastName' => 'ipsum' ,
2023-05-22 14:40:09 +00:00
'unneeded' => 'dolor'
2021-11-23 17:39:01 +00:00
],
2022-08-03 04:17:49 +00:00
'permissions' => [
2022-08-14 05:21:11 +00:00
Permission :: read ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
2022-08-03 04:17:49 +00:00
],
2021-11-23 17:39:01 +00:00
]);
2022-06-22 10:51:49 +00:00
$index = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ] . '/indexes' , array_merge ([
2021-08-08 22:08:10 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'key_lastName' ,
2021-08-08 22:08:10 +00:00
'type' => 'key' ,
'attributes' => [
'lastName' ,
],
]);
// Wait for database worker to finish creating index
2021-08-23 04:06:53 +00:00
sleep ( 2 );
2021-08-08 22:08:10 +00:00
2022-06-22 10:51:49 +00:00
$collection = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ], array_merge ([
2021-08-08 22:08:10 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2022-05-23 14:54:50 +00:00
]), []);
2021-08-08 22:08:10 +00:00
2021-08-22 14:06:59 +00:00
$unneededId = $unneeded [ 'body' ][ 'key' ];
2021-08-08 22:08:10 +00:00
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 200 , $collection [ 'headers' ][ 'status-code' ]);
2021-08-08 22:08:10 +00:00
$this -> assertIsArray ( $collection [ 'body' ][ 'attributes' ]);
$this -> assertCount ( 3 , $collection [ 'body' ][ 'attributes' ]);
2021-08-22 14:06:59 +00:00
$this -> assertEquals ( $collection [ 'body' ][ 'attributes' ][ 0 ][ 'key' ], $firstName [ 'body' ][ 'key' ]);
$this -> assertEquals ( $collection [ 'body' ][ 'attributes' ][ 1 ][ 'key' ], $lastName [ 'body' ][ 'key' ]);
$this -> assertEquals ( $collection [ 'body' ][ 'attributes' ][ 2 ][ 'key' ], $unneeded [ 'body' ][ 'key' ]);
2021-08-08 22:08:10 +00:00
$this -> assertCount ( 1 , $collection [ 'body' ][ 'indexes' ]);
2021-08-22 16:36:26 +00:00
$this -> assertEquals ( $collection [ 'body' ][ 'indexes' ][ 0 ][ 'key' ], $index [ 'body' ][ 'key' ]);
2021-08-08 22:08:10 +00:00
// Delete attribute
2024-08-16 06:18:52 +00:00
$attribute = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ] . '/attributes/' . $unneededId , array_merge ([
2021-08-08 22:08:10 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 204 , $attribute [ 'headers' ][ 'status-code' ]);
2021-08-23 04:06:53 +00:00
sleep ( 2 );
2021-06-18 17:09:07 +00:00
2021-11-23 17:39:01 +00:00
// Check document to ensure cache is purged on schema change
2022-06-22 10:51:49 +00:00
$document = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ] . '/documents/' . $document [ 'body' ][ '$id' ], array_merge ([
2021-11-23 17:39:01 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertNotContains ( $unneededId , $document [ 'body' ]);
2022-06-22 10:51:49 +00:00
$collection = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $actors [ 'body' ][ '$id' ], array_merge ([
2021-06-11 18:07:05 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2022-05-23 14:54:50 +00:00
]), []);
2020-12-05 05:31:59 +00:00
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 200 , $collection [ 'headers' ][ 'status-code' ]);
2021-06-18 17:09:07 +00:00
$this -> assertIsArray ( $collection [ 'body' ][ 'attributes' ]);
$this -> assertCount ( 2 , $collection [ 'body' ][ 'attributes' ]);
2021-08-22 16:36:26 +00:00
$this -> assertEquals ( $collection [ 'body' ][ 'attributes' ][ 0 ][ 'key' ], $firstName [ 'body' ][ 'key' ]);
$this -> assertEquals ( $collection [ 'body' ][ 'attributes' ][ 1 ][ 'key' ], $lastName [ 'body' ][ 'key' ]);
2021-06-18 17:09:07 +00:00
2021-08-08 22:08:10 +00:00
return [
'collectionId' => $actors [ 'body' ][ '$id' ],
2021-12-16 15:04:30 +00:00
'key' => $index [ 'body' ][ 'key' ],
2022-06-22 10:51:49 +00:00
'databaseId' => $databaseId
2021-08-08 22:08:10 +00:00
];
}
2021-08-23 04:06:53 +00:00
2021-08-08 22:08:10 +00:00
/**
* @ depends testDeleteAttribute
*/
2021-08-08 23:56:31 +00:00
public function testDeleteIndex ( $data ) : array
{
2022-06-22 10:51:49 +00:00
$databaseId = $data [ 'databaseId' ];
$index = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $data [ 'collectionId' ] . '/indexes/' . $data [ 'key' ], array_merge ([
2021-08-08 23:56:31 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 204 , $index [ 'headers' ][ 'status-code' ]);
2021-08-23 04:06:53 +00:00
2021-08-08 23:56:31 +00:00
// Wait for database worker to finish deleting index
2021-08-23 04:06:53 +00:00
sleep ( 2 );
2021-08-08 23:56:31 +00:00
2022-06-22 10:51:49 +00:00
$collection = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $data [ 'collectionId' ], array_merge ([
2021-08-08 23:56:31 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2021-08-23 04:06:53 +00:00
]), []);
2021-08-08 23:56:31 +00:00
$this -> assertCount ( 0 , $collection [ 'body' ][ 'indexes' ]);
return $data ;
}
/**
* @ depends testDeleteIndex
*/
2021-09-02 21:38:46 +00:00
public function testDeleteIndexOnDeleteAttribute ( $data )
{
2022-06-22 10:51:49 +00:00
$databaseId = $data [ 'databaseId' ];
$attribute1 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ 'collectionId' ] . '/attributes/string' , array_merge ([
2021-09-02 21:38:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'attribute1' ,
2021-09-02 21:38:46 +00:00
'size' => 16 ,
'required' => true ,
]);
2022-06-22 10:51:49 +00:00
$attribute2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ 'collectionId' ] . '/attributes/string' , array_merge ([
2021-09-02 21:38:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'attribute2' ,
2021-09-02 21:38:46 +00:00
'size' => 16 ,
'required' => true ,
]);
2022-07-18 13:22:23 +00:00
$this -> assertEquals ( 202 , $attribute1 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 202 , $attribute2 [ 'headers' ][ 'status-code' ]);
2021-09-02 21:38:46 +00:00
$this -> assertEquals ( 'attribute1' , $attribute1 [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'attribute2' , $attribute2 [ 'body' ][ 'key' ]);
sleep ( 2 );
2022-06-22 10:51:49 +00:00
$index1 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ 'collectionId' ] . '/indexes' , array_merge ([
2021-09-02 21:38:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'index1' ,
2021-09-02 21:38:46 +00:00
'type' => 'key' ,
'attributes' => [ 'attribute1' , 'attribute2' ],
'orders' => [ 'ASC' , 'ASC' ],
]);
2022-06-22 10:51:49 +00:00
$index2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ 'collectionId' ] . '/indexes' , array_merge ([
2021-09-02 21:38:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'index2' ,
2021-09-02 21:38:46 +00:00
'type' => 'key' ,
'attributes' => [ 'attribute2' ],
]);
2022-07-18 13:22:23 +00:00
$this -> assertEquals ( 202 , $index1 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 202 , $index2 [ 'headers' ][ 'status-code' ]);
2021-09-02 21:38:46 +00:00
$this -> assertEquals ( 'index1' , $index1 [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'index2' , $index2 [ 'body' ][ 'key' ]);
sleep ( 2 );
2021-09-21 01:23:41 +00:00
// Expected behavior: deleting attribute2 will cause index2 to be dropped, and index1 rebuilt with a single key
2022-06-22 10:51:49 +00:00
$deleted = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $data [ 'collectionId' ] . '/attributes/' . $attribute2 [ 'body' ][ 'key' ], array_merge ([
2021-09-02 21:38:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 204 , $deleted [ 'headers' ][ 'status-code' ]);
2021-09-02 21:38:46 +00:00
// wait for database worker to complete
sleep ( 2 );
2022-06-22 10:51:49 +00:00
$collection = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $data [ 'collectionId' ], array_merge ([
2021-09-02 21:38:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertEquals ( 200 , $collection [ 'headers' ][ 'status-code' ]);
$this -> assertIsArray ( $collection [ 'body' ][ 'indexes' ]);
$this -> assertCount ( 1 , $collection [ 'body' ][ 'indexes' ]);
$this -> assertEquals ( $index1 [ 'body' ][ 'key' ], $collection [ 'body' ][ 'indexes' ][ 0 ][ 'key' ]);
$this -> assertIsArray ( $collection [ 'body' ][ 'indexes' ][ 0 ][ 'attributes' ]);
$this -> assertCount ( 1 , $collection [ 'body' ][ 'indexes' ][ 0 ][ 'attributes' ]);
$this -> assertEquals ( $attribute1 [ 'body' ][ 'key' ], $collection [ 'body' ][ 'indexes' ][ 0 ][ 'attributes' ][ 0 ]);
// Delete attribute
2022-06-22 10:51:49 +00:00
$deleted = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $data [ 'collectionId' ] . '/attributes/' . $attribute1 [ 'body' ][ 'key' ], array_merge ([
2021-09-02 21:38:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 204 , $deleted [ 'headers' ][ 'status-code' ]);
2021-09-02 21:38:46 +00:00
return $data ;
}
2021-09-27 23:38:03 +00:00
public function testCleanupDuplicateIndexOnDeleteAttribute ()
2021-09-21 01:23:41 +00:00
{
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' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'databaseId' => ID :: unique (),
2022-06-22 10:51:49 +00:00
'name' => 'invalidDocumentDatabase' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'invalidDocumentDatabase' , $database [ 'body' ][ 'name' ]);
$databaseId = $database [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-09-27 23:38:03 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'collectionId' => ID :: unique (),
2021-09-27 23:38:03 +00:00
'name' => 'TestCleanupDuplicateIndexOnDeleteAttribute' ,
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
],
'documentSecurity' => true ,
2021-09-27 23:38:03 +00:00
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $collection [ 'body' ][ '$id' ]);
$collectionId = $collection [ 'body' ][ '$id' ];
2022-06-22 10:51:49 +00:00
$attribute1 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
2021-09-21 01:23:41 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'attribute1' ,
2021-09-21 01:23:41 +00:00
'size' => 16 ,
'required' => true ,
]);
2022-06-22 10:51:49 +00:00
$attribute2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
2021-09-21 01:23:41 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'attribute2' ,
2021-09-21 01:23:41 +00:00
'size' => 16 ,
'required' => true ,
]);
2022-07-18 13:22:23 +00:00
$this -> assertEquals ( 202 , $attribute1 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 202 , $attribute2 [ 'headers' ][ 'status-code' ]);
2021-09-21 01:23:41 +00:00
$this -> assertEquals ( 'attribute1' , $attribute1 [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'attribute2' , $attribute2 [ 'body' ][ 'key' ]);
sleep ( 2 );
2022-06-22 10:51:49 +00:00
$index1 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/indexes' , array_merge ([
2021-09-21 01:23:41 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'index1' ,
2021-09-21 01:23:41 +00:00
'type' => 'key' ,
'attributes' => [ 'attribute1' , 'attribute2' ],
'orders' => [ 'ASC' , 'ASC' ],
]);
2022-06-22 10:51:49 +00:00
$index2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/indexes' , array_merge ([
2021-09-21 01:23:41 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'index2' ,
2021-09-21 01:23:41 +00:00
'type' => 'key' ,
'attributes' => [ 'attribute2' ],
]);
2022-07-18 13:22:23 +00:00
$this -> assertEquals ( 202 , $index1 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 202 , $index2 [ 'headers' ][ 'status-code' ]);
2021-09-21 01:23:41 +00:00
$this -> assertEquals ( 'index1' , $index1 [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'index2' , $index2 [ 'body' ][ 'key' ]);
sleep ( 2 );
// Expected behavior: deleting attribute1 would cause index1 to be a duplicate of index2 and automatically removed
2022-06-22 10:51:49 +00:00
$deleted = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $attribute1 [ 'body' ][ 'key' ], array_merge ([
2021-09-21 01:23:41 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 204 , $deleted [ 'headers' ][ 'status-code' ]);
2021-09-21 01:23:41 +00:00
// wait for database worker to complete
sleep ( 2 );
2022-06-22 10:51:49 +00:00
$collection = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
2021-09-21 01:23:41 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertEquals ( 200 , $collection [ 'headers' ][ 'status-code' ]);
$this -> assertIsArray ( $collection [ 'body' ][ 'indexes' ]);
$this -> assertCount ( 1 , $collection [ 'body' ][ 'indexes' ]);
$this -> assertEquals ( $index2 [ 'body' ][ 'key' ], $collection [ 'body' ][ 'indexes' ][ 0 ][ 'key' ]);
$this -> assertIsArray ( $collection [ 'body' ][ 'indexes' ][ 0 ][ 'attributes' ]);
$this -> assertCount ( 1 , $collection [ 'body' ][ 'indexes' ][ 0 ][ 'attributes' ]);
$this -> assertEquals ( $attribute2 [ 'body' ][ 'key' ], $collection [ 'body' ][ 'indexes' ][ 0 ][ 'attributes' ][ 0 ]);
// Delete attribute
2022-06-22 10:51:49 +00:00
$deleted = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $attribute2 [ 'body' ][ 'key' ], array_merge ([
2021-09-21 01:23:41 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 204 , $deleted [ 'headers' ][ 'status-code' ]);
2021-09-21 01:23:41 +00:00
}
2021-09-02 21:38:46 +00:00
/**
* @ depends testDeleteIndexOnDeleteAttribute
*/
2021-08-08 22:08:10 +00:00
public function testDeleteCollection ( $data )
{
2022-06-22 10:51:49 +00:00
$databaseId = $data [ 'databaseId' ];
2021-08-08 22:08:10 +00:00
$collectionId = $data [ 'collectionId' ];
2020-12-05 05:31:59 +00:00
// Add Documents to the collection
2022-06-22 10:51:49 +00:00
$document1 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2020-12-05 05:31:59 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2022-08-14 10:33:36 +00:00
'documentId' => ID :: unique (),
2020-12-05 05:31:59 +00:00
'data' => [
'firstName' => 'Tom' ,
'lastName' => 'Holland' ,
],
2022-08-03 04:17:49 +00:00
'permissions' => [
2022-08-15 11:24:31 +00:00
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
2022-08-03 04:17:49 +00:00
],
2020-12-05 05:31:59 +00:00
]);
2022-06-22 10:51:49 +00:00
$document2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2020-12-05 05:31:59 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2022-08-14 10:33:36 +00:00
'documentId' => ID :: unique (),
2020-12-05 05:31:59 +00:00
'data' => [
'firstName' => 'Samuel' ,
'lastName' => 'Jackson' ,
],
2022-08-03 04:17:49 +00:00
'permissions' => [
2022-08-15 11:24:31 +00:00
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
2022-08-03 04:17:49 +00:00
],
2020-12-05 05:31:59 +00:00
]);
2021-06-11 18:07:05 +00:00
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 201 , $document1 [ 'headers' ][ 'status-code' ]);
2022-08-02 09:18:49 +00:00
$this -> assertIsArray ( $document1 [ 'body' ][ '$permissions' ]);
2022-08-13 14:10:28 +00:00
$this -> assertCount ( 3 , $document1 [ 'body' ][ '$permissions' ]);
2020-12-05 05:31:59 +00:00
$this -> assertEquals ( $document1 [ 'body' ][ 'firstName' ], 'Tom' );
$this -> assertEquals ( $document1 [ 'body' ][ 'lastName' ], 'Holland' );
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 201 , $document2 [ 'headers' ][ 'status-code' ]);
2022-08-02 09:18:49 +00:00
$this -> assertIsArray ( $document2 [ 'body' ][ '$permissions' ]);
2022-08-13 14:10:28 +00:00
$this -> assertCount ( 3 , $document2 [ 'body' ][ '$permissions' ]);
2020-12-05 05:31:59 +00:00
$this -> assertEquals ( $document2 [ 'body' ][ 'firstName' ], 'Samuel' );
$this -> assertEquals ( $document2 [ 'body' ][ 'lastName' ], 'Jackson' );
// Delete the actors collection
2022-06-22 10:51:49 +00:00
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
2020-12-05 05:31:59 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], $this -> getHeaders ()));
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 204 , $response [ 'headers' ][ 'status-code' ]);
2022-05-23 14:54:50 +00:00
$this -> assertEquals ( $response [ 'body' ], " " );
2020-12-05 05:31:59 +00:00
// Try to get the collection and check if it has been deleted
2022-06-22 10:51:49 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
2020-12-05 05:31:59 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ]
], $this -> getHeaders ()));
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 404 , $response [ 'headers' ][ 'status-code' ]);
2020-12-05 05:31:59 +00:00
}
2021-07-29 23:36:46 +00:00
2024-04-23 03:20:25 +00:00
/**
* @ throws Exception
*/
public function testDeleteCollectionDeletesRelatedAttributes () : void
{
$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' => 'TestDeleteCollectionDeletesRelatedAttributes' ,
]);
$databaseId = $database [ 'body' ][ '$id' ];
$collection1 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Collection1' ,
'documentSecurity' => false ,
'permissions' => [],
]);
$collection2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Collection2' ,
'documentSecurity' => false ,
'permissions' => [],
]);
$collection1 = $collection1 [ 'body' ][ '$id' ];
$collection2 = $collection2 [ 'body' ][ '$id' ];
$this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collection1 . '/attributes/relationship' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
]), [
'relatedCollectionId' => $collection2 ,
'type' => Database :: RELATION_MANY_TO_ONE ,
'twoWay' => false ,
'key' => 'collection2'
]);
sleep ( 2 );
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collection2 , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
], $this -> getHeaders ()));
sleep ( 2 );
$attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1 . '/attributes' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 0 , $attributes [ 'body' ][ 'total' ]);
}
2021-08-04 21:05:09 +00:00
2021-08-31 16:35:03 +00:00
public function testAttributeRowWidthLimit ()
{
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' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'databaseId' => ID :: unique (),
2022-06-22 10:51:49 +00:00
'name' => 'invalidDocumentDatabase' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'invalidDocumentDatabase' , $database [ 'body' ][ 'name' ]);
$databaseId = $database [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-08-31 16:35:03 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'collectionId' => ID :: custom ( 'attributeRowWidthLimit' ),
2021-08-31 16:35:03 +00:00
'name' => 'attributeRowWidthLimit' ,
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
],
'documentSecurity' => true ,
2021-08-31 16:35:03 +00:00
]);
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
2021-08-31 16:35:03 +00:00
$this -> assertEquals ( $collection [ 'body' ][ 'name' ], 'attributeRowWidthLimit' );
$collectionId = $collection [ 'body' ][ '$id' ];
// Add wide string attributes to approach row width limit
2022-05-23 14:54:50 +00:00
for ( $i = 0 ; $i < 15 ; $i ++ ) {
2022-06-22 10:51:49 +00:00
$attribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
2021-08-31 16:35:03 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => " attribute { $i } " ,
2021-08-31 16:35:03 +00:00
'size' => 1024 ,
'required' => true ,
]);
2022-08-12 12:54:27 +00:00
$this -> assertEquals ( 202 , $attribute [ 'headers' ][ 'status-code' ]);
2021-08-31 16:35:03 +00:00
}
sleep ( 5 );
2022-06-22 10:51:49 +00:00
$tooWide = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
2021-08-31 16:35:03 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'tooWide' ,
2021-08-31 16:35:03 +00:00
'size' => 1024 ,
'required' => true ,
]);
2021-09-01 14:36:01 +00:00
$this -> assertEquals ( 400 , $tooWide [ 'headers' ][ 'status-code' ]);
2024-11-12 09:27:24 +00:00
$this -> assertEquals ( 'attribute_limit_exceeded' , $tooWide [ 'body' ][ 'type' ]);
2021-08-31 16:35:03 +00:00
}
2021-07-29 23:36:46 +00:00
public function testIndexLimitException ()
{
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' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'databaseId' => ID :: unique (),
2022-06-22 10:51:49 +00:00
'name' => 'invalidDocumentDatabase' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'invalidDocumentDatabase' , $database [ 'body' ][ 'name' ]);
$databaseId = $database [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
2021-07-29 23:36:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2022-08-14 10:33:36 +00:00
'collectionId' => ID :: custom ( 'testLimitException' ),
2021-07-29 23:36:46 +00:00
'name' => 'testLimitException' ,
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
],
'documentSecurity' => true ,
2021-07-29 23:36:46 +00:00
]);
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
2021-07-29 23:36:46 +00:00
$this -> assertEquals ( $collection [ 'body' ][ 'name' ], 'testLimitException' );
$collectionId = $collection [ 'body' ][ '$id' ];
// add unique attributes for indexing
2022-05-23 14:54:50 +00:00
for ( $i = 0 ; $i < 64 ; $i ++ ) {
2021-07-29 23:36:46 +00:00
// $this->assertEquals(true, static::getDatabase()->createAttribute('indexLimit', "test{$i}", Database::VAR_STRING, 16, true));
2022-06-22 10:51:49 +00:00
$attribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
2021-07-29 23:36:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => " attribute { $i } " ,
2021-07-29 23:36:46 +00:00
'size' => 64 ,
'required' => true ,
]);
2022-08-12 12:54:27 +00:00
$this -> assertEquals ( 202 , $attribute [ 'headers' ][ 'status-code' ]);
2021-07-29 23:36:46 +00:00
}
2023-03-24 03:48:50 +00:00
sleep ( 10 );
2021-07-30 18:40:37 +00:00
2022-06-22 10:51:49 +00:00
$collection = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
2021-07-30 18:40:37 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 200 , $collection [ 'headers' ][ 'status-code' ]);
2021-07-30 18:40:37 +00:00
$this -> assertEquals ( $collection [ 'body' ][ 'name' ], 'testLimitException' );
$this -> assertIsArray ( $collection [ 'body' ][ 'attributes' ]);
$this -> assertIsArray ( $collection [ 'body' ][ 'indexes' ]);
2021-08-11 17:25:22 +00:00
$this -> assertCount ( 64 , $collection [ 'body' ][ 'attributes' ]);
$this -> assertCount ( 0 , $collection [ 'body' ][ 'indexes' ]);
2021-07-29 23:36:46 +00:00
2025-07-01 12:03:11 +00:00
$this -> assertEventually ( function () use ( $databaseId , $collectionId ) {
$collection = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
foreach ( $collection [ 'body' ][ 'attributes' ] ? ? [] as $attribute ) {
$this -> assertEquals (
'available' ,
$attribute [ 'status' ],
'attribute: ' . $attribute [ 'key' ]
);
}
return true ;
}, 60000 , 500 );
2021-10-26 00:14:12 +00:00
2022-06-15 07:47:46 +00:00
// Test indexLimit = 64
2023-11-27 12:34:29 +00:00
// MariaDB, MySQL, and MongoDB create 6 indexes per new collection
2021-07-29 23:36:46 +00:00
// Add up to the limit, then check if the next index throws IndexLimitException
2023-11-27 12:34:29 +00:00
for ( $i = 0 ; $i < 58 ; $i ++ ) {
2022-06-22 10:51:49 +00:00
$index = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/indexes' , array_merge ([
2021-07-29 23:36:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => " key_attribute { $i } " ,
2021-07-30 18:40:37 +00:00
'type' => 'key' ,
2021-07-29 23:36:46 +00:00
'attributes' => [ " attribute { $i } " ],
]);
2021-07-30 18:40:37 +00:00
2022-07-18 13:22:23 +00:00
$this -> assertEquals ( 202 , $index [ 'headers' ][ 'status-code' ]);
2021-08-24 23:35:43 +00:00
$this -> assertEquals ( " key_attribute { $i } " , $index [ 'body' ][ 'key' ]);
2021-07-29 23:36:46 +00:00
}
2021-08-24 23:35:43 +00:00
sleep ( 5 );
2021-07-29 23:36:46 +00:00
2022-06-22 10:51:49 +00:00
$collection = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
2021-07-29 23:36:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2022-08-08 11:00:03 +00:00
$this -> assertEquals ( 200 , $collection [ 'headers' ][ 'status-code' ]);
2021-07-30 18:40:37 +00:00
$this -> assertEquals ( $collection [ 'body' ][ 'name' ], 'testLimitException' );
$this -> assertIsArray ( $collection [ 'body' ][ 'attributes' ]);
$this -> assertIsArray ( $collection [ 'body' ][ 'indexes' ]);
$this -> assertCount ( 64 , $collection [ 'body' ][ 'attributes' ]);
2023-11-27 12:34:29 +00:00
$this -> assertCount ( 58 , $collection [ 'body' ][ 'indexes' ]);
2021-07-30 18:40:37 +00:00
2022-06-22 10:51:49 +00:00
$tooMany = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/indexes' , array_merge ([
2021-07-29 23:36:46 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2021-12-16 15:04:30 +00:00
'key' => 'tooMany' ,
2021-07-30 18:40:37 +00:00
'type' => 'key' ,
2021-08-24 23:35:43 +00:00
'attributes' => [ 'attribute61' ],
2021-07-29 23:36:46 +00:00
]);
$this -> assertEquals ( 400 , $tooMany [ 'headers' ][ 'status-code' ]);
2021-08-24 23:35:43 +00:00
$this -> assertEquals ( 'Index limit exceeded' , $tooMany [ 'body' ][ 'message' ]);
2021-09-02 16:46:05 +00:00
2022-06-22 10:51:49 +00:00
$collection = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
2021-09-02 16:46:05 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertEquals ( 204 , $collection [ 'headers' ][ 'status-code' ]);
2021-07-29 23:36:46 +00:00
}
2023-02-26 15:45:42 +00:00
2023-02-27 07:45:21 +00:00
public function testAttributeUpdate () : array
2023-02-26 15:45:42 +00:00
{
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'updateAttributes' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: custom ( 'updateAttributes' ),
'name' => 'updateAttributes'
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$collectionId = $collection [ 'body' ][ '$id' ];
2023-02-27 07:45:21 +00:00
/**
* Create String Attribute
*/
2023-02-26 15:45:42 +00:00
$attribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'string' ,
'size' => 1024 ,
2023-02-27 07:45:21 +00:00
'required' => false
]);
$this -> assertEquals ( 202 , $attribute [ 'headers' ][ 'status-code' ]);
/**
* Create Email Attribute
*/
$attribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/email' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'email' ,
'required' => false
]);
$this -> assertEquals ( 202 , $attribute [ 'headers' ][ 'status-code' ]);
/**
* Create IP Attribute
*/
$attribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/ip' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'ip' ,
'required' => false
]);
$this -> assertEquals ( 202 , $attribute [ 'headers' ][ 'status-code' ]);
/**
* Create URL Attribute
*/
$attribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/url' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'url' ,
'required' => false
]);
$this -> assertEquals ( 202 , $attribute [ 'headers' ][ 'status-code' ]);
/**
* Create Integer Attribute
*/
$attribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'integer' ,
'required' => false
]);
$this -> assertEquals ( 202 , $attribute [ 'headers' ][ 'status-code' ]);
/**
* Create Float Attribute
*/
$attribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'float' ,
'required' => false
]);
/**
* Create Boolean Attribute
*/
$attribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/boolean' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'boolean' ,
'required' => false
]);
/**
* Create Datetime Attribute
*/
$attribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'datetime' ,
'required' => false
2023-02-26 15:45:42 +00:00
]);
2023-02-27 07:45:21 +00:00
/**
* Create Enum Attribute
*/
$attribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'enum' ,
'required' => false ,
'elements' => [ 'lorem' , 'ipsum' ]
]);
2023-02-26 15:45:42 +00:00
$this -> assertEquals ( 202 , $attribute [ 'headers' ][ 'status-code' ]);
sleep ( 5 );
2023-02-27 07:45:21 +00:00
return [
'databaseId' => $databaseId ,
'collectionId' => $collectionId
];
}
/**
* @ depends testAttributeUpdate
*/
public function testAttributeUpdateString ( array $data )
{
$key = 'string' ;
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'lorem'
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 'lorem' , $new [ 'body' ][ 'default' ]);
2023-03-31 12:56:38 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2024-03-06 17:34:21 +00:00
$attribute = array_values ( array_filter ( $new [ 'body' ][ 'attributes' ], fn ( array $a ) => $a [ 'key' ] === $key ))[ 0 ] ? ? null ;
2023-03-31 12:56:38 +00:00
$this -> assertNotNull ( $attribute );
$this -> assertFalse ( $attribute [ 'required' ]);
$this -> assertEquals ( 'lorem' , $attribute [ 'default' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
2023-03-01 12:00:36 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => null
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-03-01 12:00:36 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertNull ( $new [ 'body' ][ 'default' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'ipsum'
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 'ipsum' , $new [ 'body' ][ 'default' ]);
/**
* Test against failure
*/
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => 'i am no boolean' ,
'default' => 'dolor'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
2023-02-26 15:45:42 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
2023-02-27 07:45:21 +00:00
'default' => 123
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'default' => 'ipsum'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
2023-02-26 15:45:42 +00:00
'default' => 'ipsum'
]);
2023-02-27 07:45:21 +00:00
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_DEFAULT_UNSUPPORTED , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
}
/**
* @ depends testAttributeUpdate
*/
public function testAttributeUpdateEmail ( array $data )
{
$key = 'email' ;
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/email/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'torsten@appwrite.io'
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 'torsten@appwrite.io' , $new [ 'body' ][ 'default' ]);
2023-03-31 12:56:38 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2024-03-06 17:34:21 +00:00
$attribute = array_values ( array_filter ( $new [ 'body' ][ 'attributes' ], fn ( array $a ) => $a [ 'key' ] === $key ))[ 0 ] ? ? null ;
2023-03-31 12:56:38 +00:00
$this -> assertNotNull ( $attribute );
$this -> assertFalse ( $attribute [ 'required' ]);
$this -> assertEquals ( 'torsten@appwrite.io' , $attribute [ 'default' ]);
2023-03-01 12:00:36 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/email/' . $key , array_merge ([
2023-03-01 12:00:36 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => null
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-03-01 12:00:36 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertNull ( $new [ 'body' ][ 'default' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/email/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'eldad@appwrite.io'
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-26 15:45:42 +00:00
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
2023-02-26 15:45:42 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2023-02-27 07:45:21 +00:00
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 'eldad@appwrite.io' , $new [ 'body' ][ 'default' ]);
/**
* Test against failure
*/
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/email/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => 'no boolean' ,
'default' => 'torsten@appwrite.io'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/email/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'i am no email'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/email/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/email/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'default' => 'ipsum'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-26 15:45:42 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/email/' . $key , array_merge ([
2023-02-26 15:45:42 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
2023-02-27 07:45:21 +00:00
'default' => 'torsten@appwrite.io'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_DEFAULT_UNSUPPORTED , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
}
/**
* @ depends testAttributeUpdate
*/
public function testAttributeUpdateIp ( array $data )
{
$key = 'ip' ;
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/ip/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => '127.0.0.1'
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( '127.0.0.1' , $new [ 'body' ][ 'default' ]);
2023-03-31 12:56:38 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2024-03-06 17:34:21 +00:00
$attribute = array_values ( array_filter ( $new [ 'body' ][ 'attributes' ], fn ( array $a ) => $a [ 'key' ] === $key ))[ 0 ] ? ? null ;
2023-03-31 12:56:38 +00:00
$this -> assertNotNull ( $attribute );
$this -> assertFalse ( $attribute [ 'required' ]);
$this -> assertEquals ( '127.0.0.1' , $attribute [ 'default' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/ip/' . $key , array_merge ([
2023-03-01 12:00:36 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => null
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-03-01 12:00:36 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertNull ( $new [ 'body' ][ 'default' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/ip/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => '192.168.0.1'
2023-02-26 15:45:42 +00:00
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-26 15:45:42 +00:00
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
2023-02-26 15:45:42 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2023-02-27 07:45:21 +00:00
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( '192.168.0.1' , $new [ 'body' ][ 'default' ]);
/**
* Test against failure
*/
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/ip/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => 'no boolean' ,
'default' => '127.0.0.1'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/ip/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'i am no ip'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/ip/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/ip/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'default' => '127.0.0.1'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/ip/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
'default' => '127.0.0.1'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_DEFAULT_UNSUPPORTED , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
}
/**
* @ depends testAttributeUpdate
*/
public function testAttributeUpdateUrl ( array $data )
{
$key = 'url' ;
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/url/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'http://appwrite.io'
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 'http://appwrite.io' , $new [ 'body' ][ 'default' ]);
2023-03-31 12:56:38 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2024-03-06 17:34:21 +00:00
$attribute = array_values ( array_filter ( $new [ 'body' ][ 'attributes' ], fn ( array $a ) => $a [ 'key' ] === $key ))[ 0 ] ? ? null ;
2023-03-31 12:56:38 +00:00
$this -> assertNotNull ( $attribute );
$this -> assertFalse ( $attribute [ 'required' ]);
$this -> assertEquals ( 'http://appwrite.io' , $attribute [ 'default' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/url/' . $key , array_merge ([
2023-03-01 12:00:36 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => null
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-03-01 12:00:36 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertNull ( $new [ 'body' ][ 'default' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/url/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'https://appwrite.io'
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 'https://appwrite.io' , $new [ 'body' ][ 'default' ]);
/**
* Test against failure
*/
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/url/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => 'no boolean' ,
'default' => 'https://appwrite.io'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/url/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'i am no url'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/url/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/url/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'default' => 'https://appwrite.io'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/url/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
'default' => 'https://appwrite.io'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_DEFAULT_UNSUPPORTED , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
}
/**
* @ depends testAttributeUpdate
*/
public function testAttributeUpdateInteger ( array $data )
{
$key = 'integer' ;
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 123 ,
'min' => 0 ,
'max' => 1000
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 123 , $new [ 'body' ][ 'default' ]);
$this -> assertEquals ( 0 , $new [ 'body' ][ 'min' ]);
$this -> assertEquals ( 1000 , $new [ 'body' ][ 'max' ]);
2023-03-31 12:56:38 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2024-03-06 17:34:21 +00:00
$attribute = array_values ( array_filter ( $new [ 'body' ][ 'attributes' ], fn ( array $a ) => $a [ 'key' ] === $key ))[ 0 ] ? ? null ;
2023-03-31 12:56:38 +00:00
$this -> assertNotNull ( $attribute );
$this -> assertFalse ( $attribute [ 'required' ]);
$this -> assertEquals ( 123 , $attribute [ 'default' ]);
$this -> assertEquals ( 0 , $attribute [ 'min' ]);
$this -> assertEquals ( 1000 , $attribute [ 'max' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-03-01 12:00:36 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => null ,
'min' => 0 ,
'max' => 1000
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-03-01 12:00:36 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertNull ( $new [ 'body' ][ 'default' ]);
$this -> assertEquals ( 0 , $new [ 'body' ][ 'min' ]);
$this -> assertEquals ( 1000 , $new [ 'body' ][ 'max' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 456 ,
'min' => 100 ,
'max' => 2000
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 456 , $new [ 'body' ][ 'default' ]);
$this -> assertEquals ( 100 , $new [ 'body' ][ 'min' ]);
$this -> assertEquals ( 2000 , $new [ 'body' ][ 'max' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-02-20 13:37:13 +00:00
'required' => false ,
'default' => 100 ,
2023-02-27 07:45:21 +00:00
'min' => 0 ,
]);
2025-02-20 13:37:13 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
2025-02-26 17:35:06 +00:00
'default' => 10 ,
'max' => 100 ,
2023-02-27 07:45:21 +00:00
]);
2025-02-20 13:37:13 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
2025-02-20 13:37:13 +00:00
/**
* Test against failure
*/
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-02-20 13:37:13 +00:00
'required' => 'no boolean' ,
'default' => 123 ,
'min' => 0 ,
2023-02-27 07:45:21 +00:00
'max' => 500
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
2025-02-20 13:37:13 +00:00
'default' => 'i am no integer' ,
2023-02-27 07:45:21 +00:00
'min' => 0 ,
2025-02-20 13:37:13 +00:00
'max' => 500
2023-02-27 07:45:21 +00:00
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 100 ,
2025-02-20 13:37:13 +00:00
'min' => 'i am no integer' ,
'max' => 500
2023-02-27 07:45:21 +00:00
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 100 ,
2025-02-20 13:37:13 +00:00
'min' => 0 ,
'max' => 'i am no integer'
2023-02-27 07:45:21 +00:00
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'min' => 0 ,
'max' => 100 ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'default' => 50 ,
'min' => 0 ,
'max' => 100 ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
'default' => 50 ,
'min' => 0 ,
'max' => 100
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_DEFAULT_UNSUPPORTED , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 50 ,
'min' => 55 ,
'max' => 100
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_VALUE_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 105 ,
'min' => 50 ,
'max' => 100
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_VALUE_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 50 ,
'min' => 200 ,
'max' => 100
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_VALUE_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
}
/**
* @ depends testAttributeUpdate
*/
public function testAttributeUpdateFloat ( array $data )
{
$key = 'float' ;
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 123.456 ,
'min' => 0.0 ,
'max' => 1000.0
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 123.456 , $new [ 'body' ][ 'default' ]);
$this -> assertEquals ( 0 , $new [ 'body' ][ 'min' ]);
$this -> assertEquals ( 1000 , $new [ 'body' ][ 'max' ]);
2023-03-31 12:56:38 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2024-03-06 17:34:21 +00:00
$attribute = array_values ( array_filter ( $new [ 'body' ][ 'attributes' ], fn ( array $a ) => $a [ 'key' ] === $key ))[ 0 ] ? ? null ;
2023-03-31 12:56:38 +00:00
$this -> assertNotNull ( $attribute );
$this -> assertFalse ( $attribute [ 'required' ]);
$this -> assertEquals ( 123.456 , $attribute [ 'default' ]);
$this -> assertEquals ( 0 , $attribute [ 'min' ]);
$this -> assertEquals ( 1000 , $attribute [ 'max' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-03-01 12:00:36 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => null ,
'min' => 0.0 ,
'max' => 1000.0
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-03-01 12:00:36 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertNull ( $new [ 'body' ][ 'default' ]);
$this -> assertEquals ( 0 , $new [ 'body' ][ 'min' ]);
$this -> assertEquals ( 1000 , $new [ 'body' ][ 'max' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 456.789 ,
'min' => 123.456 ,
'max' => 2000.0
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 456.789 , $new [ 'body' ][ 'default' ]);
$this -> assertEquals ( 123.456 , $new [ 'body' ][ 'min' ]);
$this -> assertEquals ( 2000 , $new [ 'body' ][ 'max' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-02-20 13:37:13 +00:00
'required' => false ,
2023-02-27 07:45:21 +00:00
'default' => 123.456 ,
'min' => 0.0 ,
]);
2025-02-20 13:37:13 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
2025-02-26 17:35:06 +00:00
'default' => 23.456 ,
'max' => 100.0 ,
2023-02-27 07:45:21 +00:00
]);
2025-02-20 13:37:13 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
2025-02-20 13:37:13 +00:00
/**
* Test against failure
*/
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-02-20 13:37:13 +00:00
'required' => 'no boolean' ,
2023-02-27 07:45:21 +00:00
'default' => 123.456 ,
2025-02-20 13:37:13 +00:00
'min' => 0.0 ,
'max' => 1000.0
2023-02-27 07:45:21 +00:00
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
2025-02-20 13:37:13 +00:00
'default' => 'i am no integer' ,
2023-02-27 07:45:21 +00:00
'min' => 0.0 ,
2025-02-20 13:37:13 +00:00
'max' => 500.0
2023-02-27 07:45:21 +00:00
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 123.456 ,
2025-02-20 13:37:13 +00:00
'min' => 'i am no integer' ,
'max' => 500.0
2023-02-27 07:45:21 +00:00
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 123.456 ,
2025-02-20 13:37:13 +00:00
'min' => 0.0 ,
'max' => 'i am no integer'
2023-02-27 07:45:21 +00:00
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'min' => 0.0 ,
'max' => 100.0 ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'default' => 123.456 ,
'min' => 0.0 ,
'max' => 100.0 ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
'default' => 123.456 ,
'min' => 0.0 ,
'max' => 100.0
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_DEFAULT_UNSUPPORTED , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 123.456 ,
'min' => 200.0 ,
'max' => 300.0
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_VALUE_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 123.456 ,
'min' => 0.0 ,
'max' => 100.0
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_VALUE_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/float/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 50.0 ,
'min' => 200.0 ,
'max' => 100.0
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_VALUE_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
}
/**
* @ depends testAttributeUpdate
*/
public function testAttributeUpdateBoolean ( array $data )
{
$key = 'boolean' ;
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/boolean/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => true
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( true , $new [ 'body' ][ 'default' ]);
2023-03-31 12:56:38 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2024-03-06 17:34:21 +00:00
$attribute = array_values ( array_filter ( $new [ 'body' ][ 'attributes' ], fn ( array $a ) => $a [ 'key' ] === $key ))[ 0 ] ? ? null ;
2023-03-31 12:56:38 +00:00
$this -> assertNotNull ( $attribute );
$this -> assertFalse ( $attribute [ 'required' ]);
$this -> assertEquals ( true , $attribute [ 'default' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/boolean/' . $key , array_merge ([
2023-03-01 12:00:36 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => null
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-03-01 12:00:36 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertNull ( $new [ 'body' ][ 'default' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/boolean/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => false
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( false , $new [ 'body' ][ 'default' ]);
/**
* Test against failure
*/
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/boolean/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => 'no boolean' ,
'default' => true
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/boolean/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'i am no boolean'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/boolean/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/boolean/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'default' => false
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/boolean/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
'default' => true
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_DEFAULT_UNSUPPORTED , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
}
/**
* @ depends testAttributeUpdate
*/
public function testAttributeUpdateDatetime ( array $data )
{
$key = 'datetime' ;
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => '1975-06-12 14:12:55+02:00'
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( '1975-06-12 14:12:55+02:00' , $new [ 'body' ][ 'default' ]);
2023-03-31 12:56:38 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2024-03-06 17:34:21 +00:00
$attribute = array_values ( array_filter ( $new [ 'body' ][ 'attributes' ], fn ( array $a ) => $a [ 'key' ] === $key ))[ 0 ] ? ? null ;
2023-03-31 12:56:38 +00:00
$this -> assertNotNull ( $attribute );
$this -> assertFalse ( $attribute [ 'required' ]);
$this -> assertEquals ( '1975-06-12 14:12:55+02:00' , $attribute [ 'default' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime/' . $key , array_merge ([
2023-03-01 12:00:36 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => null
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-03-01 12:00:36 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertNull ( $new [ 'body' ][ 'default' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => '1965-06-12 14:12:55+02:00'
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( '1965-06-12 14:12:55+02:00' , $new [ 'body' ][ 'default' ]);
/**
* Test against failure
*/
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => 'no boolean' ,
'default' => '1975-06-12 14:12:55+02:00'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'i am no datetime'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'default' => '1975-06-12 14:12:55+02:00'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
'default' => '1975-06-12 14:12:55+02:00'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_DEFAULT_UNSUPPORTED , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
}
/**
* @ depends testAttributeUpdate
*/
public function testAttributeUpdateEnum ( array $data )
{
$key = 'enum' ;
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'elements' => [ 'lorem' , 'ipsum' , 'dolor' ],
'required' => false ,
'default' => 'lorem'
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 'lorem' , $new [ 'body' ][ 'default' ]);
$this -> assertCount ( 3 , $new [ 'body' ][ 'elements' ]);
$this -> assertContains ( 'lorem' , $new [ 'body' ][ 'elements' ]);
$this -> assertContains ( 'ipsum' , $new [ 'body' ][ 'elements' ]);
$this -> assertContains ( 'dolor' , $new [ 'body' ][ 'elements' ]);
2023-03-31 12:56:38 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2024-03-06 17:34:21 +00:00
$attribute = array_values ( array_filter ( $new [ 'body' ][ 'attributes' ], fn ( array $a ) => $a [ 'key' ] === $key ))[ 0 ] ? ? null ;
2023-03-31 12:56:38 +00:00
$this -> assertNotNull ( $attribute );
$this -> assertFalse ( $attribute [ 'required' ]);
$this -> assertEquals ( 'lorem' , $attribute [ 'default' ]);
$this -> assertCount ( 3 , $attribute [ 'elements' ]);
$this -> assertContains ( 'lorem' , $attribute [ 'elements' ]);
$this -> assertContains ( 'ipsum' , $attribute [ 'elements' ]);
$this -> assertContains ( 'dolor' , $attribute [ 'elements' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
2023-03-01 12:00:36 +00:00
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'elements' => [ 'lorem' , 'ipsum' , 'dolor' ],
'required' => false ,
'default' => null
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-03-01 12:00:36 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertNull ( $new [ 'body' ][ 'default' ]);
$this -> assertCount ( 3 , $new [ 'body' ][ 'elements' ]);
$this -> assertContains ( 'lorem' , $new [ 'body' ][ 'elements' ]);
$this -> assertContains ( 'ipsum' , $new [ 'body' ][ 'elements' ]);
$this -> assertContains ( 'dolor' , $new [ 'body' ][ 'elements' ]);
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-03-01 12:00:36 +00:00
'content-type' => 'application/json' ,
2023-02-27 07:45:21 +00:00
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'elements' => [ 'ipsum' , 'dolor' ],
'required' => false ,
'default' => 'dolor'
]);
2023-03-02 08:31:35 +00:00
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:45:21 +00:00
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertFalse ( $new [ 'body' ][ 'required' ]);
$this -> assertEquals ( 'dolor' , $new [ 'body' ][ 'default' ]);
$this -> assertCount ( 2 , $new [ 'body' ][ 'elements' ]);
$this -> assertContains ( 'ipsum' , $new [ 'body' ][ 'elements' ]);
$this -> assertContains ( 'dolor' , $new [ 'body' ][ 'elements' ]);
/**
* Test against failure
*/
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'elements' => [],
'required' => false ,
'default' => 'lorem'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_VALUE_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'elements' => [ 'ipsum' , 'dolor' ],
'required' => false ,
'default' => 'lorem'
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_VALUE_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => 'no boolean' ,
'default' => 'lorem' ,
'elements' => [ 'lorem' , 'ipsum' , 'dolor' ],
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 123 ,
'elements' => [ 'lorem' , 'ipsum' , 'dolor' ],
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'lorem' ,
'elements' => 'i am no array' ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'lorem' ,
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
'elements' => [ 'lorem' , 'ipsum' , 'dolor' ],
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'default' => 'lorem' ,
'elements' => [ 'lorem' , 'ipsum' , 'dolor' ],
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: GENERAL_ARGUMENT_INVALID , $update [ 'body' ][ 'type' ]);
2023-02-27 07:45:21 +00:00
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/enum/' . $key , array_merge ([
2023-02-27 07:45:21 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => true ,
'default' => 'lorem' ,
'elements' => [ 'lorem' , 'ipsum' , 'dolor' ],
]);
$this -> assertEquals ( 400 , $update [ 'headers' ][ 'status-code' ]);
2023-02-27 07:47:20 +00:00
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_DEFAULT_UNSUPPORTED , $update [ 'body' ][ 'type' ]);
2023-02-26 15:45:42 +00:00
}
2023-02-27 07:59:37 +00:00
2024-08-30 09:50:42 +00:00
/**
* @ depends testAttributeUpdate
*/
public function testAttributeUpdateStringResize ( array $data )
{
$key = 'string' ;
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
$document = $this -> client -> call (
Client :: METHOD_POST ,
'/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' ,
array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]),
[
'documentId' => 'unique()' ,
'data' => [
'string' => 'string'
],
" permissions " => [ " read( \" any \" ) " ]
]
);
// Test Resize Up
$attribute = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'size' => 2048 ,
'default' => '' ,
'required' => false
]);
$this -> assertEquals ( 200 , $attribute [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 2048 , $attribute [ 'body' ][ 'size' ]);
// Test create new document with new size
$newDoc = $this -> client -> call (
Client :: METHOD_POST ,
'/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' ,
array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]),
[
'documentId' => 'unique()' ,
'data' => [
'string' => str_repeat ( 'a' , 2048 )
],
" permissions " => [ " read( \" any \" ) " ]
]
);
$this -> assertEquals ( 201 , $newDoc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 2048 , strlen ( $newDoc [ 'body' ][ 'string' ]));
// Test update document with new size
$document = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $document [ 'body' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'data' => [
'string' => str_repeat ( 'a' , 2048 )
]
]);
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 2048 , strlen ( $document [ 'body' ][ 'string' ]));
// Test Exception on resize down with data that is too large
$attribute = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'size' => 10 ,
'default' => '' ,
'required' => false
]);
$this -> assertEquals ( 400 , $attribute [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_INVALID_RESIZE , $attribute [ 'body' ][ 'type' ]);
// original documents to original size, remove new document
$document = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $document [ 'body' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'data' => [
'string' => 'string'
]
]);
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'string' , $document [ 'body' ][ 'string' ]);
$deleteDoc = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $newDoc [ 'body' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertEquals ( 204 , $deleteDoc [ 'headers' ][ 'status-code' ]);
// Test Resize Down
$attribute = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'size' => 10 ,
'default' => '' ,
'required' => false
]);
$this -> assertEquals ( 200 , $attribute [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 10 , $attribute [ 'body' ][ 'size' ]);
// Test create new document with new size
$newDoc = $this -> client -> call (
Client :: METHOD_POST ,
'/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' ,
array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]),
[
'documentId' => 'unique()' ,
'data' => [
'string' => str_repeat ( 'a' , 10 )
],
" permissions " => [ " read( \" any \" ) " ]
]
);
$this -> assertEquals ( 201 , $newDoc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 10 , strlen ( $newDoc [ 'body' ][ 'string' ]));
// Test update document with new size
$document = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $document [ 'body' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'data' => [
'string' => str_repeat ( 'a' , 10 )
]
]);
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 10 , strlen ( $document [ 'body' ][ 'string' ]));
2024-08-30 10:18:45 +00:00
// Try create document with string that is too large
$newDoc = $this -> client -> call (
Client :: METHOD_POST ,
'/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' ,
array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]),
[
'documentId' => 'unique()' ,
'data' => [
'string' => str_repeat ( 'a' , 11 )
],
" permissions " => [ " read( \" any \" ) " ]
]
);
$this -> assertEquals ( 400 , $newDoc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( AppwriteException :: DOCUMENT_INVALID_STRUCTURE , $newDoc [ 'body' ][ 'type' ]);
2024-08-30 09:50:42 +00:00
}
2023-02-27 07:59:37 +00:00
/**
* @ depends testAttributeUpdate
*/
public function testAttributeUpdateNotFound ( array $data )
{
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
$attributes = [
'string' => [
'required' => false ,
'default' => 'ipsum'
],
'email' => [
'required' => false ,
'default' => 'eldad@appwrite.io'
],
'ip' => [
'required' => false ,
'default' => '127.0.0.1'
],
'url' => [
'required' => false ,
'default' => 'https://appwrite.io'
],
'integer' => [
'required' => false ,
'default' => 5 ,
'min' => 0 ,
'max' => 10
],
'float' => [
'required' => false ,
'default' => 5.5 ,
'min' => 0.0 ,
'max' => 10.0
],
'datetime' => [
'required' => false ,
'default' => '1975-06-12 14:12:55+02:00'
],
'enum' => [
'elements' => [ 'lorem' , 'ipsum' , 'dolor' ],
'required' => false ,
'default' => 'lorem'
]
];
foreach ( $attributes as $key => $payload ) {
/**
* Check if Database exists
*/
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/i_dont_exist/collections/' . $collectionId . '/attributes/' . $key . '/unknown_' . $key , array_merge ([
2023-02-27 07:59:37 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), $payload );
$this -> assertEquals ( 404 , $update [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( AppwriteException :: DATABASE_NOT_FOUND , $update [ 'body' ][ 'type' ]);
/**
* Check if Collection exists
*/
2023-03-23 10:28:31 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/i_dont_exist/attributes/' . $key . '/unknown_' . $key , array_merge ([
2023-02-27 07:59:37 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), $payload );
$this -> assertEquals ( 404 , $update [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( AppwriteException :: COLLECTION_NOT_FOUND , $update [ 'body' ][ 'type' ]);
/**
* Check if Attribute exists
*/
2023-03-23 10:25:40 +00:00
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key . '/unknown_' . $key , array_merge ([
2023-02-27 07:59:37 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), $payload );
$this -> assertEquals ( 404 , $update [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( AppwriteException :: ATTRIBUTE_NOT_FOUND , $update [ 'body' ][ 'type' ]);
}
}
2024-08-16 06:18:52 +00:00
/**
* @ depends testAttributeUpdate
*/
public function testAttributeRename ( array $data )
{
$key = 'string' ;
$databaseId = $data [ 'databaseId' ];
$collectionId = $data [ 'collectionId' ];
// Create document to test against
$document = $this -> client -> call (
Client :: METHOD_POST ,
'/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' ,
array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]),
[
'documentId' => 'unique()' ,
'data' => [
'string' => 'string'
],
" permissions " => [ " read( \" any \" ) " ]
]
);
$this -> assertEquals ( 201 , $document [ 'headers' ][ 'status-code' ]);
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'required' => false ,
'default' => 'lorum' ,
'newKey' => 'new_string' ,
]);
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
$key = 'new_string' ;
$new = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/' . $key , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertEquals ( 'new_string' , $new [ 'body' ][ 'key' ]);
$doc1 = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $document [ 'body' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertArrayHasKey ( 'new_string' , $doc1 [ 'body' ]);
$this -> assertEquals ( 'string' , $doc1 [ 'body' ][ 'new_string' ]);
$this -> assertArrayNotHasKey ( 'string' , $doc1 [ 'body' ]);
// Try and create a new document with the new attribute
$doc2 = $this -> client -> call (
Client :: METHOD_POST ,
'/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' ,
array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]),
[
'documentId' => 'unique()' ,
'data' => [
'new_string' => 'string'
],
" permissions " => [ " read( \" any \" ) " ]
]
);
$this -> assertEquals ( 201 , $doc2 [ 'headers' ][ 'status-code' ]);
$this -> assertArrayHasKey ( 'new_string' , $doc2 [ 'body' ]);
$this -> assertEquals ( 'string' , $doc2 [ 'body' ][ 'new_string' ]);
// Expect fail, try and create a new document with the old attribute
$doc3 = $this -> client -> call (
Client :: METHOD_POST ,
'/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' ,
array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]),
[
'documentId' => 'unique()' ,
'data' => [
'string' => 'string'
],
" permissions " => [ " read( \" any \" ) " ]
]
);
$this -> assertEquals ( 400 , $doc3 [ 'headers' ][ 'status-code' ]);
}
2025-06-12 14:28:28 +00:00
public function createRelationshipCollections () : void
2024-08-16 06:18:52 +00:00
{
// Prepare the database with collections and relationships
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'databaseId' => 'database1' ,
'name' => 'Test Database'
]);
$databaseId = $database [ 'body' ][ '$id' ];
$this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => 'collection1' ,
'name' => 'level1' ,
'documentSecurity' => false ,
'permissions' => [
Permission :: create ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
]
]);
$this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => 'collection2' ,
'name' => 'level2' ,
'documentSecurity' => false ,
'permissions' => [
Permission :: create ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
]
]);
\sleep ( 2 );
}
2025-06-12 14:28:28 +00:00
public function cleanupRelationshipCollection () : void
2024-08-16 06:18:52 +00:00
{
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/database1' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
\sleep ( 2 );
}
public function testAttributeRenameRelationshipOneToMany ()
{
$databaseId = 'database1' ;
$collection1Id = 'collection1' ;
$collection2Id = 'collection2' ;
$this -> createRelationshipCollections ();
$relation = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/attributes/relationship' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'relatedCollectionId' => $collection2Id ,
'type' => 'oneToMany' ,
'twoWay' => true ,
'onDelete' => 'cascade' ,
'key' => 'level2' ,
'twoWayKey' => 'level1'
]);
\sleep ( 3 );
$collection1Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$collection1RelationAttribute = $collection1Attributes [ 'body' ][ 'attributes' ][ 0 ];
$this -> assertEquals ( $relation [ 'body' ][ 'side' ], $collection1RelationAttribute [ 'side' ]);
$this -> assertEquals ( $relation [ 'body' ][ 'twoWayKey' ], $collection1RelationAttribute [ 'twoWayKey' ]);
$this -> assertEquals ( $relation [ 'body' ][ 'relatedCollection' ], $collection1RelationAttribute [ 'relatedCollection' ]);
// Create a document for checking later
$originalDocument = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'unique()' ,
'data' => [
'level2' => [[
'$id' => 'unique()' ,
'$permissions' => [ " read( \" any \" ) " ]
]],
],
" permissions " => [ " read( \" any \" ) " ]
]);
$this -> assertEquals ( 201 , $originalDocument [ 'headers' ][ 'status-code' ]);
// Rename the attribute
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/attributes/level2' . '/relationship' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'newKey' => 'new_level_2'
]);
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
// Check the document's key has been renamed
$newDocument = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/documents/' . $originalDocument [ 'body' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-06-09 08:57:36 +00:00
]), [
2025-06-12 03:45:36 +00:00
'queries' => [
Query :: select ([ 'new_level_2.*' ]) -> toString ()
]
2025-06-09 08:57:36 +00:00
]);
2024-08-16 06:18:52 +00:00
$this -> assertArrayHasKey ( 'new_level_2' , $newDocument [ 'body' ]);
$this -> assertEquals ( 1 , count ( $newDocument [ 'body' ][ 'new_level_2' ]));
$this -> assertArrayNotHasKey ( 'level2' , $newDocument [ 'body' ]);
// Check level2 document has been renamed
$level2Document = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection2Id . '/documents/' . $newDocument [ 'body' ][ 'new_level_2' ][ 0 ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertArrayHasKey ( 'level1' , $level2Document [ 'body' ]);
$this -> assertNotEmpty ( $level2Document [ 'body' ][ 'level1' ]);
// Check if attribute was renamed on the parent's side
$collection1Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$this -> assertEquals ( 200 , $collection1Attributes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1 , count ( $collection1Attributes [ 'body' ][ 'attributes' ]));
$this -> assertEquals ( 'new_level_2' , $collection1Attributes [ 'body' ][ 'attributes' ][ 0 ][ 'key' ]);
// Check if attribute was renamed on the child's side
$collection2Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection2Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$this -> assertEquals ( 200 , $collection2Attributes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1 , count ( $collection2Attributes [ 'body' ][ 'attributes' ]));
$this -> assertEquals ( 'new_level_2' , $collection2Attributes [ 'body' ][ 'attributes' ][ 0 ][ 'twoWayKey' ]);
$this -> cleanupRelationshipCollection ();
}
public function testAttributeRenameRelationshipOneToOne ()
{
$databaseId = 'database1' ;
$collection1Id = 'collection1' ;
$collection2Id = 'collection2' ;
$this -> createRelationshipCollections ();
$relation = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/attributes/relationship' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'relatedCollectionId' => $collection2Id ,
'type' => 'oneToOne' ,
'twoWay' => true ,
'onDelete' => 'cascade' ,
'key' => 'level2' ,
'twoWayKey' => 'level1'
]);
\sleep ( 3 );
$collection1Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$collection1RelationAttribute = $collection1Attributes [ 'body' ][ 'attributes' ][ 0 ];
$this -> assertEquals ( $relation [ 'body' ][ 'side' ], $collection1RelationAttribute [ 'side' ]);
$this -> assertEquals ( $relation [ 'body' ][ 'twoWayKey' ], $collection1RelationAttribute [ 'twoWayKey' ]);
$this -> assertEquals ( $relation [ 'body' ][ 'relatedCollection' ], $collection1RelationAttribute [ 'relatedCollection' ]);
// Create a document for checking later
$originalDocument = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'unique()' ,
'data' => [
'level2' => [
'$id' => 'unique()' ,
'$permissions' => [ " read( \" any \" ) " ]
],
],
" permissions " => [ " read( \" any \" ) " ]
]);
$this -> assertEquals ( 201 , $originalDocument [ 'headers' ][ 'status-code' ]);
// Rename the attribute
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/attributes/level2' . '/relationship' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'newKey' => 'new_level_2'
]);
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
// Check the document's key has been renamed
$newDocument = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/documents/' . $originalDocument [ 'body' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-06-09 08:57:36 +00:00
]), [
2025-06-12 03:45:36 +00:00
'queries' => [
Query :: select ([ 'new_level_2.*' ]) -> toString ()
]
2025-06-09 08:57:36 +00:00
]);
2024-08-16 06:18:52 +00:00
$this -> assertArrayHasKey ( 'new_level_2' , $newDocument [ 'body' ]);
$this -> assertNotEmpty ( $newDocument [ 'body' ][ 'new_level_2' ]);
$this -> assertArrayNotHasKey ( 'level2' , $newDocument [ 'body' ]);
// Check level2 document has been renamed
$level2Document = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection2Id . '/documents/' . $newDocument [ 'body' ][ 'new_level_2' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertArrayHasKey ( 'level1' , $level2Document [ 'body' ]);
$this -> assertNotEmpty ( $level2Document [ 'body' ][ 'level1' ]);
// Check if attribute was renamed on the parent's side
$collection1Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$this -> assertEquals ( 200 , $collection1Attributes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1 , count ( $collection1Attributes [ 'body' ][ 'attributes' ]));
$this -> assertEquals ( 'new_level_2' , $collection1Attributes [ 'body' ][ 'attributes' ][ 0 ][ 'key' ]);
// Check if attribute was renamed on the child's side
$collection2Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection2Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$this -> assertEquals ( 200 , $collection2Attributes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1 , count ( $collection2Attributes [ 'body' ][ 'attributes' ]));
$this -> assertEquals ( 'new_level_2' , $collection2Attributes [ 'body' ][ 'attributes' ][ 0 ][ 'twoWayKey' ]);
$this -> cleanupRelationshipCollection ();
}
public function testAttributeRenameRelationshipManyToOne ()
{
$databaseId = 'database1' ;
$collection1Id = 'collection1' ;
$collection2Id = 'collection2' ;
$this -> createRelationshipCollections ();
$relation = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/attributes/relationship' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'relatedCollectionId' => $collection2Id ,
'type' => 'manyToOne' ,
'twoWay' => true ,
'onDelete' => 'cascade' ,
'key' => 'level2' ,
'twoWayKey' => 'level1'
]);
\sleep ( 3 );
$collection1Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$collection1RelationAttribute = $collection1Attributes [ 'body' ][ 'attributes' ][ 0 ];
$this -> assertEquals ( $relation [ 'body' ][ 'side' ], $collection1RelationAttribute [ 'side' ]);
$this -> assertEquals ( $relation [ 'body' ][ 'twoWayKey' ], $collection1RelationAttribute [ 'twoWayKey' ]);
$this -> assertEquals ( $relation [ 'body' ][ 'relatedCollection' ], $collection1RelationAttribute [ 'relatedCollection' ]);
// Create a document for checking later
$originalDocument = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'unique()' ,
'data' => [
'level2' => [
'$id' => 'unique()' ,
'$permissions' => [ " read( \" any \" ) " ]
],
],
" permissions " => [ " read( \" any \" ) " ]
]);
$this -> assertEquals ( 201 , $originalDocument [ 'headers' ][ 'status-code' ]);
// Rename the attribute
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/attributes/level2' . '/relationship' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'newKey' => 'new_level_2'
]);
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
// Check the document's key has been renamed
$newDocument = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/documents/' . $originalDocument [ 'body' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-06-09 08:57:36 +00:00
]), [
2025-06-12 03:45:36 +00:00
'queries' => [
Query :: select ([ 'new_level_2.*' ]) -> toString ()
]
2025-06-09 08:57:36 +00:00
]);
2024-08-16 06:18:52 +00:00
$this -> assertArrayHasKey ( 'new_level_2' , $newDocument [ 'body' ]);
$this -> assertNotEmpty ( $newDocument [ 'body' ][ 'new_level_2' ]);
$this -> assertArrayNotHasKey ( 'level2' , $newDocument [ 'body' ]);
// Check level2 document has been renamed
$level2Document = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection2Id . '/documents/' . $newDocument [ 'body' ][ 'new_level_2' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-06-09 09:16:43 +00:00
]), [
2025-06-12 03:45:36 +00:00
'queries' => [
Query :: select ([ '*' , 'level1.*' ]) -> toString ()
]
2025-06-09 09:16:43 +00:00
]);
2024-08-16 06:18:52 +00:00
$this -> assertArrayHasKey ( 'level1' , $level2Document [ 'body' ]);
$this -> assertNotEmpty ( $level2Document [ 'body' ][ 'level1' ]);
// Check if attribute was renamed on the parent's side
$collection1Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$this -> assertEquals ( 200 , $collection1Attributes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1 , count ( $collection1Attributes [ 'body' ][ 'attributes' ]));
$this -> assertEquals ( 'new_level_2' , $collection1Attributes [ 'body' ][ 'attributes' ][ 0 ][ 'key' ]);
// Check if attribute was renamed on the child's side
$collection2Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection2Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$this -> assertEquals ( 200 , $collection2Attributes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1 , count ( $collection2Attributes [ 'body' ][ 'attributes' ]));
$this -> assertEquals ( 'new_level_2' , $collection2Attributes [ 'body' ][ 'attributes' ][ 0 ][ 'twoWayKey' ]);
$this -> cleanupRelationshipCollection ();
}
public function testAttributeRenameRelationshipManyToMany ()
{
$databaseId = 'database1' ;
$collection1Id = 'collection1' ;
$collection2Id = 'collection2' ;
$this -> createRelationshipCollections ();
$relation = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/attributes/relationship' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'relatedCollectionId' => $collection2Id ,
'type' => 'manyToOne' ,
'twoWay' => true ,
'onDelete' => 'cascade' ,
'key' => 'level2' ,
'twoWayKey' => 'level1'
]);
\sleep ( 3 );
$collection1Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$collection1RelationAttribute = $collection1Attributes [ 'body' ][ 'attributes' ][ 0 ];
$this -> assertEquals ( $relation [ 'body' ][ 'side' ], $collection1RelationAttribute [ 'side' ]);
$this -> assertEquals ( $relation [ 'body' ][ 'twoWayKey' ], $collection1RelationAttribute [ 'twoWayKey' ]);
$this -> assertEquals ( $relation [ 'body' ][ 'relatedCollection' ], $collection1RelationAttribute [ 'relatedCollection' ]);
// Create a document for checking later
$originalDocument = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'unique()' ,
'data' => [
'level2' => [
'$id' => 'unique()' ,
'$permissions' => [ " read( \" any \" ) " ]
],
],
" permissions " => [ " read( \" any \" ) " ]
]);
$this -> assertEquals ( 201 , $originalDocument [ 'headers' ][ 'status-code' ]);
// Rename the attribute
$update = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/attributes/level2' . '/relationship' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'newKey' => 'new_level_2'
]);
$this -> assertEquals ( 200 , $update [ 'headers' ][ 'status-code' ]);
// Check the document's key has been renamed
$newDocument = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id . '/documents/' . $originalDocument [ 'body' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-06-09 08:57:36 +00:00
]), [
2025-06-12 03:45:36 +00:00
'queries' => [
Query :: select ([ 'new_level_2.*' ]) -> toString ()
]
2025-06-09 08:57:36 +00:00
]);
2024-08-16 06:18:52 +00:00
$this -> assertArrayHasKey ( 'new_level_2' , $newDocument [ 'body' ]);
$this -> assertNotEmpty ( $newDocument [ 'body' ][ 'new_level_2' ]);
$this -> assertArrayNotHasKey ( 'level2' , $newDocument [ 'body' ]);
// Check level2 document has been renamed
$level2Document = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection2Id . '/documents/' . $newDocument [ 'body' ][ 'new_level_2' ][ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-06-09 08:57:36 +00:00
]), [
2025-06-12 03:45:36 +00:00
'queries' => [
Query :: select ([ '*' , 'level1.*' ]) -> toString ()
]
2025-06-09 08:57:36 +00:00
]);
2024-08-16 06:18:52 +00:00
$this -> assertArrayHasKey ( 'level1' , $level2Document [ 'body' ]);
$this -> assertNotEmpty ( $level2Document [ 'body' ][ 'level1' ]);
// Check if attribute was renamed on the parent's side
$collection1Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection1Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$this -> assertEquals ( 200 , $collection1Attributes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1 , count ( $collection1Attributes [ 'body' ][ 'attributes' ]));
$this -> assertEquals ( 'new_level_2' , $collection1Attributes [ 'body' ][ 'attributes' ][ 0 ][ 'key' ]);
// Check if attribute was renamed on the child's side
$collection2Attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collection2Id , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
$this -> assertEquals ( 200 , $collection2Attributes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1 , count ( $collection2Attributes [ 'body' ][ 'attributes' ]));
$this -> assertEquals ( 'new_level_2' , $collection2Attributes [ 'body' ][ 'attributes' ][ 0 ][ 'twoWayKey' ]);
$this -> cleanupRelationshipCollection ();
}
2025-05-08 05:17:02 +00:00
public function testBulkCreate () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'databaseId' => ID :: unique (),
'name' => 'Bulk Create Perms' ,
]);
$this -> assertNotEmpty ( $database [ 'body' ][ '$id' ]);
$databaseId = $database [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Bulk Create Perms' ,
'documentSecurity' => true ,
'permissions' => [
Permission :: create ( Role :: any ()),
Permission :: read ( Role :: any ()),
Permission :: delete ( Role :: any ()),
Permission :: update ( Role :: any ()),
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$data = [
'$id' => $collection [ 'body' ][ '$id' ],
'databaseId' => $collection [ 'body' ][ 'databaseId' ]
];
// Await attribute
$numberAttribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ '$id' ] . '/attributes/integer' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'number' ,
'required' => true ,
]);
$this -> assertEquals ( 202 , $numberAttribute [ 'headers' ][ 'status-code' ]);
sleep ( 1 );
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $data [ '$id' ] } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => ID :: unique (),
'number' => 1 ,
],
[
'$id' => ID :: unique (),
'number' => 2 ,
],
[
'$id' => ID :: unique (),
'number' => 3 ,
],
],
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 3 , $response [ 'body' ][ 'documents' ]);
$response = $this -> client -> call ( Client :: METHOD_GET , " /databases/ { $databaseId } /collections/ { $data [ '$id' ] } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 1 , $response [ 'body' ][ 'documents' ][ 0 ][ 'number' ]);
$this -> assertEquals ( 2 , $response [ 'body' ][ 'documents' ][ 1 ][ 'number' ]);
$this -> assertEquals ( 3 , $response [ 'body' ][ 'documents' ][ 2 ][ 'number' ]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 3 , $response [ 'body' ][ 'documents' ]);
2025-05-08 06:09:37 +00:00
// TEST SUCCESS - $id is auto-assigned if not included in bulk documents
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $data [ '$id' ] } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'number' => 1 ,
]
],
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2025-05-08 05:17:02 +00:00
// TEST FAIL - Can't use data and document together
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $data [ '$id' ] } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'number' => 5
],
'documents' => [
[
'$id' => ID :: unique (),
'number' => 1 ,
]
],
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
// TEST FAIL - Can't use $documentId and create bulk documents
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $data [ '$id' ] } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'documents' => [
[
'$id' => ID :: unique (),
'number' => 1 ,
]
],
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2025-05-08 06:09:37 +00:00
// TEST FAIL - Can't include invalid ID in bulk documents
2025-05-08 05:17:02 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $data [ '$id' ] } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
2025-05-08 06:09:37 +00:00
'$id' => '$invalid' ,
2025-05-08 05:17:02 +00:00
'number' => 1 ,
]
],
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
// TEST FAIL - Can't miss number in bulk documents
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $data [ '$id' ] } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => ID :: unique (),
'number' => 1 ,
],
[
'$id' => ID :: unique (),
],
],
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
// TEST FAIL - Can't push more than APP_LIMIT_DATABASE_BATCH documents
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $data [ '$id' ] } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => array_fill ( 0 , APP_LIMIT_DATABASE_BATCH + 1 , [
'$id' => ID :: unique (),
'number' => 1 ,
]),
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2025-05-08 06:09:37 +00:00
// TEST FAIL - Can't include invalid permissions in nested documents
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $data [ '$id' ] } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => ID :: unique (),
'$permissions' => [ 'invalid' ],
'number' => 1 ,
],
],
]);
2025-05-08 05:17:02 +00:00
// TEST FAIL - Can't bulk create in a collection with relationships
2025-05-08 06:09:37 +00:00
$collection2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Bulk Related' ,
'documentSecurity' => true ,
'permissions' => [],
]);
$response = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ '$id' ] . '/attributes/relationship' , array_merge ([
2025-05-08 05:17:02 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], $this -> getHeaders ()), [
2025-05-08 06:09:37 +00:00
'relatedCollectionId' => $collection2 [ 'body' ][ '$id' ],
2025-05-08 05:17:02 +00:00
'type' => 'manyToOne' ,
'twoWay' => true ,
'onDelete' => 'cascade' ,
'key' => 'level2' ,
'twoWayKey' => 'level1'
]);
$this -> assertEquals ( 202 , $response [ 'headers' ][ 'status-code' ]);
sleep ( 1 );
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $data [ '$id' ] } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[ '$id' => ID :: unique (), 'number' => 1 ,],
[ '$id' => ID :: unique (), 'number' => 2 ,],
],
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
}
2025-05-08 06:09:37 +00:00
public function testBulkUpdate () : void
2025-05-08 05:17:02 +00:00
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'databaseId' => ID :: unique (),
'name' => 'Bulk Updates'
]);
$this -> assertNotEmpty ( $database [ 'body' ][ '$id' ]);
$databaseId = $database [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Bulk Updates' ,
'documentSecurity' => true ,
'permissions' => [
Permission :: create ( Role :: any ()),
Permission :: read ( Role :: any ()),
Permission :: delete ( Role :: any ()),
Permission :: update ( Role :: any ()),
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$data = [
'$id' => $collection [ 'body' ][ '$id' ],
'databaseId' => $collection [ 'body' ][ 'databaseId' ]
];
// Await attribute
$numberAttribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ '$id' ] . '/attributes/integer' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'number' ,
'required' => true ,
]);
$this -> assertEquals ( 202 , $numberAttribute [ 'headers' ][ 'status-code' ]);
// Wait for database worker to create attributes
sleep ( 2 );
// Create documents
$createBulkDocuments = function ( $amount = 10 ) use ( $data ) {
$documents = [];
for ( $x = 1 ; $x <= $amount ; $x ++ ) {
$documents [] = [
'$id' => ID :: unique (),
'number' => $x ,
];
}
$doc = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => $documents ,
]);
$this -> assertEquals ( 201 , $doc [ 'headers' ][ 'status-code' ]);
};
$createBulkDocuments ();
2025-06-09 14:29:01 +00:00
/**
* Wait for database to purge cache ...
*
* This test specifically failed on 1.6 . x response format ,
* could be due to the slow or overworked machine , but being safe here !
*/
sleep ( 5 );
2025-05-08 05:17:02 +00:00
// TEST: Update all documents
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'number' => 100 ,
'$permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
]
],
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 10 , $response [ 'body' ][ 'documents' ]);
2025-06-09 14:15:48 +00:00
/**
* Wait for database to purge cache ...
*
* This test specifically failed on 1.6 . x response format ,
* could be due to the slow or overworked machine , but being safe here !
*/
sleep ( 5 );
2025-05-08 05:17:02 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
Query :: equal ( 'number' , [ 100 ]) -> toString (),
]);
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 10 , $documents [ 'body' ][ 'total' ]);
2025-10-20 15:18:17 +00:00
/**
2025-10-29 09:08:08 +00:00
* Test for SUCCESS with total = false
2025-10-20 15:18:17 +00:00
*/
$documentsWithIncludeTotalFalse = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-10-29 09:08:08 +00:00
'total' => false
2025-10-20 15:18:17 +00:00
]);
2025-10-20 15:38:14 +00:00
$this -> assertEquals ( 200 , $documentsWithIncludeTotalFalse [ 'headers' ][ 'status-code' ]);
2025-10-20 15:18:17 +00:00
$this -> assertIsArray ( $documentsWithIncludeTotalFalse [ 'body' ]);
$this -> assertIsArray ( $documentsWithIncludeTotalFalse [ 'body' ][ 'documents' ]);
$this -> assertIsInt ( $documentsWithIncludeTotalFalse [ 'body' ][ 'total' ]);
$this -> assertEquals ( 0 , $documentsWithIncludeTotalFalse [ 'body' ][ 'total' ]);
$this -> assertGreaterThan ( 0 , count ( $documentsWithIncludeTotalFalse [ 'body' ][ 'documents' ]));
2025-05-08 05:17:02 +00:00
$returnedDocuments = $response [ 'body' ][ 'documents' ];
$refetchedDocuments = $documents [ 'body' ][ 'documents' ];
$this -> assertEquals ( $returnedDocuments , $refetchedDocuments );
foreach ( $documents [ 'body' ][ 'documents' ] as $document ) {
$this -> assertEquals ([
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
], $document [ '$permissions' ]);
$this -> assertEquals ( $collection [ 'body' ][ '$id' ], $document [ '$collectionId' ]);
$this -> assertEquals ( $data [ 'databaseId' ], $document [ '$databaseId' ]);
$this -> assertEquals ( $document [ 'number' ], 100 );
}
// TEST: Check permissions persist
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'number' => 200
],
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 10 , $response [ 'body' ][ 'documents' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
Query :: equal ( 'number' , [ 200 ]) -> toString (),
]);
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 10 , $documents [ 'body' ][ 'total' ]);
foreach ( $documents [ 'body' ][ 'documents' ] as $document ) {
$this -> assertEquals ([
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
], $document [ '$permissions' ]);
}
// TEST: Update documents with limit
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'number' => 300
],
'queries' => [
Query :: limit ( 5 ) -> toString (),
],
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 5 , $response [ 'body' ][ 'documents' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'queries' => [ Query :: equal ( 'number' , [ 200 ]) -> toString ()]
]);
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 5 , $documents [ 'body' ][ 'total' ]);
// TEST: Update documents with offset
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'number' => 300
],
'queries' => [
Query :: offset ( 5 ) -> toString (),
],
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 5 , $response [ 'body' ][ 'documents' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'queries' => [ Query :: equal ( 'number' , [ 300 ]) -> toString ()]
]);
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 10 , $documents [ 'body' ][ 'total' ]);
// TEST: Update documents with equals filter
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'number' => 400
],
'queries' => [
Query :: equal ( 'number' , [ 300 ]) -> toString (),
],
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 10 , $response [ 'body' ][ 'documents' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'queries' => [ Query :: equal ( 'number' , [ 400 ]) -> toString ()]
]);
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 10 , $documents [ 'body' ][ 'total' ]);
// TEST: Fail - Can't bulk update in a collection with relationships
2025-05-08 06:09:37 +00:00
$collection2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Bulk Related' ,
'documentSecurity' => true ,
'permissions' => [],
]);
2025-05-08 05:17:02 +00:00
2025-05-08 06:09:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ '$id' ] . '/attributes/relationship' , array_merge ([
2025-05-08 05:17:02 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], $this -> getHeaders ()), [
2025-05-08 06:09:37 +00:00
'relatedCollectionId' => $collection2 [ 'body' ][ '$id' ],
2025-05-08 05:17:02 +00:00
'type' => 'manyToOne' ,
'twoWay' => true ,
'onDelete' => 'cascade' ,
'key' => 'level2' ,
'twoWayKey' => 'level1'
]);
$this -> assertEquals ( 202 , $response [ 'headers' ][ 'status-code' ]);
sleep ( 1 );
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'number' => 500
],
'queries' => [
Query :: equal ( 'number' , [ 300 ]) -> toString (),
],
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
}
2025-05-08 06:09:37 +00:00
public function testBulkUpsert () : void
2025-05-08 05:17:02 +00:00
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'databaseId' => ID :: unique (),
'name' => 'Bulk Upserts'
]);
$this -> assertNotEmpty ( $database [ 'body' ][ '$id' ]);
$databaseId = $database [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Bulk Upserts' ,
'documentSecurity' => true ,
'permissions' => [
Permission :: create ( Role :: any ()),
Permission :: read ( Role :: any ()),
Permission :: delete ( Role :: any ()),
Permission :: update ( Role :: any ()),
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$data = [
'$id' => $collection [ 'body' ][ '$id' ],
'databaseId' => $collection [ 'body' ][ 'databaseId' ]
];
// Await attribute
$numberAttribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ '$id' ] . '/attributes/integer' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'number' ,
'required' => true ,
]);
$this -> assertEquals ( 202 , $numberAttribute [ 'headers' ][ 'status-code' ]);
// Wait for database worker to create attributes
sleep ( 2 );
// Create documents
$createBulkDocuments = function ( $amount = 10 ) use ( $data ) {
$documents = [];
for ( $x = 1 ; $x <= $amount ; $x ++ ) {
$documents [] = [
'$id' => " $x " ,
'number' => $x ,
];
}
$response = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => $documents ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
return $documents ;
};
$documents = $createBulkDocuments ();
// Update 1 document
$documents [ \array_key_last ( $documents )][ 'number' ] = 1000 ;
// Add 1 document
$documents [] = [ 'number' => 11 ];
// TEST: Upsert all documents
$response = $this -> client -> call ( Client :: METHOD_PUT , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => $documents ,
]);
// Unchanged docs are skipped. 2 documents should be returned, 1 updated and 1 inserted.
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 2 , $response [ 'body' ][ 'documents' ]);
$this -> assertEquals ( 1000 , $response [ 'body' ][ 'documents' ][ 0 ][ 'number' ]);
$this -> assertEquals ( 11 , $response [ 'body' ][ 'documents' ][ 1 ][ 'number' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 11 , $documents [ 'body' ][ 'total' ]);
foreach ( $documents [ 'body' ][ 'documents' ] as $index => $document ) {
$this -> assertEquals ( $collection [ 'body' ][ '$id' ], $document [ '$collectionId' ]);
$this -> assertEquals ( $data [ 'databaseId' ], $document [ '$databaseId' ]);
switch ( $index ) {
case 9 :
$this -> assertEquals ( 1000 , $document [ 'number' ]);
break ;
default :
$this -> assertEquals ( $index + 1 , $document [ 'number' ]);
}
}
// TEST: Upsert permissions
$response = $this -> client -> call ( Client :: METHOD_PUT , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => '1' ,
'number' => 1000 ,
],
[
'$id' => '10' ,
'$permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
],
'number' => 10 ,
],
],
]);
$this -> assertEquals ( 1000 , $response [ 'body' ][ 'documents' ][ 0 ][ 'number' ]);
$this -> assertEquals ([], $response [ 'body' ][ 'documents' ][ 0 ][ '$permissions' ]);
$this -> assertEquals ([
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
], $response [ 'body' ][ 'documents' ][ 1 ][ '$permissions' ]);
// TEST: Fail - Can't bulk upsert in a collection with relationships
2025-05-08 06:09:37 +00:00
$collection2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Bulk Related' ,
'documentSecurity' => true ,
'permissions' => [],
]);
2025-05-08 05:17:02 +00:00
2025-05-08 06:09:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ '$id' ] . '/attributes/relationship' , array_merge ([
2025-05-08 05:17:02 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], $this -> getHeaders ()), [
2025-05-08 06:09:37 +00:00
'relatedCollectionId' => $collection2 [ 'body' ][ '$id' ],
2025-05-08 05:17:02 +00:00
'type' => 'manyToOne' ,
'twoWay' => true ,
'onDelete' => 'cascade' ,
'key' => 'level2' ,
'twoWayKey' => 'level1'
]);
$this -> assertEquals ( 202 , $response [ 'headers' ][ 'status-code' ]);
sleep ( 1 );
$response = $this -> client -> call ( Client :: METHOD_PUT , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => '1' ,
'number' => 1000 ,
],
],
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
}
2025-05-08 06:09:37 +00:00
public function testBulkDelete () : void
2025-05-08 05:17:02 +00:00
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'databaseId' => ID :: unique (),
'name' => 'Bulk Deletes'
]);
$this -> assertNotEmpty ( $database [ 'body' ][ '$id' ]);
$databaseId = $database [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Bulk Deletes' ,
'documentSecurity' => false ,
'permissions' => [
Permission :: create ( Role :: any ()),
Permission :: read ( Role :: any ()),
Permission :: delete ( Role :: any ()),
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$data = [
'$id' => $collection [ 'body' ][ '$id' ],
'databaseId' => $collection [ 'body' ][ 'databaseId' ]
];
// Await attribute
$numberAttribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ '$id' ] . '/attributes/integer' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'number' ,
'required' => true ,
]);
$this -> assertEquals ( 202 , $numberAttribute [ 'headers' ][ 'status-code' ]);
// wait for database worker to create attributes
sleep ( 2 );
// Create documents
$createBulkDocuments = function ( $amount = 11 ) use ( $data ) {
$documents = [];
for ( $x = 0 ; $x < $amount ; $x ++ ) {
$documents [] = [
'$id' => ID :: unique (),
'number' => $x ,
];
}
$doc = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => $documents ,
]);
$this -> assertEquals ( 201 , $doc [ 'headers' ][ 'status-code' ]);
};
$createBulkDocuments ();
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 11 , $documents [ 'body' ][ 'total' ]);
// TEST: Delete all documents
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 11 , $response [ 'body' ][ 'total' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 0 , $documents [ 'body' ][ 'total' ]);
// TEST: Delete documents with query
$createBulkDocuments ();
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 11 , $documents [ 'body' ][ 'total' ]);
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'queries' => [
Query :: lessThan ( 'number' , 5 ) -> toString (),
],
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 5 , $response [ 'body' ][ 'total' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 6 , $documents [ 'body' ][ 'total' ]);
foreach ( $documents [ 'body' ][ 'documents' ] as $document ) {
$this -> assertGreaterThanOrEqual ( 5 , $document [ 'number' ]);
}
// Cleanup
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 6 , $response [ 'body' ][ 'total' ]);
// SUCCESS: Delete documents with query
$createBulkDocuments ();
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 11 , $documents [ 'body' ][ 'total' ]);
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'queries' => [
Query :: lessThan ( 'number' , 5 ) -> toString (),
],
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 5 , $response [ 'body' ][ 'total' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 6 , $documents [ 'body' ][ 'total' ]);
// Cleanup
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 6 , $response [ 'body' ][ 'total' ]);
// SUCCESS: Delete Documents with limit query
$createBulkDocuments ();
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 11 , $documents [ 'body' ][ 'total' ]);
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'queries' => [
Query :: limit ( 2 ) -> toString (),
],
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 2 , $response [ 'body' ][ 'total' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 9 , $documents [ 'body' ][ 'total' ]);
// Cleanup
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 9 , $response [ 'body' ][ 'total' ]);
// SUCCESS: Delete Documents with offset query
$createBulkDocuments ();
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 11 , $documents [ 'body' ][ 'total' ]);
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'queries' => [
Query :: offset ( 5 ) -> toString (),
],
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 6 , $response [ 'body' ][ 'total' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 5 , $documents [ 'body' ][ 'total' ]);
$lastDoc = end ( $documents [ 'body' ][ 'documents' ]);
$this -> assertNotEmpty ( $lastDoc );
$this -> assertEquals ( 4 , $lastDoc [ 'number' ]);
// Cleanup
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 5 , $response [ 'body' ][ 'total' ]);
// SUCCESS: Delete 100 documents
$createBulkDocuments ( 100 );
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 100 , $documents [ 'body' ][ 'total' ]);
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 100 , $response [ 'body' ][ 'total' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 0 , $documents [ 'body' ][ 'total' ]);
// TEST: Fail - Can't bulk delete in a collection with relationships
2025-05-08 06:09:37 +00:00
$collection2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Bulk Related' ,
'documentSecurity' => true ,
'permissions' => [],
]);
2025-05-08 05:17:02 +00:00
2025-05-08 06:09:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $data [ '$id' ] . '/attributes/relationship' , array_merge ([
2025-05-08 05:17:02 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], $this -> getHeaders ()), [
2025-05-08 06:09:37 +00:00
'relatedCollectionId' => $collection2 [ 'body' ][ '$id' ],
2025-05-08 05:17:02 +00:00
'type' => 'manyToOne' ,
'twoWay' => true ,
'onDelete' => 'cascade' ,
'key' => 'level2' ,
'twoWayKey' => 'level1'
]);
$this -> assertEquals ( 202 , $response [ 'headers' ][ 'status-code' ]);
sleep ( 1 );
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
}
2025-07-31 15:02:14 +00:00
public function testDateTimeDocument () : void
{
$databaseId = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'DateTime Test Database' ,
]);
$this -> assertEquals ( 201 , $databaseId [ 'headers' ][ 'status-code' ]);
$databaseId = $databaseId [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'create_modify_dates' ,
'documentSecurity' => true ,
'permissions' => [],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$collectionId = $collection [ 'body' ][ '$id' ];
// Create string attribute
$this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'string' ,
'size' => 128 ,
'required' => false ,
]);
// Create datetime attribute
$this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'datetime' ,
'required' => false ,
'format' => 'datetime' ,
]);
sleep ( 1 );
$date = '2000-01-01T10:00:00.000+00:00' ;
// Test - default behaviour of external datetime attribute not changed
$doc = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'doc1' ,
'data' => [
'datetime' => ''
],
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: write ( Role :: any ()),
Permission :: update ( Role :: any ()),
]
]);
$this -> assertEquals ( 201 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $doc [ 'body' ][ 'datetime' ]);
$this -> assertNotEmpty ( $doc [ 'body' ][ '$createdAt' ]);
$this -> assertNotEmpty ( $doc [ 'body' ][ '$updatedAt' ]);
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/doc1' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $doc [ 'body' ][ 'datetime' ]);
$this -> assertNotEmpty ( $doc [ 'body' ][ '$createdAt' ]);
$this -> assertNotEmpty ( $doc [ 'body' ][ '$updatedAt' ]);
// Test - modifying $createdAt and $updatedAt
$doc = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'doc2' ,
'data' => [
'$createdAt' => $date
],
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: write ( Role :: any ()),
Permission :: update ( Role :: any ()),
]
]);
$this -> assertEquals ( 201 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $doc [ 'body' ][ '$createdAt' ], $date );
$this -> assertNotEmpty ( $doc [ 'body' ][ '$updatedAt' ]);
$this -> assertNotEquals ( $doc [ 'body' ][ '$updatedAt' ], $date );
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/doc2' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $doc [ 'body' ][ '$createdAt' ], $date );
$this -> assertNotEmpty ( $doc [ 'body' ][ '$updatedAt' ]);
$this -> assertNotEquals ( $doc [ 'body' ][ '$updatedAt' ], $date );
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testSingleDocumentDateOperations () : void
{
$databaseId = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Single Date Operations Database' ,
]);
$this -> assertEquals ( 201 , $databaseId [ 'headers' ][ 'status-code' ]);
$databaseId = $databaseId [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'normal_date_operations' ,
'documentSecurity' => true ,
'permissions' => [],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$collectionId = $collection [ 'body' ][ '$id' ];
// Create string attribute
$this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'string' ,
'size' => 128 ,
'required' => false ,
]);
sleep ( 1 );
$createDate = '2000-01-01T10:00:00.000+00:00' ;
$updateDate = '2000-02-01T15:30:00.000+00:00' ;
$date1 = '2000-01-01T10:00:00.000+00:00' ;
$date2 = '2000-02-01T15:30:00.000+00:00' ;
$date3 = '2000-03-01T20:45:00.000+00:00' ;
// Test 1: Create with custom createdAt, then update with custom updatedAt
$doc = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'doc1' ,
'data' => [
'string' => 'initial' ,
'$createdAt' => $createDate
],
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: write ( Role :: any ()),
Permission :: update ( Role :: any ()),
]
]);
$this -> assertEquals ( 201 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $createDate , $doc [ 'body' ][ '$createdAt' ]);
$this -> assertNotEquals ( $createDate , $doc [ 'body' ][ '$updatedAt' ]);
// Update with custom updatedAt
$updatedDoc = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/doc1' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'data' => [
'string' => 'updated' ,
'$updatedAt' => $updateDate
]
]);
$this -> assertEquals ( 200 , $updatedDoc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $createDate , $updatedDoc [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( $updateDate , $updatedDoc [ 'body' ][ '$updatedAt' ]);
// Test 2: Create with both custom dates
$doc2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'doc2' ,
'data' => [
'string' => 'both_dates' ,
'$createdAt' => $createDate ,
'$updatedAt' => $updateDate
],
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: write ( Role :: any ()),
Permission :: update ( Role :: any ()),
]
]);
$this -> assertEquals ( 201 , $doc2 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $createDate , $doc2 [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( $updateDate , $doc2 [ 'body' ][ '$updatedAt' ]);
// Test 3: Create without dates, then update with custom dates
$doc3 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'doc3' ,
'data' => [
'string' => 'no_dates'
],
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: write ( Role :: any ()),
Permission :: update ( Role :: any ()),
]
]);
$this -> assertEquals ( 201 , $doc3 [ 'headers' ][ 'status-code' ]);
$updatedDoc3 = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/doc3' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'data' => [
'string' => 'updated_no_dates' ,
'$createdAt' => $createDate ,
'$updatedAt' => $updateDate
]
]);
$this -> assertEquals ( 200 , $updatedDoc3 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $createDate , $updatedDoc3 [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( $updateDate , $updatedDoc3 [ 'body' ][ '$updatedAt' ]);
// Test 4: Update only createdAt
$doc4 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'doc4' ,
'data' => [
'string' => 'initial'
],
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: write ( Role :: any ()),
Permission :: update ( Role :: any ()),
]
]);
$this -> assertEquals ( 201 , $doc4 [ 'headers' ][ 'status-code' ]);
$originalCreatedAt4 = $doc4 [ 'body' ][ '$createdAt' ];
$originalUpdatedAt4 = $doc4 [ 'body' ][ '$updatedAt' ];
$updatedDoc4 = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/doc4' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'data' => [
'string' => 'updated' ,
'$updatedAt' => null ,
'$createdAt' => null
],
]);
$this -> assertEquals ( 200 , $updatedDoc4 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $originalCreatedAt4 , $updatedDoc4 [ 'body' ][ '$createdAt' ]);
$this -> assertNotEquals ( $originalUpdatedAt4 , $updatedDoc4 [ 'body' ][ '$updatedAt' ]);
// Test 5: Update only updatedAt
$finalDoc4 = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/doc4' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'data' => [
'string' => 'final' ,
'$updatedAt' => $updateDate ,
'$createdAt' => $createDate
]
]);
$this -> assertEquals ( 200 , $finalDoc4 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $createDate , $finalDoc4 [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( $updateDate , $finalDoc4 [ 'body' ][ '$updatedAt' ]);
// Test 6: Create with updatedAt, update with createdAt
$doc5 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'doc5' ,
'data' => [
'string' => 'doc5' ,
'$updatedAt' => $date2
],
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: write ( Role :: any ()),
Permission :: update ( Role :: any ()),
]
]);
$this -> assertEquals ( 201 , $doc5 [ 'headers' ][ 'status-code' ]);
$this -> assertNotEquals ( $date2 , $doc5 [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( $date2 , $doc5 [ 'body' ][ '$updatedAt' ]);
$updatedDoc5 = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/doc5' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'data' => [
'string' => 'doc5_updated' ,
'$createdAt' => $date1
]
]);
$this -> assertEquals ( 200 , $updatedDoc5 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $date1 , $updatedDoc5 [ 'body' ][ '$createdAt' ]);
$this -> assertNotEquals ( $date2 , $updatedDoc5 [ 'body' ][ '$updatedAt' ]);
// Test 7: Create with both dates, update with different dates
$doc6 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'doc6' ,
'data' => [
'string' => 'doc6' ,
'$createdAt' => $date1 ,
'$updatedAt' => $date2
],
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: write ( Role :: any ()),
Permission :: update ( Role :: any ()),
]
]);
$this -> assertEquals ( 201 , $doc6 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $date1 , $doc6 [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( $date2 , $doc6 [ 'body' ][ '$updatedAt' ]);
$updatedDoc6 = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/doc6' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'data' => [
'string' => 'doc6_updated' ,
'$createdAt' => $date3 ,
'$updatedAt' => $date3
]
]);
$this -> assertEquals ( 200 , $updatedDoc6 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $date3 , $updatedDoc6 [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( $date3 , $updatedDoc6 [ 'body' ][ '$updatedAt' ]);
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testBulkDocumentDateOperations () : void
{
$databaseId = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Bulk Date Operations Database' ,
]);
$this -> assertEquals ( 201 , $databaseId [ 'headers' ][ 'status-code' ]);
$databaseId = $databaseId [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'bulk_date_operations' ,
'documentSecurity' => true ,
'permissions' => [],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$collectionId = $collection [ 'body' ][ '$id' ];
// Create string attribute
$this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'string' ,
'size' => 128 ,
'required' => false ,
]);
sleep ( 1 );
$createDate = '2000-01-01T10:00:00.000+00:00' ;
$updateDate = '2000-02-01T15:30:00.000+00:00' ;
// Test 1: Bulk create with different date configurations
$documents = [
[
'$id' => 'doc1' ,
'string' => 'doc1' ,
'$createdAt' => $createDate ,
'$permissions' => [ Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),]
],
[
'$id' => 'doc2' ,
'string' => 'doc2' ,
'$updatedAt' => $updateDate ,
'$permissions' => [ Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),]
],
[
'$id' => 'doc3' ,
'string' => 'doc3' ,
'$createdAt' => $createDate ,
'$updatedAt' => $updateDate ,
'$permissions' => [ Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),]
],
[
'$id' => 'doc4' ,
'string' => 'doc4' ,
'$permissions' => [ Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),]
],
[
'$id' => 'doc5' ,
'string' => 'doc5' ,
'$createdAt' => null ,
'$permissions' => [ Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),]
],
[
'$id' => 'doc6' ,
'string' => 'doc6' ,
'$updatedAt' => null ,
'$permissions' => [ Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),]
]
];
// Create all documents in one bulk operation
$bulkCreateResponse = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documents' => $documents
]);
$this -> assertEquals ( 201 , $bulkCreateResponse [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( count ( $documents ), $bulkCreateResponse [ 'body' ][ 'documents' ]);
// Verify initial state
foreach ([ 'doc1' , 'doc3' ] as $id ) {
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $id , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $createDate , $doc [ 'body' ][ '$createdAt' ], " createdAt mismatch for $id " );
}
foreach ([ 'doc2' , 'doc3' ] as $id ) {
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $id , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $updateDate , $doc [ 'body' ][ '$updatedAt' ], " updatedAt mismatch for $id " );
}
foreach ([ 'doc4' , 'doc5' , 'doc6' ] as $id ) {
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $id , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $doc [ 'body' ][ '$createdAt' ], " createdAt missing for $id " );
$this -> assertNotEmpty ( $doc [ 'body' ][ '$updatedAt' ], " updatedAt missing for $id " );
}
// Test 2: Bulk update with custom dates
$updateData = [
'data' => [
'string' => 'updated' ,
'$createdAt' => $createDate ,
'$updatedAt' => $updateDate ,
'$permissions' => [ Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),]
],
];
// Use bulk update instead of individual updates
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), $updateData );
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 6 , $response [ 'body' ][ 'documents' ]);
// Verify updated state
foreach ([ 'doc1' , 'doc3' ] as $id ) {
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $id , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $createDate , $doc [ 'body' ][ '$createdAt' ], " createdAt mismatch for $id " );
$this -> assertEquals ( $updateDate , $doc [ 'body' ][ '$updatedAt' ], " updatedAt mismatch for $id " );
$this -> assertEquals ( 'updated' , $doc [ 'body' ][ 'string' ], " string mismatch for $id " );
}
foreach ([ 'doc2' , 'doc4' , 'doc5' , 'doc6' ] as $id ) {
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $id , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $updateDate , $doc [ 'body' ][ '$updatedAt' ], " updatedAt mismatch for $id " );
$this -> assertEquals ( 'updated' , $doc [ 'body' ][ 'string' ], " string mismatch for $id " );
}
$newDate = '2000-03-01T20:45:00.000+00:00' ;
$updateDataEnabled = [
'data' => [
'string' => 'enabled_update' ,
'$createdAt' => $newDate ,
'$updatedAt' => $newDate
],
];
// Use bulk update instead of individual updates
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), $updateDataEnabled );
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 6 , $response [ 'body' ][ 'documents' ]);
// Verify final state
foreach ([ 'doc1' , 'doc2' , 'doc3' , 'doc4' , 'doc5' , 'doc6' ] as $id ) {
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $id , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $newDate , $doc [ 'body' ][ '$createdAt' ], " createdAt mismatch for $id " );
$this -> assertEquals ( $newDate , $doc [ 'body' ][ '$updatedAt' ], " updatedAt mismatch for $id " );
$this -> assertEquals ( 'enabled_update' , $doc [ 'body' ][ 'string' ], " string mismatch for $id " );
}
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testUpsertDateOperations () : void
{
$databaseId = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Upsert Date Operations Database' ,
]);
$this -> assertEquals ( 201 , $databaseId [ 'headers' ][ 'status-code' ]);
$databaseId = $databaseId [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'upsert_date_operations' ,
'documentSecurity' => true ,
'permissions' => [],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$collectionId = $collection [ 'body' ][ '$id' ];
// Create string attribute
$this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'string' ,
'size' => 128 ,
'required' => false ,
]);
sleep ( 1 );
$createDate = '2000-01-01T10:00:00.000+00:00' ;
$updateDate = '2000-02-01T15:30:00.000+00:00' ;
$date1 = '2000-01-01T10:00:00.000+00:00' ;
$date2 = '2000-02-01T15:30:00.000+00:00' ;
$date3 = '2000-03-01T20:45:00.000+00:00' ;
// Test 1: Upsert new document with custom createdAt
$upsertDoc1 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'upsert1' ,
'data' => [
'string' => 'upsert1_initial' ,
'$permissions' => [
Permission :: read ( Role :: any ()),
Permission :: write ( Role :: any ()),
Permission :: update ( Role :: any ()),
],
'$createdAt' => $createDate
],
]);
$this -> assertEquals ( 201 , $upsertDoc1 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $createDate , $upsertDoc1 [ 'body' ][ '$createdAt' ]);
$this -> assertNotEquals ( $createDate , $upsertDoc1 [ 'body' ][ '$updatedAt' ]);
// Test 2: Upsert existing document with custom updatedAt
$updatedUpsertDoc1 = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/upsert1' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'data' => [
'string' => 'upsert1_updated' ,
'$updatedAt' => $updateDate
],
]);
$this -> assertEquals ( 200 , $updatedUpsertDoc1 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $createDate , $updatedUpsertDoc1 [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( $updateDate , $updatedUpsertDoc1 [ 'body' ][ '$updatedAt' ]);
// Test 3: Upsert new document with both custom dates
$upsertDoc2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => 'upsert2' ,
'data' => [
'string' => 'upsert2_both_dates' ,
'$permissions' => [
Permission :: read ( Role :: any ()),
Permission :: write ( Role :: any ()),
Permission :: update ( Role :: any ()),
],
'$createdAt' => $createDate ,
'$updatedAt' => $updateDate
],
]);
$this -> assertEquals ( 201 , $upsertDoc2 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $createDate , $upsertDoc2 [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( $updateDate , $upsertDoc2 [ 'body' ][ '$updatedAt' ]);
// Test 4: Upsert existing document with different dates
$updatedUpsertDoc2 = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/upsert2' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'data' => [
'string' => 'upsert2_updated' ,
'$createdAt' => $date3 ,
'$updatedAt' => $date3 ,
'$permissions' => [
Permission :: read ( Role :: any ()),
Permission :: write ( Role :: any ()),
Permission :: update ( Role :: any ()),
],
]
]);
$this -> assertEquals ( 200 , $updatedUpsertDoc2 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $date3 , $updatedUpsertDoc2 [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( $date3 , $updatedUpsertDoc2 [ 'body' ][ '$updatedAt' ]);
// Test 5: Bulk upsert operations with custom dates
$upsertDocuments = [
[
'$id' => 'bulk_upsert1' ,
'string' => 'bulk_upsert1_initial' ,
'$createdAt' => $createDate
],
[
'$id' => 'bulk_upsert2' ,
'string' => 'bulk_upsert2_initial' ,
'$updatedAt' => $updateDate
],
[
'$id' => 'bulk_upsert3' ,
'string' => 'bulk_upsert3_initial' ,
'$createdAt' => $createDate ,
'$updatedAt' => $updateDate
],
[
'$id' => 'bulk_upsert4' ,
'string' => 'bulk_upsert4_initial'
]
];
// Create documents using bulk upsert
$response = $this -> client -> call ( Client :: METHOD_PUT , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documents' => $upsertDocuments
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 4 , $response [ 'body' ][ 'documents' ]);
// Test 7: Verify initial bulk upsert state
foreach ([ 'bulk_upsert1' , 'bulk_upsert3' ] as $id ) {
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $id , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $createDate , $doc [ 'body' ][ '$createdAt' ], " createdAt mismatch for $id " );
}
foreach ([ 'bulk_upsert2' , 'bulk_upsert3' ] as $id ) {
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $id , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $updateDate , $doc [ 'body' ][ '$updatedAt' ], " updatedAt mismatch for $id " );
}
foreach ([ 'bulk_upsert4' ] as $id ) {
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $id , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $doc [ 'body' ][ '$createdAt' ], " createdAt missing for $id " );
$this -> assertNotEmpty ( $doc [ 'body' ][ '$updatedAt' ], " updatedAt missing for $id " );
}
// Test 8: Bulk upsert update with custom dates
$newDate = '2000-04-01T12:00:00.000+00:00' ;
$updateUpsertData = [
'data' => [
'string' => 'bulk_upsert_updated' ,
'$createdAt' => $newDate ,
'$updatedAt' => $newDate
],
'queries' => [ Query :: equal ( '$id' , [ 'bulk_upsert1' , 'bulk_upsert2' , 'bulk_upsert3' , 'bulk_upsert4' ]) -> toString ()]
];
$upsertIds = [ 'bulk_upsert1' , 'bulk_upsert2' , 'bulk_upsert3' , 'bulk_upsert4' ];
// Use bulk update instead of individual updates
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), $updateUpsertData );
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 4 , $response [ 'body' ][ 'documents' ]);
// Verify updated state
foreach ( $upsertIds as $id ) {
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $id , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $newDate , $doc [ 'body' ][ '$createdAt' ], " createdAt mismatch for $id " );
$this -> assertEquals ( $newDate , $doc [ 'body' ][ '$updatedAt' ], " updatedAt mismatch for $id " );
$this -> assertEquals ( 'bulk_upsert_updated' , $doc [ 'body' ][ 'string' ], " string mismatch for $id " );
}
// Test 9: checking by passing null to each
$updateUpsertDataNull = [
'data' => [
'string' => 'bulk_upsert_null_test' ,
'$createdAt' => null ,
'$updatedAt' => null
],
'queries' => [ Query :: equal ( '$id' , [ 'bulk_upsert1' , 'bulk_upsert2' , 'bulk_upsert3' , 'bulk_upsert4' ]) -> toString ()]
];
// Use bulk update instead of individual updates
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), $updateUpsertDataNull );
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 4 , $response [ 'body' ][ 'documents' ]);
// Verify null handling
foreach ( $upsertIds as $id ) {
$doc = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $id , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 200 , $doc [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $doc [ 'body' ][ '$createdAt' ], " createdAt missing for $id " );
$this -> assertNotEmpty ( $doc [ 'body' ][ '$updatedAt' ], " updatedAt missing for $id " );
}
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
2025-08-22 07:17:35 +00:00
public function testSpatialBulkOperations () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'databaseId' => ID :: unique (),
'name' => 'Spatial Bulk Operations Test Database'
]);
$this -> assertNotEmpty ( $database [ 'body' ][ '$id' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// Create collection with spatial attributes
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Spatial Bulk Operations Collection' ,
'documentSecurity' => true ,
'permissions' => [
Permission :: create ( Role :: any ()),
Permission :: read ( Role :: any ()),
Permission :: delete ( Role :: any ()),
Permission :: update ( Role :: any ()),
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$collectionId = $collection [ 'body' ][ '$id' ];
// Create string attribute
$nameAttribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'name' ,
'size' => 256 ,
'required' => true ,
]);
$this -> assertEquals ( 202 , $nameAttribute [ 'headers' ][ 'status-code' ]);
// Create point attribute
$pointAttribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/point' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'location' ,
'required' => true ,
]);
$this -> assertEquals ( 202 , $pointAttribute [ 'headers' ][ 'status-code' ]);
// Create polygon attribute
$polygonAttribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/polygon' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'area' ,
'required' => false ,
]);
$this -> assertEquals ( 202 , $polygonAttribute [ 'headers' ][ 'status-code' ]);
// Wait for attributes to be created
sleep ( 2 );
// Test 1: Bulk create with spatial data
$spatialDocuments = [];
for ( $i = 0 ; $i < 5 ; $i ++ ) {
$spatialDocuments [] = [
'$id' => ID :: unique (),
'name' => 'Location ' . $i ,
'location' => [ 10.0 + $i , 20.0 + $i ], // POINT
'area' => [
[ 10.0 + $i , 20.0 + $i ],
[ 11.0 + $i , 20.0 + $i ],
[ 11.0 + $i , 21.0 + $i ],
[ 10.0 + $i , 21.0 + $i ],
[ 10.0 + $i , 20.0 + $i ]
] // POLYGON
];
}
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $collectionId } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => $spatialDocuments ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 5 , $response [ 'body' ][ 'documents' ]);
// Verify created documents have proper spatial data
foreach ( $response [ 'body' ][ 'documents' ] as $index => $document ) {
$this -> assertNotEmpty ( $document [ '$id' ]);
$this -> assertNotEmpty ( $document [ 'name' ]);
$this -> assertIsArray ( $document [ 'location' ]);
$this -> assertIsArray ( $document [ 'area' ]);
$this -> assertCount ( 2 , $document [ 'location' ]); // POINT has 2 coordinates
// Check polygon structure - it might be stored as an array of arrays
if ( is_array ( $document [ 'area' ][ 0 ])) {
$this -> assertGreaterThan ( 1 , count ( $document [ 'area' ][ 0 ])); // POLYGON has multiple points
} else {
$this -> assertGreaterThan ( 1 , count ( $document [ 'area' ])); // POLYGON has multiple points
}
$this -> assertEquals ( 'Location ' . $index , $document [ 'name' ]);
$this -> assertEquals ([ 10.0 + $index , 20.0 + $index ], $document [ 'location' ]);
}
// Test 2: Bulk update with spatial data
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'name' => 'Updated Location' ,
'location' => [ 15.0 , 25.0 ], // New POINT
'area' => [
[ 15.0 , 25.0 ],
[ 16.0 , 25.0 ],
[ 16.0 , 26.0 ],
[ 15.0 , 26.0 ],
[ 15.0 , 25.0 ]
] // New POLYGON
],
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 5 , $response [ 'body' ][ 'documents' ]);
// Verify updated documents
foreach ( $response [ 'body' ][ 'documents' ] as $document ) {
$this -> assertEquals ( 'Updated Location' , $document [ 'name' ]);
$this -> assertEquals ([ 15.0 , 25.0 ], $document [ 'location' ]);
// The area might be stored as an array of arrays, so check the first element
$this -> assertIsArray ( $document [ 'area' ]);
if ( is_array ( $document [ 'area' ][ 0 ])) {
// If it's an array of arrays, check the first polygon
$this -> assertEquals ([
[ 15.0 , 25.0 ],
[ 16.0 , 25.0 ],
[ 16.0 , 26.0 ],
[ 15.0 , 26.0 ],
[ 15.0 , 25.0 ]
], $document [ 'area' ][ 0 ]);
} else {
// If it's a direct array, check the whole thing
$this -> assertEquals ([
[ 15.0 , 25.0 ],
[ 16.0 , 25.0 ],
[ 16.0 , 26.0 ],
[ 15.0 , 26.0 ],
[ 15.0 , 25.0 ]
], $document [ 'area' ]);
}
}
// Test 3: Bulk upsert with spatial data
$upsertDocuments = [
[
'$id' => 'upsert1' ,
'name' => 'Upsert Location 1' ,
'location' => [ 30.0 , 40.0 ],
'area' => [
[ 30.0 , 40.0 ],
[ 31.0 , 40.0 ],
[ 31.0 , 41.0 ],
[ 30.0 , 41.0 ],
[ 30.0 , 40.0 ]
]
],
[
'$id' => 'upsert2' ,
'name' => 'Upsert Location 2' ,
'location' => [ 35.0 , 45.0 ],
'area' => [
[ 35.0 , 45.0 ],
[ 36.0 , 45.0 ],
[ 36.0 , 46.0 ],
[ 35.0 , 46.0 ],
[ 35.0 , 45.0 ]
]
]
];
$response = $this -> client -> call ( Client :: METHOD_PUT , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => $upsertDocuments ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 2 , $response [ 'body' ][ 'documents' ]);
// Verify upserted documents
foreach ( $response [ 'body' ][ 'documents' ] as $document ) {
$this -> assertNotEmpty ( $document [ '$id' ]);
$this -> assertIsArray ( $document [ 'location' ]);
$this -> assertIsArray ( $document [ 'area' ]);
// Verify the spatial data structure
$this -> assertCount ( 2 , $document [ 'location' ]); // POINT has 2 coordinates
if ( is_array ( $document [ 'area' ][ 0 ])) {
$this -> assertGreaterThan ( 1 , count ( $document [ 'area' ][ 0 ])); // POLYGON has multiple points
} else {
$this -> assertGreaterThan ( 1 , count ( $document [ 'area' ])); // POLYGON has multiple points
}
}
// Test 4: Edge cases for spatial bulk operations
// Test 4a: Invalid point coordinates (should fail)
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $collectionId } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => ID :: unique (),
'name' => 'Invalid Point' ,
2025-09-02 17:30:31 +00:00
'location' => [ 1000.0 , 2000.0 ],
'area' => [ 10.0 , 10.0 ]
2025-08-22 07:17:35 +00:00
]
],
]);
2025-09-02 17:30:31 +00:00
// invalid polygon
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2025-08-22 07:17:35 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $collectionId } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => ID :: unique (),
'name' => 'Invalid Polygon' ,
'location' => [ 10.0 , 20.0 ],
'area' => [
[ 10.0 , 20.0 ],
[ 11.0 , 20.0 ]
]
]
],
]);
2025-09-02 17:30:31 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2025-08-22 07:17:35 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $collectionId } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => ID :: unique (),
'name' => 'Missing Location' ,
// Missing required 'location' attribute
'area' => [
[ 10.0 , 20.0 ],
[ 11.0 , 20.0 ],
[ 11.0 , 21.0 ],
[ 10.0 , 21.0 ],
[ 10.0 , 20.0 ]
]
]
],
]);
// This should fail due to missing required attribute
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
// Test 4e: Mixed valid and invalid documents in bulk (should fail)
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $collectionId } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => ID :: unique (),
'name' => 'Valid Document' ,
'location' => [ 10.0 , 20.0 ],
'area' => [
[ 10.0 , 20.0 ],
[ 11.0 , 20.0 ],
[ 11.0 , 21.0 ],
[ 10.0 , 21.0 ],
[ 10.0 , 20.0 ]
]
],
[
'$id' => ID :: unique (),
'name' => 'Invalid Document' ,
// Missing required 'location' attribute
'area' => [
[ 10.0 , 20.0 ],
[ 11.0 , 20.0 ],
[ 11.0 , 21.0 ],
[ 10.0 , 21.0 ],
[ 10.0 , 20.0 ]
]
]
],
]);
// This should fail due to mixed valid/invalid documents
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
// Test 4f: Very large spatial data (stress test)
$largePolygon = [];
for ( $i = 0 ; $i < 1000 ; $i ++ ) {
$largePolygon [] = [ $i * 0.001 , $i * 0.001 ];
}
$largePolygon [] = [ 0 , 0 ]; // Close the polygon
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $collectionId } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => ID :: unique (),
'name' => 'Large Polygon Test' ,
'location' => [ 0.0 , 0.0 ],
'area' => $largePolygon
]
],
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
// Test 4g: Null values in spatial attributes (should fail)
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $collectionId } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => ID :: unique (),
'name' => 'Null Values Test' ,
'location' => null , // Null point
'area' => null // Null polygon
]
],
]);
// This should fail due to null values
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
// Test 4h: Bulk operations with spatial data exceeding limits
$largeBulkDocuments = [];
for ( $i = 0 ; $i < 100 ; $i ++ ) {
$largeBulkDocuments [] = [
'$id' => ID :: unique (),
'name' => 'Bulk Test ' . $i ,
'location' => [ $i * 0.1 , $i * 0.1 ],
'area' => [
[ $i * 0.1 , $i * 0.1 ],
[( $i + 1 ) * 0.1 , $i * 0.1 ],
[( $i + 1 ) * 0.1 , ( $i + 1 ) * 0.1 ],
[ $i * 0.1 , ( $i + 1 ) * 0.1 ],
[ $i * 0.1 , $i * 0.1 ]
]
];
}
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $collectionId } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => $largeBulkDocuments ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testSpatialBulkOperationsWithLineStrings () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'databaseId' => ID :: unique (),
'name' => 'Spatial LineString Bulk Operations Test Database'
]);
$this -> assertNotEmpty ( $database [ 'body' ][ '$id' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// Create collection with line string attributes
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Spatial LineString Bulk Operations Collection' ,
'documentSecurity' => true ,
'permissions' => [
Permission :: create ( Role :: any ()),
Permission :: read ( Role :: any ()),
Permission :: delete ( Role :: any ()),
Permission :: update ( Role :: any ()),
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$collectionId = $collection [ 'body' ][ '$id' ];
// Create string attribute
$nameAttribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'name' ,
'size' => 256 ,
'required' => true ,
]);
$this -> assertEquals ( 202 , $nameAttribute [ 'headers' ][ 'status-code' ]);
// Create line string attribute
$lineAttribute = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/line' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'path' ,
'required' => true ,
]);
// Handle both 201 (created) and 202 (accepted) status codes
$this -> assertEquals ( 202 , $lineAttribute [ 'headers' ][ 'status-code' ]);
// Wait for attributes to be created
sleep ( 2 );
// Test bulk create with line string data
$lineStringDocuments = [];
for ( $i = 0 ; $i < 3 ; $i ++ ) {
$lineStringDocuments [] = [
'$id' => ID :: unique (),
'name' => 'Path ' . $i ,
'path' => [
[ $i * 10 , $i * 10 ],
[( $i + 1 ) * 10 , ( $i + 1 ) * 10 ],
[( $i + 2 ) * 10 , ( $i + 2 ) * 10 ]
] // LINE STRING with 3 points
];
}
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $collectionId } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => $lineStringDocuments ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 3 , $response [ 'body' ][ 'documents' ]);
// Verify created documents have proper line string data
foreach ( $response [ 'body' ][ 'documents' ] as $index => $document ) {
$this -> assertNotEmpty ( $document [ '$id' ]);
$this -> assertNotEmpty ( $document [ 'name' ]);
$this -> assertIsArray ( $document [ 'path' ]);
$this -> assertGreaterThan ( 1 , count ( $document [ 'path' ])); // LINE STRING has multiple points
$this -> assertEquals ( 'Path ' . $index , $document [ 'name' ]);
$this -> assertCount ( 3 , $document [ 'path' ]); // Each line string has 3 points
}
// Test bulk update with line string data
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'name' => 'Updated Path' ,
'path' => [
[ 0 , 0 ],
[ 50 , 50 ],
2025-09-11 16:25:36 +00:00
[ 80 , 80 ]
2025-08-22 07:17:35 +00:00
] // New LINE STRING
],
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 3 , $response [ 'body' ][ 'documents' ]);
// Verify updated documents
foreach ( $response [ 'body' ][ 'documents' ] as $document ) {
$this -> assertEquals ( 'Updated Path' , $document [ 'name' ]);
$this -> assertEquals ([
[ 0 , 0 ],
[ 50 , 50 ],
2025-09-11 16:25:36 +00:00
[ 80 , 80 ]
2025-08-22 07:17:35 +00:00
], $document [ 'path' ]);
}
// Test: Invalid line string (single point - should fail)
$response = $this -> client -> call ( Client :: METHOD_POST , " /databases/ { $databaseId } /collections/ { $collectionId } /documents " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documents' => [
[
'$id' => ID :: unique (),
'name' => 'Invalid Line String' ,
'path' => [[ 10 , 20 ]] // Single point - invalid line string
]
],
]);
2025-09-02 17:30:31 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2025-08-22 07:17:35 +00:00
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId . '/collections/' . $collectionId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
2025-12-01 08:43:50 +00:00
public function testCreateCollectionWithAttributesAndIndexes () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Test Multi Create' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// Test: Create collection with attributes and indexes in one call
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: custom ( 'movies' ),
'name' => 'Movies' ,
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: create ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
],
'documentSecurity' => true ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
'required' => true ,
],
[
'key' => 'year' ,
'type' => Database :: VAR_INTEGER ,
'required' => false ,
'default' => 2024 ,
],
[
'key' => 'rating' ,
'type' => Database :: VAR_FLOAT ,
'required' => false ,
],
[
'key' => 'active' ,
'type' => Database :: VAR_BOOLEAN ,
'required' => false ,
'default' => true ,
],
],
'indexes' => [
[
'key' => 'idx_title' ,
'type' => Database :: INDEX_KEY ,
'attributes' => [ 'title' ],
],
[
'key' => 'idx_year' ,
'type' => Database :: INDEX_KEY ,
'attributes' => [ 'year' ],
'orders' => [ 'DESC' ],
],
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Movies' , $collection [ 'body' ][ 'name' ]);
$this -> assertEquals ( 'movies' , $collection [ 'body' ][ '$id' ]);
// Verify attributes were created and are available
$attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/movies/attributes' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertEquals ( 200 , $attributes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 4 , $attributes [ 'body' ][ 'total' ]);
$attrByKey = [];
foreach ( $attributes [ 'body' ][ 'attributes' ] as $attr ) {
$attrByKey [ $attr [ 'key' ]] = $attr ;
}
$this -> assertEquals ( 'available' , $attrByKey [ 'title' ][ 'status' ]);
$this -> assertEquals ( Database :: VAR_STRING , $attrByKey [ 'title' ][ 'type' ]);
$this -> assertEquals ( 256 , $attrByKey [ 'title' ][ 'size' ]);
$this -> assertTrue ( $attrByKey [ 'title' ][ 'required' ]);
$this -> assertEquals ( 'available' , $attrByKey [ 'year' ][ 'status' ]);
$this -> assertEquals ( Database :: VAR_INTEGER , $attrByKey [ 'year' ][ 'type' ]);
$this -> assertFalse ( $attrByKey [ 'year' ][ 'required' ]);
$this -> assertEquals ( 2024 , $attrByKey [ 'year' ][ 'default' ]);
$this -> assertEquals ( 'available' , $attrByKey [ 'rating' ][ 'status' ]);
$this -> assertEquals ( Database :: VAR_FLOAT , $attrByKey [ 'rating' ][ 'type' ]);
$this -> assertEquals ( 'available' , $attrByKey [ 'active' ][ 'status' ]);
$this -> assertEquals ( Database :: VAR_BOOLEAN , $attrByKey [ 'active' ][ 'type' ]);
$this -> assertTrue ( $attrByKey [ 'active' ][ 'default' ]);
// Verify indexes were created and are available
$indexes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/movies/indexes' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertEquals ( 200 , $indexes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 2 , $indexes [ 'body' ][ 'total' ]);
$idxByKey = [];
foreach ( $indexes [ 'body' ][ 'indexes' ] as $idx ) {
$idxByKey [ $idx [ 'key' ]] = $idx ;
}
$this -> assertEquals ( 'available' , $idxByKey [ 'idx_title' ][ 'status' ]);
$this -> assertEquals ( Database :: INDEX_KEY , $idxByKey [ 'idx_title' ][ 'type' ]);
$this -> assertEquals ([ 'title' ], $idxByKey [ 'idx_title' ][ 'attributes' ]);
$this -> assertEquals ( 'available' , $idxByKey [ 'idx_year' ][ 'status' ]);
$this -> assertEquals ( Database :: INDEX_KEY , $idxByKey [ 'idx_year' ][ 'type' ]);
$this -> assertEquals ([ 'year' ], $idxByKey [ 'idx_year' ][ 'attributes' ]);
$this -> assertEquals ([ 'DESC' ], $idxByKey [ 'idx_year' ][ 'orders' ]);
// Verify we can create documents using the attributes
$document = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/movies/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => ID :: unique (),
'data' => [
'title' => 'The Matrix' ,
'year' => 1999 ,
'rating' => 8.7 ,
'active' => true ,
],
]);
$this -> assertEquals ( 201 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'The Matrix' , $document [ 'body' ][ 'title' ]);
$this -> assertEquals ( 1999 , $document [ 'body' ][ 'year' ]);
$this -> assertEquals ( 8.7 , $document [ 'body' ][ 'rating' ]);
$this -> assertTrue ( $document [ 'body' ][ 'active' ]);
// Test: Create document with default values
$document2 = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/movies/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => ID :: unique (),
'data' => [
'title' => 'New Movie' ,
],
]);
$this -> assertEquals ( 201 , $document2 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'New Movie' , $document2 [ 'body' ][ 'title' ]);
$this -> assertEquals ( 2024 , $document2 [ 'body' ][ 'year' ]); // default value
$this -> assertTrue ( $document2 [ 'body' ][ 'active' ]); // default value
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testCreateCollectionWithAttributesAndIndexesErrors () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Test Multi Create Errors' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// Test: Invalid attribute type
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Invalid Type' ,
'attributes' => [
[
'key' => 'test' ,
'type' => 'invalid_type' ,
'size' => 256 ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Index referencing non-existent attribute
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Invalid Index' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
'indexes' => [
[
'key' => 'idx_invalid' ,
'type' => Database :: INDEX_KEY ,
'attributes' => [ 'nonexistent' ],
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: String attribute without size
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'No Size' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
],
],
]);
// Should succeed with default size
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Required attribute with default value (should fail)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Required With Default' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
'required' => true ,
'default' => 'test' ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Duplicate attribute keys
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Duplicate Keys' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 128 ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Index on system attribute ($id)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'System Attr Index' ,
'attributes' => [],
'indexes' => [
[
'key' => 'idx_id' ,
'type' => Database :: INDEX_KEY ,
'attributes' => [ '$id' ],
],
],
]);
// Should succeed - system attributes can be indexed
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
2025-12-03 08:17:38 +00:00
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testCreateCollectionCleanupOnFailure () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Test Cleanup' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
$collectionId = ID :: unique ();
// Test: Create collection with invalid index referencing non-existent attribute (should fail)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => $collectionId ,
'name' => 'Should Fail' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
'indexes' => [
[
'key' => 'idx_invalid' ,
'type' => Database :: INDEX_KEY ,
'attributes' => [ 'nonexistent' ],
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Verify collection was cleaned up - creating with same ID should succeed
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => $collectionId ,
'name' => 'Should Succeed' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
2025-12-01 08:43:50 +00:00
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testCreateCollectionWithEnumAttribute () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Test Enum' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// Test: Create collection with enum attribute
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: custom ( 'status_collection' ),
'name' => 'Status Collection' ,
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: create ( Role :: any ()),
],
'attributes' => [
[
'key' => 'status' ,
'type' => Database :: VAR_STRING ,
'size' => 32 ,
'required' => true ,
'format' => 'enum' ,
'elements' => [ 'pending' , 'active' , 'completed' , 'cancelled' ],
],
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
// Verify attribute
$attributes = $this -> client -> call ( Client :: METHOD_GET , '/databases/' . $databaseId . '/collections/status_collection/attributes' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
$this -> assertEquals ( 200 , $attributes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1 , $attributes [ 'body' ][ 'total' ]);
$this -> assertEquals ( 'available' , $attributes [ 'body' ][ 'attributes' ][ 0 ][ 'status' ]);
$this -> assertEquals ( 'enum' , $attributes [ 'body' ][ 'attributes' ][ 0 ][ 'format' ]);
$this -> assertEquals ([ 'pending' , 'active' , 'completed' , 'cancelled' ], $attributes [ 'body' ][ 'attributes' ][ 0 ][ 'elements' ]);
// Test creating document with valid enum value
$document = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/status_collection/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => ID :: unique (),
'data' => [
'status' => 'active' ,
],
]);
$this -> assertEquals ( 201 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'active' , $document [ 'body' ][ 'status' ]);
// Test creating document with invalid enum value
$document = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections/status_collection/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'documentId' => ID :: unique (),
'data' => [
'status' => 'invalid_status' ,
],
]);
$this -> assertEquals ( 400 , $document [ 'headers' ][ 'status-code' ]);
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
2025-12-03 09:15:44 +00:00
public function testCreateCollectionAttributeValidationEdgeCases () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Test Attribute Edge Cases' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// Test: Reserved attribute key ($id)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Reserved Key Test' ,
'attributes' => [
[
'key' => '$id' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Reserved attribute key ($createdAt)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Reserved Key Test 2' ,
'attributes' => [
[
'key' => '$createdAt' ,
'type' => Database :: VAR_DATETIME ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Integer default value with wrong type (string instead of int)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Wrong Default Type' ,
'attributes' => [
[
'key' => 'count' ,
'type' => Database :: VAR_INTEGER ,
'default' => 'not_an_integer' ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Boolean default value with wrong type
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Wrong Boolean Default' ,
'attributes' => [
[
'key' => 'active' ,
'type' => Database :: VAR_BOOLEAN ,
'default' => 'yes' ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: min > max for integer
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Min Greater Than Max' ,
'attributes' => [
[
'key' => 'score' ,
'type' => Database :: VAR_INTEGER ,
'min' => 100 ,
'max' => 10 ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Default value outside min/max range
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Default Out of Range' ,
'attributes' => [
[
'key' => 'score' ,
'type' => Database :: VAR_INTEGER ,
'min' => 0 ,
'max' => 100 ,
'default' => 150 ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: String default exceeds size
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Default Exceeds Size' ,
'attributes' => [
[
'key' => 'name' ,
'type' => Database :: VAR_STRING ,
'size' => 5 ,
'default' => 'This is way too long for size 5' ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: 'signed' on non-numeric type
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Signed On String' ,
'attributes' => [
[
'key' => 'name' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
'signed' => true ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Array attribute with default value
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Array With Default' ,
'attributes' => [
[
'key' => 'tags' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
'array' => true ,
'default' => [ 'tag1' , 'tag2' ],
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
2025-12-03 09:38:37 +00:00
// Test: Format on non-string type (format is only allowed for strings)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Format On Integer' ,
'attributes' => [
[
'key' => 'count' ,
'type' => Database :: VAR_INTEGER ,
'format' => 'enum' ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
2025-12-03 09:15:44 +00:00
// Test: Valid integer with min/max range and default within range (should succeed)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Valid Range' ,
'attributes' => [
[
'key' => 'score' ,
'type' => Database :: VAR_INTEGER ,
'min' => 0 ,
'max' => 100 ,
'default' => 50 ,
],
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testCreateCollectionEnumValidationEdgeCases () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Test Enum Edge Cases' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// Test: Enum with empty elements array
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Empty Enum Elements' ,
'attributes' => [
[
'key' => 'status' ,
'type' => Database :: VAR_STRING ,
'size' => 32 ,
'format' => 'enum' ,
'elements' => [],
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Enum with empty string element
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Empty String Element' ,
'attributes' => [
[
'key' => 'status' ,
'type' => Database :: VAR_STRING ,
'size' => 32 ,
'format' => 'enum' ,
'elements' => [ 'active' , '' , 'inactive' ],
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Enum default not in elements
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Default Not In Elements' ,
'attributes' => [
[
'key' => 'status' ,
'type' => Database :: VAR_STRING ,
'size' => 32 ,
'format' => 'enum' ,
'elements' => [ 'active' , 'inactive' ],
'default' => 'pending' ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Enum with valid default in elements (should succeed)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Valid Enum Default' ,
'attributes' => [
[
'key' => 'status' ,
'type' => Database :: VAR_STRING ,
'size' => 32 ,
'format' => 'enum' ,
'elements' => [ 'active' , 'inactive' , 'pending' ],
'default' => 'pending' ,
],
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testCreateCollectionIndexValidationEdgeCases () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Test Index Edge Cases' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// Test: Duplicate index keys
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Duplicate Index Keys' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
'indexes' => [
[
'key' => 'idx_title' ,
'type' => Database :: INDEX_KEY ,
'attributes' => [ 'title' ],
],
[
'key' => 'idx_title' ,
'type' => Database :: INDEX_UNIQUE ,
'attributes' => [ 'title' ],
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Invalid index type
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Invalid Index Type' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
'indexes' => [
[
'key' => 'idx_title' ,
'type' => 'invalid_type' ,
'attributes' => [ 'title' ],
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Empty attributes array in index
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Empty Index Attributes' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
'indexes' => [
[
'key' => 'idx_empty' ,
'type' => Database :: INDEX_KEY ,
'attributes' => [],
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Orders array length mismatch
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Orders Length Mismatch' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
[
'key' => 'year' ,
'type' => Database :: VAR_INTEGER ,
],
],
'indexes' => [
[
'key' => 'idx_compound' ,
'type' => Database :: INDEX_KEY ,
'attributes' => [ 'title' , 'year' ],
'orders' => [ 'ASC' ], // Only one order for two attributes
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Lengths array length mismatch
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Lengths Mismatch' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
[
'key' => 'description' ,
'type' => Database :: VAR_STRING ,
'size' => 1024 ,
],
],
'indexes' => [
[
'key' => 'idx_compound' ,
'type' => Database :: INDEX_KEY ,
'attributes' => [ 'title' , 'description' ],
'lengths' => [ 100 ], // Only one length for two attributes
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Invalid order value
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Invalid Order' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
'indexes' => [
[
'key' => 'idx_title' ,
'type' => Database :: INDEX_KEY ,
'attributes' => [ 'title' ],
'orders' => [ 'INVALID' ],
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Valid compound index with proper orders/lengths (should succeed)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Valid Compound Index' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
[
'key' => 'year' ,
'type' => Database :: VAR_INTEGER ,
],
],
'indexes' => [
[
'key' => 'idx_compound' ,
'type' => Database :: INDEX_KEY ,
'attributes' => [ 'title' , 'year' ],
'orders' => [ 'ASC' , 'DESC' ],
],
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testCreateCollectionRelationshipValidation () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Test Relationship Validation' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// First create a target collection for relationships
$targetCollection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: custom ( 'authors' ),
'name' => 'Authors' ,
'attributes' => [
[
'key' => 'name' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
'required' => true ,
],
],
]);
$this -> assertEquals ( 201 , $targetCollection [ 'headers' ][ 'status-code' ]);
// Test: Relationship without relatedCollection
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Missing Related Collection' ,
'attributes' => [
[
'key' => 'author' ,
'type' => Database :: VAR_RELATIONSHIP ,
'relationType' => Database :: RELATION_ONE_TO_ONE ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Relationship without relationType
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Missing Relation Type' ,
'attributes' => [
[
'key' => 'author' ,
'type' => Database :: VAR_RELATIONSHIP ,
'relatedCollection' => 'authors' ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Invalid relationType
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Invalid Relation Type' ,
'attributes' => [
[
'key' => 'author' ,
'type' => Database :: VAR_RELATIONSHIP ,
'relatedCollection' => 'authors' ,
'relationType' => 'invalid_type' ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Invalid onDelete value
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Invalid OnDelete' ,
'attributes' => [
[
'key' => 'author' ,
'type' => Database :: VAR_RELATIONSHIP ,
'relatedCollection' => 'authors' ,
'relationType' => Database :: RELATION_ONE_TO_ONE ,
'onDelete' => 'invalid_action' ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Relationship with array=true (invalid)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Relationship As Array' ,
'attributes' => [
[
'key' => 'author' ,
'type' => Database :: VAR_RELATIONSHIP ,
'relatedCollection' => 'authors' ,
'relationType' => Database :: RELATION_ONE_TO_ONE ,
'array' => true ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: twoWay with non-boolean value
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Invalid TwoWay' ,
'attributes' => [
[
'key' => 'author' ,
'type' => Database :: VAR_RELATIONSHIP ,
'relatedCollection' => 'authors' ,
'relationType' => Database :: RELATION_ONE_TO_ONE ,
'twoWay' => 'yes' ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Valid relationship (should succeed)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: custom ( 'books' ),
'name' => 'Books' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
'required' => true ,
],
[
'key' => 'author' ,
'type' => Database :: VAR_RELATIONSHIP ,
'relatedCollection' => 'authors' ,
'relationType' => Database :: RELATION_MANY_TO_ONE ,
'twoWay' => true ,
'twoWayKey' => 'books' ,
'onDelete' => Database :: RELATION_MUTATE_CASCADE ,
],
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testCreateCollectionDatetimeValidation () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Test Datetime Validation' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// Test: Invalid datetime default (not ISO 8601)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Invalid Datetime Default' ,
'attributes' => [
[
'key' => 'publishedAt' ,
'type' => Database :: VAR_DATETIME ,
'default' => 'not-a-date' ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Valid datetime with ISO 8601 default (should succeed)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Valid Datetime' ,
'attributes' => [
[
'key' => 'publishedAt' ,
'type' => Database :: VAR_DATETIME ,
],
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testCreateCollectionFloatValidation () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Test Float Validation' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// Test: Float with min > max
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Float Min Greater Max' ,
'attributes' => [
[
'key' => 'price' ,
'type' => Database :: VAR_FLOAT ,
'min' => 100.50 ,
'max' => 10.25 ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Float default outside range
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Float Default Out of Range' ,
'attributes' => [
[
'key' => 'price' ,
'type' => Database :: VAR_FLOAT ,
'min' => 0.0 ,
'max' => 100.0 ,
'default' => 150.50 ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Valid float with range (should succeed)
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Valid Float Range' ,
'attributes' => [
[
'key' => 'price' ,
'type' => Database :: VAR_FLOAT ,
'min' => 0.0 ,
'max' => 1000.0 ,
'default' => 99.99 ,
],
],
]);
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
public function testCreateCollectionMissingRequiredFields () : void
{
// Create database
$database = $this -> client -> call ( Client :: METHOD_POST , '/databases' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'Test Missing Fields' ,
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$databaseId = $database [ 'body' ][ '$id' ];
// Test: Attribute without key
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Missing Attribute Key' ,
'attributes' => [
[
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Attribute without type
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Missing Attribute Type' ,
'attributes' => [
[
'key' => 'title' ,
'size' => 256 ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Index without key
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Missing Index Key' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
'indexes' => [
[
'type' => Database :: INDEX_KEY ,
'attributes' => [ 'title' ],
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Index without type
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Missing Index Type' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
'indexes' => [
[
'key' => 'idx_title' ,
'attributes' => [ 'title' ],
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Test: Index without attributes
$collection = $this -> client -> call ( Client :: METHOD_POST , '/databases/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Missing Index Attributes' ,
'attributes' => [
[
'key' => 'title' ,
'type' => Database :: VAR_STRING ,
'size' => 256 ,
],
],
'indexes' => [
[
'key' => 'idx_title' ,
'type' => Database :: INDEX_KEY ,
],
],
]);
$this -> assertEquals ( 400 , $collection [ 'headers' ][ 'status-code' ]);
// Cleanup
$this -> client -> call ( Client :: METHOD_DELETE , '/databases/' . $databaseId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
2022-05-23 14:54:50 +00:00
}