mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
added tests for bulk operation
This commit is contained in:
1 parent
a80c410d07
commit
3755d58d62
2 files changed
+1518
No files matched your search
@@ -7029,4 +7029,956 @@ trait DatabasesBase
|
||||
]);
|
||||
$this->assertEquals(400, $inc3['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testSpatialPointColumns(): void
|
||||
{
|
||||
$database = $this->client->call(Client::METHOD_POST, '/tablesdb', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Spatial Point Test Database'
|
||||
]);
|
||||
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create table with spatial and non-spatial columns
|
||||
$table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'tableId' => ID::unique(),
|
||||
'name' => 'Spatial Point Table',
|
||||
'rowSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::user($this->getUser()['$id'])),
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
Permission::update(Role::user($this->getUser()['$id'])),
|
||||
Permission::delete(Role::user($this->getUser()['$id'])),
|
||||
],
|
||||
]);
|
||||
|
||||
$tableId = $table['body']['$id'];
|
||||
|
||||
// Create string column
|
||||
$this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
// Create point column
|
||||
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/point', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'location',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $response['headers']['status-code']);
|
||||
|
||||
sleep(2);
|
||||
|
||||
// Create row with point column
|
||||
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rowId' => ID::unique(),
|
||||
'data' => [
|
||||
'name' => 'Test Location',
|
||||
'location' => [40.7128, -74.0060]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals([40.7128, -74.0060], $response['body']['location']);
|
||||
$rowId = $response['body']['$id'];
|
||||
|
||||
// Read row with point column
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . $rowId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals([40.7128, -74.0060], $response['body']['location']);
|
||||
|
||||
// Update row with new point coordinates
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . $rowId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'location' => [40.7589, -73.9851]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals([40.7589, -73.9851], $response['body']['location']);
|
||||
|
||||
// Upsert row with point column
|
||||
$response = $this->client->call(Client::METHOD_PUT, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . ID::unique(), array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rowId' => ID::unique(),
|
||||
'data' => [
|
||||
'name' => 'Upserted Location',
|
||||
'location' => [34.0522, -118.2437]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals([34.0522, -118.2437], $response['body']['location']);
|
||||
|
||||
// Create row without permissions (should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'rowId' => ID::unique(),
|
||||
'data' => [
|
||||
'name' => 'Unauthorized Location',
|
||||
'location' => [0, 0]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(401, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialLineColumns(): void
|
||||
{
|
||||
$database = $this->client->call(Client::METHOD_POST, '/tablesdb', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Spatial Line Test Database'
|
||||
]);
|
||||
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create table with spatial and non-spatial columns
|
||||
$table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'tableId' => ID::unique(),
|
||||
'name' => 'Spatial Line Table',
|
||||
'rowSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::user($this->getUser()['$id'])),
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
Permission::update(Role::user($this->getUser()['$id'])),
|
||||
Permission::delete(Role::user($this->getUser()['$id'])),
|
||||
],
|
||||
]);
|
||||
|
||||
$tableId = $table['body']['$id'];
|
||||
|
||||
// Create integer column
|
||||
$this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/integer', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'distance',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
// Create line column
|
||||
$this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/line', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'route',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
sleep(2);
|
||||
|
||||
// Create row with line column
|
||||
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rowId' => ID::unique(),
|
||||
'data' => [
|
||||
'distance' => 100,
|
||||
'route' => [[40.7128, -74.0060], [40.7589, -73.9851]]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals([[40.7128, -74.0060], [40.7589, -73.9851]], $response['body']['route']);
|
||||
$rowId = $response['body']['$id'];
|
||||
|
||||
// Read row
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . $rowId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals([[40.7128, -74.0060], [40.7589, -73.9851]], $response['body']['route']);
|
||||
|
||||
// Update row
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . $rowId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'route' => [[40.7128, -74.0060], [40.7589, -73.9851], [40.7505, -73.9934]]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals([[40.7128, -74.0060], [40.7589, -73.9851], [40.7505, -73.9934]], $response['body']['route']);
|
||||
|
||||
// Upsert row with line column
|
||||
$response = $this->client->call(Client::METHOD_PUT, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . ID::unique(), array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rowId' => ID::unique(),
|
||||
'data' => [
|
||||
'distance' => 200,
|
||||
'route' => [[34.0522, -118.2437], [34.0736, -118.2400]]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals([[34.0522, -118.2437], [34.0736, -118.2400]], $response['body']['route']);
|
||||
|
||||
// Delete row
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . $rowId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
$this->assertEquals(204, $response['headers']['status-code']);
|
||||
|
||||
// Verify row is deleted
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . $rowId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialPolygonColumns(): void
|
||||
{
|
||||
$database = $this->client->call(Client::METHOD_POST, '/tablesdb', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Spatial Polygon Test Database'
|
||||
]);
|
||||
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create table with spatial and non-spatial columns
|
||||
$table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'tableId' => ID::unique(),
|
||||
'name' => 'Spatial Polygon Table',
|
||||
'rowSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::user($this->getUser()['$id'])),
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
Permission::update(Role::user($this->getUser()['$id'])),
|
||||
Permission::delete(Role::user($this->getUser()['$id'])),
|
||||
],
|
||||
]);
|
||||
|
||||
$tableId = $table['body']['$id'];
|
||||
|
||||
// Create boolean column
|
||||
$this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/boolean', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'active',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
// Create polygon column
|
||||
$this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/polygon', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'area',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
sleep(2);
|
||||
|
||||
// Create row with polygon column
|
||||
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rowId' => ID::unique(),
|
||||
'data' => [
|
||||
'active' => true,
|
||||
'area' => [[[40.7128, -74.0060], [40.7589, -74.0060], [40.7589, -73.9851], [40.7128, -73.9851], [40.7128, -74.0060]]]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals([[[40.7128, -74.0060], [40.7589, -74.0060], [40.7589, -73.9851], [40.7128, -73.9851], [40.7128, -74.0060]]], $response['body']['area']);
|
||||
$rowId = $response['body']['$id'];
|
||||
|
||||
// Read row
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . $rowId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals([[[40.7128, -74.0060], [40.7589, -74.0060], [40.7589, -73.9851], [40.7128, -73.9851], [40.7128, -74.0060]]], $response['body']['area']);
|
||||
|
||||
// Update row with new polygon
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . $rowId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'area' => [[[40.7128, -74.0060], [40.7589, -74.0060], [40.7589, -73.9851], [40.7128, -73.9851], [40.7505, -73.9934], [40.7128, -74.0060]]]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals([[[40.7128, -74.0060], [40.7589, -74.0060], [40.7589, -73.9851], [40.7128, -73.9851], [40.7505, -73.9934], [40.7128, -74.0060]]], $response['body']['area']);
|
||||
|
||||
// Upsert row with polygon column
|
||||
$response = $this->client->call(Client::METHOD_PUT, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . ID::unique(), array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rowId' => ID::unique(),
|
||||
'data' => [
|
||||
'active' => false,
|
||||
'area' => [[[34.0522, -118.2437], [34.0736, -118.2437], [34.0736, -118.2400], [34.0522, -118.2400], [34.0522, -118.2437]]]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals([[[34.0522, -118.2437], [34.0736, -118.2437], [34.0736, -118.2400], [34.0522, -118.2400], [34.0522, -118.2437]]], $response['body']['area']);
|
||||
|
||||
// Create row missing required polygon (should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rowId' => ID::unique(),
|
||||
'data' => [
|
||||
'active' => true
|
||||
]
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialColumnsMixedTable(): void
|
||||
{
|
||||
$database = $this->client->call(Client::METHOD_POST, '/tablesdb', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Mixed Spatial Test Database'
|
||||
]);
|
||||
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create table with multiple spatial and non-spatial columns
|
||||
$table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'tableId' => ID::unique(),
|
||||
'name' => 'Mixed Spatial Table',
|
||||
'rowSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::user($this->getUser()['$id'])),
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
Permission::update(Role::user($this->getUser()['$id'])),
|
||||
Permission::delete(Role::user($this->getUser()['$id'])),
|
||||
],
|
||||
]);
|
||||
|
||||
$tableId = $table['body']['$id'];
|
||||
|
||||
// Create multiple columns
|
||||
$this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/point', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'center',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/line', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'boundary',
|
||||
'required' => false,
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/polygon', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'coverage',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
sleep(3);
|
||||
|
||||
// Create row with all spatial columns
|
||||
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rowId' => ID::unique(),
|
||||
'data' => [
|
||||
'name' => 'Central Park',
|
||||
'center' => [40.7829, -73.9654],
|
||||
'boundary' => [[40.7649, -73.9814], [40.8009, -73.9494]],
|
||||
'coverage' => [[[40.7649, -73.9814], [40.8009, -73.9814], [40.8009, -73.9494], [40.7649, -73.9494], [40.7649, -73.9814]]]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals([40.7829, -73.9654], $response['body']['center']);
|
||||
$this->assertEquals([[40.7649, -73.9814], [40.8009, -73.9494]], $response['body']['boundary']);
|
||||
$this->assertEquals([[[40.7649, -73.9814], [40.8009, -73.9814], [40.8009, -73.9494], [40.7649, -73.9494], [40.7649, -73.9814]]], $response['body']['coverage']);
|
||||
$rowId = $response['body']['$id'];
|
||||
|
||||
// Update row with new spatial data
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows/' . $rowId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'center' => [40.7505, -73.9934],
|
||||
'boundary' => [[40.7305, -74.0134], [40.7705, -73.9734]],
|
||||
'coverage' => [[[40.7305, -74.0134], [40.7705, -74.0134], [40.7705, -73.9734], [40.7305, -73.9734], [40.7305, -74.0134]]]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals([40.7505, -73.9934], $response['body']['center']);
|
||||
$this->assertEquals([[40.7305, -74.0134], [40.7705, -73.9734]], $response['body']['boundary']);
|
||||
$this->assertEquals([[[40.7305, -74.0134], [40.7705, -74.0134], [40.7705, -73.9734], [40.7305, -73.9734], [40.7305, -74.0134]]], $response['body']['coverage']);
|
||||
|
||||
// Create row with minimal required columns
|
||||
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rowId' => ID::unique(),
|
||||
'data' => [
|
||||
'name' => 'Minimal Location',
|
||||
'center' => [0, 0],
|
||||
'coverage' => [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals([0, 0], $response['body']['center']);
|
||||
|
||||
// Permission validation - create without user context
|
||||
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'rowId' => ID::unique(),
|
||||
'data' => [
|
||||
'name' => 'Unauthorized Location',
|
||||
'center' => [0, 0],
|
||||
'coverage' => [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(401, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialQuery(): void
|
||||
{
|
||||
$database = $this->client->call(Client::METHOD_POST, '/tablesdb', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Spatial Query Test Database'
|
||||
]);
|
||||
|
||||
$this->assertNotEmpty($database['body']['$id']);
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create table with spatial columns
|
||||
$table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'tableId' => ID::unique(),
|
||||
'name' => 'Spatial Query Table',
|
||||
'rowSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $table['headers']['status-code']);
|
||||
$tableId = $table['body']['$id'];
|
||||
|
||||
// Create string column
|
||||
$nameColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
$this->assertEquals(202, $nameColumn['headers']['status-code']);
|
||||
|
||||
// Create point column
|
||||
$pointColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/point', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'pointAttr',
|
||||
'required' => true,
|
||||
]);
|
||||
$this->assertEquals(202, $pointColumn['headers']['status-code']);
|
||||
|
||||
// Create line column
|
||||
$lineColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/line', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'lineAttr',
|
||||
'required' => true,
|
||||
]);
|
||||
$this->assertEquals(202, $lineColumn['headers']['status-code']);
|
||||
|
||||
// Create polygon column
|
||||
$polygonColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/polygon', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'polyAttr',
|
||||
'required' => true,
|
||||
]);
|
||||
$this->assertEquals(202, $polygonColumn['headers']['status-code']);
|
||||
|
||||
// Wait for columns to be created
|
||||
sleep(2);
|
||||
|
||||
// Create test rows with spatial data
|
||||
$rows = [
|
||||
[
|
||||
'$id' => 'row1',
|
||||
'name' => 'Test Row 1',
|
||||
'pointAttr' => [6.0, 6.0],
|
||||
'lineAttr' => [[1.0, 1.0], [2.0, 2.0]],
|
||||
'polyAttr' => [[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]]]
|
||||
],
|
||||
[
|
||||
'$id' => 'row2',
|
||||
'name' => 'Test Row 2',
|
||||
'pointAttr' => [7.0, 6.0],
|
||||
'lineAttr' => [[10.0, 10.0], [20.0, 20.0]],
|
||||
'polyAttr' => [[[20.0, 20.0], [30.0, 20.0], [30.0, 30.0], [20.0, 30.0], [20.0, 20.0]]]
|
||||
],
|
||||
[
|
||||
'$id' => 'row3',
|
||||
'name' => 'Test Row 3',
|
||||
'pointAttr' => [25.0, 25.0],
|
||||
'lineAttr' => [[25.0, 25.0], [35.0, 35.0]],
|
||||
'polyAttr' => [[[40.0, 40.0], [50.0, 40.0], [50.0, 50.0], [40.0, 50.0], [40.0, 40.0]]]
|
||||
]
|
||||
];
|
||||
|
||||
foreach ($rows as $r) {
|
||||
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rowId' => $r['$id'],
|
||||
'data' => [
|
||||
'name' => $r['name'],
|
||||
'pointAttr' => $r['pointAttr'],
|
||||
'lineAttr' => $r['lineAttr'],
|
||||
'polyAttr' => $r['polyAttr']
|
||||
]
|
||||
]);
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
// Equality on non-spatial column (name)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::equal('name', ['Test Row 1'])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(1, $response['body']['documents']);
|
||||
$this->assertEquals('row1', $response['body']['documents'][0]['$id']);
|
||||
|
||||
// Polygon column queries
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::equal('polyAttr', [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]]]])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(1, $response['body']['documents']);
|
||||
$this->assertEquals('row1', $response['body']['documents'][0]['$id']);
|
||||
|
||||
// Not equal queries
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::notEqual('pointAttr', [[6.0, 6.0]])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(2, $response['body']['documents']);
|
||||
|
||||
// contains on line (point on line)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::contains('lineAttr', [[1.0, 1.0]])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(1, $response['body']['documents']);
|
||||
$this->assertEquals('row1', $response['body']['documents'][0]['$id']);
|
||||
|
||||
// notContains on polygon (point outside all polygons)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::notContains('polyAttr', [[15.0, 15.0]])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(3, $response['body']['total']);
|
||||
|
||||
// intersects on polygon (point inside row1 polygon)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::intersects('polyAttr', [[5.0, 5.0]])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(1, $response['body']['total']);
|
||||
$this->assertEquals('row1', $response['body']['documents'][0]['$id']);
|
||||
|
||||
// notIntersects on polygon (point outside all polygons)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::notIntersects('polyAttr', [[60.0, 60.0]])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(3, $response['body']['total']);
|
||||
|
||||
// overlaps on polygon (polygon overlapping row1)
|
||||
$overlapPoly = [[[5.0, 5.0], [12.0, 5.0], [12.0, 12.0], [5.0, 12.0], [5.0, 5.0]]];
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::overlaps('polyAttr', [$overlapPoly])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(1, $response['body']['total']);
|
||||
$this->assertEquals('row1', $response['body']['documents'][0]['$id']);
|
||||
|
||||
// notOverlaps on polygon (polygon that overlaps none)
|
||||
$noOverlapPoly = [[[60.0, 60.0], [70.0, 60.0], [70.0, 70.0], [60.0, 70.0], [60.0, 60.0]]];
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::notOverlaps('polyAttr', [$noOverlapPoly])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(3, $response['body']['total']);
|
||||
|
||||
// distance (equals) on point
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::distance('pointAttr', [[[6.0, 6.0], 1.0]])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(1, $response['body']['total']);
|
||||
$this->assertEquals('row2', $response['body']['documents'][0]['$id']);
|
||||
|
||||
// notDistance (outside radius) on point
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::notDistance('pointAttr', [[[6.0, 6.0], 1.0]])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(2, $response['body']['total']);
|
||||
|
||||
// distanceGreaterThan
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::distanceGreaterThan('pointAttr', [[[6.0, 6.0], 5.0]])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(1, $response['body']['total']);
|
||||
|
||||
// distanceLessThan
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::distanceLessThan('pointAttr', [[[6.0, 6.0], 0.5]])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(1, $response['body']['total']);
|
||||
|
||||
// crosses on line (query line crosses row1 line)
|
||||
$crossLine = [[1.0, 2.0], [2.0, 1.0]];
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::crosses('lineAttr', [$crossLine])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(1, $response['body']['total']);
|
||||
$this->assertEquals('row1', $response['body']['documents'][0]['$id']);
|
||||
|
||||
// notCrosses on line (query line does not cross any stored lines)
|
||||
$nonCrossLine = [[0.0, 1.0], [0.0, 2.0]];
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::notCrosses('lineAttr', [$nonCrossLine])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(3, $response['body']['total']);
|
||||
|
||||
// touches on polygon (query polygon touches row1 polygon at corner)
|
||||
$touchPoly = [[[10.0, 10.0], [20.0, 10.0], [20.0, 20.0], [10.0, 20.0], [10.0, 10.0]]];
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::touches('polyAttr', [$touchPoly])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(2, $response['body']['total']);
|
||||
$this->assertEquals('row1', $response['body']['documents'][0]['$id']);
|
||||
|
||||
// notTouches on polygon (polygon far away should not touch)
|
||||
$farPoly = [[[60.0, 60.0], [70.0, 60.0], [70.0, 70.0], [60.0, 70.0], [60.0, 60.0]]];
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::notTouches('polyAttr', [$farPoly])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(3, $response['body']['total']);
|
||||
|
||||
// Select specific columns
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::select(['name', 'pointAttr'])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(3, $response['body']['documents']);
|
||||
foreach ($response['body']['documents'] as $doc) {
|
||||
$this->assertArrayHasKey('name', $doc);
|
||||
$this->assertArrayHasKey('pointAttr', $doc);
|
||||
$this->assertArrayNotHasKey('lineAttr', $doc);
|
||||
$this->assertArrayNotHasKey('polyAttr', $doc);
|
||||
}
|
||||
|
||||
// Order by name
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::orderAsc('name')->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(3, $response['body']['documents']);
|
||||
$this->assertEquals('Test Row 1', $response['body']['documents'][0]['name']);
|
||||
$this->assertEquals('Test Row 2', $response['body']['documents'][1]['name']);
|
||||
$this->assertEquals('Test Row 3', $response['body']['documents'][2]['name']);
|
||||
|
||||
// Limit results
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::limit(2)->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(2, $response['body']['documents']);
|
||||
|
||||
// Offset results
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::offset(1)->toString(), Query::limit(2)->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(2, $response['body']['documents']);
|
||||
|
||||
// Complex query with multiple conditions
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['name', 'pointAttr'])->toString(),
|
||||
Query::orderAsc('name')->toString(),
|
||||
Query::limit(1)->toString()
|
||||
]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(1, $response['body']['documents']);
|
||||
$this->assertEquals('Test Row 1', $response['body']['documents'][0]['name']);
|
||||
|
||||
// Query with no results
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::equal('name', ['Non-existent Row'])->toString()]
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(0, $response['body']['documents']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
}
|
||||
@@ -6132,4 +6132,570 @@ class DatabasesCustomServerTest extends Scope
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialBulkOperations(): void
|
||||
{
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, '/tablesdb', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Spatial Bulk Operations Test Database'
|
||||
]);
|
||||
|
||||
$this->assertNotEmpty($database['body']['$id']);
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create table with spatial columns
|
||||
$table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'tableId' => ID::unique(),
|
||||
'name' => 'Spatial Bulk Operations Table',
|
||||
'rowSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $table['headers']['status-code']);
|
||||
$tableId = $table['body']['$id'];
|
||||
|
||||
// Create string column
|
||||
$nameColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $nameColumn['headers']['status-code']);
|
||||
|
||||
// Create point column
|
||||
$pointColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/point', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'location',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $pointColumn['headers']['status-code']);
|
||||
|
||||
// Create polygon column
|
||||
$polygonColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/polygon', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'area',
|
||||
'required' => false,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $polygonColumn['headers']['status-code']);
|
||||
|
||||
// Wait for columns to be created
|
||||
sleep(2);
|
||||
|
||||
// Test 1: Bulk create with spatial data
|
||||
$spatialRows = [];
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$spatialRows[] = [
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Location ' . $i,
|
||||
'location' => [10.0 + $i, 20.0 + $i], // POINT
|
||||
'area' => [
|
||||
[10.0 + $i, 20.0 + $i],
|
||||
[11.0 + $i, 20.0 + $i],
|
||||
[11.0 + $i, 21.0 + $i],
|
||||
[10.0 + $i, 21.0 + $i],
|
||||
[10.0 + $i, 20.0 + $i]
|
||||
] // POLYGON
|
||||
];
|
||||
}
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => $spatialRows,
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertCount(5, $response['body']['rows']);
|
||||
|
||||
// Verify created rows have proper spatial data
|
||||
foreach ($response['body']['rows'] as $index => $row) {
|
||||
$this->assertNotEmpty($row['$id']);
|
||||
$this->assertNotEmpty($row['name']);
|
||||
$this->assertIsArray($row['location']);
|
||||
$this->assertIsArray($row['area']);
|
||||
$this->assertCount(2, $row['location']); // POINT has 2 coordinates
|
||||
|
||||
// Check polygon structure - it might be stored as an array of arrays
|
||||
if (is_array($row['area'][0])) {
|
||||
$this->assertGreaterThan(1, count($row['area'][0])); // POLYGON has multiple points
|
||||
} else {
|
||||
$this->assertGreaterThan(1, count($row['area'])); // POLYGON has multiple points
|
||||
}
|
||||
|
||||
$this->assertEquals('Location ' . $index, $row['name']);
|
||||
$this->assertEquals([10.0 + $index, 20.0 + $index], $row['location']);
|
||||
}
|
||||
|
||||
// Test 2: Bulk update with spatial data
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'name' => 'Updated Location',
|
||||
'location' => [15.0, 25.0], // New POINT
|
||||
'area' => [
|
||||
[15.0, 25.0],
|
||||
[16.0, 25.0],
|
||||
[16.0, 26.0],
|
||||
[15.0, 26.0],
|
||||
[15.0, 25.0]
|
||||
] // New POLYGON
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(5, $response['body']['rows']);
|
||||
|
||||
// Verify updated rows
|
||||
foreach ($response['body']['rows'] as $row) {
|
||||
$this->assertEquals('Updated Location', $row['name']);
|
||||
$this->assertEquals([15.0, 25.0], $row['location']);
|
||||
// The area might be stored as an array of arrays, so check the first element
|
||||
$this->assertIsArray($row['area']);
|
||||
if (is_array($row['area'][0])) {
|
||||
// If it's an array of arrays, check the first polygon
|
||||
$this->assertEquals([
|
||||
[15.0, 25.0],
|
||||
[16.0, 25.0],
|
||||
[16.0, 26.0],
|
||||
[15.0, 26.0],
|
||||
[15.0, 25.0]
|
||||
], $row['area'][0]);
|
||||
} else {
|
||||
// If it's a direct array, check the whole thing
|
||||
$this->assertEquals([
|
||||
[15.0, 25.0],
|
||||
[16.0, 25.0],
|
||||
[16.0, 26.0],
|
||||
[15.0, 26.0],
|
||||
[15.0, 25.0]
|
||||
], $row['area']);
|
||||
}
|
||||
}
|
||||
|
||||
// Test 3: Bulk upsert with spatial data
|
||||
$upsertRows = [
|
||||
[
|
||||
'$id' => 'upsert1',
|
||||
'name' => 'Upsert Location 1',
|
||||
'location' => [30.0, 40.0],
|
||||
'area' => [
|
||||
[30.0, 40.0],
|
||||
[31.0, 40.0],
|
||||
[31.0, 41.0],
|
||||
[30.0, 41.0],
|
||||
[30.0, 40.0]
|
||||
]
|
||||
],
|
||||
[
|
||||
'$id' => 'upsert2',
|
||||
'name' => 'Upsert Location 2',
|
||||
'location' => [35.0, 45.0],
|
||||
'area' => [
|
||||
[35.0, 45.0],
|
||||
[36.0, 45.0],
|
||||
[36.0, 46.0],
|
||||
[35.0, 46.0],
|
||||
[35.0, 45.0]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PUT, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => $upsertRows,
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(2, $response['body']['rows']);
|
||||
|
||||
// Verify upserted rows
|
||||
foreach ($response['body']['rows'] as $row) {
|
||||
$this->assertNotEmpty($row['$id']);
|
||||
$this->assertIsArray($row['location']);
|
||||
$this->assertIsArray($row['area']);
|
||||
|
||||
// Verify the spatial data structure
|
||||
$this->assertCount(2, $row['location']); // POINT has 2 coordinates
|
||||
if (is_array($row['area'][0])) {
|
||||
$this->assertGreaterThan(1, count($row['area'][0])); // POLYGON has multiple points
|
||||
} else {
|
||||
$this->assertGreaterThan(1, count($row['area'])); // POLYGON has multiple points
|
||||
}
|
||||
}
|
||||
|
||||
// Test 4: Edge cases for spatial bulk operations
|
||||
|
||||
// Test 4a: Invalid point coordinates (should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Point',
|
||||
'location' => [1000.0, 2000.0], // Invalid coordinates
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0],
|
||||
[11.0, 21.0],
|
||||
[10.0, 21.0],
|
||||
[10.0, 20.0]
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// Coordinates are not validated strictly; creation should succeed
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
// Test 4b: Invalid polygon (insufficient points - should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Polygon',
|
||||
'location' => [10.0, 20.0],
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0]
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
// Test 4c: Missing required location (should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Missing Location',
|
||||
// Missing required 'location' attribute
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0],
|
||||
[11.0, 21.0],
|
||||
[10.0, 21.0],
|
||||
[10.0, 20.0]
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// This should fail due to missing required attribute
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test 4d: Mixed valid and invalid rows in bulk (should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Valid Row',
|
||||
'location' => [10.0, 20.0],
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0],
|
||||
[11.0, 21.0],
|
||||
[10.0, 21.0],
|
||||
[10.0, 20.0]
|
||||
]
|
||||
],
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Row',
|
||||
// Missing required 'location' attribute
|
||||
'area' => [
|
||||
[10.0, 20.0],
|
||||
[11.0, 20.0],
|
||||
[11.0, 21.0],
|
||||
[10.0, 21.0],
|
||||
[10.0, 20.0]
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// This should fail due to mixed valid/invalid rows
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test 4e: Very large spatial data (stress test)
|
||||
$largePolygon = [];
|
||||
for ($i = 0; $i < 1000; $i++) {
|
||||
$largePolygon[] = [$i * 0.001, $i * 0.001];
|
||||
}
|
||||
$largePolygon[] = [0, 0]; // Close the polygon
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Large Polygon Test',
|
||||
'location' => [0.0, 0.0],
|
||||
'area' => $largePolygon
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
// Test 4f: Null values in spatial attributes (should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Null Values Test',
|
||||
'location' => null, // Null point
|
||||
'area' => null // Null polygon
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// This should fail due to null values
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test 4g: Bulk operations with spatial data exceeding limits
|
||||
$largeBulkRows = [];
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$largeBulkRows[] = [
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Bulk Test ' . $i,
|
||||
'location' => [$i * 0.1, $i * 0.1],
|
||||
'area' => [
|
||||
[$i * 0.1, $i * 0.1],
|
||||
[($i + 1) * 0.1, $i * 0.1],
|
||||
[($i + 1) * 0.1, ($i + 1) * 0.1],
|
||||
[$i * 0.1, ($i + 1) * 0.1],
|
||||
[$i * 0.1, $i * 0.1]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => $largeBulkRows,
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
|
||||
public function testSpatialBulkOperationsWithLineStrings(): void
|
||||
{
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, '/tablesdb', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Spatial LineString Bulk Operations Test Database'
|
||||
]);
|
||||
|
||||
$this->assertNotEmpty($database['body']['$id']);
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create table with line string columns
|
||||
$table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'tableId' => ID::unique(),
|
||||
'name' => 'Spatial LineString Bulk Operations Table',
|
||||
'rowSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $table['headers']['status-code']);
|
||||
$tableId = $table['body']['$id'];
|
||||
|
||||
// Create string column
|
||||
$nameColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $nameColumn['headers']['status-code']);
|
||||
|
||||
// Create line string column
|
||||
$lineColumn = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/line', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'path',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
// Handle both 201 (created) and 202 (accepted) status codes
|
||||
$this->assertEquals(202, $lineColumn['headers']['status-code']);
|
||||
|
||||
// Wait for columns to be created
|
||||
sleep(2);
|
||||
|
||||
// Test bulk create with line string data
|
||||
$lineStringRows = [];
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$lineStringRows[] = [
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Path ' . $i,
|
||||
'path' => [
|
||||
[$i * 10, $i * 10],
|
||||
[($i + 1) * 10, ($i + 1) * 10],
|
||||
[($i + 2) * 10, ($i + 2) * 10]
|
||||
] // LINE STRING with 3 points
|
||||
];
|
||||
}
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => $lineStringRows,
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertCount(3, $response['body']['rows']);
|
||||
|
||||
// Verify created rows have proper line string data
|
||||
foreach ($response['body']['rows'] as $index => $row) {
|
||||
$this->assertNotEmpty($row['$id']);
|
||||
$this->assertNotEmpty($row['name']);
|
||||
$this->assertIsArray($row['path']);
|
||||
$this->assertGreaterThan(1, count($row['path'])); // LINE STRING has multiple points
|
||||
$this->assertEquals('Path ' . $index, $row['name']);
|
||||
$this->assertCount(3, $row['path']); // Each line string has 3 points
|
||||
}
|
||||
|
||||
// Test bulk update with line string data
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'name' => 'Updated Path',
|
||||
'path' => [
|
||||
[0, 0],
|
||||
[50, 50],
|
||||
[100, 100]
|
||||
] // New LINE STRING
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(3, $response['body']['rows']);
|
||||
|
||||
// Verify updated rows
|
||||
foreach ($response['body']['rows'] as $row) {
|
||||
$this->assertEquals('Updated Path', $row['name']);
|
||||
$this->assertEquals([
|
||||
[0, 0],
|
||||
[50, 50],
|
||||
[100, 100]
|
||||
], $row['path']);
|
||||
}
|
||||
|
||||
// Test: Invalid line string (single point - should fail)
|
||||
$response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'rows' => [
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'name' => 'Invalid Line String',
|
||||
'path' => [[10, 20]] // Single point - invalid line string
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// Single point linestrings are accepted as arrays; creation should succeed
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user