mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Add comprehensive tests for Query::select with users endpoint
Co-authored-by: jakeb994 <jakeb994@gmail.com>
This commit is contained in:
@@ -1861,4 +1861,352 @@ trait UsersBase
|
||||
|
||||
// TODO add test for session delete
|
||||
// TODO add test for all sessions delete
|
||||
|
||||
/**
|
||||
* @depends testCreateUser
|
||||
*/
|
||||
public function testListUsersWithSelect(array $data): void
|
||||
{
|
||||
/**
|
||||
* Test Query::select with regular attributes
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'email'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
|
||||
// Verify only selected attributes are present
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
$this->assertArrayHasKey('email', $user);
|
||||
|
||||
// Verify other attributes are not present
|
||||
$this->assertArrayNotHasKey('status', $user);
|
||||
$this->assertArrayNotHasKey('registration', $user);
|
||||
$this->assertArrayNotHasKey('passwordUpdate', $user);
|
||||
$this->assertArrayNotHasKey('phone', $user);
|
||||
|
||||
/**
|
||||
* Test Query::select with subQuery attributes (sessions, tokens)
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'sessions', 'tokens'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
|
||||
// SubQuery attributes should not be directly present in select but data should be available
|
||||
// The implementation removes subQuery attributes from select and handles them via skipFilters
|
||||
$this->assertArrayNotHasKey('sessions', $user);
|
||||
$this->assertArrayNotHasKey('tokens', $user);
|
||||
|
||||
// Verify other attributes are not present
|
||||
$this->assertArrayNotHasKey('email', $user);
|
||||
$this->assertArrayNotHasKey('status', $user);
|
||||
|
||||
/**
|
||||
* Test Query::select with mixed attributes (regular + subQuery)
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['name', 'email', 'memberships', 'targets'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
$this->assertArrayHasKey('email', $user);
|
||||
|
||||
// SubQuery attributes (memberships) should not be in select result
|
||||
$this->assertArrayNotHasKey('memberships', $user);
|
||||
|
||||
// targets should be available since subQueryTargets is not skipped by default
|
||||
$this->assertArrayHasKey('targets', $user);
|
||||
|
||||
/**
|
||||
* Test Query::select with only subQuery attributes
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['sessions', 'challenges', 'authenticators'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
|
||||
// When only subQuery attributes are selected, all attributes should be returned
|
||||
// since no select query is passed to database
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
$this->assertArrayHasKey('email', $user);
|
||||
|
||||
/**
|
||||
* Test Query::select with system attributes
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', '$createdAt', '$updatedAt', 'name'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('$createdAt', $user);
|
||||
$this->assertArrayHasKey('$updatedAt', $user);
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
$this->assertArrayNotHasKey('email', $user);
|
||||
|
||||
/**
|
||||
* Test Query::select with multiple select queries (should be consolidated)
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name'])->toString(),
|
||||
Query::select(['email', 'status'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
|
||||
$user = $response['body']['users'][0];
|
||||
// All attributes from both select queries should be present
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
$this->assertArrayHasKey('email', $user);
|
||||
$this->assertArrayHasKey('status', $user);
|
||||
$this->assertArrayNotHasKey('registration', $user);
|
||||
|
||||
/**
|
||||
* Test Query::select with targets (should not be skipped by default)
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'targets'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
$this->assertArrayHasKey('targets', $user); // targets should be available
|
||||
|
||||
/**
|
||||
* Test invalid select attributes
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['nonExistentAttribute'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
$this->assertStringContainsString('not found', $response['body']['message']);
|
||||
|
||||
/**
|
||||
* Test Query::select with mixed valid and invalid attributes
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'invalidAttribute'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
$this->assertStringContainsString('not found', $response['body']['message']);
|
||||
|
||||
/**
|
||||
* Test Query::select combined with other queries
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'email'])->toString(),
|
||||
Query::equal('status', [true])->toString(),
|
||||
Query::limit(5)->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
$this->assertLessThanOrEqual(5, count($response['body']['users']));
|
||||
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
$this->assertArrayHasKey('email', $user);
|
||||
$this->assertArrayNotHasKey('status', $user);
|
||||
$this->assertArrayNotHasKey('registration', $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateUser
|
||||
*/
|
||||
public function testListUsersSelectEdgeCases(array $data): void
|
||||
{
|
||||
/**
|
||||
* Test empty select query - should return all attributes
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select([])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
$this->assertArrayHasKey('email', $user);
|
||||
$this->assertArrayHasKey('status', $user);
|
||||
|
||||
/**
|
||||
* Test select with duplicate attributes - should deduplicate
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'name', '$id', 'email'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
$this->assertArrayHasKey('email', $user);
|
||||
$this->assertArrayNotHasKey('status', $user);
|
||||
|
||||
/**
|
||||
* Test select with only targets (should be available since subQueryTargets not skipped by default)
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['targets'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
|
||||
// Since targets is the only selected attribute and it's a subQuery attribute,
|
||||
// but subQueryTargets is not skipped by default, all attributes should be returned
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('targets', $user);
|
||||
|
||||
/**
|
||||
* Core functionality test: verify subQuery attributes handling
|
||||
* This test specifically validates the PR requirements
|
||||
*/
|
||||
|
||||
// Test that sessions/tokens are handled correctly (removed from select, added to skipFilters)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'sessions'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
// sessions should not be present as it's removed from select and handled via skipFilters
|
||||
$this->assertArrayNotHasKey('sessions', $user);
|
||||
$this->assertArrayNotHasKey('email', $user); // Not selected
|
||||
|
||||
// Test that targets are NOT removed (since subQueryTargets is not skipped by default)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'targets'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$user = $response['body']['users'][0];
|
||||
$this->assertArrayHasKey('$id', $user);
|
||||
$this->assertArrayHasKey('name', $user);
|
||||
$this->assertArrayHasKey('targets', $user); // Should be present
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user