2025-09-19 14:14:46 +00:00
< ? php
2025-09-20 12:51:00 +00:00
namespace Tests\E2E\Services\Databases\DocumentsDB ;
2025-09-19 14:14:46 +00:00
2025-09-20 12:50:50 +00:00
use Appwrite\Extend\Exception ;
2025-09-19 14:14:46 +00:00
use Tests\E2E\Client ;
2025-09-20 12:50:50 +00:00
use Utopia\Database\Database ;
use Utopia\Database\DateTime ;
use Utopia\Database\Document ;
2025-09-19 14:14:46 +00:00
use Utopia\Database\Helpers\ID ;
2025-09-20 12:50:50 +00:00
use Utopia\Database\Helpers\Permission ;
use Utopia\Database\Helpers\Role ;
use Utopia\Database\Query ;
use Utopia\Database\Validator\Datetime as DatetimeValidator ;
2025-09-19 14:14:46 +00:00
trait DatabasesBase
{
public function testCreateDatabase () : array
{
/**
* Test for SUCCESS
*/
2025-09-26 12:31:39 +00:00
$database = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'databaseId' => ID :: unique (),
'name' => 'Test Database'
]);
2025-09-19 14:14:46 +00:00
2025-09-26 12:31:39 +00:00
$this -> assertNotEmpty ( $database [ 'body' ][ '$id' ]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Test Database' , $database [ 'body' ][ 'name' ]);
$this -> assertEquals ( 'documentsdb' , $database [ 'body' ][ 'type' ]);
2025-09-19 14:14:46 +00:00
2025-09-26 12:31:39 +00:00
return [ 'databaseId' => $database [ 'body' ][ '$id' ]];
}
2025-09-20 12:50:50 +00:00
/**
* @ depends testCreateDatabase
*/
public function testCreateCollection ( array $data ) : array
{
$databaseId = $data [ 'databaseId' ];
/**
* Test for SUCCESS
*/
$movies = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Movies' ,
'documentSecurity' => true ,
'permissions' => [
Permission :: create ( Role :: user ( $this -> getUser ()[ '$id' ])),
],
]);
$this -> assertEquals ( 201 , $movies [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $movies [ 'body' ][ 'name' ], 'Movies' );
$actors = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Actors' ,
'documentSecurity' => true ,
'permissions' => [
Permission :: create ( Role :: user ( $this -> getUser ()[ '$id' ])),
],
]);
$this -> assertEquals ( 201 , $actors [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $actors [ 'body' ][ 'name' ], 'Actors' );
return [
'databaseId' => $databaseId ,
'moviesId' => $movies [ 'body' ][ '$id' ],
'actorsId' => $actors [ 'body' ][ '$id' ],
];
}
/**
* @ depends testCreateCollection
*/
public function testConsoleProject ( array $data ) : void
{
if ( $this -> getSide () === 'server' ) {
// Server side can't get past the invalid key check anyway
$this -> expectNotToPerformAssertions ();
return ;
}
$response = $this -> client -> call (
Client :: METHOD_GET ,
'/documentsdb/console/collections/' . $data [ 'moviesId' ] . '/documents' ,
array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => 'console' ,
], $this -> getHeaders ())
);
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'general_access_forbidden' , $response [ 'body' ][ 'type' ]);
$this -> assertEquals ( 'This endpoint is not available for the console project. The Appwrite Console is a reserved project ID and cannot be used with the Appwrite SDKs and APIs. Please check if your project ID is correct.' , $response [ 'body' ][ 'message' ]);
$response = $this -> client -> call (
Client :: METHOD_GET ,
'/documentsdb/console/collections/' . $data [ 'moviesId' ] . '/documents' ,
array_merge ([
'content-type' => 'application/json' ,
// 'x-appwrite-project' => '', empty header
], $this -> getHeaders ())
);
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'No Appwrite project was specified. Please specify your project ID when initializing your Appwrite SDK.' , $response [ 'body' ][ 'message' ]);
}
/**
* @ depends testCreateCollection
*/
public function testDisableCollection ( array $data ) : void
{
$databaseId = $data [ 'databaseId' ];
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'name' => 'Movies' ,
'enabled' => false ,
'documentSecurity' => true ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertFalse ( $response [ 'body' ][ 'enabled' ]);
if ( $this -> getSide () === 'client' ) {
$responseCreateDocument = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'data' => [
'title' => 'Captain America' ,
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
],
]);
$this -> assertEquals ( 404 , $responseCreateDocument [ 'headers' ][ 'status-code' ]);
$responseListDocument = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 404 , $responseListDocument [ 'headers' ][ 'status-code' ]);
$responseGetDocument = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/someID' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 404 , $responseGetDocument [ 'headers' ][ 'status-code' ]);
}
$response = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'name' => 'Movies' ,
'enabled' => true ,
'documentSecurity' => true ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertTrue ( $response [ 'body' ][ 'enabled' ]);
}
2025-09-25 14:28:59 +00:00
2025-09-20 12:50:50 +00:00
/**
* @ depends testCreateCollection
2025-09-25 14:28:59 +00:00
*/
public function testCreateIndexes ( array $data ) : array
2025-09-20 12:50:50 +00:00
{
$databaseId = $data [ 'databaseId' ];
2025-09-25 14:28:59 +00:00
$titleIndex = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-09-25 14:28:59 +00:00
'key' => 'titleIndex' ,
'type' => 'fulltext' ,
'attributes' => [ 'title' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $titleIndex [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'titleIndex' , $titleIndex [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'fulltext' , $titleIndex [ 'body' ][ 'type' ]);
$this -> assertCount ( 1 , $titleIndex [ 'body' ][ 'attributes' ]);
$this -> assertEquals ( 'title' , $titleIndex [ 'body' ][ 'attributes' ][ 0 ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$releaseYearIndex = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'releaseYear' ,
2025-09-25 14:28:59 +00:00
'type' => 'key' ,
'attributes' => [ 'releaseYear' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $releaseYearIndex [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'releaseYear' , $releaseYearIndex [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'key' , $releaseYearIndex [ 'body' ][ 'type' ]);
$this -> assertCount ( 1 , $releaseYearIndex [ 'body' ][ 'attributes' ]);
$this -> assertEquals ( 'releaseYear' , $releaseYearIndex [ 'body' ][ 'attributes' ][ 0 ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$releaseWithDate1 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-09-25 14:28:59 +00:00
'key' => 'releaseYearDated' ,
'type' => 'key' ,
'attributes' => [ 'releaseYear' , '$createdAt' , '$updatedAt' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $releaseWithDate1 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'releaseYearDated' , $releaseWithDate1 [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'key' , $releaseWithDate1 [ 'body' ][ 'type' ]);
$this -> assertCount ( 3 , $releaseWithDate1 [ 'body' ][ 'attributes' ]);
$this -> assertEquals ( 'releaseYear' , $releaseWithDate1 [ 'body' ][ 'attributes' ][ 0 ]);
$this -> assertEquals ( '$createdAt' , $releaseWithDate1 [ 'body' ][ 'attributes' ][ 1 ]);
$this -> assertEquals ( '$updatedAt' , $releaseWithDate1 [ 'body' ][ 'attributes' ][ 2 ]);
$releaseWithDate2 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'key' => 'birthDay' ,
2025-09-25 14:28:59 +00:00
'type' => 'key' ,
'attributes' => [ 'birthDay' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $releaseWithDate2 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'birthDay' , $releaseWithDate2 [ 'body' ][ 'key' ]);
$this -> assertEquals ( 'key' , $releaseWithDate2 [ 'body' ][ 'type' ]);
$this -> assertCount ( 1 , $releaseWithDate2 [ 'body' ][ 'attributes' ]);
$this -> assertEquals ( 'birthDay' , $releaseWithDate2 [ 'body' ][ 'attributes' ][ 0 ]);
// Test for failure
$fulltextReleaseYear = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-09-25 14:28:59 +00:00
'key' => 'releaseYearDated' ,
'type' => 'fulltext' ,
'attributes' => [ 'releaseYear' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 409 , $fulltextReleaseYear [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $fulltextReleaseYear [ 'body' ][ 'message' ], 'Index with the requested key already exists. Try again with a different key.' );
$noAttributes = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-09-25 14:28:59 +00:00
'key' => 'none' ,
'type' => 'key' ,
'attributes' => [],
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 400 , $noAttributes [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $noAttributes [ 'body' ][ 'message' ], 'No attributes provided for index' );
$duplicates = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
]), [
'key' => 'duplicate' ,
'type' => 'fulltext' ,
'attributes' => [ 'releaseYear' , 'releaseYear' ],
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 400 , $duplicates [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $duplicates [ 'body' ][ 'message' ], 'Duplicate attributes provided' );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$tooLong = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
]), [
2025-09-25 14:28:59 +00:00
'key' => 'tooLong' ,
'type' => 'key' ,
'attributes' => [ 'description' , 'tagline' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
// no errors in documentsdb
$this -> assertEquals ( 202 , $tooLong [ 'headers' ][ 'status-code' ]);
$fulltextArray = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
]), [
2025-09-25 14:28:59 +00:00
'key' => 'ft' ,
'type' => 'fulltext' ,
'attributes' => [ 'actors' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $fulltextArray [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$actorsArray = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
2025-09-20 12:50:50 +00:00
]), [
2025-09-25 14:28:59 +00:00
'key' => 'index-actors' ,
'type' => 'key' ,
'attributes' => [ 'actors' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $actorsArray [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$twoLevelsArray = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
2025-09-20 12:50:50 +00:00
]), [
2025-09-25 14:28:59 +00:00
'key' => 'index-ip-actors' ,
'type' => 'key' ,
'attributes' => [ 'releaseYear' , 'actors' ], // 2 levels
'orders' => [ 'DESC' , 'DESC' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $twoLevelsArray [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$unknown = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
2025-09-20 12:50:50 +00:00
]), [
2025-09-25 14:28:59 +00:00
'key' => 'index-unknown' ,
2025-09-20 12:50:50 +00:00
'type' => 'key' ,
2025-09-25 14:28:59 +00:00
'attributes' => [ 'Unknown' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $unknown [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$index1 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
]), [
2025-09-25 14:28:59 +00:00
'key' => 'integers-order' ,
'type' => 'key' ,
'attributes' => [ 'integers' ], // array attribute
'orders' => [ 'DESC' ], // Check order is removed in API
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $index1 [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$index2 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
]), [
'key' => 'integers-size' ,
'type' => 'key' ,
'attributes' => [ 'integers' ], // array attribute
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $index2 [ 'headers' ][ 'status-code' ]);
/**
* Create Indexes by worker
*/
sleep ( 2 );
$movies = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ], array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
]), []);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertIsArray ( $movies [ 'body' ][ 'indexes' ]);
$this -> assertCount ( 11 , $movies [ 'body' ][ 'indexes' ]);
$this -> assertEquals ( $titleIndex [ 'body' ][ 'key' ], $movies [ 'body' ][ 'indexes' ][ 0 ][ 'key' ]);
$this -> assertEquals ( $releaseYearIndex [ 'body' ][ 'key' ], $movies [ 'body' ][ 'indexes' ][ 1 ][ 'key' ]);
$this -> assertEquals ( $releaseWithDate1 [ 'body' ][ 'key' ], $movies [ 'body' ][ 'indexes' ][ 2 ][ 'key' ]);
$this -> assertEquals ( $releaseWithDate2 [ 'body' ][ 'key' ], $movies [ 'body' ][ 'indexes' ][ 3 ][ 'key' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEventually ( function () use ( $databaseId , $data ) {
$movies = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
foreach ( $movies [ 'body' ][ 'indexes' ] as $index ) {
$this -> assertEquals ( 'available' , $index [ 'status' ]);
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
return true ;
}, 60000 , 500 );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
return $data ;
2025-09-20 12:50:50 +00:00
}
/**
2025-09-26 12:31:39 +00:00
* @ depends testCreateCollection
2025-09-20 12:50:50 +00:00
*/
2025-09-25 14:28:59 +00:00
public function testGetIndexByKeyWithLengths ( array $data ) : void
2025-09-20 12:50:50 +00:00
{
$databaseId = $data [ 'databaseId' ];
2025-09-25 14:28:59 +00:00
$collectionId = $data [ 'moviesId' ];
// Test case for valid lengths
$create = $this -> client -> call ( Client :: METHOD_POST , " /documentsdb/ { $databaseId } /collections/ { $collectionId } /indexes " , [
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
], [
'key' => 'lengthTestIndex' ,
'type' => 'key' ,
'attributes' => [ 'title' , 'description' ],
'lengths' => [ 128 , 200 ]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $create [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Fetch index and check correct lengths
$index = $this -> client -> call ( Client :: METHOD_GET , " /documentsdb/ { $databaseId } /collections/ { $collectionId } /indexes/lengthTestIndex " , [
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $index [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'lengthTestIndex' , $index [ 'body' ][ 'key' ]);
$this -> assertEquals ([ 128 , 200 ], $index [ 'body' ][ 'lengths' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test case for lengths array overriding
// set a length for an array attribute, it should get overriden with Database::ARRAY_INDEX_LENGTH
$create = $this -> client -> call ( Client :: METHOD_POST , " /documentsdb/ { $databaseId } /collections/ { $collectionId } /indexes " , [
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
], [
'key' => 'lengthOverrideTestIndex' ,
'type' => 'key' ,
'attributes' => [ 'actors' ],
2025-09-26 12:31:39 +00:00
'lengths' => [ Database :: ARRAY_INDEX_LENGTH ]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $create [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$index = $this -> client -> call ( Client :: METHOD_GET , " /documentsdb/ { $databaseId } /collections/ { $collectionId } /indexes/lengthOverrideTestIndex " , [
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ([ Database :: ARRAY_INDEX_LENGTH ], $index [ 'body' ][ 'lengths' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test case for count of lengths greater than attributes (should throw 400)
$create = $this -> client -> call ( Client :: METHOD_POST , " /documentsdb/ { $databaseId } /collections/ { $collectionId } /indexes " , [
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
], [
'key' => 'lengthCountExceededIndex' ,
'type' => 'key' ,
'attributes' => [ 'title' ],
'lengths' => [ 128 , 128 ]
2025-09-20 12:50:50 +00:00
]);
2025-09-26 12:31:39 +00:00
$this -> assertEquals ( 202 , $create [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test case for lengths exceeding total of 768
$create = $this -> client -> call ( Client :: METHOD_POST , " /documentsdb/ { $databaseId } /collections/ { $collectionId } /indexes " , [
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
], [
'key' => 'lengthTooLargeIndex' ,
'type' => 'key' ,
'attributes' => [ 'title' , 'description' , 'tagline' , 'actors' ],
'lengths' => [ 256 , 256 , 256 , 20 ]
2025-09-20 12:50:50 +00:00
]);
2025-09-26 12:31:39 +00:00
$this -> assertEquals ( 202 , $create [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test case for negative length values
$create = $this -> client -> call ( Client :: METHOD_POST , " /documentsdb/ { $databaseId } /collections/ { $collectionId } /indexes " , [
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
], [
'key' => 'negativeLengthIndex' ,
'type' => 'key' ,
'attributes' => [ 'title' ],
'lengths' => [ - 1 ]
2025-09-20 12:50:50 +00:00
]);
2025-09-26 12:31:39 +00:00
$this -> assertEquals ( 202 , $create [ 'headers' ][ 'status-code' ]);
2025-09-25 14:28:59 +00:00
}
/**
* @ depends testCreateIndexes
*/
public function testListIndexes ( array $data ) : void
{
$databaseId = $data [ 'databaseId' ];
$response = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
2025-09-20 12:50:50 +00:00
]), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: equal ( 'type' , [ 'key' ]) -> toString (),
Query :: limit ( 2 ) -> toString ()
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 2 , \count ( $response [ 'body' ][ 'indexes' ]));
$response = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
2025-09-20 12:50:50 +00:00
]), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: select ([ 'key' ]) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( Exception :: GENERAL_ARGUMENT_INVALID , $response [ 'body' ][ 'type' ]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* @ depends testCreateIndexes
*/
public function testCreateDocument ( array $data ) : array
{
$databaseId = $data [ 'databaseId' ];
$document1 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'data' => [
'title' => 'Captain America' ,
'releaseYear' => 1944 ,
'birthDay' => '1975-06-12 14:12:55+02:00' ,
'actors' => [
'Chris Evans' ,
'Samuel Jackson' ,
]
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$document2 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'data' => [
'title' => 'Spider-Man: Far From Home' ,
'releaseYear' => 2019 ,
'birthDay' => null ,
'actors' => [
'Tom Holland' ,
'Zendaya Maree Stoermer' ,
'Samuel Jackson' ,
],
'integers' => [ 50 , 60 ]
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$document3 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'data' => [
'title' => 'Spider-Man: Homecoming' ,
'releaseYear' => 2017 ,
'birthDay' => '1975-06-12 14:12:55 America/New_York' ,
'duration' => 65 ,
'actors' => [
'Tom Holland' ,
'Zendaya Maree Stoermer' ,
],
'integers' => [ 50 ]
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
]
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document4 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'data' => [
'releaseYear' => 2020 , // Missing title, expect an 400 error
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
]
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document1 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $data [ 'moviesId' ], $document1 [ 'body' ][ '$collectionId' ]);
$this -> assertArrayNotHasKey ( '$collection' , $document1 [ 'body' ]);
$this -> assertEquals ( $databaseId , $document1 [ 'body' ][ '$databaseId' ]);
$this -> assertEquals ( $document1 [ 'body' ][ 'title' ], 'Captain America' );
$this -> assertEquals ( $document1 [ 'body' ][ 'releaseYear' ], 1944 );
$this -> assertIsArray ( $document1 [ 'body' ][ '$permissions' ]);
$this -> assertCount ( 3 , $document1 [ 'body' ][ '$permissions' ]);
$this -> assertCount ( 2 , $document1 [ 'body' ][ 'actors' ]);
$this -> assertEquals ( $document1 [ 'body' ][ 'actors' ][ 0 ], 'Chris Evans' );
$this -> assertEquals ( $document1 [ 'body' ][ 'actors' ][ 1 ], 'Samuel Jackson' );
$this -> assertEquals ( $document1 [ 'body' ][ 'birthDay' ], '1975-06-12T12:12:55.000+00:00' );
$this -> assertTrue ( array_key_exists ( '$sequence' , $document1 [ 'body' ]));
$this -> assertIsInt ( $document1 [ 'body' ][ '$sequence' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document2 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $data [ 'moviesId' ], $document2 [ 'body' ][ '$collectionId' ]);
$this -> assertArrayNotHasKey ( '$collection' , $document2 [ 'body' ]);
$this -> assertEquals ( $databaseId , $document2 [ 'body' ][ '$databaseId' ]);
$this -> assertEquals ( $document2 [ 'body' ][ 'title' ], 'Spider-Man: Far From Home' );
$this -> assertEquals ( $document2 [ 'body' ][ 'releaseYear' ], 2019 );
$this -> assertEquals ( $document2 [ 'body' ][ 'duration' ], null );
$this -> assertIsArray ( $document2 [ 'body' ][ '$permissions' ]);
$this -> assertCount ( 3 , $document2 [ 'body' ][ '$permissions' ]);
$this -> assertCount ( 3 , $document2 [ 'body' ][ 'actors' ]);
$this -> assertEquals ( $document2 [ 'body' ][ 'actors' ][ 0 ], 'Tom Holland' );
$this -> assertEquals ( $document2 [ 'body' ][ 'actors' ][ 1 ], 'Zendaya Maree Stoermer' );
$this -> assertEquals ( $document2 [ 'body' ][ 'actors' ][ 2 ], 'Samuel Jackson' );
$this -> assertEquals ( $document2 [ 'body' ][ 'birthDay' ], null );
$this -> assertEquals ( $document2 [ 'body' ][ 'integers' ][ 0 ], 50 );
$this -> assertEquals ( $document2 [ 'body' ][ 'integers' ][ 1 ], 60 );
$this -> assertTrue ( array_key_exists ( '$sequence' , $document2 [ 'body' ]));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document3 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $data [ 'moviesId' ], $document3 [ 'body' ][ '$collectionId' ]);
$this -> assertArrayNotHasKey ( '$collection' , $document3 [ 'body' ]);
$this -> assertEquals ( $databaseId , $document3 [ 'body' ][ '$databaseId' ]);
$this -> assertEquals ( $document3 [ 'body' ][ 'title' ], 'Spider-Man: Homecoming' );
$this -> assertEquals ( $document3 [ 'body' ][ 'releaseYear' ], 2017 );
$this -> assertEquals ( $document3 [ 'body' ][ 'duration' ], 65 );
$this -> assertIsArray ( $document3 [ 'body' ][ '$permissions' ]);
$this -> assertCount ( 3 , $document3 [ 'body' ][ '$permissions' ]);
$this -> assertCount ( 2 , $document3 [ 'body' ][ 'actors' ]);
$this -> assertEquals ( $document3 [ 'body' ][ 'actors' ][ 0 ], 'Tom Holland' );
$this -> assertEquals ( $document3 [ 'body' ][ 'actors' ][ 1 ], 'Zendaya Maree Stoermer' );
$this -> assertEquals ( $document3 [ 'body' ][ 'birthDay' ], '1975-06-12T18:12:55.000+00:00' ); // UTC for NY
$this -> assertTrue ( array_key_exists ( '$sequence' , $document3 [ 'body' ]));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 400 , $document4 [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
return $data ;
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* @ depends testCreateIndexes
*/
public function testUpsertDocument ( array $data ) : void
{
$databaseId = $data [ 'databaseId' ];
$documentId = ID :: unique ();
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Ragnarok' ,
'releaseYear' => 2000
],
'permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ()),
],
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 3 , $document [ 'body' ][ '$permissions' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 'Thor: Ragnarok' , $document [ 'body' ][ 'title' ]);
2025-09-20 12:50:50 +00:00
/**
2025-09-25 14:28:59 +00:00
* Resubmit same document , nothing to update
2025-09-20 12:50:50 +00:00
*/
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Ragnarok' ,
'releaseYear' => 2000 ,
'integers' => [],
'birthDay' => null ,
'duration' => null ,
'starringActors' => [],
'actors' => [],
'tagline' => '' ,
'description' => '' ,
],
'permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ()),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Thor: Ragnarok' , $document [ 'body' ][ 'title' ]);
$this -> assertCount ( 3 , $document [ 'body' ][ '$permissions' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Love and Thunder' ,
'releaseYear' => 2000
],
'permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ()),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Thor: Love and Thunder' , $document [ 'body' ][ 'title' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 'Thor: Love and Thunder' , $document [ 'body' ][ 'title' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// removing permission to read and delete
$document = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Love and Thunder' ,
'releaseYear' => 2000
],
'permissions' => [
Permission :: update ( Role :: users ())
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
// shouldn't be able to read as no read permission
$document = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
switch ( $this -> getSide ()) {
case 'client' :
$this -> assertEquals ( 404 , $document [ 'headers' ][ 'status-code' ]);
break ;
case 'server' :
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
break ;
}
// shouldn't be able to delete as no delete permission
$document = $this -> client -> call ( Client :: METHOD_DELETE , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
// simulating for the client
// the document should not be allowed to be deleted as needed downward
if ( $this -> getSide () === 'client' ) {
$this -> assertEquals ( 401 , $document [ 'headers' ][ 'status-code' ]);
}
// giving the delete permission
$document = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Love and Thunder' ,
'releaseYear' => 2000
],
'permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ())
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_DELETE , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
$this -> assertEquals ( 204 , $document [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// relationship behaviour
$person = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-20 12:50:50 +00:00
]), [
2025-09-25 14:28:59 +00:00
'collectionId' => 'person-upsert' ,
'name' => 'person' ,
'permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ()),
Permission :: create ( Role :: users ()),
],
'documentSecurity' => true ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $person [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$library = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-20 12:50:50 +00:00
]), [
2025-09-25 14:28:59 +00:00
'collectionId' => 'library-upsert' ,
'name' => 'library' ,
'permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: create ( Role :: users ()),
Permission :: delete ( Role :: users ()),
],
'documentSecurity' => true ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $library [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// upserting values
$documentId = ID :: unique ();
$person1 = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $person [ 'body' ][ '$id' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'data' => [
'library' => [
'$id' => 'library1' ,
'$permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ()),
],
'libraryName' => 'Library 1' ,
],
],
'permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ()),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 'Library 1' , $person1 [ 'body' ][ 'library' ][ 'libraryName' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $person [ 'body' ][ '$id' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: select ([ 'fullName' , 'library.*' ]) -> toString (),
Query :: equal ( 'library' , [ 'library1' ]) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 1 , $documents [ 'body' ][ 'total' ]);
$this -> assertEquals ( 'Library 1' , $documents [ 'body' ][ 'documents' ][ 0 ][ 'library' ][ 'libraryName' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$person1 = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $person [ 'body' ][ '$id' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'data' => [
'library' => [
'$id' => 'library1' ,
'$permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ()),
],
'libraryName' => 'Library 2' ,
],
],
'permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ()),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
// data should get updated
$this -> assertEquals ( 'Library 2' , $person1 [ 'body' ][ 'library' ][ 'libraryName' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $person [ 'body' ][ '$id' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: select ([ 'fullName' , 'library.*' ]) -> toString (),
Query :: equal ( 'library' , [ 'library1' ]) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 1 , $documents [ 'body' ][ 'total' ]);
$this -> assertEquals ( 'Library 2' , $documents [ 'body' ][ 'documents' ][ 0 ][ 'library' ][ 'libraryName' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// data should get added
$person1 = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $person [ 'body' ][ '$id' ] . '/documents/' . ID :: unique (), array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'data' => [
'library' => [
'$id' => 'library2' ,
'$permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ()),
],
'libraryName' => 'Library 2' ,
],
],
'permissions' => [
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ()),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 'Library 2' , $person1 [ 'body' ][ 'library' ][ 'libraryName' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $person [ 'body' ][ '$id' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: select ([ 'fullName' , 'library.*' ]) -> toString ()
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 2 , $documents [ 'body' ][ 'total' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// test without passing permissions
$document = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Ragnarok' ,
'releaseYear' => 2000
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Thor: Ragnarok' , $document [ 'body' ][ 'title' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
]));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$deleteResponse = $this -> client -> call ( Client :: METHOD_DELETE , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
]));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 204 , $deleteResponse [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
if ( $this -> getSide () === 'client' ) {
// Skipped on server side: Creating a document with no permissions results in an empty permissions array, whereas on client side it assigns permissions to the current user
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// test without passing permissions
$document = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Ragnarok' ,
'releaseYear' => 2000
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Thor: Ragnarok' , $document [ 'body' ][ 'title' ]);
$this -> assertCount ( 3 , $document [ 'body' ][ '$permissions' ]);
$permissionsCreated = $document [ 'body' ][ '$permissions' ];
// checking the default created permission
$defaultPermission = [
2025-09-20 12:50:50 +00:00
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
2025-09-25 14:28:59 +00:00
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ]))
];
// ignoring the order of the permission and checking the permissions
$this -> assertEqualsCanonicalizing ( $defaultPermission , $permissionsCreated );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ]
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// updating the created doc
$document = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Ragnarok' ,
'releaseYear' => 2002
]
]);
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Thor: Ragnarok' , $document [ 'body' ][ 'title' ]);
$this -> assertEquals ( 2002 , $document [ 'body' ][ 'releaseYear' ]);
$this -> assertCount ( 3 , $document [ 'body' ][ '$permissions' ]);
$this -> assertEquals ( $permissionsCreated , $document [ 'body' ][ '$permissions' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// removing the delete permission
$document = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Ragnarok' ,
'releaseYear' => 2002
],
'permissions' => [
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ]))
]
]);
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Thor: Ragnarok' , $document [ 'body' ][ 'title' ]);
$this -> assertEquals ( 2002 , $document [ 'body' ][ 'releaseYear' ]);
$this -> assertCount ( 1 , $document [ 'body' ][ '$permissions' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$deleteResponse = $this -> client -> call ( Client :: METHOD_DELETE , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ]
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 401 , $deleteResponse [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// giving the delete permission
$document = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Ragnarok' ,
'releaseYear' => 2002
],
'permissions' => [
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ]))
]
]);
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Thor: Ragnarok' , $document [ 'body' ][ 'title' ]);
$this -> assertEquals ( 2002 , $document [ 'body' ][ 'releaseYear' ]);
$this -> assertCount ( 2 , $document [ 'body' ][ '$permissions' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$deleteResponse = $this -> client -> call ( Client :: METHOD_DELETE , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ]
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 204 , $deleteResponse [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// upsertion for the related document without passing permissions
// data should get added
$newPersonId = ID :: unique ();
$personNoPerm = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $person [ 'body' ][ '$id' ] . '/documents/' . $newPersonId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'library' => [
'$id' => 'library3' ,
'libraryName' => 'Library 3' ,
],
],
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 'Library 3' , $personNoPerm [ 'body' ][ 'library' ][ 'libraryName' ]);
$this -> assertCount ( 3 , $personNoPerm [ 'body' ][ 'library' ][ '$permissions' ]);
$this -> assertCount ( 3 , $personNoPerm [ 'body' ][ '$permissions' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $person [ 'body' ][ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'queries' => [
Query :: select ([ 'fullName' , 'library.*' ]) -> toString ()
],
]);
$this -> assertGreaterThanOrEqual ( 1 , $documents [ 'body' ][ 'total' ]);
$documentsDetails = $documents [ 'body' ][ 'documents' ];
foreach ( $documentsDetails as $doc ) {
$this -> assertCount ( 3 , $doc [ '$permissions' ]);
}
$found = false ;
foreach ( $documents [ 'body' ][ 'documents' ] as $doc ) {
if ( isset ( $doc [ 'library' ][ 'libraryName' ]) && $doc [ 'library' ][ 'libraryName' ] === 'Library 3' ) {
$found = true ;
break ;
}
}
$this -> assertTrue ( $found , 'Library 3 should be present in the upserted documents.' );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Fetch the related library and assert on its permissions (should be default/inherited)
$library3 = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $library [ 'body' ][ '$id' ] . '/documents/library3' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $library3 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Library 3' , $library3 [ 'body' ][ 'libraryName' ]);
$this -> assertArrayHasKey ( '$permissions' , $library3 [ 'body' ]);
$this -> assertCount ( 3 , $library3 [ 'body' ][ '$permissions' ]);
$this -> assertNotEmpty ( $library3 [ 'body' ][ '$permissions' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Readonly attributes are ignored
$personNoPerm = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $person [ 'body' ][ '$id' ] . '/documents/' . $newPersonId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => [
'$id' => 'some-other-id' ,
'$collectionId' => 'some-other-collection' ,
'$databaseId' => 'some-other-database' ,
'$createdAt' => '2024-01-01T00:00:00Z' ,
'$updatedAt' => '2024-01-01T00:00:00Z' ,
'library' => [
'$id' => 'library3' ,
'libraryName' => 'Library 3' ,
'$createdAt' => '2024-01-01T00:00:00Z' ,
'$updatedAt' => '2024-01-01T00:00:00Z' ,
],
],
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$update = $personNoPerm ;
$update [ 'body' ][ '$id' ] = 'random' ;
$update [ 'body' ][ '$sequence' ] = 123 ;
$update [ 'body' ][ '$databaseId' ] = 'random' ;
$update [ 'body' ][ '$collectionId' ] = 'random' ;
$update [ 'body' ][ '$createdAt' ] = '2024-01-01T00:00:00.000+00:00' ;
$update [ 'body' ][ '$updatedAt' ] = '2024-01-01T00:00:00.000+00:00' ;
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$upserted = $this -> client -> call ( Client :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $person [ 'body' ][ '$id' ] . '/documents/' . $newPersonId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'data' => $update [ 'body' ]
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $upserted [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $personNoPerm [ 'body' ][ '$id' ], $upserted [ 'body' ][ '$id' ]);
$this -> assertEquals ( $personNoPerm [ 'body' ][ '$collectionId' ], $upserted [ 'body' ][ '$collectionId' ]);
$this -> assertEquals ( $personNoPerm [ 'body' ][ '$databaseId' ], $upserted [ 'body' ][ '$databaseId' ]);
$this -> assertEquals ( $personNoPerm [ 'body' ][ '$sequence' ], $upserted [ 'body' ][ '$sequence' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
if ( $this -> getSide () === 'client' ) {
$this -> assertEquals ( $personNoPerm [ 'body' ][ '$createdAt' ], $upserted [ 'body' ][ '$createdAt' ]);
$this -> assertNotEquals ( '2024-01-01T00:00:00.000+00:00' , $upserted [ 'body' ][ '$updatedAt' ]);
} else {
$this -> assertEquals ( '2024-01-01T00:00:00.000+00:00' , $upserted [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( '2024-01-01T00:00:00.000+00:00' , $upserted [ 'body' ][ '$updatedAt' ]);
}
}
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* @ depends testCreateDocument
*/
public function testListDocuments ( array $data ) : array
{
$databaseId = $data [ 'databaseId' ];
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: orderAsc ( 'releaseYear' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1944 , $documents [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertEquals ( 2017 , $documents [ 'body' ][ 'documents' ][ 1 ][ 'releaseYear' ]);
$this -> assertEquals ( 2019 , $documents [ 'body' ][ 'documents' ][ 2 ][ 'releaseYear' ]);
$this -> assertTrue ( array_key_exists ( '$sequence' , $documents [ 'body' ][ 'documents' ][ 0 ]));
$this -> assertTrue ( array_key_exists ( '$sequence' , $documents [ 'body' ][ 'documents' ][ 1 ]));
$this -> assertTrue ( array_key_exists ( '$sequence' , $documents [ 'body' ][ 'documents' ][ 2 ]));
$this -> assertCount ( 3 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
foreach ( $documents [ 'body' ][ 'documents' ] as $document ) {
$this -> assertEquals ( $data [ 'moviesId' ], $document [ '$collectionId' ]);
$this -> assertArrayNotHasKey ( '$collection' , $document );
$this -> assertEquals ( $databaseId , $document [ '$databaseId' ]);
}
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: orderDesc ( 'releaseYear' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1944 , $documents [ 'body' ][ 'documents' ][ 2 ][ 'releaseYear' ]);
$this -> assertEquals ( 2017 , $documents [ 'body' ][ 'documents' ][ 1 ][ 'releaseYear' ]);
$this -> assertEquals ( 2019 , $documents [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertCount ( 3 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// creating a dummy doc with null description
$document1 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
2025-09-20 12:50:50 +00:00
'documentId' => ID :: unique (),
'data' => [
2025-09-25 14:28:59 +00:00
'title' => 'Dummy' ,
'releaseYear' => 1944 ,
'birthDay' => '1975-06-12 14:12:55+02:00' ,
'actors' => [
'Dummy' ,
],
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document1 [ 'headers' ][ 'status-code' ]);
// fetching docs with cursor after the dummy doc with order attr description which is null
$documentsPaginated = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: orderAsc ( 'dummy' ) -> toString (),
Query :: cursorAfter ( new Document ([ '$id' => $document1 [ 'body' ][ '$id' ]])) -> toString ()
],
]);
// should throw 400 as the order attr description of the selected doc is null
$this -> assertEquals ( 400 , $documentsPaginated [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// deleting the dummy doc created
$this -> client -> call ( Client :: METHOD_DELETE , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $document1 [ 'body' ][ '$id' ], array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
return [ 'documents' => $documents [ 'body' ][ 'documents' ], 'databaseId' => $databaseId ];
2025-09-20 12:50:50 +00:00
}
2025-09-25 14:28:59 +00:00
/**
* @ depends testListDocuments
*/
public function testGetDocument ( array $data ) : void
2025-09-20 12:50:50 +00:00
{
2025-09-25 14:28:59 +00:00
$databaseId = $data [ 'databaseId' ];
foreach ( $data [ 'documents' ] as $document ) {
$response = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $document [ '$collectionId' ] . '/documents/' . $document [ '$id' ], array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $response [ 'body' ][ '$id' ], $document [ '$id' ]);
$this -> assertEquals ( $document [ '$collectionId' ], $response [ 'body' ][ '$collectionId' ]);
$this -> assertArrayNotHasKey ( '$collection' , $response [ 'body' ]);
$this -> assertEquals ( $document [ '$databaseId' ], $response [ 'body' ][ '$databaseId' ]);
$this -> assertEquals ( $response [ 'body' ][ 'title' ], $document [ 'title' ]);
$this -> assertEquals ( $response [ 'body' ][ 'releaseYear' ], $document [ 'releaseYear' ]);
$this -> assertEquals ( $response [ 'body' ][ '$permissions' ], $document [ '$permissions' ]);
$this -> assertEquals ( $response [ 'body' ][ 'birthDay' ], $document [ 'birthDay' ]);
$this -> assertTrue ( array_key_exists ( '$sequence' , $response [ 'body' ]));
$this -> assertFalse ( array_key_exists ( '$tenant' , $response [ 'body' ]));
}
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* @ depends testListDocuments
*/
public function testGetDocumentWithQueries ( array $data ) : void
{
$databaseId = $data [ 'databaseId' ];
$document = $data [ 'documents' ][ 0 ];
$response = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $document [ '$collectionId' ] . '/documents/' . $document [ '$id' ], array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: select ([ 'title' , 'releaseYear' , '$id' ]) -> toString (),
2025-09-20 12:50:50 +00:00
],
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $document [ 'title' ], $response [ 'body' ][ 'title' ]);
$this -> assertEquals ( $document [ 'releaseYear' ], $response [ 'body' ][ 'releaseYear' ]);
$this -> assertArrayNotHasKey ( 'birthDay' , $response [ 'body' ]);
$sequence = $response [ 'body' ][ '$sequence' ];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Query by sequence
$response = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $document [ '$collectionId' ] . '/documents/' . $document [ '$id' ], array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: equal ( '$sequence' , [ $sequence ])
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $document [ 'title' ], $response [ 'body' ][ 'title' ]);
$this -> assertEquals ( $document [ 'releaseYear' ], $response [ 'body' ][ 'releaseYear' ]);
$this -> assertTrue ( array_key_exists ( '$sequence' , $response [ 'body' ]));
}
/**
* @ depends testCreateDocument
*/
public function testListDocumentsAfterPagination ( array $data ) : array
{
$databaseId = $data [ 'databaseId' ];
/**
* Test after without order .
*/
$base = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $base [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Captain America' , $base [ 'body' ][ 'documents' ][ 0 ][ 'title' ]);
$this -> assertEquals ( 'Spider-Man: Far From Home' , $base [ 'body' ][ 'documents' ][ 1 ][ 'title' ]);
$this -> assertEquals ( 'Spider-Man: Homecoming' , $base [ 'body' ][ 'documents' ][ 2 ][ 'title' ]);
$this -> assertCount ( 3 , $base [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: cursorAfter ( new Document ([ '$id' => $base [ 'body' ][ 'documents' ][ 0 ][ '$id' ]])) -> toString ()
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $base [ 'body' ][ 'documents' ][ 1 ][ '$id' ], $documents [ 'body' ][ 'documents' ][ 0 ][ '$id' ]);
$this -> assertEquals ( $base [ 'body' ][ 'documents' ][ 2 ][ '$id' ], $documents [ 'body' ][ 'documents' ][ 1 ][ '$id' ]);
$this -> assertCount ( 2 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: cursorAfter ( new Document ([ '$id' => $base [ 'body' ][ 'documents' ][ 2 ][ '$id' ]])) -> toString ()
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEmpty ( $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* Test with ASC order and after .
*/
$base = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: orderAsc ( 'releaseYear' ) -> toString ()
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $base [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1944 , $base [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertEquals ( 2017 , $base [ 'body' ][ 'documents' ][ 1 ][ 'releaseYear' ]);
$this -> assertEquals ( 2019 , $base [ 'body' ][ 'documents' ][ 2 ][ 'releaseYear' ]);
$this -> assertCount ( 3 , $base [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: cursorAfter ( new Document ([ '$id' => $base [ 'body' ][ 'documents' ][ 1 ][ '$id' ]])) -> toString (),
Query :: orderAsc ( 'releaseYear' ) -> toString ()
],
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $base [ 'body' ][ 'documents' ][ 2 ][ '$id' ], $documents [ 'body' ][ 'documents' ][ 0 ][ '$id' ]);
$this -> assertCount ( 1 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* Test with DESC order and after .
*/
$base = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: orderDesc ( 'releaseYear' ) -> toString ()
],
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $base [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1944 , $base [ 'body' ][ 'documents' ][ 2 ][ 'releaseYear' ]);
$this -> assertEquals ( 2017 , $base [ 'body' ][ 'documents' ][ 1 ][ 'releaseYear' ]);
$this -> assertEquals ( 2019 , $base [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertCount ( 3 , $base [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: cursorAfter ( new Document ([ '$id' => $base [ 'body' ][ 'documents' ][ 1 ][ '$id' ]])) -> toString (),
Query :: orderDesc ( 'releaseYear' ) -> toString ()
],
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $base [ 'body' ][ 'documents' ][ 2 ][ '$id' ], $documents [ 'body' ][ 'documents' ][ 0 ][ '$id' ]);
$this -> assertCount ( 1 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* Test after with unknown document .
*/
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: cursorAfter ( new Document ([ '$id' => 'unknown' ])) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 400 , $documents [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* Test null value for cursor
*/
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
'{"method":"cursorAfter","values":[null]}' ,
2025-09-20 12:50:50 +00:00
],
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 400 , $documents [ 'headers' ][ 'status-code' ]);
return [];
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* @ depends testCreateDocument
*/
public function testListDocumentsBeforePagination ( array $data ) : array
{
$databaseId = $data [ 'databaseId' ];
/**
* Test before without order .
*/
$base = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $base [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Captain America' , $base [ 'body' ][ 'documents' ][ 0 ][ 'title' ]);
$this -> assertEquals ( 'Spider-Man: Far From Home' , $base [ 'body' ][ 'documents' ][ 1 ][ 'title' ]);
$this -> assertEquals ( 'Spider-Man: Homecoming' , $base [ 'body' ][ 'documents' ][ 2 ][ 'title' ]);
$this -> assertCount ( 3 , $base [ 'body' ][ 'documents' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: cursorBefore ( new Document ([ '$id' => $base [ 'body' ][ 'documents' ][ 2 ][ '$id' ]])) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $base [ 'body' ][ 'documents' ][ 0 ][ '$id' ], $documents [ 'body' ][ 'documents' ][ 0 ][ '$id' ]);
$this -> assertEquals ( $base [ 'body' ][ 'documents' ][ 1 ][ '$id' ], $documents [ 'body' ][ 'documents' ][ 1 ][ '$id' ]);
$this -> assertCount ( 2 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: cursorBefore ( new Document ([ '$id' => $base [ 'body' ][ 'documents' ][ 0 ][ '$id' ]])) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEmpty ( $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* Test with ASC order and after .
*/
$base = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: orderAsc ( 'releaseYear' ) -> toString (),
],
]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $base [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1944 , $base [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertEquals ( 2017 , $base [ 'body' ][ 'documents' ][ 1 ][ 'releaseYear' ]);
$this -> assertEquals ( 2019 , $base [ 'body' ][ 'documents' ][ 2 ][ 'releaseYear' ]);
$this -> assertCount ( 3 , $base [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: cursorBefore ( new Document ([ '$id' => $base [ 'body' ][ 'documents' ][ 1 ][ '$id' ]])) -> toString (),
Query :: orderAsc ( 'releaseYear' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $base [ 'body' ][ 'documents' ][ 0 ][ '$id' ], $documents [ 'body' ][ 'documents' ][ 0 ][ '$id' ]);
$this -> assertCount ( 1 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* Test with DESC order and after .
*/
$base = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: orderDesc ( 'releaseYear' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $base [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1944 , $base [ 'body' ][ 'documents' ][ 2 ][ 'releaseYear' ]);
$this -> assertEquals ( 2017 , $base [ 'body' ][ 'documents' ][ 1 ][ 'releaseYear' ]);
$this -> assertEquals ( 2019 , $base [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertCount ( 3 , $base [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: cursorBefore ( new Document ([ '$id' => $base [ 'body' ][ 'documents' ][ 1 ][ '$id' ]])) -> toString (),
Query :: orderDesc ( 'releaseYear' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $base [ 'body' ][ 'documents' ][ 0 ][ '$id' ], $documents [ 'body' ][ 'documents' ][ 0 ][ '$id' ]);
$this -> assertCount ( 1 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
return [];
2025-09-20 12:50:50 +00:00
}
2025-09-25 14:28:59 +00:00
/**
* @ depends testCreateDocument
*/
public function testListDocumentsLimitAndOffset ( array $data ) : array
2025-09-20 12:50:50 +00:00
{
2025-09-25 14:28:59 +00:00
$databaseId = $data [ 'databaseId' ];
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: orderAsc ( 'releaseYear' ) -> toString (),
Query :: limit ( 1 ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1944 , $documents [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertCount ( 1 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: orderAsc ( 'releaseYear' ) -> toString (),
Query :: limit ( 2 ) -> toString (),
Query :: offset ( 1 ) -> toString (),
2025-09-20 12:50:50 +00:00
],
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 2017 , $documents [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertEquals ( 2019 , $documents [ 'body' ][ 'documents' ][ 1 ][ 'releaseYear' ]);
$this -> assertCount ( 2 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
return [];
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* @ depends testCreateDocument
*/
public function testDocumentsListQueries ( array $data ) : array
{
$databaseId = $data [ 'databaseId' ];
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: search ( 'title' , 'Captain America' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1944 , $documents [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertCount ( 1 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: equal ( '$id' , [ $documents [ 'body' ][ 'documents' ][ 0 ][ '$id' ]]) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1944 , $documents [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertCount ( 1 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: search ( 'title' , 'Homecoming' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 2017 , $documents [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertCount ( 1 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: search ( 'title' , 'spider' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 2019 , $documents [ 'body' ][ 'documents' ][ 0 ][ 'releaseYear' ]);
$this -> assertEquals ( 2017 , $documents [ 'body' ][ 'documents' ][ 1 ][ 'releaseYear' ]);
$this -> assertCount ( 2 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
'{"method":"contains","attribute":"title","values":[bad]}'
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 400 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Invalid query: Syntax error' , $documents [ 'body' ][ 'message' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: contains ( 'title' , [ 'spi' ]) -> toString (), // like query
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 2 , $documents [ 'body' ][ 'total' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: equal ( 'releaseYear' , [ 1944 ]) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertCount ( 1 , $documents [ 'body' ][ 'documents' ]);
$this -> assertEquals ( 'Captain America' , $documents [ 'body' ][ 'documents' ][ 0 ][ 'title' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: notEqual ( 'releaseYear' , 1944 ) -> toString (),
2025-09-20 12:50:50 +00:00
],
]);
2025-09-25 14:28:59 +00:00
$this -> assertCount ( 2 , $documents [ 'body' ][ 'documents' ]);
$this -> assertEquals ( 'Spider-Man: Far From Home' , $documents [ 'body' ][ 'documents' ][ 0 ][ 'title' ]);
$this -> assertEquals ( 'Spider-Man: Homecoming' , $documents [ 'body' ][ 'documents' ][ 1 ][ 'title' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: greaterThan ( '$createdAt' , '1976-06-12' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertCount ( 3 , $documents [ 'body' ][ 'documents' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: lessThan ( '$createdAt' , '1976-06-12' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertCount ( 0 , $documents [ 'body' ][ 'documents' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: contains ( 'actors' , [ 'Tom Holland' , 'Samuel Jackson' ]) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 3 , $documents [ 'body' ][ 'total' ]);
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: contains ( 'actors' , [ 'Tom' ]) -> toString (), // Full-match not like
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 0 , $documents [ 'body' ][ 'total' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: greaterThan ( 'birthDay' , '16/01/2024 12:00:00AM' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 400 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Invalid query: Query value is invalid for attribute "birthDay"' , $documents [ 'body' ][ 'message' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: greaterThan ( 'birthDay' , '1960-01-01 10:10:10+02:30' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( '1975-06-12T12:12:55.000+00:00' , $documents [ 'body' ][ 'documents' ][ 0 ][ 'birthDay' ]);
$this -> assertEquals ( '1975-06-12T18:12:55.000+00:00' , $documents [ 'body' ][ 'documents' ][ 1 ][ 'birthDay' ]);
$this -> assertCount ( 2 , $documents [ 'body' ][ 'documents' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: isNull ( 'integers' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1 , $documents [ 'body' ][ 'total' ]);
/**
* Test for Failure
*/
$conditions = [];
for ( $i = 0 ; $i < APP_DATABASE_QUERY_MAX_VALUES + 1 ; $i ++ ) {
$conditions [] = $i ;
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'queries' => [
Query :: equal ( 'releaseYear' , $conditions ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 400 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Invalid query: Query on attribute has greater than ' . APP_DATABASE_QUERY_MAX_VALUES . ' values: releaseYear' , $documents [ 'body' ][ 'message' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$value = '' ;
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
for ( $i = 0 ; $i < 101 ; $i ++ ) {
$value .= " [ " . $i . " ] Too long title to cross 2k chars query limit " ;
}
$documents = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: search ( 'title' , $value ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
// Todo: Not sure what to do we with Query length Test VS old? JSON validator will fails if query string will be truncated?
//$this->assertEquals(400, $documents['headers']['status-code']);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Todo: Disabled for CL - Uncomment after ProxyDatabase cleanup for find method
// $documents = $this->client->call(Client::METHOD_GET, '/documentsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()), [
// 'queries' => [
// Query::search('actors', 'Tom')->toString(),
// ],
// ]);
// $this->assertEquals(400, $documents['headers']['status-code']);
// $this->assertEquals('Invalid query: Cannot query search on attribute "actors" because it is an array.', $documents['body']['message']);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
return [];
2025-09-20 12:50:50 +00:00
}
2025-09-25 14:28:59 +00:00
/**
* @ depends testCreateDocument
*/
public function testUpdateDocument ( array $data ) : array
2025-09-20 12:50:50 +00:00
{
2025-09-25 14:28:59 +00:00
$databaseId = $data [ 'databaseId' ];
$document = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'data' => [
'title' => 'Thor: Ragnaroc' ,
'releaseYear' => 2017 ,
'birthDay' => '1976-06-12 14:12:55' ,
'actors' => [],
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$id = $document [ 'body' ][ '$id' ];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $data [ 'moviesId' ], $document [ 'body' ][ '$collectionId' ]);
$this -> assertArrayNotHasKey ( '$collection' , $document [ 'body' ]);
$this -> assertEquals ( $databaseId , $document [ 'body' ][ '$databaseId' ]);
$this -> assertEquals ( $document [ 'body' ][ 'title' ], 'Thor: Ragnaroc' );
$this -> assertEquals ( $document [ 'body' ][ 'releaseYear' ], 2017 );
$dateValidator = new DatetimeValidator ();
$this -> assertEquals ( true , $dateValidator -> isValid ( $document [ 'body' ][ '$createdAt' ]));
$this -> assertEquals ( true , $dateValidator -> isValid ( $document [ 'body' ][ 'birthDay' ]));
$this -> assertContains ( Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])), $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])), $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])), $document [ 'body' ][ '$permissions' ]);
$document = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Ragnarok' ,
],
2025-09-20 12:50:50 +00:00
'permissions' => [
2025-09-25 14:28:59 +00:00
Permission :: read ( Role :: users ()),
Permission :: update ( Role :: users ()),
Permission :: delete ( Role :: users ()),
2025-09-20 12:50:50 +00:00
],
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $document [ 'body' ][ '$id' ], $id );
$this -> assertEquals ( $data [ 'moviesId' ], $document [ 'body' ][ '$collectionId' ]);
$this -> assertArrayNotHasKey ( '$collection' , $document [ 'body' ]);
$this -> assertEquals ( $databaseId , $document [ 'body' ][ '$databaseId' ]);
$this -> assertEquals ( $document [ 'body' ][ 'title' ], 'Thor: Ragnarok' );
$this -> assertEquals ( $document [ 'body' ][ 'releaseYear' ], 2017 );
$this -> assertContains ( Permission :: read ( Role :: users ()), $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: update ( Role :: users ()), $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: delete ( Role :: users ()), $document [ 'body' ][ '$permissions' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$id = $document [ 'body' ][ '$id' ];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $data [ 'moviesId' ], $document [ 'body' ][ '$collectionId' ]);
$this -> assertArrayNotHasKey ( '$collection' , $document [ 'body' ]);
$this -> assertEquals ( $databaseId , $document [ 'body' ][ '$databaseId' ]);
$this -> assertEquals ( $document [ 'body' ][ 'title' ], 'Thor: Ragnarok' );
$this -> assertEquals ( $document [ 'body' ][ 'releaseYear' ], 2017 );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-timestamp' => DateTime :: formatTz ( DateTime :: now ()),
], $this -> getHeaders ()), [
'data' => [
'title' => 'Thor: Ragnarok' ,
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test readonly attributes are ignored
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-timestamp' => DateTime :: formatTz ( DateTime :: now ()),
], $this -> getHeaders ()), [
'data' => [
'$id' => 'newId' ,
'$sequence' => 9999 ,
'$collectionId' => 'newCollectionId' ,
'$databaseId' => 'newDatabaseId' ,
'$createdAt' => '2024-01-01T00:00:00.000+00:00' ,
'$updatedAt' => '2024-01-01T00:00:00.000+00:00' ,
'title' => 'Thor: Ragnarok' ,
2025-09-20 12:50:50 +00:00
],
2025-09-25 14:28:59 +00:00
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $id , $response [ 'body' ][ '$id' ]);
$this -> assertEquals ( $data [ 'moviesId' ], $response [ 'body' ][ '$collectionId' ]);
$this -> assertEquals ( $databaseId , $response [ 'body' ][ '$databaseId' ]);
$this -> assertNotEquals ( 9999 , $response [ 'body' ][ '$sequence' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
if ( $this -> getSide () === 'client' ) {
$this -> assertNotEquals ( '2024-01-01T00:00:00.000+00:00' , $response [ 'body' ][ '$createdAt' ]);
$this -> assertNotEquals ( '2024-01-01T00:00:00.000+00:00' , $response [ 'body' ][ '$updatedAt' ]);
} else {
$this -> assertEquals ( '2024-01-01T00:00:00.000+00:00' , $response [ 'body' ][ '$createdAt' ]);
$this -> assertEquals ( '2024-01-01T00:00:00.000+00:00' , $response [ 'body' ][ '$updatedAt' ]);
2025-09-20 12:50:50 +00:00
}
2025-09-25 14:28:59 +00:00
return [];
}
/**
* @ depends testCreateDocument
*/
public function testDeleteDocument ( array $data ) : array
{
$databaseId = $data [ 'databaseId' ];
$document = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'title' => 'Thor: Ragnarok' ,
'releaseYear' => 2017 ,
'birthDay' => '1975-06-12 14:12:55' ,
'actors' => [],
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$id = $document [ 'body' ][ '$id' ];
$this -> assertEquals ( 201 , $document [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_DELETE , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 204 , $document [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 404 , $document [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
return $data ;
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
public function testInvalidDocumentStructure () : void
{
$database = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'databaseId' => ID :: unique (),
'name' => 'InvalidDocumentDatabase' ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'InvalidDocumentDatabase' , $database [ 'body' ][ 'name' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$databaseId = $database [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'invalidDocumentStructure' ,
'permissions' => [
Permission :: create ( Role :: any ()),
Permission :: read ( Role :: any ()),
],
'documentSecurity' => true ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'invalidDocumentStructure' , $collection [ 'body' ][ 'name' ]);
$collectionId = $collection [ 'body' ][ '$id' ];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$collection = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
]), []);
// no default values in documentsdb
$this -> assertCount ( 0 , $collection [ 'body' ][ 'attributes' ]);
/**
* Test for successful validation
*/
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$goodEmail = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'email' => 'user@example.com' ,
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$goodEnum = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'enum' => 'yes' ,
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$goodIp = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'ip' => '1.1.1.1' ,
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$goodUrl = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'url' => 'http://www.example.com' ,
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$goodRange = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'range' => 3 ,
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$goodFloatRange = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'floatRange' => 1.4 ,
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$goodProbability = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'probability' => 0.99999 ,
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$notTooHigh = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'upperBound' => 8 ,
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$notTooLow = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'lowerBound' => 8 ,
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $goodEmail [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 201 , $goodEnum [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 201 , $goodIp [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 201 , $goodUrl [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 201 , $goodRange [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 201 , $goodFloatRange [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 201 , $goodProbability [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 201 , $notTooHigh [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 201 , $notTooLow [ 'headers' ][ 'status-code' ]);
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* @ depends testDeleteDocument
*/
public function testDefaultPermissions ( array $data ) : array
{
$databaseId = $data [ 'databaseId' ];
$document = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'title' => 'Captain America' ,
'releaseYear' => 1944 ,
'actors' => [],
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$id = $document [ 'body' ][ '$id' ];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $document [ 'body' ][ 'title' ], 'Captain America' );
$this -> assertEquals ( $document [ 'body' ][ 'releaseYear' ], 1944 );
$this -> assertIsArray ( $document [ 'body' ][ '$permissions' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
if ( $this -> getSide () == 'client' ) {
$this -> assertCount ( 3 , $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])), $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])), $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])), $document [ 'body' ][ '$permissions' ]);
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
if ( $this -> getSide () == 'server' ) {
$this -> assertCount ( 0 , $document [ 'body' ][ '$permissions' ]);
$this -> assertEquals ([], $document [ 'body' ][ '$permissions' ]);
}
// Updated Permissions
$document = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'data' => [
'title' => 'Captain America 2' ,
'releaseYear' => 1945 ,
'actors' => [],
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ]))
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $document [ 'body' ][ 'title' ], 'Captain America 2' );
$this -> assertEquals ( $document [ 'body' ][ 'releaseYear' ], 1945 );
// This differs from the old permissions model because we don't inherit
// existing document permissions on update, unless none were supplied,
// so that specific types can be removed if wanted.
$this -> assertCount ( 2 , $document [ 'body' ][ '$permissions' ]);
$this -> assertEquals ([
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
], $document [ 'body' ][ '$permissions' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $document [ 'body' ][ 'title' ], 'Captain America 2' );
$this -> assertEquals ( $document [ 'body' ][ 'releaseYear' ], 1945 );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertCount ( 2 , $document [ 'body' ][ '$permissions' ]);
$this -> assertEquals ([
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
], $document [ 'body' ][ '$permissions' ]);
// Reset Permissions
$document = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'data' => [
'title' => 'Captain America 3' ,
'releaseYear' => 1946 ,
'actors' => [],
],
'permissions' => [],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $document [ 'body' ][ 'title' ], 'Captain America 3' );
$this -> assertEquals ( $document [ 'body' ][ 'releaseYear' ], 1946 );
$this -> assertCount ( 0 , $document [ 'body' ][ '$permissions' ]);
$this -> assertEquals ([], $document [ 'body' ][ '$permissions' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Check client side can no longer read the document.
$document = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
switch ( $this -> getSide ()) {
case 'client' :
$this -> assertEquals ( 404 , $document [ 'headers' ][ 'status-code' ]);
break ;
case 'server' :
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
break ;
}
return $data ;
2025-09-20 12:50:50 +00:00
}
2025-09-25 14:28:59 +00:00
public function testEnforceCollectionAndDocumentPermissions () : void
2025-09-20 12:50:50 +00:00
{
2025-09-25 14:28:59 +00:00
$database = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
]), [
2025-09-20 12:50:50 +00:00
'databaseId' => ID :: unique (),
2025-09-25 14:28:59 +00:00
'name' => 'EnforceCollectionAndDocumentPermissions' ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'EnforceCollectionAndDocumentPermissions' , $database [ 'body' ][ 'name' ]);
2025-09-20 12:50:50 +00:00
$databaseId = $database [ 'body' ][ '$id' ];
2025-09-25 14:28:59 +00:00
$user = $this -> getUser ()[ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
2025-09-25 14:28:59 +00:00
'name' => 'enforceCollectionAndDocumentPermissions' ,
2025-09-20 12:50:50 +00:00
'documentSecurity' => true ,
'permissions' => [
2025-09-25 14:28:59 +00:00
Permission :: read ( Role :: user ( $user )),
Permission :: create ( Role :: user ( $user )),
Permission :: update ( Role :: user ( $user )),
Permission :: delete ( Role :: user ( $user )),
2025-09-20 12:50:50 +00:00
],
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $collection [ 'body' ][ 'name' ], 'enforceCollectionAndDocumentPermissions' );
$this -> assertEquals ( $collection [ 'body' ][ 'documentSecurity' ], true );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$collectionId = $collection [ 'body' ][ '$id' ];
2025-09-20 12:50:50 +00:00
sleep ( 2 );
2025-09-25 14:28:59 +00:00
$index = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-09-25 14:28:59 +00:00
'key' => 'key_attribute' ,
'type' => 'key' ,
'attributes' => [ 'attributes' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $index [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'key_attribute' , $index [ 'body' ][ 'key' ]);
// wait for db to add attribute
2025-09-20 12:50:50 +00:00
sleep ( 2 );
2025-09-25 14:28:59 +00:00
$document1 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'data' => [
2025-09-25 14:28:59 +00:00
'attribute' => 'one' ,
2025-09-20 12:50:50 +00:00
],
'permissions' => [
2025-09-25 14:28:59 +00:00
Permission :: read ( Role :: user ( $user )),
Permission :: update ( Role :: user ( $user )),
Permission :: delete ( Role :: user ( $user )),
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document1 [ 'headers' ][ 'status-code' ]);
$document2 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'attribute' => 'one' ,
],
'permissions' => [
Permission :: update ( Role :: user ( $user )),
Permission :: delete ( Role :: user ( $user )),
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document2 [ 'headers' ][ 'status-code' ]);
$document3 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , [
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
], [
'documentId' => ID :: unique (),
'data' => [
'attribute' => 'one' ,
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( 'other' ))),
Permission :: update ( Role :: user ( ID :: custom ( 'other' ))),
],
]);
$this -> assertEquals ( 201 , $document3 [ 'headers' ][ 'status-code' ]);
$documentsUser1 = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
// Current user has read permission on the collection so can get any document
$this -> assertEquals ( 3 , $documentsUser1 [ 'body' ][ 'total' ]);
$this -> assertCount ( 3 , $documentsUser1 [ 'body' ][ 'documents' ]);
$document3GetWithCollectionRead = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $document3 [ 'body' ][ '$id' ], array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Current user has read permission on the collection so can get any document
$this -> assertEquals ( 200 , $document3GetWithCollectionRead [ 'headers' ][ 'status-code' ]);
$email = uniqid () . 'user@localhost.test' ;
$password = 'password' ;
$name = 'User Name' ;
$this -> client -> call ( Client :: METHOD_POST , '/account' , [
'origin' => 'http://localhost' ,
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], [
2025-09-25 14:28:59 +00:00
'userId' => ID :: custom ( 'other' ),
'email' => $email ,
'password' => $password ,
'name' => $name ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$session2 = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], [
'email' => $email ,
'password' => $password ,
]);
$session2 = $session2 [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document3GetWithDocumentRead = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $document3 [ 'body' ][ '$id' ], [
'origin' => 'http://localhost' ,
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session2 ,
]);
// Current user has no collection permissions but has read permission for this document
$this -> assertEquals ( 200 , $document3GetWithDocumentRead [ 'headers' ][ 'status-code' ]);
$document2GetFailure = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $document2 [ 'body' ][ '$id' ], [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session2 ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
// Current user has no collection or document permissions for this document
$this -> assertEquals ( 404 , $document2GetFailure [ 'headers' ][ 'status-code' ]);
$documentsUser2 = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , [
'origin' => 'http://localhost' ,
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session2 ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
// Current user has no collection permissions but has read permission for one document
$this -> assertEquals ( 1 , $documentsUser2 [ 'body' ][ 'total' ]);
$this -> assertCount ( 1 , $documentsUser2 [ 'body' ][ 'documents' ]);
}
public function testEnforceCollectionPermissions () : void
{
$database = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-09-25 14:28:59 +00:00
'databaseId' => ID :: unique (),
'name' => 'EnforceCollectionPermissions' ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'EnforceCollectionPermissions' , $database [ 'body' ][ 'name' ]);
$databaseId = $database [ 'body' ][ '$id' ];
$user = $this -> getUser ()[ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-09-25 14:28:59 +00:00
'collectionId' => ID :: unique (),
'name' => 'enforceCollectionPermissions' ,
'permissions' => [
Permission :: read ( Role :: user ( $user )),
Permission :: create ( Role :: user ( $user )),
Permission :: update ( Role :: user ( $user )),
Permission :: delete ( Role :: user ( $user )),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $collection [ 'body' ][ 'name' ], 'enforceCollectionPermissions' );
$this -> assertEquals ( $collection [ 'body' ][ 'documentSecurity' ], false );
$collectionId = $collection [ 'body' ][ '$id' ];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$index = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-09-25 14:28:59 +00:00
'key' => 'key_attribute' ,
'type' => 'key' ,
'attributes' => [ 'attributes' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $index [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'key_attribute' , $index [ 'body' ][ 'key' ]);
\sleep ( 2 );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document1 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
2025-09-20 12:50:50 +00:00
'data' => [
2025-09-25 14:28:59 +00:00
'attribute' => 'one' ,
2025-09-20 12:50:50 +00:00
],
'permissions' => [
2025-09-25 14:28:59 +00:00
Permission :: read ( Role :: user ( $user )),
Permission :: update ( Role :: user ( $user )),
Permission :: delete ( Role :: user ( $user )),
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document1 [ 'headers' ][ 'status-code' ]);
$document2 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'attribute' => 'one' ,
],
'permissions' => [
Permission :: update ( Role :: user ( $user )),
Permission :: delete ( Role :: user ( $user )),
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document2 [ 'headers' ][ 'status-code' ]);
$document3 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , [
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
], [
'documentId' => ID :: unique (),
'data' => [
'attribute' => 'one' ,
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( 'other2' ))),
Permission :: update ( Role :: user ( ID :: custom ( 'other2' ))),
],
]);
$this -> assertEquals ( 201 , $document3 [ 'headers' ][ 'status-code' ]);
$documentsUser1 = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
// Current user has read permission on the collection so can get any document
$this -> assertEquals ( 3 , $documentsUser1 [ 'body' ][ 'total' ]);
$this -> assertCount ( 3 , $documentsUser1 [ 'body' ][ 'documents' ]);
$document3GetWithCollectionRead = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $document3 [ 'body' ][ '$id' ], array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Current user has read permission on the collection so can get any document
$this -> assertEquals ( 200 , $document3GetWithCollectionRead [ 'headers' ][ 'status-code' ]);
$email = uniqid () . 'user2@localhost.test' ;
$password = 'password' ;
$name = 'User Name' ;
$this -> client -> call ( Client :: METHOD_POST , '/account' , [
'origin' => 'http://localhost' ,
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], [
2025-09-25 14:28:59 +00:00
'userId' => ID :: custom ( 'other2' ),
'email' => $email ,
'password' => $password ,
'name' => $name ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$session2 = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], [
'email' => $email ,
'password' => $password ,
]);
$session2 = $session2 [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document3GetWithDocumentRead = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $document3 [ 'body' ][ '$id' ], [
'origin' => 'http://localhost' ,
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session2 ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
// other2 has no collection permissions and document permissions are disabled
$this -> assertEquals ( 404 , $document3GetWithDocumentRead [ 'headers' ][ 'status-code' ]);
$documentsUser2 = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , [
'origin' => 'http://localhost' ,
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session2 ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
// other2 has no collection permissions and document permissions are disabled
$this -> assertEquals ( 401 , $documentsUser2 [ 'headers' ][ 'status-code' ]);
// Enable document permissions
$collection = $this -> client -> call ( CLient :: METHOD_PUT , '/documentsdb/' . $databaseId . '/collections/' . $collectionId , [
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
], [
'name' => $collection [ 'body' ][ 'name' ],
'documentSecurity' => true ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$documentsUser2 = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , [
'origin' => 'http://localhost' ,
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session2 ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
// Current user has no collection permissions read access to one document
$this -> assertEquals ( 1 , $documentsUser2 [ 'body' ][ 'total' ]);
$this -> assertCount ( 1 , $documentsUser2 [ 'body' ][ 'documents' ]);
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* @ depends testDefaultPermissions
*/
public function testUniqueIndexDuplicate ( array $data ) : array
{
$databaseId = $data [ 'databaseId' ];
$uniqueIndex = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/indexes' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-09-25 14:28:59 +00:00
'key' => 'unique_title' ,
'type' => 'unique' ,
'attributes' => [ 'title' ],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 202 , $uniqueIndex [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
sleep ( 2 );
2025-09-25 14:28:59 +00:00
// test for failure
$duplicate = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
2025-09-20 12:50:50 +00:00
'data' => [
2025-09-25 14:28:59 +00:00
'title' => 'Captain America' ,
'releaseYear' => 1944 ,
'actors' => [
'Chris Evans' ,
'Samuel Jackson' ,
]
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 409 , $duplicate [ 'headers' ][ 'status-code' ]);
// Test for exception when updating document to conflict
$document = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'title' => 'Captain America 5' ,
'releaseYear' => 1944 ,
'actors' => [
'Chris Evans' ,
'Samuel Jackson' ,
]
],
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test for exception when updating document to conflict
$duplicate = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $document [ 'body' ][ '$id' ], array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'data' => [
'title' => 'Captain America' ,
'releaseYear' => 1944 ,
'actors' => [
'Chris Evans' ,
'Samuel Jackson' ,
]
2025-09-20 12:50:50 +00:00
],
'permissions' => [
2025-09-25 14:28:59 +00:00
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 409 , $duplicate [ 'headers' ][ 'status-code' ]);
return $data ;
}
/**
* @ depends testUniqueIndexDuplicate
*/
public function testPersistentCreatedAt ( array $data ) : array
{
$headers = $this -> getSide () === 'client' ? array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()) : [
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
];
$document = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $data [ 'databaseId' ] . '/collections/' . $data [ 'moviesId' ] . '/documents' , $headers , [
'documentId' => ID :: unique (),
'data' => [
'title' => 'Creation Date Test' ,
'releaseYear' => 2000
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( $document [ 'body' ][ 'title' ], 'Creation Date Test' );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documentId = $document [ 'body' ][ '$id' ];
$createdAt = $document [ 'body' ][ '$createdAt' ];
$updatedAt = $document [ 'body' ][ '$updatedAt' ];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
\sleep ( 1 );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $data [ 'databaseId' ] . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , $headers , [
2025-09-20 12:50:50 +00:00
'data' => [
2025-09-25 14:28:59 +00:00
'title' => 'Updated Date Test' ,
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
$updatedAtSecond = $document [ 'body' ][ '$updatedAt' ];
$this -> assertEquals ( $document [ 'body' ][ 'title' ], 'Updated Date Test' );
$this -> assertEquals ( $document [ 'body' ][ '$createdAt' ], $createdAt );
$this -> assertNotEquals ( $document [ 'body' ][ '$updatedAt' ], $updatedAt );
\sleep ( 1 );
$document = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $data [ 'databaseId' ] . '/collections/' . $data [ 'moviesId' ] . '/documents/' . $documentId , $headers , [
'data' => [
'title' => 'Again Updated Date Test' ,
'$createdAt' => '2022-08-01 13:09:23.040' ,
'$updatedAt' => '2022-08-01 13:09:23.050'
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
if ( $this -> getSide () === 'client' ) {
$this -> assertEquals ( $document [ 'body' ][ 'title' ], 'Again Updated Date Test' );
$this -> assertNotEquals ( $document [ 'body' ][ '$createdAt' ], DateTime :: formatTz ( '2022-08-01 13:09:23.040' ));
$this -> assertNotEquals ( $document [ 'body' ][ '$updatedAt' ], DateTime :: formatTz ( '2022-08-01 13:09:23.050' ));
} else {
$this -> assertEquals ( $document [ 'body' ][ 'title' ], 'Again Updated Date Test' );
$this -> assertEquals ( $document [ 'body' ][ '$createdAt' ], DateTime :: formatTz ( '2022-08-01 13:09:23.040' ));
$this -> assertEquals ( $document [ 'body' ][ '$updatedAt' ], DateTime :: formatTz ( '2022-08-01 13:09:23.050' ));
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
}
return $data ;
2025-09-20 12:50:50 +00:00
}
2025-09-25 14:28:59 +00:00
public function testUpdatePermissionsWithEmptyPayload () : array
2025-09-20 12:50:50 +00:00
{
2025-09-25 14:28:59 +00:00
// Create Database
$database = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
2025-09-25 14:28:59 +00:00
]), [
2025-09-20 12:50:50 +00:00
'databaseId' => ID :: unique (),
2025-09-25 14:28:59 +00:00
'name' => 'Empty Permissions' ,
2025-09-20 12:50:50 +00:00
]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
2025-09-25 14:28:59 +00:00
2025-09-20 12:50:50 +00:00
$databaseId = $database [ 'body' ][ '$id' ];
2025-09-25 14:28:59 +00:00
// Create collection
$movies = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
2025-09-25 14:28:59 +00:00
'name' => 'Movies' ,
2025-09-20 12:50:50 +00:00
'permissions' => [
2025-09-25 14:28:59 +00:00
Permission :: create ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
2025-09-20 12:50:50 +00:00
],
2025-09-25 14:28:59 +00:00
'documentSecurity' => true ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $movies [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $movies [ 'body' ][ 'name' ], 'Movies' );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$moviesId = $movies [ 'body' ][ '$id' ];
2025-09-20 12:50:50 +00:00
sleep ( 2 );
2025-09-25 14:28:59 +00:00
// add document
$document = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $moviesId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'data' => [
'title' => 'Captain America' ,
],
'permissions' => [
Permission :: read ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$id = $document [ 'body' ][ '$id' ];
$this -> assertEquals ( 201 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 3 , $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: read ( Role :: any ()), $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: update ( Role :: any ()), $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: delete ( Role :: any ()), $document [ 'body' ][ '$permissions' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Send only read permission
$document = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $moviesId . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'permissions' => [
Permission :: read ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 1 , $document [ 'body' ][ '$permissions' ]);
// Send only mutation permissions
$document = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $moviesId . '/documents/' . $id , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()), [
'permissions' => [
Permission :: update ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
Permission :: delete ( Role :: user ( ID :: custom ( $this -> getUser ()[ '$id' ]))),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
if ( $this -> getSide () == 'server' ) {
$this -> assertEquals ( 200 , $document [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 2 , $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])), $document [ 'body' ][ '$permissions' ]);
$this -> assertContains ( Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])), $document [ 'body' ][ '$permissions' ]);
}
// remove collection
$this -> client -> call ( Client :: METHOD_DELETE , '/documentsdb/' . $databaseId . '/collections/' . $moviesId , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
return [];
2025-09-20 12:50:50 +00:00
}
2025-09-25 14:28:59 +00:00
/**
* @ throws \Utopia\Database\Exception
* @ throws \Utopia\Database\Exception\Query
*/
public function testOrQueries () : void
2025-09-20 12:50:50 +00:00
{
2025-09-25 14:28:59 +00:00
// Create database
2025-09-20 12:50:50 +00:00
$database = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'databaseId' => ID :: unique (),
2025-09-25 14:28:59 +00:00
'name' => 'Or queries'
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertNotEmpty ( $database [ 'body' ][ '$id' ]);
$this -> assertEquals ( 201 , $database [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'Or queries' , $database [ 'body' ][ 'name' ]);
2025-09-20 12:50:50 +00:00
$databaseId = $database [ 'body' ][ '$id' ];
2025-09-25 14:28:59 +00:00
// Create Collection
$presidents = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
2025-09-25 14:28:59 +00:00
'name' => 'USA Presidents' ,
2025-09-20 12:50:50 +00:00
'documentSecurity' => true ,
'permissions' => [
2025-09-25 14:28:59 +00:00
Permission :: create ( Role :: user ( $this -> getUser ()[ '$id' ])),
2025-09-20 12:50:50 +00:00
],
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $presidents [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $presidents [ 'body' ][ 'name' ], 'USA Presidents' );
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document1 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $presidents [ 'body' ][ '$id' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
2025-09-20 12:50:50 +00:00
'data' => [
2025-09-25 14:28:59 +00:00
'first_name' => 'Donald' ,
'last_name' => 'Trump' ,
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document1 [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document2 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $presidents [ 'body' ][ '$id' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
2025-09-20 12:50:50 +00:00
'data' => [
2025-09-25 14:28:59 +00:00
'first_name' => 'George' ,
'last_name' => 'Bush' ,
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
2025-09-20 12:50:50 +00:00
]
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document2 [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$document3 = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $presidents [ 'body' ][ '$id' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'documentId' => ID :: unique (),
'data' => [
'first_name' => 'Joe' ,
'last_name' => 'Biden' ,
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
]
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $document3 [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$documents = $this -> client -> call (
Client :: METHOD_GET ,
'/documentsdb/' . $databaseId . '/collections/' . $presidents [ 'body' ][ '$id' ] . '/documents' ,
array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()),
[
'queries' => [
Query :: select ([ 'first_name' , 'last_name' ]) -> toString (),
Query :: or ([
Query :: equal ( 'first_name' , [ 'Donald' ]),
Query :: equal ( 'last_name' , [ 'Bush' ])
]) -> toString (),
Query :: limit ( 999 ) -> toString (),
Query :: offset ( 0 ) -> toString ()
],
]
);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $documents [ 'headers' ][ 'status-code' ]);
$this -> assertCount ( 2 , $documents [ 'body' ][ 'documents' ]);
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
/**
* @ depends testCreateDatabase
*/
public function testTimeout ( array $data ) : void
{
$collection = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $data [ 'databaseId' ] . '/collections' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
'collectionId' => ID :: unique (),
'name' => 'Slow Queries' ,
'documentSecurity' => true ,
'permissions' => [
Permission :: create ( Role :: user ( $this -> getUser ()[ '$id' ])),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $collection [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$data = [
'$id' => $collection [ 'body' ][ '$id' ],
'databaseId' => $collection [ 'body' ][ 'databaseId' ]
];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
for ( $i = 0 ; $i < 10 ; $i ++ ) {
$this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'data' => [
'longtext' => file_get_contents ( __DIR__ . '../../../../../resources/longtext.txt' ),
],
'permissions' => [
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: update ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: delete ( Role :: user ( $this -> getUser ()[ '$id' ])),
]
]);
}
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $data [ 'databaseId' ] . '/collections/' . $data [ '$id' ] . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
'x-appwrite-timeout' => 1 ,
2025-09-20 12:50:50 +00:00
], $this -> getHeaders ()), [
2025-09-25 14:28:59 +00:00
'queries' => [
Query :: notEqual ( 'longtext' , 'appwrite' ) -> toString (),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 408 , $response [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$this -> client -> call ( Client :: METHOD_DELETE , '/documentsdb/' . $data [ 'databaseId' ], array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]));
}
2025-09-25 14:28:59 +00:00
/**
* @ throws \Exception
*/
public function testIncrementAttribute () : void
2025-09-20 12:50:50 +00:00
{
$database = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'databaseId' => ID :: unique (),
2025-09-25 14:28:59 +00:00
'name' => 'CounterDatabase'
2025-09-20 12:50:50 +00:00
]);
$databaseId = $database [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-09-25 14:28:59 +00:00
'collectionId' => ID :: unique (),
'name' => 'CounterCollection' ,
2025-09-20 12:50:50 +00:00
'documentSecurity' => true ,
'permissions' => [
2025-09-25 14:28:59 +00:00
Permission :: create ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
2025-09-20 12:50:50 +00:00
],
]);
2025-09-25 14:28:59 +00:00
$collectionId = $collection [ 'body' ][ '$id' ];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Create document with initial count = 5
$doc = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
'data' => [
2025-09-25 14:28:59 +00:00
'count' => 5
2025-09-20 12:50:50 +00:00
],
'permissions' => [
2025-09-25 14:28:59 +00:00
Permission :: read ( Role :: any ()),
Permission :: update ( Role :: any ()),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 201 , $doc [ 'headers' ][ 'status-code' ]);
$docId = $doc [ 'body' ][ '$id' ];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Increment by default 1
$inc = $this -> client -> call ( Client :: METHOD_PATCH , " /documentsdb/ $databaseId /collections/ $collectionId /documents/ $docId /count/increment " , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
]));
$this -> assertEquals ( 200 , $inc [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 6 , $inc [ 'body' ][ 'count' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Verify count = 6
$get = $this -> client -> call ( Client :: METHOD_GET , " /documentsdb/ $databaseId /collections/ $collectionId /documents/ $docId " , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
$this -> assertEquals ( 6 , $get [ 'body' ][ 'count' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Increment by custom value 4
$inc2 = $this -> client -> call ( Client :: METHOD_PATCH , " /documentsdb/ $databaseId /collections/ $collectionId /documents/ $docId /count/increment " , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
2025-09-25 14:28:59 +00:00
'value' => 4
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $inc2 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 10 , $inc2 [ 'body' ][ 'count' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$get2 = $this -> client -> call ( Client :: METHOD_GET , " /documentsdb/ $databaseId /collections/ $collectionId /documents/ $docId " , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
], $this -> getHeaders ()));
$this -> assertEquals ( 10 , $get2 [ 'body' ][ 'count' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test max limit exceeded
$err = $this -> client -> call ( Client :: METHOD_PATCH , " /documentsdb/ $databaseId /collections/ $collectionId /documents/ $docId /count/increment " , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
]), [ 'max' => 8 ]);
$this -> assertEquals ( 400 , $err [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test attribute not found
$notFound = $this -> client -> call ( Client :: METHOD_PATCH , " /documentsdb/ $databaseId /collections/ $collectionId /documents/ $docId /unknown/increment " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2025-09-26 12:31:39 +00:00
$this -> assertEquals ( 200 , $notFound [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test increment with value 0
$inc3 = $this -> client -> call ( Client :: METHOD_PATCH , " /documentsdb/ $databaseId /collections/ $collectionId /documents/ $docId /count/increment " , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
2025-09-25 14:28:59 +00:00
'value' => 0
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 400 , $inc3 [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
}
2025-09-25 14:28:59 +00:00
public function testDecrementAttribute () : void
2025-09-20 12:50:50 +00:00
{
$database = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
], [
'databaseId' => ID :: unique (),
2025-09-25 14:28:59 +00:00
'name' => 'CounterDatabase'
2025-09-20 12:50:50 +00:00
]);
$databaseId = $database [ 'body' ][ '$id' ];
$collection = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ]
]), [
2025-09-25 14:28:59 +00:00
'collectionId' => ID :: unique (),
'name' => 'CounterCollection' ,
2025-09-20 12:50:50 +00:00
'documentSecurity' => true ,
'permissions' => [
2025-09-25 14:28:59 +00:00
Permission :: create ( Role :: user ( $this -> getUser ()[ '$id' ])),
Permission :: read ( Role :: user ( $this -> getUser ()[ '$id' ])),
2025-09-20 12:50:50 +00:00
],
]);
2025-09-25 14:28:59 +00:00
$collectionId = $collection [ 'body' ][ '$id' ];
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Create document with initial count = 10
$doc = $this -> client -> call ( Client :: METHOD_POST , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()), [
'documentId' => ID :: unique (),
2025-09-25 14:28:59 +00:00
'data' => [ 'count' => 10 ],
2025-09-20 12:50:50 +00:00
'permissions' => [
2025-09-25 14:28:59 +00:00
Permission :: read ( Role :: any ()),
Permission :: update ( Role :: any ()),
],
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$documentId = $doc [ 'body' ][ '$id' ];
// Decrement by default 1 (count = 10 -> 9)
$dec = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId . '/count/decrement' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
]));
$this -> assertEquals ( 200 , $dec [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 9 , $dec [ 'body' ][ 'count' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
$get = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 9 , $get [ 'body' ][ 'count' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Decrement by custom value 3 (count 9 -> 6)
$dec2 = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId . '/count/decrement' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
2025-09-25 14:28:59 +00:00
'value' => 3
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 200 , $dec2 [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 6 , $dec2 [ 'body' ][ 'count' ]);
$get2 = $this -> client -> call ( Client :: METHOD_GET , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], $this -> getHeaders ()));
$this -> assertEquals ( 6 , $get2 [ 'body' ][ 'count' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test min limit exceeded
$err = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId . '/count/decrement' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [ 'min' => 7 ]);
$this -> assertEquals ( 400 , $err [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test min limit exceeded with custom value
$err = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId . '/count/decrement' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
2025-09-25 14:28:59 +00:00
'value' => 3 ,
'min' => 5 ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 400 , $err [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test min limit 0
$err = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId . '/count/decrement' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
]), [
'value' => 10 ,
'min' => 0 ,
2025-09-20 12:50:50 +00:00
]);
2025-09-25 14:28:59 +00:00
$this -> assertEquals ( 400 , $err [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test type error on non-numeric attribute
$typeErr = $this -> client -> call ( Client :: METHOD_PATCH , '/documentsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId . '/count/decrement' , array_merge ([
2025-09-20 12:50:50 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-09-25 14:28:59 +00:00
]), [ 'value' => 'not-a-number' ]);
$this -> assertEquals ( 400 , $typeErr [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
2025-09-25 14:28:59 +00:00
// Test decrement with value 0
$inc3 = $this -> client -> call ( Client :: METHOD_PATCH , " /documentsdb/ $databaseId /collections/ $collectionId /documents/ $documentId /count/increment " , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'value' => 0
]);
$this -> assertEquals ( 400 , $inc3 [ 'headers' ][ 'status-code' ]);
2025-09-20 12:50:50 +00:00
}
2025-09-19 14:14:46 +00:00
}