appwrite/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php

6713 lines
273 KiB
PHP
Raw Normal View History

2020-07-08 09:11:12 +00:00
<?php
2020-12-26 12:10:14 +00:00
namespace Tests\E2E\Services\Projects;
2020-07-08 09:11:12 +00:00
use Appwrite\Extend\Exception;
use Appwrite\Tests\Async;
2020-07-08 09:11:12 +00:00
use Tests\E2E\Client;
2023-12-10 10:03:01 +00:00
use Tests\E2E\General\UsageTest;
2024-03-06 17:34:21 +00:00
use Tests\E2E\Scopes\ProjectConsole;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Utopia\Database\DateTime;
2023-12-20 10:55:09 +00:00
use Utopia\Database\Document;
2022-12-14 15:42:25 +00:00
use Utopia\Database\Helpers\ID;
2025-12-09 13:04:25 +00:00
use Utopia\Database\Helpers\Permission;
use Utopia\Database\Helpers\Role;
2023-12-20 10:55:09 +00:00
use Utopia\Database\Query;
2025-03-19 07:32:48 +00:00
use Utopia\System\System;
2020-07-08 09:11:12 +00:00
class ProjectsConsoleClientTest extends Scope
{
use ProjectsBase;
use ProjectConsole;
use SideClient;
use Async;
2020-07-08 09:11:12 +00:00
2023-03-14 07:21:56 +00:00
/**
2024-07-03 08:27:54 +00:00
* @group smtpAndTemplates
* @group projectsCRUD
*/
2020-07-08 09:11:12 +00:00
public function testCreateProject(): array
{
/**
* Test for SUCCESS
*/
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2022-08-14 10:33:36 +00:00
'teamId' => ID::unique(),
2020-07-08 09:11:12 +00:00
'name' => 'Project Test',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$this->assertEquals('Project Test', $team['body']['name']);
$this->assertNotEmpty($team['body']['$id']);
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2022-08-14 10:33:36 +00:00
'projectId' => ID::unique(),
2020-07-08 09:11:12 +00:00
'name' => 'Project Test',
'teamId' => $team['body']['$id'],
2025-03-19 07:32:48 +00:00
'region' => System::getEnv('_APP_REGION', 'default')
2020-07-08 09:11:12 +00:00
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('Project Test', $response['body']['name']);
$this->assertEquals($team['body']['$id'], $response['body']['teamId']);
2026-02-17 06:24:22 +00:00
$this->assertEquals(PROJECT_STATUS_ACTIVE, $response['body']['status']);
2020-07-08 09:11:12 +00:00
$this->assertArrayHasKey('platforms', $response['body']);
$this->assertArrayHasKey('webhooks', $response['body']);
$this->assertArrayHasKey('keys', $response['body']);
$projectId = $response['body']['$id'];
2022-11-24 21:37:11 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
'teamId' => $team['body']['$id'],
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('Project Test', $response['body']['name']);
$this->assertEquals($team['body']['$id'], $response['body']['teamId']);
2026-02-17 06:24:22 +00:00
$this->assertEquals(PROJECT_STATUS_ACTIVE, $response['body']['status']);
2022-11-24 21:37:11 +00:00
$this->assertArrayHasKey('platforms', $response['body']);
$this->assertArrayHasKey('webhooks', $response['body']);
$this->assertArrayHasKey('keys', $response['body']);
2020-07-08 09:11:12 +00:00
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2022-08-14 10:33:36 +00:00
'projectId' => ID::unique(),
2020-07-08 09:11:12 +00:00
'name' => '',
'teamId' => $team['body']['$id'],
2025-03-19 07:32:48 +00:00
'region' => System::getEnv('_APP_REGION', 'default')
2020-07-08 09:11:12 +00:00
]);
$this->assertEquals(400, $response['headers']['status-code']);
2020-07-08 09:11:12 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2022-08-14 10:33:36 +00:00
'projectId' => ID::unique(),
2020-07-08 09:11:12 +00:00
'name' => 'Project Test',
2025-03-19 07:32:48 +00:00
'region' => System::getEnv('_APP_REGION', 'default')
2020-07-08 09:11:12 +00:00
]);
2024-09-05 03:20:19 +00:00
$this->assertEquals(401, $response['headers']['status-code']);
2020-07-08 09:11:12 +00:00
2023-04-29 07:43:33 +00:00
return [
'projectId' => $projectId,
'teamId' => $team['body']['$id']
];
}
2025-12-09 13:04:25 +00:00
public function testDeleteProjectWithMultiDB(): void
{
// Create a team and project
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'MultiDB Team',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$teamId = $team['body']['$id'];
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'MultiDB Project',
'teamId' => $teamId,
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $project['headers']['status-code']);
$projectId = $project['body']['$id'];
$projectAdminHeaders = array_merge($this->getHeaders(), [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-mode' => 'admin',
]);
// Create legacy database and collection
$database = $this->client->call(Client::METHOD_POST, '/databases', $projectAdminHeaders, [
'databaseId' => ID::unique(),
'name' => 'Legacy DB',
]);
$this->assertEquals(201, $database['headers']['status-code']);
$databaseId = $database['body']['$id'];
$collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', $projectAdminHeaders, [
'collectionId' => ID::unique(),
'name' => 'Legacy Collection',
'documentSecurity' => true,
'permissions' => [
Permission::create(Role::any()),
],
]);
$this->assertEquals(201, $collection['headers']['status-code']);
// Create documentsdb database and collection
$documentsDb = $this->client->call(Client::METHOD_POST, '/documentsdb', $projectAdminHeaders, [
'databaseId' => ID::unique(),
'name' => 'Documents DB',
]);
$this->assertEquals(201, $documentsDb['headers']['status-code']);
$documentsDbId = $documentsDb['body']['$id'];
$documentsCollection = $this->client->call(Client::METHOD_POST, '/documentsdb/' . $documentsDbId . '/collections', $projectAdminHeaders, [
'collectionId' => ID::unique(),
'name' => 'Documents Collection',
'documentSecurity' => true,
'permissions' => [
Permission::create(Role::any()),
],
]);
$this->assertEquals(201, $documentsCollection['headers']['status-code']);
// Create vectordb database and collection
$vectorDb = $this->client->call(Client::METHOD_POST, '/vectordb', $projectAdminHeaders, [
'databaseId' => ID::unique(),
'name' => 'Vector DB',
]);
$this->assertEquals(201, $vectorDb['headers']['status-code']);
$vectorDbId = $vectorDb['body']['$id'];
$vectorCollection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $vectorDbId . '/collections', $projectAdminHeaders, [
'collectionId' => ID::unique(),
'name' => 'Vector Collection',
'dimension' => 3,
'documentSecurity' => true,
'permissions' => [
Permission::create(Role::any()),
],
]);
$this->assertEquals(201, $vectorCollection['headers']['status-code']);
2025-12-09 13:04:25 +00:00
// Delete project
$delete = $this->client->call(Client::METHOD_DELETE, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(204, $delete['headers']['status-code']);
// Ensure project is gone
$getProject = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(404, $getProject['headers']['status-code']);
}
public function testCreateDuplicateProject(): void
2023-04-29 07:43:33 +00:00
{
// Create a team
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Duplicate Test Team',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$teamId = $team['body']['$id'];
// Create a project
$projectId = ID::unique();
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => $projectId,
'name' => 'Original Project',
'teamId' => $teamId,
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $response['headers']['status-code']);
2023-04-29 07:43:33 +00:00
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => $projectId,
'name' => 'Project Duplicate',
'teamId' => $teamId,
2025-03-19 07:32:48 +00:00
'region' => System::getEnv('_APP_REGION', 'default')
2023-04-29 07:43:33 +00:00
]);
2023-04-29 20:24:45 +00:00
$this->assertEquals(409, $response['headers']['status-code']);
$this->assertEquals(409, $response['body']['code']);
2023-04-29 07:43:33 +00:00
$this->assertEquals(Exception::PROJECT_ALREADY_EXISTS, $response['body']['type']);
2020-07-08 09:11:12 +00:00
}
/** @group projectsCRUD */
2023-05-02 07:28:46 +00:00
public function testTransferProjectTeam()
{
/**
* Test for SUCCESS
*/
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Team 1',
2023-05-02 07:28:46 +00:00
]);
$this->assertEquals(201, $team['headers']['status-code']);
$this->assertEquals('Team 1', $team['body']['name']);
2023-05-02 07:28:46 +00:00
$this->assertNotEmpty($team['body']['$id']);
$team1 = $team['body']['$id'];
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Team 2',
2023-05-02 07:28:46 +00:00
]);
$this->assertEquals(201, $team['headers']['status-code']);
$this->assertEquals('Team 2', $team['body']['name']);
2023-05-02 07:28:46 +00:00
$this->assertNotEmpty($team['body']['$id']);
$team2 = $team['body']['$id'];
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Team 1 Project',
2023-05-02 07:28:46 +00:00
'teamId' => $team1,
2025-03-19 07:32:48 +00:00
'region' => System::getEnv('_APP_REGION', 'default'),
2023-05-02 07:28:46 +00:00
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('Team 1 Project', $response['body']['name']);
2023-05-02 07:28:46 +00:00
$this->assertEquals($team1, $response['body']['teamId']);
$this->assertArrayHasKey('platforms', $response['body']);
$this->assertArrayHasKey('webhooks', $response['body']);
$this->assertArrayHasKey('keys', $response['body']);
$projectId = $response['body']['$id'];
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId . '/team', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => $team2,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('Team 1 Project', $response['body']['name']);
2023-05-02 07:28:46 +00:00
$this->assertEquals($team2, $response['body']['teamId']);
2020-07-08 09:11:12 +00:00
}
2020-07-08 15:20:18 +00:00
/**
* @group projectsCRUD
2020-07-08 15:20:18 +00:00
* @depends testCreateProject
*/
2022-04-18 16:21:45 +00:00
public function testListProject($data): array
2020-07-08 15:20:18 +00:00
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
2020-07-08 15:20:18 +00:00
/**
* Test for SUCCESS
*/
2021-09-23 07:01:10 +00:00
2020-07-08 15:20:18 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertEquals($id, $response['body']['projects'][0]['$id']);
$this->assertEquals('Project Test', $response['body']['projects'][0]['name']);
2021-09-23 07:01:10 +00:00
/**
* Test search queries
*/
2021-09-21 08:22:13 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders(), [
'search' => $id
]));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(4, $response['body']['total']);
2021-09-23 07:01:10 +00:00
$this->assertIsArray($response['body']['projects']);
$this->assertCount(4, $response['body']['projects']);
$this->assertEquals('Project Test', $response['body']['projects'][0]['name']);
2021-09-21 08:22:13 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders(), [
'search' => 'Project Test'
]));
2021-09-23 07:01:10 +00:00
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertEquals(4, $response['body']['total']);
2021-09-23 07:01:10 +00:00
$this->assertIsArray($response['body']['projects']);
$this->assertCount(4, $response['body']['projects']);
2021-09-23 07:01:10 +00:00
$this->assertEquals($response['body']['projects'][0]['$id'], $data['projectId']);
2021-09-21 08:22:13 +00:00
/**
2022-08-31 16:00:14 +00:00
* Test pagination
*/
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2022-08-14 10:33:36 +00:00
'teamId' => ID::unique(),
'name' => 'Project Test 2',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$this->assertEquals('Project Test 2', $team['body']['name']);
$this->assertNotEmpty($team['body']['$id']);
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2022-08-14 10:33:36 +00:00
'projectId' => ID::unique(),
'name' => 'Project Test 2',
'teamId' => $team['body']['$id'],
2025-03-19 07:32:48 +00:00
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('Project Test 2', $response['body']['name']);
$this->assertEquals($team['body']['$id'], $response['body']['teamId']);
$this->assertArrayHasKey('platforms', $response['body']);
$this->assertArrayHasKey('webhooks', $response['body']);
$this->assertArrayHasKey('keys', $response['body']);
2022-08-31 16:00:14 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
2022-10-03 07:16:49 +00:00
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::equal('teamId', [$team['body']['$id']])->toString(),
],
2022-10-03 07:16:49 +00:00
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertCount(1, $response['body']['projects']);
2022-10-03 07:54:55 +00:00
$this->assertEquals($team['body']['$id'], $response['body']['projects'][0]['teamId']);
2022-10-03 07:16:49 +00:00
2022-08-31 16:00:14 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::limit(1)->toString(),
],
2022-08-31 16:00:14 +00:00
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertCount(1, $response['body']['projects']);
$this->assertEquals('Project Test', $response['body']['projects'][0]['name']);
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::offset(3)->toString(),
],
2022-08-31 16:00:14 +00:00
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertCount(2, $response['body']['projects']);
$this->assertEquals('Team 1 Project', $response['body']['projects'][0]['name']);
2022-08-31 16:00:14 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::equal('name', ['Project Test 2'])->toString(),
],
2022-08-31 16:00:14 +00:00
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertCount(1, $response['body']['projects']);
$this->assertEquals('Project Test 2', $response['body']['projects'][0]['name']);
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::orderDesc()->toString(),
],
2022-08-31 16:00:14 +00:00
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertCount(5, $response['body']['projects']);
2022-08-31 16:00:14 +00:00
$this->assertEquals('Project Test 2', $response['body']['projects'][0]['name']);
$this->assertEquals('Team 1 Project', $response['body']['projects'][1]['name']);
2022-08-31 16:00:14 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertCount(5, $response['body']['projects']);
$this->assertEquals('Project Test', $response['body']['projects'][0]['name']);
$this->assertEquals('Original Project', $response['body']['projects'][2]['name']);
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2022-04-18 16:21:45 +00:00
], $this->getHeaders()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::cursorAfter(new Document(['$id' => $response['body']['projects'][0]['$id']]))->toString(),
],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertCount(4, $response['body']['projects']);
$this->assertEquals('Original Project', $response['body']['projects'][1]['name']);
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2022-04-18 16:21:45 +00:00
], $this->getHeaders()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::cursorBefore(new Document(['$id' => $response['body']['projects'][0]['$id']]))->toString(),
],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertCount(1, $response['body']['projects']);
$this->assertEquals('Project Test', $response['body']['projects'][0]['name']);
2020-07-08 15:20:18 +00:00
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2022-04-18 16:21:45 +00:00
], $this->getHeaders()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::cursorAfter(new Document(['$id' => 'unknown']))->toString(),
],
]);
$this->assertEquals(400, $response['headers']['status-code']);
2020-07-08 15:20:18 +00:00
2020-07-09 09:13:14 +00:00
return $data;
2020-07-08 15:20:18 +00:00
}
/**
* @group projectsCRUD
*/
public function testListProjectsQuerySelect(): void
{
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Query Select Test Team',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$teamId = $team['body']['$id'];
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Query Select Test Project',
'teamId' => $teamId,
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $project['headers']['status-code']);
$projectId = $project['body']['$id'];
/**
* Test Query.select - basic fields
*/
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name'])->toString(),
],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertGreaterThan(0, count($response['body']['projects']));
$project = $response['body']['projects'][0];
$this->assertArrayHasKey('$id', $project);
$this->assertArrayHasKey('name', $project);
$this->assertArrayNotHasKey('platforms', $project);
$this->assertArrayNotHasKey('webhooks', $project);
$this->assertArrayNotHasKey('keys', $project);
$this->assertArrayNotHasKey('devKeys', $project);
$this->assertArrayNotHasKey('oAuthProviders', $project);
$this->assertArrayNotHasKey('smtpEnabled', $project);
$this->assertArrayNotHasKey('smtpHost', $project);
$this->assertArrayNotHasKey('authLimit', $project);
$this->assertArrayNotHasKey('authDuration', $project);
/**
* Test Query.select - multiple fields
*/
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name', 'teamId', 'description', '$createdAt', '$updatedAt'])->toString(),
],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertGreaterThan(0, count($response['body']['projects']));
$project = $response['body']['projects'][0];
$this->assertArrayHasKey('$id', $project);
$this->assertArrayHasKey('name', $project);
$this->assertArrayHasKey('teamId', $project);
$this->assertArrayHasKey('description', $project);
$this->assertArrayHasKey('$createdAt', $project);
$this->assertArrayHasKey('$updatedAt', $project);
$this->assertArrayNotHasKey('platforms', $project);
$this->assertArrayNotHasKey('webhooks', $project);
$this->assertArrayNotHasKey('keys', $project);
$this->assertArrayNotHasKey('devKeys', $project);
$this->assertArrayNotHasKey('oAuthProviders', $project);
$this->assertArrayNotHasKey('smtpEnabled', $project);
$this->assertArrayNotHasKey('authLimit', $project);
/**
* Test Query.select combined with filters
*/
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name', 'teamId'])->toString(),
Query::equal('name', ['Query Select Test Project'])->toString(),
],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertCount(1, $response['body']['projects']);
$project = $response['body']['projects'][0];
$this->assertArrayHasKey('$id', $project);
$this->assertArrayHasKey('name', $project);
$this->assertArrayHasKey('teamId', $project);
$this->assertEquals('Query Select Test Project', $project['name']);
$this->assertEquals($teamId, $project['teamId']);
$this->assertArrayNotHasKey('platforms', $project);
$this->assertArrayNotHasKey('webhooks', $project);
$this->assertArrayNotHasKey('keys', $project);
$this->assertArrayNotHasKey('devKeys', $project);
$this->assertArrayNotHasKey('oAuthProviders', $project);
$this->assertArrayNotHasKey('smtpEnabled', $project);
$this->assertArrayNotHasKey('authLimit', $project);
/**
* Test Query.select combined with limit
*/
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name'])->toString(),
Query::limit(2)->toString(),
],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertLessThanOrEqual(2, count($response['body']['projects']));
foreach ($response['body']['projects'] as $p) {
$this->assertArrayHasKey('$id', $p);
$this->assertArrayHasKey('name', $p);
$this->assertArrayNotHasKey('platforms', $p);
$this->assertArrayNotHasKey('webhooks', $p);
$this->assertArrayNotHasKey('keys', $p);
$this->assertArrayNotHasKey('devKeys', $p);
$this->assertArrayNotHasKey('oAuthProviders', $p);
$this->assertArrayNotHasKey('smtpEnabled', $p);
$this->assertArrayNotHasKey('authLimit', $p);
}
/**
* Test Query.select with subquery attributes (platforms, webhooks, etc.)
* When explicitly selected, subqueries should still run
*/
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name', 'platforms'])->toString(),
],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertGreaterThan(0, count($response['body']['projects']));
$project = $response['body']['projects'][0];
$this->assertArrayHasKey('$id', $project);
$this->assertArrayHasKey('name', $project);
$this->assertArrayHasKey('platforms', $project);
$this->assertIsArray($project['platforms']);
$this->assertArrayNotHasKey('webhooks', $project);
$this->assertArrayNotHasKey('keys', $project);
$this->assertArrayNotHasKey('devKeys', $project);
$this->assertArrayNotHasKey('oAuthProviders', $project);
$this->assertArrayNotHasKey('smtpEnabled', $project);
$this->assertArrayNotHasKey('authLimit', $project);
/**
* Test Query.select with expanded attributes
* webhooks and keys should load their subquery data when selected
*/
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name', 'webhooks', 'keys'])->toString(),
],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertGreaterThan(0, count($response['body']['projects']));
$project = $response['body']['projects'][0];
$this->assertArrayHasKey('$id', $project);
$this->assertArrayHasKey('name', $project);
$this->assertArrayHasKey('webhooks', $project);
$this->assertArrayHasKey('keys', $project);
$this->assertIsArray($project['webhooks']);
$this->assertIsArray($project['keys']);
$this->assertArrayNotHasKey('platforms', $project);
$this->assertArrayNotHasKey('devKeys', $project);
$this->assertArrayNotHasKey('smtpEnabled', $project);
$this->assertArrayNotHasKey('authLimit', $project);
2025-12-19 10:22:19 +00:00
/**
* Test Query.select with wildcard '*'
* Should return all fields like no select query
*/
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::select(['*'])->toString(),
],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertGreaterThan(0, count($response['body']['projects']));
$project = $response['body']['projects'][0];
$this->assertArrayHasKey('$id', $project);
$this->assertArrayHasKey('name', $project);
$this->assertArrayHasKey('teamId', $project);
$this->assertArrayHasKey('platforms', $project);
$this->assertArrayHasKey('webhooks', $project);
$this->assertArrayHasKey('keys', $project);
$this->assertArrayHasKey('devKeys', $project);
$this->assertArrayHasKey('oAuthProviders', $project);
$this->assertArrayHasKey('smtpEnabled', $project);
$this->assertArrayHasKey('smtpHost', $project);
$this->assertArrayHasKey('authLimit', $project);
$this->assertArrayHasKey('authDuration', $project);
/**
* Test Query.select with invalid attribute
*/
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'invalidAttribute'])->toString(),
],
]);
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertEquals('Invalid `queries` param: Invalid query: Attribute not found in schema: invalidAttribute', $response['body']['message']);
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(204, $response['headers']['status-code']);
}
public function testGetProject(): void
2020-07-08 09:11:12 +00:00
{
// Create a team
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Get Project Test Team',
]);
$this->assertEquals(201, $team['headers']['status-code']);
// Create a project
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
'teamId' => $team['body']['$id'],
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $response['headers']['status-code']);
$id = $response['body']['$id'];
2020-07-08 09:11:12 +00:00
/**
* Test for SUCCESS
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
2020-07-08 09:11:12 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertEquals($id, $response['body']['$id']);
$this->assertEquals('Project Test', $response['body']['name']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/projects/empty', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(404, $response['headers']['status-code']);
$projectId = str_repeat('very_long_id', 10);
if ($this->isMongoDB()) { // to support mongodb UID length
$projectId = str_repeat('long_id', 20);
}
2020-07-08 09:11:12 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/'.$projectId, array_merge([
2020-07-08 09:11:12 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
2025-10-27 12:38:44 +00:00
$this->assertContains($response['headers']['status-code'], [400, 404]);
2020-07-08 09:11:12 +00:00
}
2020-07-08 15:20:18 +00:00
/**
* @depends testCreateProject
*/
2022-04-18 16:21:45 +00:00
public function testGetProjectUsage($data): array
2020-07-08 15:20:18 +00:00
{
$this->markTestIncomplete(
'This test is failing right now due to functions collection.'
);
2020-07-08 15:20:18 +00:00
/**
* Test for SUCCESS
*/
2023-10-25 07:39:59 +00:00
$response = $this->client->call(Client::METHOD_GET, '/project/usage', array_merge([
2020-07-08 15:20:18 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2023-12-10 10:03:01 +00:00
], $this->getHeaders()), [
'startDate' => UsageTest::getToday(),
'endDate' => UsageTest::getTomorrow(),
]);
2020-07-08 15:20:18 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
2023-12-10 10:03:01 +00:00
$this->assertEquals(8, count($response['body']));
2020-07-08 15:20:18 +00:00
$this->assertNotEmpty($response['body']);
2023-08-20 12:29:43 +00:00
$this->assertIsArray($response['body']['requests']);
$this->assertIsArray($response['body']['network']);
2023-11-26 20:57:57 +00:00
$this->assertIsNumeric($response['body']['executionsTotal']);
2025-05-05 09:15:55 +00:00
$this->assertIsNumeric($response['body']['rowsTotal']);
2023-11-26 20:57:57 +00:00
$this->assertIsNumeric($response['body']['databasesTotal']);
$this->assertIsNumeric($response['body']['bucketsTotal']);
$this->assertIsNumeric($response['body']['usersTotal']);
$this->assertIsNumeric($response['body']['filesStorageTotal']);
2024-06-11 05:36:32 +00:00
$this->assertIsNumeric($response['body']['deploymentStorageTotal']);
2025-01-09 16:37:26 +00:00
$this->assertIsNumeric($response['body']['authPhoneTotal']);
$this->assertIsNumeric($response['body']['authPhoneEstimate']);
2023-11-26 20:57:57 +00:00
2020-07-08 15:20:18 +00:00
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/projects/empty', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(404, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_GET, '/projects/id-is-really-long-id-is-really-long-id-is-really-long-id-is-really-long', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(400, $response['headers']['status-code']);
2020-10-27 19:48:38 +00:00
return $data;
2020-07-09 09:13:14 +00:00
}
2025-10-16 08:55:12 +00:00
public function testUpdateProject(): void
2020-07-09 09:13:14 +00:00
{
2025-10-16 08:55:12 +00:00
// Create a team
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Update Project Test Team',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$teamId = $team['body']['$id'];
// Create a project
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
'teamId' => $teamId,
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $response['headers']['status-code']);
$id = $response['body']['$id'];
2020-07-09 09:13:14 +00:00
/**
* Test for SUCCESS
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id, array_merge([
2020-07-09 09:13:14 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2022-08-14 10:33:36 +00:00
'projectId' => ID::unique(),
2020-07-09 09:13:14 +00:00
'name' => 'Project Test 2',
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('Project Test 2', $response['body']['name']);
2020-11-20 23:31:17 +00:00
$this->assertArrayHasKey('platforms', $response['body']);
$this->assertArrayHasKey('webhooks', $response['body']);
$this->assertArrayHasKey('keys', $response['body']);
2020-07-09 09:13:14 +00:00
$projectId = $response['body']['$id'];
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2022-08-14 10:33:36 +00:00
'projectId' => ID::unique(),
2020-07-09 09:13:14 +00:00
'name' => '',
]);
2024-09-05 03:22:10 +00:00
$this->assertEquals(401, $response['headers']['status-code']);
2020-07-09 09:13:14 +00:00
}
2023-03-10 02:44:43 +00:00
/**
2023-03-14 07:21:56 +00:00
* @group smtpAndTemplates
2023-03-10 02:44:43 +00:00
* @depends testCreateProject
*/
2023-03-10 02:46:34 +00:00
public function testUpdateProjectSMTP($data): array
{
2023-03-10 02:44:43 +00:00
$id = $data['projectId'];
$smtpHost = System::getEnv('_APP_SMTP_HOST', "maildev");
$smtpPort = intval(System::getEnv('_APP_SMTP_PORT', "1025"));
$smtpUsername = System::getEnv('_APP_SMTP_USERNAME', 'user');
$smtpPassword = System::getEnv('_APP_SMTP_PASSWORD', 'password');
/**
* Test for SUCCESS: Valid Credentials
*/
2023-03-10 02:44:43 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'enabled' => true,
2023-08-30 04:30:44 +00:00
'senderEmail' => 'mailer@appwrite.io',
'senderName' => 'Mailer',
'host' => $smtpHost,
'port' => $smtpPort,
'username' => $smtpUsername,
'password' => $smtpPassword,
2023-03-10 02:44:43 +00:00
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertTrue($response['body']['smtpEnabled']);
2023-08-30 04:30:44 +00:00
$this->assertEquals('mailer@appwrite.io', $response['body']['smtpSenderEmail']);
$this->assertEquals('Mailer', $response['body']['smtpSenderName']);
$this->assertEquals($smtpHost, $response['body']['smtpHost']);
$this->assertEquals($smtpPort, $response['body']['smtpPort']);
$this->assertEquals($smtpUsername, $response['body']['smtpUsername']);
$this->assertEquals($smtpPassword, $response['body']['smtpPassword']);
2023-03-10 02:44:43 +00:00
$this->assertEquals('', $response['body']['smtpSecure']);
2023-03-14 07:21:56 +00:00
// Check the project
2023-03-14 07:21:56 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertTrue($response['body']['smtpEnabled']);
2023-08-30 04:30:44 +00:00
$this->assertEquals('mailer@appwrite.io', $response['body']['smtpSenderEmail']);
$this->assertEquals('Mailer', $response['body']['smtpSenderName']);
$this->assertEquals($smtpHost, $response['body']['smtpHost']);
$this->assertEquals($smtpPort, $response['body']['smtpPort']);
$this->assertEquals($smtpUsername, $response['body']['smtpUsername']);
$this->assertEquals($smtpPassword, $response['body']['smtpPassword']);
2023-03-14 07:21:56 +00:00
$this->assertEquals('', $response['body']['smtpSecure']);
2023-03-17 06:37:16 +00:00
/**
* Test for FAILURE: Invalid Credentials
*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'enabled' => true,
'senderEmail' => 'fail@appwrite.io',
'senderName' => 'Failing Mailer',
'host' => $smtpHost,
'port' => $smtpPort,
'username' => 'invalid-user',
'password' => 'bad-password',
]);
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertEquals(Exception::PROJECT_SMTP_CONFIG_INVALID, $response['body']['type']);
$this->assertStringContainsStringIgnoringCase('Could not authenticate', $response['body']['message']);
2023-03-14 07:21:56 +00:00
return $data;
}
2023-12-19 15:19:57 +00:00
/**
* @group smtpAndTemplates
*/
2025-10-16 08:55:12 +00:00
public function testCreateProjectSMTPTests(): void
2023-12-19 15:19:57 +00:00
{
$smtpHost = System::getEnv('_APP_SMTP_HOST', "maildev");
$smtpPort = intval(System::getEnv('_APP_SMTP_PORT', "1025"));
$smtpUsername = System::getEnv('_APP_SMTP_USERNAME', 'user');
$smtpPassword = System::getEnv('_APP_SMTP_PASSWORD', 'password');
2025-10-16 08:55:12 +00:00
// Create a team
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Create Project SMTP Tests Test Team',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$teamId = $team['body']['$id'];
// Create a project
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
'teamId' => $teamId,
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $response['headers']['status-code']);
$id = $response['body']['$id'];
2023-12-19 22:31:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/smtp/tests', array_merge([
2023-12-19 15:19:57 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2024-06-20 14:49:56 +00:00
'emails' => ['testuser@appwrite.io', 'testusertwo@appwrite.io'],
2024-01-15 11:00:33 +00:00
'senderEmail' => 'custommailer@appwrite.io',
'senderName' => 'Custom Mailer',
'replyTo' => 'reply@appwrite.io',
'host' => $smtpHost,
'port' => $smtpPort,
'username' => $smtpUsername,
'password' => $smtpPassword,
2023-12-19 15:19:57 +00:00
]);
$this->assertEquals(204, $response['headers']['status-code']);
2024-01-15 11:00:33 +00:00
$emails = $this->getLastEmail(2);
$this->assertCount(2, $emails);
$this->assertEquals('custommailer@appwrite.io', $emails[0]['from'][0]['address']);
$this->assertEquals('Custom Mailer', $emails[0]['from'][0]['name']);
$this->assertEquals('reply@appwrite.io', $emails[0]['replyTo'][0]['address']);
$this->assertEquals('Custom Mailer', $emails[0]['replyTo'][0]['name']);
2024-01-17 11:22:08 +00:00
$this->assertEquals('Custom SMTP email sample', $emails[0]['subject']);
$this->assertStringContainsStringIgnoringCase('working correctly', $emails[0]['text']);
$this->assertStringContainsStringIgnoringCase('working correctly', $emails[0]['html']);
$this->assertStringContainsStringIgnoringCase('251 Little Falls Drive', $emails[0]['text']);
$this->assertStringContainsStringIgnoringCase('251 Little Falls Drive', $emails[0]['html']);
2024-01-15 11:00:33 +00:00
$to = [
$emails[0]['to'][0]['address'],
$emails[1]['to'][0]['address']
];
\sort($to);
$this->assertEquals('testuser@appwrite.io', $to[0]);
$this->assertEquals('testusertwo@appwrite.io', $to[1]);
2023-12-19 21:39:40 +00:00
2024-01-17 16:47:26 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/smtp/tests', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2024-06-20 14:49:56 +00:00
'emails' => ['u1@appwrite.io', 'u2@appwrite.io', 'u3@appwrite.io', 'u4@appwrite.io', 'u5@appwrite.io', 'u6@appwrite.io', 'u7@appwrite.io', 'u8@appwrite.io', 'u9@appwrite.io', 'u10@appwrite.io'],
2024-01-17 16:47:26 +00:00
'senderEmail' => 'custommailer@appwrite.io',
'senderName' => 'Custom Mailer',
'replyTo' => 'reply@appwrite.io',
'host' => $smtpHost,
'port' => $smtpPort,
'username' => $smtpUsername,
'password' => $smtpPassword,
2024-01-17 16:47:26 +00:00
]);
$this->assertEquals(204, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/smtp/tests', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2024-06-20 14:49:56 +00:00
'emails' => ['u1@appwrite.io', 'u2@appwrite.io', 'u3@appwrite.io', 'u4@appwrite.io', 'u5@appwrite.io', 'u6@appwrite.io', 'u7@appwrite.io', 'u8@appwrite.io', 'u9@appwrite.io', 'u10@appwrite.io', 'u11@appwrite.io'],
2024-01-17 16:47:26 +00:00
'senderEmail' => 'custommailer@appwrite.io',
'senderName' => 'Custom Mailer',
'replyTo' => 'reply@appwrite.io',
'host' => $smtpHost,
'port' => $smtpPort,
'username' => $smtpUsername,
'password' => $smtpPassword,
2024-01-17 16:47:26 +00:00
]);
$this->assertEquals(400, $response['headers']['status-code']);
2023-12-19 15:19:57 +00:00
}
2023-03-14 07:21:56 +00:00
/**
2023-03-14 07:24:03 +00:00
* @group smtpAndTemplates
2023-08-29 02:41:48 +00:00
* @depends testUpdateProjectSMTP
*/
2023-03-14 07:21:56 +00:00
public function testUpdateTemplates($data): array
{
$id = $data['projectId'];
2023-03-14 09:13:43 +00:00
/** Get Default Email Template */
2023-04-18 07:13:52 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/templates/email/verification/en-us', array_merge([
2023-03-14 07:21:56 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals('Account Verification for {{project}}', $response['body']['subject']);
2023-08-30 05:31:21 +00:00
$this->assertEquals('', $response['body']['senderEmail']);
2023-03-14 07:21:56 +00:00
$this->assertEquals('verification', $response['body']['type']);
2023-04-18 07:13:52 +00:00
$this->assertEquals('en-us', $response['body']['locale']);
2023-03-14 07:24:03 +00:00
2023-03-14 09:13:43 +00:00
/** Update Email template */
2023-04-18 07:13:52 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/templates/email/verification/en-us', array_merge([
2023-03-14 07:21:56 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'subject' => 'Please verify your email',
'message' => 'Please verify your email {{url}}',
'senderName' => 'Appwrite Custom',
'senderEmail' => 'custom@appwrite.io',
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals('Please verify your email', $response['body']['subject']);
$this->assertEquals('Appwrite Custom', $response['body']['senderName']);
$this->assertEquals('custom@appwrite.io', $response['body']['senderEmail']);
$this->assertEquals('verification', $response['body']['type']);
2023-04-18 07:13:52 +00:00
$this->assertEquals('en-us', $response['body']['locale']);
2023-03-14 07:21:56 +00:00
$this->assertEquals('Please verify your email {{url}}', $response['body']['message']);
2023-03-14 09:13:43 +00:00
/** Get Updated Email Template */
2023-04-18 07:13:52 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/templates/email/verification/en-us', array_merge([
2023-03-14 07:21:56 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals('Please verify your email', $response['body']['subject']);
$this->assertEquals('Appwrite Custom', $response['body']['senderName']);
$this->assertEquals('custom@appwrite.io', $response['body']['senderEmail']);
$this->assertEquals('verification', $response['body']['type']);
2023-04-18 07:13:52 +00:00
$this->assertEquals('en-us', $response['body']['locale']);
2023-03-14 07:21:56 +00:00
$this->assertEquals('Please verify your email {{url}}', $response['body']['message']);
2023-08-25 15:13:25 +00:00
// Temporary disabled until implemented
// /** Get Default SMS Template */
// $response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/templates/sms/verification/en-us', array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()));
// $this->assertEquals(200, $response['headers']['status-code']);
// $this->assertEquals('verification', $response['body']['type']);
// $this->assertEquals('en-us', $response['body']['locale']);
// $this->assertEquals('{{token}}', $response['body']['message']);
// /** Update SMS template */
// $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/templates/sms/verification/en-us', array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()), [
// 'message' => 'Please verify your email {{token}}',
// ]);
// $this->assertEquals(200, $response['headers']['status-code']);
// $this->assertEquals('verification', $response['body']['type']);
// $this->assertEquals('en-us', $response['body']['locale']);
// $this->assertEquals('Please verify your email {{token}}', $response['body']['message']);
// /** Get Updated SMS Template */
// $response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/templates/sms/verification/en-us', array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()));
// $this->assertEquals(200, $response['headers']['status-code']);
// $this->assertEquals('verification', $response['body']['type']);
// $this->assertEquals('en-us', $response['body']['locale']);
// $this->assertEquals('Please verify your email {{token}}', $response['body']['message']);
2023-03-14 09:13:43 +00:00
2023-03-10 02:44:43 +00:00
return $data;
}
/** @depends testCreateProject */
2022-11-01 14:43:18 +00:00
public function testUpdateProjectAuthDuration($data): array
2022-11-01 11:15:45 +00:00
{
$id = $data['projectId'];
2022-11-15 10:19:35 +00:00
// Check defaults
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
2025-11-04 07:51:03 +00:00
$this->assertEquals(TOKEN_EXPIRATION_LOGIN_LONG, $response['body']['authDuration']); // 1 Year
2022-11-15 10:19:35 +00:00
2022-11-01 11:15:45 +00:00
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/duration', array_merge([
2022-11-01 11:15:45 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'duration' => 10, // Set session duration to 10 seconds
2022-11-01 11:15:45 +00:00
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('Project Test', $response['body']['name']);
2022-11-01 11:15:45 +00:00
$this->assertArrayHasKey('platforms', $response['body']);
$this->assertArrayHasKey('webhooks', $response['body']);
$this->assertArrayHasKey('keys', $response['body']);
$this->assertEquals(10, $response['body']['authDuration']);
2022-11-01 11:15:45 +00:00
$projectId = $response['body']['$id'];
// Create New User
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
], $this->getHeaders()), [
'userId' => 'unique()',
'email' => 'test' . rand(0, 9999) . '@example.com',
'password' => 'password',
'name' => 'Test User',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$userEmail = $response['body']['email'];
// Create New User Session
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
]), [
'email' => $userEmail,
'password' => 'password',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$sessionCookie = $response['headers']['set-cookie'];
// Test for SUCCESS
$response = $this->client->call(Client::METHOD_GET, '/account', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'Cookie' => $sessionCookie,
]));
$this->assertEquals(200, $response['headers']['status-code']);
// Eventually session expires, within 15 seconds (10+variance)
$this->assertEventually(function () use ($projectId, $sessionCookie) {
// Get User
$response = $this->client->call(Client::METHOD_GET, '/account', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'Cookie' => $sessionCookie,
]));
2022-11-01 11:15:45 +00:00
$this->assertEquals(401, $response['headers']['status-code']);
}, timeoutMs: 15 * 1000);
2022-11-01 11:15:45 +00:00
// Set session duration to 10min
2024-01-15 20:04:36 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/duration', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'duration' => 600, // seconds
2024-01-15 20:04:36 +00:00
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(600, $response['body']['authDuration']);
2024-01-15 20:04:36 +00:00
2026-02-10 11:01:38 +00:00
// Ensure session is still expired (new duration only affects new sessions)
2024-01-15 20:04:36 +00:00
$response = $this->client->call(Client::METHOD_GET, '/account', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'Cookie' => $sessionCookie,
]));
$this->assertEquals(401, $response['headers']['status-code']);
2022-11-01 11:15:45 +00:00
// Return project back to normal
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/duration', array_merge([
2022-11-01 11:15:45 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2025-11-04 07:51:03 +00:00
'duration' => TOKEN_EXPIRATION_LOGIN_LONG,
2022-11-01 11:15:45 +00:00
]);
$this->assertEquals(200, $response['headers']['status-code']);
$projectId = $response['body']['$id'];
2022-11-01 11:34:56 +00:00
// Check project is back to normal
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
2025-11-04 07:51:03 +00:00
$this->assertEquals(TOKEN_EXPIRATION_LOGIN_LONG, $response['body']['authDuration']); // 1 Year
2022-11-01 11:34:56 +00:00
2022-11-01 11:15:45 +00:00
return ['projectId' => $projectId];
}
public function testUpdateProjectInvalidateSessions(): void
{
// Create a team for the test project
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Session Invalidation Test Team',
]);
$this->assertEquals(201, $team['headers']['status-code']);
// Create a test project
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Session Invalidation Test Project',
'teamId' => $team['body']['$id'],
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $response['headers']['status-code']);
$id = $response['body']['$id'];
// Check defaults
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertTrue($response['body']['authInvalidateSessions']);
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/session-invalidation', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'enabled' => false,
]);
$this->assertFalse($response['body']['authInvalidateSessions']);
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertFalse($response['body']['authInvalidateSessions']);
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/session-invalidation', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'enabled' => true,
]);
$this->assertTrue($response['body']['authInvalidateSessions']);
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertTrue($response['body']['authInvalidateSessions']);
}
2025-10-16 08:59:57 +00:00
public function testUpdateProjectOAuth(): void
2020-07-09 09:13:14 +00:00
{
2025-10-16 08:59:57 +00:00
// Create a team
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Update Project OAuth Test Team',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$teamId = $team['body']['$id'];
// Create a project
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
'teamId' => $teamId,
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $response['headers']['status-code']);
$id = $response['body']['$id'];
2024-05-06 06:29:15 +00:00
$providers = require(__DIR__ . '/../../../../app/config/oAuthProviders.php');
2020-07-09 09:13:14 +00:00
/**
* Test for SUCCESS
*/
2020-10-27 19:48:38 +00:00
foreach ($providers as $key => $provider) {
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/oauth2', array_merge([
2020-07-09 09:13:14 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'provider' => $key,
2022-04-18 16:21:45 +00:00
'appId' => 'AppId-' . ucfirst($key),
'secret' => 'Secret-' . ucfirst($key),
2020-07-09 09:13:14 +00:00
]);
2022-04-18 16:21:45 +00:00
2020-07-09 09:13:14 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
}
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
2020-07-09 09:13:14 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertEquals($id, $response['body']['$id']);
2020-10-27 19:48:38 +00:00
foreach ($providers as $key => $provider) {
2022-08-19 09:43:03 +00:00
$asserted = false;
2023-10-25 17:33:23 +00:00
foreach ($response['body']['oAuthProviders'] as $responseProvider) {
if ($responseProvider['key'] === $key) {
2022-08-19 09:43:03 +00:00
$this->assertEquals('AppId-' . ucfirst($key), $responseProvider['appId']);
$this->assertEquals('Secret-' . ucfirst($key), $responseProvider['secret']);
$this->assertFalse($responseProvider['enabled']);
$asserted = true;
break;
}
}
$this->assertTrue($asserted);
}
// Enable providers
$i = 0;
foreach ($providers as $key => $provider) {
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/oauth2', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'provider' => $key,
'enabled' => $i === 0 ? false : true // On first provider, test enabled=false
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$i++;
}
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertEquals($id, $response['body']['$id']);
$i = 0;
foreach ($providers as $key => $provider) {
$asserted = false;
2023-10-25 17:33:23 +00:00
foreach ($response['body']['oAuthProviders'] as $responseProvider) {
if ($responseProvider['key'] === $key) {
2022-08-19 09:43:03 +00:00
// On first provider, test enabled=false
$this->assertEquals($i !== 0, $responseProvider['enabled']);
$asserted = true;
break;
}
}
$this->assertTrue($asserted);
$i++;
2020-07-09 09:13:14 +00:00
}
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/oauth2', array_merge([
2020-07-09 09:13:14 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'provider' => 'unknown',
2022-08-27 03:16:37 +00:00
'appId' => 'AppId',
2020-07-09 09:13:14 +00:00
'secret' => 'Secret',
]);
$this->assertEquals(400, $response['headers']['status-code']);
}
2025-10-16 08:59:57 +00:00
public function testUpdateProjectAuthStatus(): void
2021-02-28 21:22:03 +00:00
{
2025-10-16 08:59:57 +00:00
// Create a team
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Update Project Auth Status Test Team',
]);
2022-04-18 16:21:45 +00:00
2025-10-16 08:59:57 +00:00
$this->assertEquals(201, $team['headers']['status-code']);
$teamId = $team['body']['$id'];
// Create a project
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
'teamId' => $teamId,
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $response['headers']['status-code']);
$id = $response['body']['$id'];
2022-04-18 16:21:45 +00:00
2025-10-16 08:59:57 +00:00
$auth = require(__DIR__ . '/../../../../app/config/auth.php');
2022-04-18 16:21:45 +00:00
$originalEmail = uniqid() . 'user@localhost.test';
2021-02-28 21:22:03 +00:00
$originalPassword = 'password';
$originalName = 'User Name';
2022-04-18 16:21:45 +00:00
2021-02-28 21:22:03 +00:00
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
2022-08-14 10:33:36 +00:00
'userId' => ID::unique(),
2021-02-28 21:22:03 +00:00
'email' => $originalEmail,
'password' => $originalPassword,
'name' => $originalName,
]);
2022-06-14 08:17:50 +00:00
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
2021-02-28 21:22:03 +00:00
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'email' => $originalEmail,
'password' => $originalPassword,
]);
2023-12-08 23:17:13 +00:00
$session = $response['cookies']['a_session_' . $id];
2021-02-28 21:22:03 +00:00
/**
* Test for SUCCESS
*/
foreach ($auth as $index => $method) {
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/' . $index, array_merge([
2021-02-28 21:22:03 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'status' => false,
]);
2022-04-18 16:21:45 +00:00
2021-02-28 21:22:03 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
2021-02-28 21:22:03 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
2022-04-18 16:21:45 +00:00
$this->assertEquals(false, $response['body']['auth' . ucfirst($method['key'])]);
2021-02-28 21:22:03 +00:00
}
2022-04-18 16:21:45 +00:00
$email = uniqid() . 'user@localhost.test';
2021-02-28 21:22:03 +00:00
$password = 'password';
$name = 'User Name';
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
2022-08-14 10:33:36 +00:00
'userId' => ID::unique(),
2021-02-28 21:22:03 +00:00
'email' => $email,
'password' => $password,
'name' => $name,
]);
$this->assertEquals($response['headers']['status-code'], 501);
$response = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $id,
2022-04-18 16:21:45 +00:00
'cookie' => 'a_session_' . $id . '=' . $session,
2021-02-28 21:22:03 +00:00
]), [
2022-08-14 10:33:36 +00:00
'teamId' => ID::unique(),
2021-02-28 21:22:03 +00:00
'name' => 'Arsenal'
]);
$this->assertEquals(201, $response['headers']['status-code']);
$teamUid = $response['body']['$id'];
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
2021-02-28 21:22:03 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $id,
2022-04-18 16:21:45 +00:00
'cookie' => 'a_session_' . $id . '=' . $session,
2021-02-28 21:22:03 +00:00
]), [
'email' => $email,
'name' => 'Friend User',
'roles' => ['admin', 'editor'],
'url' => 'http://localhost:5000/join-us#title'
]);
$this->assertEquals($response['headers']['status-code'], 501);
$response = $this->client->call(Client::METHOD_POST, '/account/jwt', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $id,
2022-04-18 16:21:45 +00:00
'cookie' => 'a_session_' . $id . '=' . $session,
2021-02-28 21:22:03 +00:00
]));
$this->assertEquals($response['headers']['status-code'], 501);
2022-06-14 08:17:50 +00:00
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
2021-02-28 21:22:03 +00:00
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'email' => $originalEmail,
'password' => $originalPassword,
]);
2022-04-18 16:21:45 +00:00
2021-02-28 21:22:03 +00:00
$this->assertEquals($response['headers']['status-code'], 501);
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/anonymous', array_merge([
2021-04-03 08:56:32 +00:00
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]));
2021-04-03 08:56:32 +00:00
$this->assertEquals($response['headers']['status-code'], 501);
2021-02-28 21:22:03 +00:00
// Cleanup
foreach ($auth as $index => $method) {
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/' . $index, array_merge([
2021-02-28 21:22:03 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'status' => true,
]);
}
}
/**
* @depends testCreateProject
2021-02-28 21:22:03 +00:00
*/
2022-04-18 16:21:45 +00:00
public function testUpdateProjectAuthLimit($data): array
2021-02-28 21:22:03 +00:00
{
$id = $data['projectId'] ?? '';
2022-04-18 16:21:45 +00:00
2021-02-28 21:22:03 +00:00
/**
* Test for SUCCESS
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/limit', array_merge([
2021-02-28 21:22:03 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'limit' => 1,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
2022-04-18 16:21:45 +00:00
$email = uniqid() . 'user@localhost.test';
2021-02-28 21:22:03 +00:00
$password = 'password';
$name = 'User Name';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
2022-08-14 10:33:36 +00:00
'userId' => ID::unique(),
2021-02-28 21:22:03 +00:00
'email' => $email,
'password' => $password,
'name' => $name,
]);
// Creating A Team
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Test Team 1',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$teamId = $team['body']['$id'];
$email = uniqid() . 'user@localhost.test';
// Creating A User Using Team membership
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamId . '/memberships', array_merge($this->getHeaders(), [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-mode' => 'admin',
]), [
'email' => $email,
'roles' => [],
'url' => 'http://localhost',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$email = uniqid() . 'user@localhost.test';
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'userId' => ID::unique(),
'email' => $email,
'password' => $password,
'name' => $name,
]);
$this->assertEquals(Exception::USER_COUNT_EXCEEDED, $response['body']['type']);
2024-05-22 01:42:34 +00:00
$this->assertEquals(400, $response['headers']['status-code']);
2021-02-28 21:22:03 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/limit', array_merge([
2021-02-28 21:22:03 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'limit' => 0,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
2022-04-18 16:21:45 +00:00
$email = uniqid() . 'user@localhost.test';
2021-02-28 21:22:03 +00:00
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
2022-08-14 10:33:36 +00:00
'userId' => ID::unique(),
2021-02-28 21:22:03 +00:00
'email' => $email,
'password' => $password,
'name' => $name,
]);
$this->assertEquals($response['headers']['status-code'], 201);
return $data;
}
2025-12-29 17:41:35 +00:00
public function testUpdateProjectAuthSessionsLimit(): void
2022-12-09 11:54:23 +00:00
{
2025-12-29 17:41:35 +00:00
$id = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testUpdateProjectAuthSessionsLimit',
'region' => System::getEnv('_APP_REGION', 'default')
]);
2022-12-09 11:54:23 +00:00
/**
* Test for failure
*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/max-sessions', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'limit' => 0,
]);
$this->assertEquals(400, $response['headers']['status-code']);
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/max-sessions', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'limit' => 1,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
2022-12-27 10:40:24 +00:00
$this->assertEquals(1, $response['body']['authSessionsLimit']);
2022-12-09 11:54:23 +00:00
$email = uniqid() . 'user@localhost.test';
$password = 'password';
$name = 'User Name';
/**
* Create new user
*/
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'userId' => ID::unique(),
'email' => $email,
'password' => $password,
'name' => $name,
]);
2022-12-11 07:15:47 +00:00
$this->assertEquals(201, $response['headers']['status-code']);
2022-12-09 11:54:23 +00:00
/**
* create new session
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'email' => $email,
'password' => $password,
]);
2022-12-11 07:15:47 +00:00
$this->assertEquals(201, $response['headers']['status-code']);
2022-12-09 11:54:23 +00:00
$sessionId1 = $response['body']['$id'];
/**
* create new session
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'email' => $email,
'password' => $password,
]);
2022-12-11 07:15:47 +00:00
$this->assertEquals(201, $response['headers']['status-code']);
2022-12-09 11:54:23 +00:00
$sessionCookie = $response['headers']['set-cookie'];
$sessionId2 = $response['body']['$id'];
sleep(5); // fixes flaky tests.
2022-12-09 11:54:23 +00:00
/**
* List sessions
*/
$this->assertEventually(function () use ($id, $sessionCookie, $sessionId2) {
$response = $this->client->call(Client::METHOD_GET, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'Cookie' => $sessionCookie,
]);
2022-12-09 11:54:23 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
$sessions = $response['body']['sessions'];
2022-12-09 11:54:23 +00:00
$this->assertEquals(1, count($sessions));
$this->assertEquals($sessionId2, $sessions[0]['$id']);
2025-12-24 10:52:02 +00:00
}, 120_000, 300);
2022-12-09 11:54:23 +00:00
2022-12-12 05:02:48 +00:00
/**
* Reset Limit
*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/max-sessions', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'limit' => 10,
]);
2025-12-29 17:41:35 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
2022-12-09 11:54:23 +00:00
}
2022-12-18 06:27:41 +00:00
/**
* @depends testUpdateProjectAuthLimit
*/
public function testUpdateProjectAuthPasswordHistory($data): array
{
$id = $data['projectId'] ?? '';
/**
* Test for Failure
*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/password-history', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'limit' => 25,
]);
$this->assertEquals(400, $response['headers']['status-code']);
2022-12-18 06:27:41 +00:00
/**
* Test for Success
*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/password-history', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'limit' => 1,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(1, $response['body']['authPasswordHistory']);
$email = uniqid() . 'user@localhost.test';
$password = 'password';
$name = 'User Name';
/**
* Create new user
*/
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'userId' => ID::unique(),
'email' => $email,
'password' => $password,
'name' => $name,
]);
$this->assertEquals(201, $response['headers']['status-code']);
2022-12-19 05:07:41 +00:00
$userId = $response['body']['$id'];
2022-12-18 06:27:41 +00:00
// create session
$session = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
], [
'email' => $email,
'password' => $password,
]);
$this->assertEquals(201, $session['headers']['status-code']);
2023-12-08 23:36:01 +00:00
$session = $session['cookies']['a_session_' . $id];
2022-12-18 06:27:41 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'cookie' => 'a_session_' . $id . '=' . $session,
]), [
'oldPassword' => $password,
'password' => $password,
]);
$this->assertEquals(400, $response['headers']['status-code']);
2022-12-19 05:07:41 +00:00
2022-12-19 08:28:02 +00:00
$headers = array_merge($this->getHeaders(), [
'x-appwrite-mode' => 'admin',
2022-12-19 05:07:41 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $id,
2022-12-19 08:28:02 +00:00
]);
$response = $this->client->call(Client::METHOD_PATCH, '/users/' . $userId . '/password', $headers, [
2022-12-19 05:07:41 +00:00
'password' => $password,
]);
2022-12-18 06:27:41 +00:00
$this->assertEquals(400, $response['headers']['status-code']);
2022-12-18 06:27:41 +00:00
2022-12-18 06:31:14 +00:00
2024-03-06 17:34:21 +00:00
/**
2024-06-20 14:49:56 +00:00
* Reset
*/
2022-12-18 06:27:41 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/password-history', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'limit' => 0,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(0, $response['body']['authPasswordHistory']);
return $data;
}
2024-02-14 06:40:19 +00:00
/**
2024-06-20 15:01:20 +00:00
* @group smtpAndTemplates
2024-06-20 15:14:02 +00:00
* @group projectsCRUD
*
* @depends testCreateProject
2024-06-20 15:01:20 +00:00
* */
2024-02-14 06:40:19 +00:00
public function testUpdateMockNumbers($data)
{
$id = $data['projectId'] ?? '';
/**
* Test for Failure
*/
/** Trying to pass an empty body to the endpoint */
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2024-06-20 14:49:56 +00:00
], $this->getHeaders()), []);
2024-02-14 06:40:19 +00:00
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertEquals('Param "numbers" is not optional.', $response['body']['message']);
/** Trying to pass body with incorrect structure */
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'numbers' => [
2024-02-14 17:22:43 +00:00
'phone' => '+1655513432',
2024-02-14 06:40:19 +00:00
'otp' => '123456'
]
]);
$this->assertEquals(400, $response['headers']['status-code']);
2024-06-20 14:49:56 +00:00
$this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and Invalid payload structure. Please check the "phone" and "otp" fields', $response['body']['message']);
2024-02-14 06:40:19 +00:00
/** Trying to pass an OTP longer than 6 characters*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'numbers' => [
[
2024-02-14 17:22:43 +00:00
'phone' => '+1655513432',
2024-02-14 06:40:19 +00:00
'otp' => '12345678'
]
]
]);
$this->assertEquals(400, $response['headers']['status-code']);
2024-07-21 19:30:06 +00:00
$this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and Invalid OTP. Please make sure the OTP is a 6 digit number', $response['body']['message']);
2024-02-14 06:40:19 +00:00
/** Trying to pass an OTP shorter than 6 characters*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'numbers' => [
[
2024-02-14 17:22:43 +00:00
'phone' => '+1655513432',
2024-02-14 06:40:19 +00:00
'otp' => '123'
]
]
]);
$this->assertEquals(400, $response['headers']['status-code']);
2024-07-21 19:30:06 +00:00
$this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and Invalid OTP. Please make sure the OTP is a 6 digit number', $response['body']['message']);
/** Trying to pass an OTP with non numeric characters */
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'numbers' => [
[
'phone' => '+1655513432',
'otp' => '123re2'
]
]
]);
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and Invalid OTP. Please make sure the OTP is a 6 digit number', $response['body']['message']);
2024-02-14 06:40:19 +00:00
/** Trying to pass an invalid phone number */
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'numbers' => [
[
2024-02-14 17:22:43 +00:00
'phone' => '1655234',
2024-02-14 06:40:19 +00:00
'otp' => '123456'
]
]
]);
$this->assertEquals(400, $response['headers']['status-code']);
2024-06-20 14:49:56 +00:00
$this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and Phone number must start with a \'+\' can have a maximum of fifteen digits.', $response['body']['message']);
2024-02-14 06:40:19 +00:00
/** Trying to pass a number longer than 15 digits */
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'numbers' => [
[
2024-02-14 17:22:43 +00:00
'phone' => '+1234567890987654',
2024-02-14 06:40:19 +00:00
'otp' => '123456'
]
]
]);
2024-07-21 19:30:06 +00:00
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and Phone number must start with a \'+\' can have a maximum of fifteen digits.', $response['body']['message']);
/** Trying to pass duplicate numbers */
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'numbers' => [
[
'phone' => '+1655513432',
'otp' => '123456'
],
[
'phone' => '+1655513432',
'otp' => '123456'
]
]
]);
2024-02-14 06:40:19 +00:00
$this->assertEquals(400, $response['headers']['status-code']);
2024-07-21 19:45:39 +00:00
$this->assertEquals('Duplicate phone numbers are not allowed.', $response['body']['message']);
2024-02-14 06:40:19 +00:00
$numbers = [];
for ($i = 0; $i < 11; $i++) {
$numbers[] = [
2024-02-14 17:22:43 +00:00
'phone' => '+1655513432',
2024-02-14 06:40:19 +00:00
'otp' => '123456'
];
}
2024-02-14 17:22:43 +00:00
2024-02-14 06:40:19 +00:00
/** Trying to pass more than 10 values */
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'numbers' => $numbers
]);
$this->assertEquals(400, $response['headers']['status-code']);
2024-10-08 07:54:40 +00:00
$this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and Phone number must start with a \'+\' can have a maximum of fifteen digits.', $response['body']['message']);
2024-02-14 06:40:19 +00:00
/**
* Test for success
*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'numbers' => []
]);
$this->assertEquals(200, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'numbers' => [
[
2024-02-14 17:22:43 +00:00
'phone' => '+1655513432',
2024-02-14 06:40:19 +00:00
'otp' => '123456'
]
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
// Create phone session for this project and check if the mock number is used
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/phone', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
2024-06-20 14:31:33 +00:00
'userId' => 'unique()',
'phone' => '+1655513432',
2024-02-14 06:40:19 +00:00
]);
$this->assertEquals(201, $response['headers']['status-code']);
$userId = $response['body']['userId'];
$response = $this->client->call(Client::METHOD_PUT, '/account/sessions/phone', array_merge([
'content-type' => 'application/json',
2024-06-20 15:01:20 +00:00
'x-appwrite-project' => $id,
]), [
'userId' => $userId,
'secret' => '654321', // Try a random code
]);
$this->assertEquals(401, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_PUT, '/account/sessions/phone', array_merge([
'content-type' => 'application/json',
2024-02-14 06:40:19 +00:00
'x-appwrite-project' => $id,
]), [
2024-06-20 14:31:33 +00:00
'userId' => $userId,
'secret' => '123456',
2024-02-14 06:40:19 +00:00
]);
$this->assertEquals(201, $response['headers']['status-code']);
}
2022-12-26 05:46:35 +00:00
/**
* @depends testUpdateProjectAuthLimit
*/
public function testUpdateProjectAuthPasswordDictionary($data): array
{
$id = $data['projectId'] ?? '';
$password = 'password';
$name = 'User Name';
/**
* Test for Success
*/
/**
* create account
*/
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'userId' => ID::unique(),
'email' => uniqid() . 'user@localhost.test',
'password' => $password,
'name' => $name,
]);
$this->assertEquals(201, $response['headers']['status-code']);
$userId = $response['body']['$id'];
/**
* Create user
*/
$user = $this->client->call(Client::METHOD_POST, '/users', array_merge($this->getHeaders(), [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-mode' => 'admin',
]), [
'userId' => ID::unique(),
'email' => uniqid() . 'user@localhost.test',
'password' => 'password',
'name' => 'Cristiano Ronaldo',
]);
$this->assertEquals(201, $response['headers']['status-code']);
/**
* Enable Disctionary
*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/password-dictionary', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'enabled' => true,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(true, $response['body']['authPasswordDictionary']);
/**
* Test for failure
*/
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'userId' => ID::unique(),
'email' => uniqid() . 'user@localhost.test',
'password' => $password,
'name' => $name,
]);
2022-12-26 10:22:25 +00:00
$this->assertEquals(400, $response['headers']['status-code']);
2022-12-26 05:47:20 +00:00
2022-12-26 05:46:35 +00:00
/**
* Create user
*/
$user = $this->client->call(Client::METHOD_POST, '/users', array_merge($this->getHeaders(), [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-mode' => 'admin',
]), [
'userId' => ID::unique(),
'email' => uniqid() . 'user@localhost.test',
'password' => 'password',
'name' => 'Cristiano Ronaldo',
]);
2022-12-26 10:22:25 +00:00
$this->assertEquals(400, $response['headers']['status-code']);
2022-12-26 05:46:35 +00:00
$headers = array_merge($this->getHeaders(), [
'x-appwrite-mode' => 'admin',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]);
$response = $this->client->call(Client::METHOD_PATCH, '/users/' . $userId . '/password', $headers, [
'password' => $password,
]);
2022-12-26 10:22:25 +00:00
$this->assertEquals(400, $response['headers']['status-code']);
2022-12-26 05:46:35 +00:00
2024-03-06 17:34:21 +00:00
/**
2024-06-20 14:49:56 +00:00
* Reset
*/
2022-12-26 05:46:35 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/password-history', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'limit' => 0,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(0, $response['body']['authPasswordHistory']);
/**
* Reset
*/
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/password-dictionary', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2022-12-26 10:22:25 +00:00
'enabled' => false,
2022-12-26 05:46:35 +00:00
]);
$this->assertEquals(200, $response['headers']['status-code']);
2022-12-26 10:22:25 +00:00
$this->assertEquals(false, $response['body']['authPasswordDictionary']);
2022-12-26 05:46:35 +00:00
return $data;
}
/**
* @depends testCreateProject
*/
public function testUpdateDisallowPersonalData($data): void
{
$id = $data['projectId'] ?? '';
/**
* Enable Disallowing of Personal Data
*/
2023-07-20 13:12:41 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/personal-data', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'enabled' => true,
]);
$this->assertEquals(200, $response['headers']['status-code']);
2023-07-19 22:24:32 +00:00
$this->assertEquals(true, $response['body']['authPersonalDataCheck']);
/**
* Test for failure
*/
$email = uniqid() . 'user@localhost.test';
$password = 'password';
$name = 'username';
$userId = ID::unique();
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'email' => $email,
'password' => $email,
'name' => $name,
'userId' => $userId
]);
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertEquals(400, $response['body']['code']);
$this->assertEquals(Exception::USER_PASSWORD_PERSONAL_DATA, $response['body']['type']);
2023-04-13 20:59:35 +00:00
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'email' => $email,
'password' => $name,
'name' => $name,
'userId' => $userId
]);
$phone = '+123456789';
$response = $this->client->call(Client::METHOD_POST, '/users', array_merge($this->getHeaders(), [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-mode' => 'admin',
]), [
'email' => $email,
'password' => $phone,
'name' => $name,
'userId' => $userId,
'phone' => $phone
]);
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertEquals(400, $response['body']['code']);
$this->assertEquals(Exception::USER_PASSWORD_PERSONAL_DATA, $response['body']['type']);
/** Test for success */
$email = uniqid() . 'user@localhost.test';
$password = 'password';
$name = 'username';
$userId = ID::unique();
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
'email' => $email,
'password' => $password,
'name' => $name,
'userId' => $userId
]);
$this->assertEquals(201, $response['headers']['status-code']);
2024-02-25 10:25:51 +00:00
$response = $this->client->call(Client::METHOD_POST, '/users', array_merge($this->getHeaders(), [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
2024-02-25 10:25:51 +00:00
'x-appwrite-mode' => 'admin',
]), [
2024-02-25 10:25:51 +00:00
// Empty password
'email' => uniqid() . 'user@localhost.test',
'name' => 'User',
'userId' => ID::unique(),
]);
$this->assertEquals(201, $response['headers']['status-code']);
$email = uniqid() . 'user@localhost.test';
$userId = ID::unique();
$response = $this->client->call(Client::METHOD_POST, '/users', array_merge($this->getHeaders(), [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-mode' => 'admin',
]), [
'email' => $email,
'password' => $password,
'name' => $name,
'userId' => $userId,
'phone' => $phone
]);
$this->assertEquals(201, $response['headers']['status-code']);
/**
* Reset
*/
2023-07-20 13:12:41 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/personal-data', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'enabled' => false,
]);
$this->assertEquals(200, $response['headers']['status-code']);
2023-07-19 22:24:32 +00:00
$this->assertEquals(false, $response['body']['authPersonalDataCheck']);
}
2023-11-05 23:34:44 +00:00
public function testUpdateProjectServicesAll(): void
{
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
'teamId' => ID::unique(),
'name' => 'Project Test',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$this->assertNotEmpty($team['body']['$id']);
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
'projectId' => ID::unique(),
'name' => 'Project Test',
'teamId' => $team['body']['$id'],
2025-03-19 07:32:48 +00:00
'region' => System::getEnv('_APP_REGION', 'default')
2023-11-05 23:34:44 +00:00
]);
$this->assertEquals(201, $project['headers']['status-code']);
$this->assertNotEmpty($project['body']['$id']);
$id = $project['body']['$id'];
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service/all', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
'status' => false,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$matches = [];
$pattern = '/serviceStatusFor.*/';
foreach ($response['body'] as $key => $value) {
if (\preg_match($pattern, $key)) {
$matches[$key] = $value;
}
}
foreach ($matches as $value) {
$this->assertFalse($value);
}
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service/all', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
'status' => true,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
$this->assertEquals(200, $response['headers']['status-code']);
$matches = [];
foreach ($response['body'] as $key => $value) {
if (\preg_match($pattern, $key)) {
$matches[$key] = $value;
}
}
foreach ($matches as $value) {
$this->assertTrue($value);
}
}
2022-12-18 06:27:41 +00:00
2021-07-29 10:56:25 +00:00
public function testUpdateProjectServiceStatusAdmin(): array
2021-07-29 10:28:17 +00:00
{
2021-07-29 10:56:25 +00:00
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
2022-08-14 10:33:36 +00:00
'teamId' => ID::unique(),
2021-07-29 10:56:25 +00:00
'name' => 'Project Test',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$this->assertNotEmpty($team['body']['$id']);
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
2022-08-14 10:33:36 +00:00
'projectId' => ID::unique(),
2021-07-29 10:56:25 +00:00
'name' => 'Project Test',
'teamId' => $team['body']['$id'],
2025-03-19 07:32:48 +00:00
'region' => System::getEnv('_APP_REGION', 'default')
2021-07-29 10:56:25 +00:00
]);
$this->assertEquals(201, $project['headers']['status-code']);
$this->assertNotEmpty($project['body']['$id']);
$id = $project['body']['$id'];
2024-03-04 12:58:28 +00:00
$services = require(__DIR__ . '/../../../../app/config/services.php');
2021-07-29 10:28:17 +00:00
/**
* Test for Disabled
*/
foreach ($services as $service) {
2022-04-18 16:21:45 +00:00
if (!$service['optional']) {
2021-08-01 08:00:13 +00:00
continue;
}
2021-08-01 10:15:06 +00:00
$key = $service['key'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service', array_merge([
2021-07-29 10:28:17 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2021-07-29 10:56:25 +00:00
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
2021-08-01 10:15:06 +00:00
'service' => $key,
2021-07-29 10:28:17 +00:00
'status' => false,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
2021-07-29 10:28:17 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2021-07-29 10:56:25 +00:00
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
2021-07-29 10:28:17 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
2022-04-18 16:21:45 +00:00
$this->assertEquals(false, $response['body']['serviceStatusFor' . ucfirst($key)]);
2021-07-29 10:28:17 +00:00
}
2022-04-18 16:21:45 +00:00
2021-07-29 10:28:17 +00:00
/**
2021-07-29 10:56:25 +00:00
* Admin request must succeed
2021-07-29 10:28:17 +00:00
*/
2022-04-18 16:21:45 +00:00
2021-07-29 10:28:17 +00:00
$response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
2021-07-29 10:56:25 +00:00
// 'x-appwrite-project' => $this->getProject()['$id'],
2021-07-29 10:28:17 +00:00
'x-appwrite-project' => $id,
2021-07-29 10:56:25 +00:00
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
'x-appwrite-mode' => 'admin'
]));
2022-04-18 16:21:45 +00:00
2021-07-29 10:56:25 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
2021-07-29 10:28:17 +00:00
foreach ($services as $service) {
2022-04-18 16:21:45 +00:00
if (!$service['optional']) {
2021-08-01 10:15:06 +00:00
continue;
}
$key = $service['key'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service/', array_merge([
2021-07-29 10:28:17 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2021-08-01 10:15:06 +00:00
'service' => $key,
2021-07-29 10:28:17 +00:00
'status' => true,
]);
}
2021-07-29 10:56:25 +00:00
return ['projectId' => $id];
2021-07-29 10:28:17 +00:00
}
2021-07-29 10:56:25 +00:00
/** @depends testUpdateProjectServiceStatusAdmin */
2022-04-18 16:21:45 +00:00
public function testUpdateProjectServiceStatus($data): void
2021-07-29 10:28:17 +00:00
{
2021-07-29 10:56:25 +00:00
$id = $data['projectId'];
2021-07-29 10:28:17 +00:00
2024-03-04 12:58:28 +00:00
$services = require(__DIR__ . '/../../../../app/config/services.php');
2021-07-29 10:28:17 +00:00
/**
* Test for Disabled
*/
foreach ($services as $service) {
2022-04-18 16:21:45 +00:00
if (!$service['optional']) {
2021-08-01 10:15:06 +00:00
continue;
}
$key = $service['key'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service', array_merge([
2021-07-29 10:28:17 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
2021-08-01 10:15:06 +00:00
'service' => $key,
2021-07-29 10:28:17 +00:00
'status' => false,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
2021-07-29 10:28:17 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
2022-04-18 16:21:45 +00:00
$this->assertEquals(false, $response['body']['serviceStatusFor' . ucfirst($key)]);
2021-07-29 10:28:17 +00:00
}
/**
2021-07-29 10:56:25 +00:00
* Test for FAILURE
2021-07-29 10:28:17 +00:00
*/
$response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $id,
2021-07-29 10:56:25 +00:00
], $this->getHeaders()));
2021-07-29 10:28:17 +00:00
2024-02-26 12:28:57 +00:00
$this->assertEquals(403, $response['headers']['status-code']);
2021-07-29 10:56:25 +00:00
$response = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $id,
]), [
2022-08-14 10:33:36 +00:00
'teamId' => ID::unique(),
2021-07-29 10:56:25 +00:00
'name' => 'Arsenal'
]);
2024-02-26 12:28:57 +00:00
$this->assertEquals(403, $response['headers']['status-code']);
2021-07-29 10:56:25 +00:00
// Cleanup
foreach ($services as $service) {
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service/', array_merge([
2021-07-29 10:56:25 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'service' => $service,
'status' => true,
]);
}
2021-07-29 10:28:17 +00:00
}
/** @depends testUpdateProjectServiceStatusAdmin */
public function testUpdateProjectServiceStatusServer($data): void
{
$id = $data['projectId'];
2024-03-04 12:58:28 +00:00
$services = require(__DIR__ . '/../../../../app/config/services.php');
/**
* Test for Disabled
*/
foreach ($services as $service) {
if (!$service['optional']) {
continue;
}
$key = $service['key'] ?? '';
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
'service' => $key,
'status' => false,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals(false, $response['body']['serviceStatusFor' . ucfirst($key)]);
}
// Create API Key
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
2026-02-09 13:34:05 +00:00
'keyId' => ID::unique(),
'name' => 'Key Test',
'scopes' => ['functions.read', 'teams.write'],
]);
$this->assertEquals(201, $response['headers']['status-code']);
$keyId = $response['body']['$id'];
$keySecret = $response['body']['secret'];
/**
* Request with API Key must succeed
*/
$response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-key' => $keySecret,
2022-08-30 14:04:42 +00:00
'x-sdk-name' => 'python'
]));
$this->assertEquals(200, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-key' => $keySecret,
2022-08-30 14:04:42 +00:00
'x-sdk-name' => 'php'
]), [
2022-08-14 10:33:36 +00:00
'teamId' => ID::unique(),
'name' => 'Arsenal'
]);
$this->assertEquals(201, $response['headers']['status-code']);
2022-08-30 14:04:42 +00:00
/** Check that the API key has been updated */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys/' . $keyId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertArrayHasKey('sdks', $response['body']);
$this->assertCount(2, $response['body']['sdks']);
2022-08-30 17:33:54 +00:00
$this->assertContains('python', $response['body']['sdks']);
$this->assertContains('php', $response['body']['sdks']);
2022-08-30 14:04:42 +00:00
$this->assertArrayHasKey('accessedAt', $response['body']);
$this->assertNotEmpty($response['body']['accessedAt']);
2022-08-30 18:26:02 +00:00
// Cleanup
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/keys/' . $keyId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), []);
$this->assertEquals(204, $response['headers']['status-code']);
foreach ($services as $service) {
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service/', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'service' => $service,
'status' => true,
]);
}
}
2020-07-09 09:13:14 +00:00
/**
* @depends testCreateProject
*/
public function testCreateProjectWebhook($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
2020-07-09 09:13:14 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/webhooks', array_merge([
2020-07-09 09:13:14 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Webhook Test',
2022-04-18 16:21:45 +00:00
'events' => ['users.*.create', 'users.*.update.email'],
2020-07-09 09:13:14 +00:00
'url' => 'https://appwrite.io',
'security' => true,
'httpUser' => 'username',
'httpPass' => 'password',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
2022-04-18 16:21:45 +00:00
$this->assertContains('users.*.create', $response['body']['events']);
$this->assertContains('users.*.update.email', $response['body']['events']);
2020-07-09 09:13:14 +00:00
$this->assertCount(2, $response['body']['events']);
$this->assertEquals('https://appwrite.io', $response['body']['url']);
2020-07-11 13:01:04 +00:00
$this->assertIsBool($response['body']['security']);
$this->assertEquals(true, $response['body']['security']);
2020-07-09 09:13:14 +00:00
$this->assertEquals('username', $response['body']['httpUser']);
2022-04-18 16:21:45 +00:00
$data = array_merge($data, ['webhookId' => $response['body']['$id'], 'signatureKey' => $response['body']['signatureKey']]);
2020-07-09 09:13:14 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/webhooks', array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Webhook Test',
2022-04-18 16:21:45 +00:00
'events' => ['account.unknown', 'users.*.update.email'],
2020-07-11 13:01:04 +00:00
'url' => 'https://appwrite.io',
'security' => true,
'httpUser' => 'username',
'httpPass' => 'password',
]);
$this->assertEquals(400, $response['headers']['status-code']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/webhooks', array_merge([
2022-02-16 15:16:37 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Webhook Test',
2022-04-18 16:21:45 +00:00
'events' => ['users.*.create', 'users.*.update.email'],
2022-02-16 15:16:37 +00:00
'url' => 'invalid://appwrite.io',
]);
$this->assertEquals(400, $response['headers']['status-code']);
2020-07-11 13:01:04 +00:00
return $data;
}
2020-07-12 13:43:47 +00:00
/**
* @depends testCreateProjectWebhook
*/
public function testListProjectWebhook($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
2020-07-12 13:43:47 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/webhooks', array_merge([
2020-07-12 13:43:47 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
2022-02-27 09:57:09 +00:00
$this->assertEquals(1, $response['body']['total']);
2022-04-18 16:21:45 +00:00
2020-07-12 13:43:47 +00:00
/**
* Test for FAILURE
*/
return $data;
}
2020-07-11 13:01:04 +00:00
/**
* @depends testCreateProjectWebhook
*/
public function testGetProjectWebhook($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
$webhookId = $data['webhookId'] ?? '';
2020-07-11 13:01:04 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/webhooks/' . $webhookId, array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($webhookId, $response['body']['$id']);
2022-04-18 16:21:45 +00:00
$this->assertContains('users.*.create', $response['body']['events']);
$this->assertContains('users.*.update.email', $response['body']['events']);
2020-07-11 13:01:04 +00:00
$this->assertCount(2, $response['body']['events']);
$this->assertEquals('https://appwrite.io', $response['body']['url']);
$this->assertEquals('username', $response['body']['httpUser']);
$this->assertEquals('password', $response['body']['httpPass']);
2022-04-18 16:21:45 +00:00
2020-07-11 13:01:04 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/webhooks/error', array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
return $data;
}
/**
* @depends testCreateProjectWebhook
*/
public function testUpdateProjectWebhook($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
$webhookId = $data['webhookId'] ?? '';
2020-07-11 13:01:04 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/webhooks/' . $webhookId, array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Webhook Test Update',
2022-04-18 16:21:45 +00:00
'events' => ['users.*.delete', 'users.*.sessions.*.delete', 'buckets.*.files.*.create'],
2020-07-11 13:01:04 +00:00
'url' => 'https://appwrite.io/new',
'security' => false,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($webhookId, $response['body']['$id']);
$this->assertEquals('Webhook Test Update', $response['body']['name']);
2022-04-18 16:21:45 +00:00
$this->assertContains('users.*.delete', $response['body']['events']);
$this->assertContains('users.*.sessions.*.delete', $response['body']['events']);
$this->assertContains('buckets.*.files.*.create', $response['body']['events']);
2020-07-11 13:01:04 +00:00
$this->assertCount(3, $response['body']['events']);
$this->assertEquals('https://appwrite.io/new', $response['body']['url']);
$this->assertIsBool($response['body']['security']);
$this->assertEquals(false, $response['body']['security']);
$this->assertEquals('', $response['body']['httpUser']);
2020-11-20 23:31:17 +00:00
$this->assertEquals('', $response['body']['httpPass']);
2020-07-11 13:01:04 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/webhooks/' . $webhookId, array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($webhookId, $response['body']['$id']);
$this->assertEquals('Webhook Test Update', $response['body']['name']);
2022-04-18 16:21:45 +00:00
$this->assertContains('users.*.delete', $response['body']['events']);
$this->assertContains('users.*.sessions.*.delete', $response['body']['events']);
$this->assertContains('buckets.*.files.*.create', $response['body']['events']);
2020-07-11 13:01:04 +00:00
$this->assertCount(3, $response['body']['events']);
$this->assertEquals('https://appwrite.io/new', $response['body']['url']);
$this->assertIsBool($response['body']['security']);
$this->assertEquals(false, $response['body']['security']);
$this->assertEquals('', $response['body']['httpUser']);
2020-11-20 23:31:17 +00:00
$this->assertEquals('', $response['body']['httpPass']);
2022-04-18 16:21:45 +00:00
2020-07-11 13:01:04 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/webhooks/' . $webhookId, array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Webhook Test Update',
2022-04-18 16:21:45 +00:00
'events' => ['users.*.delete', 'users.*.sessions.*.delete', 'buckets.*.files.*.unknown'],
2020-07-11 13:01:04 +00:00
'url' => 'https://appwrite.io/new',
'security' => false,
]);
$this->assertEquals(400, $response['headers']['status-code']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/webhooks/' . $webhookId, array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Webhook Test Update',
2022-04-18 16:21:45 +00:00
'events' => ['users.*.delete', 'users.*.sessions.*.delete', 'buckets.*.files.*.create'],
2020-07-11 13:01:04 +00:00
'url' => 'appwrite.io/new',
'security' => false,
]);
$this->assertEquals(400, $response['headers']['status-code']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/webhooks/' . $webhookId, array_merge([
2022-02-16 15:16:37 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Webhook Test Update',
2022-04-18 16:21:45 +00:00
'events' => ['users.*.delete', 'users.*.sessions.*.delete', 'buckets.*.files.*.create'],
2022-02-16 15:16:37 +00:00
'url' => 'invalid://appwrite.io/new',
]);
$this->assertEquals(400, $response['headers']['status-code']);
2020-07-11 13:01:04 +00:00
return $data;
}
/**
* @depends testCreateProjectWebhook
*/
public function testUpdateProjectWebhookSignature($data): void
{
$id = $data['projectId'] ?? '';
$webhookId = $data['webhookId'] ?? '';
$signatureKey = $data['signatureKey'] ?? '';
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/webhooks/' . $webhookId . '/signature', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['signatureKey']);
$this->assertNotEquals($signatureKey, $response['body']['signatureKey']);
}
2020-07-11 13:01:04 +00:00
/**
* @depends testCreateProjectWebhook
*/
public function testDeleteProjectWebhook($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
$webhookId = $data['webhookId'] ?? '';
2020-07-11 13:01:04 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/webhooks/' . $webhookId, array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/webhooks/' . $webhookId, array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
2022-04-18 16:21:45 +00:00
2020-07-11 13:01:04 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/webhooks/error', array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
2020-07-09 09:13:14 +00:00
2020-07-11 13:01:04 +00:00
$this->assertEquals(404, $response['headers']['status-code']);
2020-07-09 09:13:14 +00:00
return $data;
2020-07-08 15:20:18 +00:00
}
2020-07-11 13:01:04 +00:00
// Keys
/**
* @depends testCreateProject
*/
public function testCreateProjectKey($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
2020-07-11 13:01:04 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2026-02-09 13:34:05 +00:00
'keyId' => ID::unique(),
2020-07-11 13:01:04 +00:00
'name' => 'Key Test',
'scopes' => ['teams.read', 'teams.write'],
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('Key Test', $response['body']['name']);
$this->assertContains('teams.read', $response['body']['scopes']);
$this->assertContains('teams.write', $response['body']['scopes']);
$this->assertNotEmpty($response['body']['secret']);
2022-08-30 14:04:42 +00:00
$this->assertArrayHasKey('sdks', $response['body']);
$this->assertEmpty($response['body']['sdks']);
$this->assertArrayHasKey('accessedAt', $response['body']);
$this->assertEmpty($response['body']['accessedAt']);
2022-04-18 16:21:45 +00:00
2026-02-09 13:34:05 +00:00
/**
* Test for SUCCESS without key ID
*/
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Key Custom',
'scopes' => ['teams.read', 'teams.write'],
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
/**
* Test for SUCCESS with custom ID
*/
$customKeyId = \uniqid() . 'custom-id';
2026-02-09 13:34:05 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'keyId' => $customKeyId,
'name' => 'Key Custom',
'scopes' => ['teams.read', 'teams.write'],
]);
2026-02-09 15:53:18 +00:00
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertSame($customKeyId, $response['body']['$id']);
/**
* Test for FAILURE with custom ID
*/
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'keyId' => $customKeyId,
'name' => 'Key Custom',
'scopes' => ['teams.read', 'teams.write'],
]);
$this->assertEquals(409, $response['headers']['status-code']);
2026-02-09 15:42:14 +00:00
/**
* Test for SUCCESS with magic string ID
*/
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'keyId' => 'unique()',
'name' => 'Key Custom',
'scopes' => ['teams.read', 'teams.write'],
]);
2026-02-09 13:34:05 +00:00
$this->assertEquals(201, $response['headers']['status-code']);
2026-02-09 15:42:14 +00:00
$this->assertNotEmpty($response['body']['$id']);
2026-02-09 15:53:18 +00:00
$this->assertNotSame('unique()', $response['body']['$id']);
2022-04-18 16:21:45 +00:00
2022-05-31 15:41:12 +00:00
$data = array_merge($data, [
'keyId' => $response['body']['$id'],
'secret' => $response['body']['secret']
]);
2020-07-11 13:01:04 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2026-02-09 13:34:05 +00:00
'keyId' => ID::unique(),
2020-07-11 13:01:04 +00:00
'name' => 'Key Test',
'scopes' => ['unknown'],
]);
$this->assertEquals(400, $response['headers']['status-code']);
return $data;
}
2022-05-31 15:41:12 +00:00
2020-07-12 13:43:47 +00:00
/**
* @depends testCreateProjectKey
*/
public function testListProjectKey($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
2020-07-12 13:43:47 +00:00
/** Create a second key with an expiry for query testing */
$expireDate = DateTime::addSeconds(new \DateTime(), 3600);
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Key Test 2',
'scopes' => ['users.read'],
'expire' => $expireDate,
]);
$this->assertEquals(201, $response['headers']['status-code']);
$key2Id = $response['body']['$id'];
/** List all keys (no queries) */
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
2020-07-12 13:43:47 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(5, $response['body']['total']);
$this->assertCount(5, $response['body']['keys']);
/** List keys with limit */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::limit(1)->toString(),
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertCount(1, $response['body']['keys']);
$this->assertEquals(5, $response['body']['total']);
/** List keys with offset */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::offset(1)->toString(),
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertCount(4, $response['body']['keys']);
$this->assertEquals(5, $response['body']['total']);
/** List keys with cursor after */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::cursorAfter(new Document(['$id' => $data['keyId']]))->toString(),
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertCount(1, $response['body']['keys']);
$this->assertEquals(5, $response['body']['total']);
$this->assertEquals($key2Id, $response['body']['keys'][0]['$id']);
/** List keys filtering by expire (lessThan now — should match none) */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::lessThan('expire', (new \DateTime())->format('Y-m-d H:i:s'))->toString(),
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(0, $response['body']['total']);
/** List keys filtering by expire (greaterThan now — should match the key with expiry) */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::greaterThan('expire', (new \DateTime())->format('Y-m-d H:i:s'))->toString(),
]
]);
2022-06-01 06:26:55 +00:00
2020-07-12 13:43:47 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
2022-02-27 09:57:09 +00:00
$this->assertEquals(1, $response['body']['total']);
$this->assertCount(1, $response['body']['keys']);
2026-02-09 15:58:44 +00:00
/** List keys filtering by name (equal — exact match) */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::equal('name', ['Key Test'])->toString(),
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(1, $response['body']['total']);
$this->assertCount(1, $response['body']['keys']);
$this->assertEquals('Key Test', $response['body']['keys'][0]['name']);
/** List keys filtering by name (equal — multiple values) */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::equal('name', ['Key Test', 'Key Test 2'])->toString(),
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(2, $response['body']['total']);
$this->assertCount(2, $response['body']['keys']);
/** List keys filtering by name (equal — no match) */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::equal('name', ['Non Existent Key'])->toString(),
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(0, $response['body']['total']);
$this->assertCount(0, $response['body']['keys']);
/** List keys filtering by scopes (contains — match key with teams.read) */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::contains('scopes', ['teams.read'])->toString(),
]
]);
2022-06-01 06:26:55 +00:00
2020-07-12 13:43:47 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
2026-02-09 15:53:18 +00:00
$this->assertEquals(4, $response['body']['total']);
$this->assertCount(4, $response['body']['keys']);
2026-02-09 15:58:44 +00:00
/** List keys filtering by scopes (contains — match key with users.read) */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::contains('scopes', ['users.read'])->toString(),
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(1, $response['body']['total']);
$this->assertCount(1, $response['body']['keys']);
/** List keys filtering by scopes (contains — no match) */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::contains('scopes', ['databases.read'])->toString(),
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(0, $response['body']['total']);
$this->assertCount(0, $response['body']['keys']);
/** List keys filtering by name and scopes combined */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::equal('name', ['Key Test'])->toString(),
Query::contains('scopes', ['teams.read'])->toString(),
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(1, $response['body']['total']);
$this->assertCount(1, $response['body']['keys']);
$this->assertEquals('Key Test', $response['body']['keys'][0]['name']);
/** List keys with orderDesc */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
2026-02-09 16:12:30 +00:00
Query::orderDesc('$createdAt')->toString(),
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertCount(5, $response['body']['keys']);
$this->assertGreaterThan($response['body']['keys'][1]['$createdAt'], $response['body']['keys'][0]['$createdAt']);
/** List keys with total disabled */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'total' => false,
'queries' => [
Query::limit(1)->toString()
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertCount(1, $response['body']['keys']);
$this->assertEquals(0, $response['body']['total']);
2022-04-18 16:21:45 +00:00
2020-07-12 13:43:47 +00:00
/**
* Test for FAILURE
*/
/** Test invalid query attribute */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::equal('secret', ['test'])->toString(),
]
]);
$this->assertEquals(400, $response['headers']['status-code']);
/** Test invalid cursor */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::cursorAfter(new Document(['$id' => 'invalid']))->toString(),
]
]);
$this->assertEquals(400, $response['headers']['status-code']);
2020-07-12 13:43:47 +00:00
return $data;
}
2022-05-31 15:41:12 +00:00
2020-07-11 13:01:04 +00:00
/**
* @depends testCreateProjectKey
*/
public function testGetProjectKey($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
$keyId = $data['keyId'] ?? '';
2020-07-11 13:01:04 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys/' . $keyId, array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($keyId, $response['body']['$id']);
2026-02-09 13:34:05 +00:00
$this->assertEquals('Key Custom', $response['body']['name']);
2020-07-11 13:01:04 +00:00
$this->assertContains('teams.read', $response['body']['scopes']);
$this->assertContains('teams.write', $response['body']['scopes']);
$this->assertCount(2, $response['body']['scopes']);
$this->assertNotEmpty($response['body']['secret']);
2022-08-30 14:04:42 +00:00
$this->assertArrayHasKey('sdks', $response['body']);
$this->assertEmpty($response['body']['sdks']);
$this->assertArrayHasKey('accessedAt', $response['body']);
$this->assertEmpty($response['body']['accessedAt']);
2022-04-18 16:21:45 +00:00
2020-07-11 13:01:04 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys/error', array_merge([
2020-07-11 13:01:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
return $data;
}
2022-05-31 15:41:12 +00:00
/**
2022-06-01 06:26:55 +00:00
* @depends testCreateProject
2022-05-31 15:41:12 +00:00
*/
public function testValidateProjectKey($data): void
{
2025-04-16 00:30:22 +00:00
$projectId = $data['projectId'] ?? '';
$teamId = $data['teamId'] ?? '';
2022-05-31 15:41:12 +00:00
2022-06-01 06:26:55 +00:00
/**
* Test for SUCCESS
*/
2025-04-16 00:30:22 +00:00
// Expiring key
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $projectId . '/keys', array_merge([
2022-05-31 15:41:12 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2022-06-01 06:26:55 +00:00
], $this->getHeaders()), [
2026-02-09 13:34:05 +00:00
'keyId' => ID::unique(),
2022-06-01 06:26:55 +00:00
'name' => 'Key Test',
2025-04-16 00:30:22 +00:00
'scopes' => ['users.write'],
2022-07-13 14:02:49 +00:00
'expire' => DateTime::addSeconds(new \DateTime(), 3600),
2022-06-01 06:26:55 +00:00
]);
2025-04-16 00:30:22 +00:00
$response = $this->client->call(Client::METHOD_POST, '/users', [
2022-06-01 06:26:55 +00:00
'content-type' => 'application/json',
2025-04-16 00:30:22 +00:00
'x-appwrite-project' => $projectId,
2022-06-01 06:26:55 +00:00
'x-appwrite-key' => $response['body']['secret']
2025-04-16 00:30:22 +00:00
], [
'userId' => ID::unique(),
]);
2022-06-01 06:26:55 +00:00
2025-04-16 00:30:22 +00:00
$this->assertEquals(201, $response['headers']['status-code']);
2022-06-01 06:26:55 +00:00
2025-04-16 00:30:22 +00:00
// No expiry
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $projectId . '/keys', array_merge([
2022-06-01 06:26:55 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2026-02-09 13:34:05 +00:00
'keyId' => ID::unique(),
2022-06-01 06:26:55 +00:00
'name' => 'Key Test',
'scopes' => ['health.read'],
2022-07-05 18:55:20 +00:00
'expire' => null,
2022-06-01 06:26:55 +00:00
]);
2022-06-03 09:12:19 +00:00
$response = $this->client->call(Client::METHOD_GET, '/health', [
2022-06-01 06:26:55 +00:00
'content-type' => 'application/json',
2025-04-16 00:30:22 +00:00
'x-appwrite-project' => $projectId,
2022-06-01 06:26:55 +00:00
'x-appwrite-key' => $response['body']['secret']
], []);
$this->assertEquals(200, $response['headers']['status-code']);
/**
* Test for FAILURE
*/
2025-04-16 00:30:22 +00:00
// Expired key
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $projectId . '/keys', array_merge([
2022-06-01 06:26:55 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2026-02-09 13:34:05 +00:00
'keyId' => ID::unique(),
2022-06-01 06:26:55 +00:00
'name' => 'Key Test',
'scopes' => ['health.read'],
2022-07-13 14:02:49 +00:00
'expire' => DateTime::addSeconds(new \DateTime(), -3600),
2022-06-01 06:26:55 +00:00
]);
2022-06-03 09:12:19 +00:00
$response = $this->client->call(Client::METHOD_GET, '/health', [
2022-06-01 06:26:55 +00:00
'content-type' => 'application/json',
2025-04-16 00:30:22 +00:00
'x-appwrite-project' => $projectId,
2022-06-01 06:26:55 +00:00
'x-appwrite-key' => $response['body']['secret']
2025-04-16 00:30:22 +00:00
]);
$this->assertEquals(401, $response['headers']['status-code']);
// Invalid key
$bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'bucketId' => ID::unique(),
'name' => 'Test Bucket',
]);
$this->assertEquals(201, $bucket['headers']['status-code']);
$this->assertNotEmpty($bucket['body']['$id']);
$bucketId = $bucket['body']['$id'];
$response = $this->client->call(Client::METHOD_GET, "/storage/buckets/{$bucketId}/files", [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => 'invalid-key'
]);
$this->assertEquals(401, $response['headers']['status-code']);
// Invalid scopes
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $projectId . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2026-02-09 13:34:05 +00:00
'keyId' => ID::unique(),
2025-04-16 00:30:22 +00:00
'name' => 'Key Test',
'scopes' => ['teams.read'],
'expire' => DateTime::addSeconds(new \DateTime(), 3600),
]);
$response = $this->client->call(Client::METHOD_GET, '/users', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $response['body']['secret']
]);
$this->assertEquals(401, $response['headers']['status-code']);
// Invalid key from different project
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test 2',
'teamId' => $teamId,
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $response['headers']['status-code']);
$project2Id = $response['body']['$id'];
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $project2Id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2026-02-09 13:34:05 +00:00
'keyId' => ID::unique(),
2025-04-16 00:30:22 +00:00
'name' => 'Key Test',
'scopes' => ['health.read'],
'expire' => DateTime::addSeconds(new \DateTime(), 3600),
]);
$response = $this->client->call(Client::METHOD_GET, '/health', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $response['body']['secret']
]);
2022-06-01 06:26:55 +00:00
$this->assertEquals(401, $response['headers']['status-code']);
2022-05-31 15:41:12 +00:00
}
2020-07-11 13:26:04 +00:00
/**
* @depends testCreateProjectKey
*/
public function testUpdateProjectKey($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
$keyId = $data['keyId'] ?? '';
2020-07-11 13:26:04 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/keys/' . $keyId, array_merge([
2020-07-11 13:26:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Key Test Update',
'scopes' => ['users.read', 'users.write', 'collections.read', 'tables.read'],
2022-07-13 14:02:49 +00:00
'expire' => DateTime::addSeconds(new \DateTime(), 360),
2020-07-11 13:26:04 +00:00
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($keyId, $response['body']['$id']);
$this->assertEquals('Key Test Update', $response['body']['name']);
$this->assertContains('users.read', $response['body']['scopes']);
$this->assertContains('users.write', $response['body']['scopes']);
$this->assertContains('collections.read', $response['body']['scopes']);
$this->assertContains('tables.read', $response['body']['scopes']);
$this->assertCount(4, $response['body']['scopes']);
2022-08-30 14:04:42 +00:00
$this->assertArrayHasKey('sdks', $response['body']);
$this->assertEmpty($response['body']['sdks']);
$this->assertArrayHasKey('accessedAt', $response['body']);
$this->assertEmpty($response['body']['accessedAt']);
2020-07-11 13:26:04 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys/' . $keyId, array_merge([
2020-07-11 13:26:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($keyId, $response['body']['$id']);
$this->assertEquals('Key Test Update', $response['body']['name']);
$this->assertContains('users.read', $response['body']['scopes']);
$this->assertContains('users.write', $response['body']['scopes']);
$this->assertContains('collections.read', $response['body']['scopes']);
$this->assertContains('tables.read', $response['body']['scopes']);
$this->assertCount(4, $response['body']['scopes']);
2022-08-30 14:04:42 +00:00
$this->assertArrayHasKey('sdks', $response['body']);
$this->assertEmpty($response['body']['sdks']);
$this->assertArrayHasKey('accessedAt', $response['body']);
$this->assertEmpty($response['body']['accessedAt']);
2022-04-18 16:21:45 +00:00
2020-07-11 13:26:04 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/keys/' . $keyId, array_merge([
2020-07-11 13:26:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Key Test Update',
'scopes' => ['users.read', 'users.write', 'collections.read', 'unknown'],
]);
$this->assertEquals(400, $response['headers']['status-code']);
return $data;
}
/**
* @depends testCreateProjectKey
*/
public function testDeleteProjectKey($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
$keyId = $data['keyId'] ?? '';
2020-07-11 13:26:04 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/keys/' . $keyId, array_merge([
2020-07-11 13:26:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys/' . $keyId, array_merge([
2020-07-11 13:26:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
2022-04-18 16:21:45 +00:00
2020-07-11 13:26:04 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/keys/error', array_merge([
2020-07-11 13:26:04 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
return $data;
}
2020-07-11 19:40:58 +00:00
2024-05-16 08:39:15 +00:00
/**
* @depends testCreateProject
*/
public function testCreateProjectKeyOutdated($data): void
{
$id = $data['projectId'] ?? '';
$response = $this->client->call(Client::METHOD_POST, '/mock/api-key-unprefixed', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => $id
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertContains('users.read', $response['body']['scopes']);
$this->assertNotEmpty($response['body']['secret']);
$this->assertStringStartsNotWith(API_KEY_STANDARD . '_', $response['body']['secret']);
$keyId = $response['body']['$id'];
$secret = $response['body']['secret'];
$response = $this->client->call(Client::METHOD_GET, '/users', [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-key' => $secret
], []);
$this->assertEquals(200, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/keys/' . $keyId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
}
2024-05-29 09:33:39 +00:00
// JWT Keys
/**
* @depends testCreateProject
*/
public function testJWTKey($data): void
{
$id = $data['projectId'] ?? '';
// Create JWT key
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/jwts', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'duration' => 5,
'scopes' => ['users.read'],
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['jwt']);
$jwt = $response['body']['jwt'];
// Ensure JWT key works
$response = $this->client->call(Client::METHOD_GET, '/users', [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-key' => $jwt,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertArrayHasKey('users', $response['body']);
// Ensure JWT key respect scopes
$response = $this->client->call(Client::METHOD_GET, '/functions', [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-key' => $jwt,
]);
$this->assertEquals(401, $response['headers']['status-code']);
// Ensure JWT key expires
\sleep(10);
$response = $this->client->call(Client::METHOD_GET, '/users', [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-key' => $jwt,
]);
$this->assertEquals(401, $response['headers']['status-code']);
}
2020-07-12 11:57:31 +00:00
// Platforms
/**
* @depends testCreateProject
*/
public function testCreateProjectPlatform($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
2020-07-12 11:57:31 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'type' => 'web',
'name' => 'Web App',
'hostname' => 'localhost',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('web', $response['body']['type']);
$this->assertEquals('Web App', $response['body']['name']);
$this->assertEquals('', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('localhost', $response['body']['hostname']);
2022-04-18 16:21:45 +00:00
2020-07-12 11:57:31 +00:00
$data = array_merge($data, ['platformWebId' => $response['body']['$id']]);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'type' => 'flutter-ios',
'name' => 'Flutter App (iOS)',
'key' => 'com.example.ios',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('flutter-ios', $response['body']['type']);
$this->assertEquals('Flutter App (iOS)', $response['body']['name']);
$this->assertEquals('com.example.ios', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
2022-04-18 16:21:45 +00:00
2020-07-12 11:57:31 +00:00
$data = array_merge($data, ['platformFultteriOSId' => $response['body']['$id']]);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'type' => 'flutter-android',
'name' => 'Flutter App (Android)',
'key' => 'com.example.android',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('flutter-android', $response['body']['type']);
$this->assertEquals('Flutter App (Android)', $response['body']['name']);
$this->assertEquals('com.example.android', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
2022-04-18 16:21:45 +00:00
2020-07-12 11:57:31 +00:00
$data = array_merge($data, ['platformFultterAndroidId' => $response['body']['$id']]);
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'type' => 'flutter-web',
'name' => 'Flutter App (Web)',
'hostname' => 'flutter.appwrite.io',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('flutter-web', $response['body']['type']);
$this->assertEquals('Flutter App (Web)', $response['body']['name']);
$this->assertEquals('', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('flutter.appwrite.io', $response['body']['hostname']);
$data = array_merge($data, ['platformFultterWebId' => $response['body']['$id']]);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'type' => 'apple-ios',
'name' => 'iOS App',
'key' => 'com.example.ios',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('apple-ios', $response['body']['type']);
$this->assertEquals('iOS App', $response['body']['name']);
$this->assertEquals('com.example.ios', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
$data = array_merge($data, ['platformAppleIosId' => $response['body']['$id']]);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'type' => 'apple-macos',
'name' => 'macOS App',
'key' => 'com.example.macos',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('apple-macos', $response['body']['type']);
$this->assertEquals('macOS App', $response['body']['name']);
$this->assertEquals('com.example.macos', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
$data = array_merge($data, ['platformAppleMacOsId' => $response['body']['$id']]);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'type' => 'apple-watchos',
'name' => 'watchOS App',
'key' => 'com.example.watchos',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('apple-watchos', $response['body']['type']);
$this->assertEquals('watchOS App', $response['body']['name']);
$this->assertEquals('com.example.watchos', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
$data = array_merge($data, ['platformAppleWatchOsId' => $response['body']['$id']]);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'type' => 'apple-tvos',
'name' => 'tvOS App',
'key' => 'com.example.tvos',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('apple-tvos', $response['body']['type']);
$this->assertEquals('tvOS App', $response['body']['name']);
$this->assertEquals('com.example.tvos', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
$data = array_merge($data, ['platformAppleTvOsId' => $response['body']['$id']]);
2020-07-12 11:57:31 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'type' => 'unknown',
'name' => 'Web App',
'hostname' => 'localhost',
]);
2021-12-01 11:48:23 +00:00
$this->assertEquals(400, $response['headers']['status-code']);
2020-07-12 11:57:31 +00:00
return $data;
}
2020-07-12 13:43:47 +00:00
/**
* @depends testCreateProjectPlatform
*/
public function testListProjectPlatform($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
2021-12-01 11:48:23 +00:00
$this->assertEventually(function () use ($id) {
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
2020-07-12 13:43:47 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(8, $response['body']['total']);
});
2020-07-12 13:43:47 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
2020-07-12 13:43:47 +00:00
return $data;
}
2020-07-12 11:57:31 +00:00
/**
* @depends testCreateProjectPlatform
*/
public function testGetProjectPlatform($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
2021-12-01 11:48:23 +00:00
2020-10-14 21:11:12 +00:00
$platformWebId = $data['platformWebId'] ?? '';
2020-07-12 11:57:31 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformWebId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformWebId, $response['body']['$id']);
$this->assertEquals('web', $response['body']['type']);
$this->assertEquals('Web App', $response['body']['name']);
$this->assertEquals('', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('localhost', $response['body']['hostname']);
2022-04-18 16:21:45 +00:00
2020-10-14 21:11:12 +00:00
$platformFultteriOSId = $data['platformFultteriOSId'] ?? '';
2020-07-12 11:57:31 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformFultteriOSId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformFultteriOSId, $response['body']['$id']);
$this->assertEquals('flutter-ios', $response['body']['type']);
$this->assertEquals('Flutter App (iOS)', $response['body']['name']);
$this->assertEquals('com.example.ios', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
2022-04-18 16:21:45 +00:00
2020-10-14 21:11:12 +00:00
$platformFultterAndroidId = $data['platformFultterAndroidId'] ?? '';
2020-07-12 11:57:31 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformFultterAndroidId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformFultterAndroidId, $response['body']['$id']);
$this->assertEquals('flutter-android', $response['body']['type']);
$this->assertEquals('Flutter App (Android)', $response['body']['name']);
$this->assertEquals('com.example.android', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
2021-10-13 13:44:52 +00:00
$platformFultterWebId = $data['platformFultterWebId'] ?? '';
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformFultterWebId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformFultterWebId, $response['body']['$id']);
$this->assertEquals('flutter-web', $response['body']['type']);
$this->assertEquals('Flutter App (Web)', $response['body']['name']);
$this->assertEquals('', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('flutter.appwrite.io', $response['body']['hostname']);
2021-10-13 13:44:52 +00:00
$platformAppleIosId = $data['platformAppleIosId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformAppleIosId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformAppleIosId, $response['body']['$id']);
$this->assertEquals('apple-ios', $response['body']['type']);
$this->assertEquals('iOS App', $response['body']['name']);
$this->assertEquals('com.example.ios', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
$platformAppleMacOsId = $data['platformAppleMacOsId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformAppleMacOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformAppleMacOsId, $response['body']['$id']);
$this->assertEquals('apple-macos', $response['body']['type']);
$this->assertEquals('macOS App', $response['body']['name']);
$this->assertEquals('com.example.macos', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
$platformAppleWatchOsId = $data['platformAppleWatchOsId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformAppleWatchOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformAppleWatchOsId, $response['body']['$id']);
$this->assertEquals('apple-watchos', $response['body']['type']);
$this->assertEquals('watchOS App', $response['body']['name']);
$this->assertEquals('com.example.watchos', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
$platformAppleTvOsId = $data['platformAppleTvOsId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformAppleTvOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformAppleTvOsId, $response['body']['$id']);
$this->assertEquals('apple-tvos', $response['body']['type']);
$this->assertEquals('tvOS App', $response['body']['name']);
$this->assertEquals('com.example.tvos', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
2020-07-12 11:57:31 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/error', array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
return $data;
}
/**
* @depends testCreateProjectPlatform
*/
public function testUpdateProjectPlatform($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
2020-07-12 11:57:31 +00:00
2020-10-14 21:11:12 +00:00
$platformWebId = $data['platformWebId'] ?? '';
2020-07-12 11:57:31 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/platforms/' . $platformWebId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Web App 2',
'hostname' => 'localhost-new',
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformWebId, $response['body']['$id']);
$this->assertEquals('web', $response['body']['type']);
$this->assertEquals('Web App 2', $response['body']['name']);
$this->assertEquals('', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('localhost-new', $response['body']['hostname']);
2020-10-14 21:11:12 +00:00
$platformFultteriOSId = $data['platformFultteriOSId'] ?? '';
2020-07-12 11:57:31 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/platforms/' . $platformFultteriOSId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Flutter App (iOS) 2',
'key' => 'com.example.ios2',
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformFultteriOSId, $response['body']['$id']);
$this->assertEquals('flutter-ios', $response['body']['type']);
$this->assertEquals('Flutter App (iOS) 2', $response['body']['name']);
$this->assertEquals('com.example.ios2', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
2022-04-18 16:21:45 +00:00
2020-10-14 21:11:12 +00:00
$platformFultterAndroidId = $data['platformFultterAndroidId'] ?? '';
2020-07-12 11:57:31 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/platforms/' . $platformFultterAndroidId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Flutter App (Android) 2',
'key' => 'com.example.android2',
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformFultterAndroidId, $response['body']['$id']);
$this->assertEquals('flutter-android', $response['body']['type']);
$this->assertEquals('Flutter App (Android) 2', $response['body']['name']);
$this->assertEquals('com.example.android2', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
$platformFultterWebId = $data['platformFultterWebId'] ?? '';
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/platforms/' . $platformFultterWebId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Flutter App (Web) 2',
'hostname' => 'flutter2.appwrite.io',
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformFultterWebId, $response['body']['$id']);
$this->assertEquals('flutter-web', $response['body']['type']);
$this->assertEquals('Flutter App (Web) 2', $response['body']['name']);
$this->assertEquals('', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('flutter2.appwrite.io', $response['body']['hostname']);
2021-10-13 13:44:52 +00:00
$platformAppleIosId = $data['platformAppleIosId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/platforms/' . $platformAppleIosId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'iOS App 2',
'key' => 'com.example.ios2',
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformAppleIosId, $response['body']['$id']);
$this->assertEquals('apple-ios', $response['body']['type']);
$this->assertEquals('iOS App 2', $response['body']['name']);
$this->assertEquals('com.example.ios2', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
$platformAppleMacOsId = $data['platformAppleMacOsId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/platforms/' . $platformAppleMacOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'macOS App 2',
'key' => 'com.example.macos2',
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformAppleMacOsId, $response['body']['$id']);
$this->assertEquals('apple-macos', $response['body']['type']);
$this->assertEquals('macOS App 2', $response['body']['name']);
$this->assertEquals('com.example.macos2', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
$platformAppleWatchOsId = $data['platformAppleWatchOsId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/platforms/' . $platformAppleWatchOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'watchOS App 2',
'key' => 'com.example.watchos2',
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformAppleWatchOsId, $response['body']['$id']);
$this->assertEquals('apple-watchos', $response['body']['type']);
$this->assertEquals('watchOS App 2', $response['body']['name']);
$this->assertEquals('com.example.watchos2', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
$platformAppleTvOsId = $data['platformAppleTvOsId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/platforms/' . $platformAppleTvOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'tvOS App 2',
'key' => 'com.example.tvos2',
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($platformAppleTvOsId, $response['body']['$id']);
$this->assertEquals('apple-tvos', $response['body']['type']);
$this->assertEquals('tvOS App 2', $response['body']['name']);
$this->assertEquals('com.example.tvos2', $response['body']['key']);
$this->assertEquals('', $response['body']['store']);
$this->assertEquals('', $response['body']['hostname']);
2020-07-12 11:57:31 +00:00
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $id . '/platforms/error', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Flutter App (Android) 2',
'key' => 'com.example.android2',
]);
$this->assertEquals(404, $response['headers']['status-code']);
2020-07-12 11:57:31 +00:00
return $data;
}
/**
* @depends testCreateProjectPlatform
*/
public function testDeleteProjectPlatform($data): array
{
2020-10-14 21:11:12 +00:00
$id = $data['projectId'] ?? '';
2022-04-18 16:21:45 +00:00
2020-10-14 21:11:12 +00:00
$platformWebId = $data['platformWebId'] ?? '';
2020-07-12 11:57:31 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/platforms/' . $platformWebId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformWebId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
2020-10-14 21:11:12 +00:00
$platformFultteriOSId = $data['platformFultteriOSId'] ?? '';
2020-07-12 11:57:31 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/platforms/' . $platformFultteriOSId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformFultteriOSId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
2020-10-14 21:11:12 +00:00
$platformFultterAndroidId = $data['platformFultterAndroidId'] ?? '';
2020-07-12 11:57:31 +00:00
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/platforms/' . $platformFultterAndroidId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformFultterAndroidId, array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2021-10-13 13:44:52 +00:00
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
$platformFultterWebId = $data['platformFultterWebId'] ?? '';
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/platforms/' . $platformFultterWebId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformFultterWebId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
2021-10-13 13:44:52 +00:00
$platformAppleIosId = $data['platformAppleIosId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/platforms/' . $platformAppleIosId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformAppleIosId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
$platformAppleMacOsId = $data['platformAppleMacOsId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/platforms/' . $platformAppleMacOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformAppleMacOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
$platformAppleWatchOsId = $data['platformAppleWatchOsId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/platforms/' . $platformAppleWatchOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformAppleWatchOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
$platformAppleTvOsId = $data['platformAppleTvOsId'] ?? '';
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/platforms/' . $platformAppleTvOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms/' . $platformAppleTvOsId, array_merge([
2021-10-13 13:44:52 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2020-07-12 11:57:31 +00:00
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
/**
* Test for FAILURE
*/
2022-04-18 16:21:45 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/webhooks/error', array_merge([
2020-07-12 11:57:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
return $data;
}
2020-07-12 13:43:47 +00:00
2022-10-03 08:06:48 +00:00
public function testDeleteProject(): array
{
$data = [];
// Create a team and a project
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Amazing Team',
2022-10-03 08:06:48 +00:00
]);
$this->assertEquals(201, $team['headers']['status-code']);
$this->assertEquals('Amazing Team', $team['body']['name']);
2022-10-03 08:06:48 +00:00
$this->assertNotEmpty($team['body']['$id']);
$teamId = $team['body']['$id'];
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Amazing Project',
'teamId' => $teamId,
2025-03-19 07:32:48 +00:00
'region' => System::getEnv('_APP_REGION', 'default')
2022-10-03 08:06:48 +00:00
]);
$this->assertEquals(201, $project['headers']['status-code']);
$this->assertEquals('Amazing Project', $project['body']['name']);
$this->assertEquals($teamId, $project['body']['teamId']);
$this->assertNotEmpty($project['body']['$id']);
$projectId = $project['body']['$id'];
// Ensure I can get both team and project
$team = $this->client->call(Client::METHOD_GET, '/teams/' . $teamId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $team['headers']['status-code']);
$project = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $project['headers']['status-code']);
// Delete Project
2023-05-25 01:26:13 +00:00
$project = $this->client->call(Client::METHOD_DELETE, '/projects/' . $projectId, array_merge([
2022-10-03 08:06:48 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
2022-10-03 08:06:48 +00:00
$this->assertEquals(204, $project['headers']['status-code']);
2022-10-03 08:06:48 +00:00
// Ensure I can get team but not a project
$team = $this->client->call(Client::METHOD_GET, '/teams/' . $teamId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $team['headers']['status-code']);
$project = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(404, $project['headers']['status-code']);
return $data;
}
2024-10-17 14:05:17 +00:00
public function testDeleteSharedProject(): void
{
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Amazing Team',
]);
$teamId = $team['body']['$id'];
// Ensure deleting one project does not affect another project
$project1 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Amazing Project 1',
'teamId' => $teamId,
2025-03-19 07:32:48 +00:00
'region' => System::getEnv('_APP_REGION', 'default')
]);
$project2 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Amazing Project 2',
'teamId' => $teamId,
2025-03-19 07:32:48 +00:00
'region' => System::getEnv('_APP_REGION', 'default')
]);
$project1Id = $project1['body']['$id'];
$project2Id = $project2['body']['$id'];
// Create user in each project
$key1 = $this->client->call(Client::METHOD_POST, '/projects/' . $project1Id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2026-02-09 13:34:05 +00:00
'keyId' => ID::unique(),
'name' => 'Key Test',
'scopes' => ['users.read', 'users.write'],
]);
$user1 = $this->client->call(Client::METHOD_POST, '/users', [
'content-type' => 'application/json',
'x-appwrite-project' => $project1Id,
'x-appwrite-key' => $key1['body']['secret'],
], [
'userId' => ID::unique(),
'email' => 'test1@appwrite.io',
'password' => 'password',
]);
$this->assertEquals(201, $user1['headers']['status-code']);
$key2 = $this->client->call(Client::METHOD_POST, '/projects/' . $project2Id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2026-02-09 13:34:05 +00:00
'keyId' => ID::unique(),
'name' => 'Key Test',
'scopes' => ['users.read', 'users.write'],
]);
$user2 = $this->client->call(Client::METHOD_POST, '/users', [
'content-type' => 'application/json',
'x-appwrite-project' => $project2Id,
'x-appwrite-key' => $key2['body']['secret'],
], [
'userId' => ID::unique(),
'email' => 'test2@appwrite.io',
'password' => 'password',
]);
$this->assertEquals(201, $user2['headers']['status-code']);
// Delete project 1
$project1 = $this->client->call(Client::METHOD_DELETE, '/projects/' . $project1Id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(204, $project1['headers']['status-code']);
// Ensure project 2 user is still there
$this->assertEventually(function () use ($user2, $project2Id, $key2) {
$response = $this->client->call(Client::METHOD_GET, '/users/' . $user2['body']['$id'], [
'content-type' => 'application/json',
'x-appwrite-project' => $project2Id,
'x-appwrite-key' => $key2['body']['secret'],
]);
$this->assertEquals(200, $response['headers']['status-code']);
});
2024-11-21 03:49:49 +00:00
// Create another user in project 2 in case read hits stale cache
$user3 = $this->client->call(Client::METHOD_POST, '/users', [
'content-type' => 'application/json',
'x-appwrite-project' => $project2Id,
'x-appwrite-key' => $key2['body']['secret'],
], [
'userId' => ID::unique(),
'email' => 'test3@appwrite.io'
]);
$this->assertEquals(201, $user3['headers']['status-code']);
}
2024-10-17 14:05:17 +00:00
/**
* @depends testCreateProject
*/
public function testCreateProjectVariable(array $data)
{
/**
* Test for SUCCESS
*/
$variable = $this->client->call(Client::METHOD_POST, '/project/variables', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'key' => 'APP_TEST',
2025-02-10 14:29:28 +00:00
'value' => 'TESTINGVALUE',
'secret' => false
2024-10-17 14:05:17 +00:00
]);
$this->assertEquals(201, $variable['headers']['status-code']);
2025-02-10 16:37:07 +00:00
$this->assertEquals('APP_TEST', $variable['body']['key']);
$this->assertEquals('TESTINGVALUE', $variable['body']['value']);
$this->assertFalse($variable['body']['secret']);
2024-10-17 14:05:17 +00:00
$variableId = $variable['body']['$id'];
2024-10-21 14:33:57 +00:00
// test for secret variable
$variable = $this->client->call(Client::METHOD_POST, '/project/variables', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'key' => 'APP_TEST_1',
'value' => 'TESTINGVALUE_1',
'secret' => true
]);
$this->assertEquals(201, $variable['headers']['status-code']);
$this->assertEquals('APP_TEST_1', $variable['body']['key']);
$this->assertEmpty($variable['body']['value']);
$secretVariableId = $variable['body']['$id'];
2024-10-17 14:05:17 +00:00
/**
* Test for FAILURE
*/
// Test for duplicate key
$variable = $this->client->call(Client::METHOD_POST, '/project/variables', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'key' => 'APP_TEST',
'value' => 'ANOTHERTESTINGVALUE'
]);
$this->assertEquals(409, $variable['headers']['status-code']);
// Test for invalid key
$variable = $this->client->call(Client::METHOD_POST, '/project/variables', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'key' => str_repeat("A", 256),
'value' => 'TESTINGVALUE'
]);
$this->assertEquals(400, $variable['headers']['status-code']);
// Test for invalid value
$variable = $this->client->call(Client::METHOD_POST, '/project/variables', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'key' => 'LONGKEY',
'value' => str_repeat("#", 8193),
]);
$this->assertEquals(400, $variable['headers']['status-code']);
return array_merge(
$data,
[
'variableId' => $variableId,
2024-10-21 14:33:57 +00:00
'secretVariableId' => $secretVariableId
2024-10-17 14:05:17 +00:00
]
);
}
/**
* @depends testCreateProjectVariable
*/
public function testListVariables(array $data)
{
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_GET, '/project/variables', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
2024-10-21 14:33:57 +00:00
$this->assertCount(2, $response['body']['variables']);
$this->assertEquals(2, $response['body']['total']);
2024-10-17 14:05:17 +00:00
$this->assertEquals("APP_TEST", $response['body']['variables'][0]['key']);
$this->assertEquals("TESTINGVALUE", $response['body']['variables'][0]['value']);
2024-10-21 14:33:57 +00:00
$this->assertEquals("APP_TEST_1", $response['body']['variables'][1]['key']);
$this->assertEmpty($response['body']['variables'][1]['value']);
2024-10-17 14:05:17 +00:00
return $data;
}
/**
* @depends testListVariables
*/
public function testGetVariable(array $data)
{
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_GET, '/project/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals("APP_TEST", $response['body']['key']);
$this->assertEquals("TESTINGVALUE", $response['body']['value']);
2024-10-21 14:33:57 +00:00
$response = $this->client->call(Client::METHOD_GET, '/project/variables/' . $data['secretVariableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals("APP_TEST_1", $response['body']['key']);
$this->assertEmpty($response['body']['value']);
2025-02-11 12:50:54 +00:00
$this->assertTrue($response['body']['secret']);
2024-10-21 14:33:57 +00:00
2024-10-17 14:05:17 +00:00
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/project/variables/NON_EXISTING_VARIABLE', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
$this->assertEquals(404, $response['headers']['status-code']);
return $data;
}
/**
* @depends testGetVariable
*/
public function testUpdateVariable(array $data)
{
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PUT, '/project/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'key' => 'APP_TEST_UPDATE',
'value' => 'TESTINGVALUEUPDATED'
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE", $response['body']['key']);
$this->assertEquals("TESTINGVALUEUPDATED", $response['body']['value']);
$variable = $this->client->call(Client::METHOD_GET, '/project/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
$this->assertEquals(200, $variable['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE", $variable['body']['key']);
$this->assertEquals("TESTINGVALUEUPDATED", $variable['body']['value']);
2024-10-21 14:33:57 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/project/variables/' . $data['secretVariableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'key' => 'APP_TEST_UPDATE_1',
'value' => 'TESTINGVALUEUPDATED_1'
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE_1", $response['body']['key']);
$this->assertEmpty($response['body']['value']);
$variable = $this->client->call(Client::METHOD_GET, '/project/variables/' . $data['secretVariableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
$this->assertEquals(200, $variable['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE_1", $variable['body']['key']);
$this->assertEmpty($variable['body']['value']);
2025-02-11 12:50:54 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/project/variables/' . $data['secretVariableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'key' => 'APP_TEST_UPDATE_1',
'secret' => false,
]);
$this->assertEquals(400, $response['headers']['status-code']);
2024-10-17 18:37:44 +00:00
$response = $this->client->call(Client::METHOD_GET, '/project/variables', array_merge([
2024-10-17 14:05:17 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
2024-10-17 18:37:44 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
2024-10-21 14:33:57 +00:00
$this->assertCount(2, $response['body']['variables']);
2024-10-17 18:37:44 +00:00
$this->assertEquals("APP_TEST_UPDATE", $response['body']['variables'][0]['key']);
2024-10-21 14:33:57 +00:00
$this->assertEquals("APP_TEST_UPDATE_1", $response['body']['variables'][1]['key']);
2024-10-17 14:05:17 +00:00
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PUT, '/project/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
$this->assertEquals(400, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_PUT, '/project/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'value' => 'TESTINGVALUEUPDATED_2'
]);
$this->assertEquals(400, $response['headers']['status-code']);
$longKey = str_repeat("A", 256);
$response = $this->client->call(Client::METHOD_PUT, '/project/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'key' => $longKey,
'value' => 'TESTINGVALUEUPDATED'
]);
$this->assertEquals(400, $response['headers']['status-code']);
$longValue = str_repeat("#", 8193);
$response = $this->client->call(Client::METHOD_PUT, '/project/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'key' => 'APP_TEST_UPDATE',
'value' => $longValue
]);
$this->assertEquals(400, $response['headers']['status-code']);
2024-10-17 18:37:44 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/project/variables/NON_EXISTING_VARIABLE', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'key' => 'APP_TEST_UPDATE',
'value' => 'TESTINGVALUEUPDATED'
]);
$this->assertEquals(404, $response['headers']['status-code']);
2024-10-17 14:05:17 +00:00
return $data;
}
/**
* @depends testUpdateVariable
*/
public function testDeleteVariable(array $data)
{
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_DELETE, '/project/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
$this->assertEquals(204, $response['headers']['status-code']);
2024-10-21 14:33:57 +00:00
$this->assertEquals(204, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_DELETE, '/project/variables/' . $data['secretVariableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
2024-10-17 14:05:17 +00:00
$response = $this->client->call(Client::METHOD_GET, '/project/variables', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
2024-10-18 10:18:59 +00:00
$this->assertCount(0, $response['body']['variables']);
2024-10-17 14:05:17 +00:00
$this->assertEquals(0, $response['body']['total']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_DELETE, '/project/variables/NON_EXISTING_VARIABLE', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectId'],
'x-appwrite-mode' => 'admin',
], $this->getHeaders()));
$this->assertEquals(404, $response['headers']['status-code']);
return $data;
}
/**
* Devkeys Tests starts here ------------------------------------------------
*/
/**
2026-01-05 21:51:03 +00:00
* @group abuseEnabled
*/
public function testCreateProjectDevKey(): void
{
/**
* Test for SUCCESS
*/
$id = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testCreateProjectDevKey',
'region' => System::getEnv('_APP_REGION', 'default')
]);
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/dev-keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), 36000)
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('Key Test', $response['body']['name']);
$this->assertNotEmpty($response['body']['secret']);
$this->assertArrayHasKey('accessedAt', $response['body']);
$this->assertEmpty($response['body']['accessedAt']);
/** Create a second dev key */
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/dev-keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Dev Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), 36000)
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals('Dev Key Test', $response['body']['name']);
$this->assertNotEmpty($response['body']['secret']);
$this->assertArrayHasKey('accessedAt', $response['body']);
$this->assertEmpty($response['body']['accessedAt']);
/**
* Test for FAILURE
*/
/** TEST expiry date is required */
$res = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/dev-keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Key Test'
]);
$this->assertEquals(400, $res['headers']['status-code']);
}
/**
2026-01-05 21:51:03 +00:00
* @group abuseEnabled
*/
public function testListProjectDevKey(): void
{
/**
* Test for SUCCESS
*/
$projectId = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testListProjectDevKey',
'region' => System::getEnv('_APP_REGION', 'default')
]);
/** Create devKey 1 */
$this->setupDevKey([
'projectId' => $projectId,
'name' => 'Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), 36000)
]);
/** Create devKey 2 */
$this->setupDevKey([
'projectId' => $projectId,
'name' => 'Dev Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), 36000)
]);
/** List all dev keys */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/dev-keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(2, $response['body']['total']);
/** List dev keys with limit */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/dev-keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::limit(1)->toString()
]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(1, $response['body']['total']);
/** List dev keys with search */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/dev-keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(2, $response['body']['total']);
$this->assertEquals('Key Test', $response['body']['devKeys'][0]['name']);
$this->assertEquals('Dev Key Test', $response['body']['devKeys'][1]['name']);
/** List dev keys with querying `expire` */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/dev-keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [Query::lessThan('expire', (new \DateTime())->format('Y-m-d H:i:s'))->toString()]
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(0, $response['body']['total']); // No dev keys expired
/**
* Test for FAILURE
*/
/** Test for search with invalid query */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/dev-keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::search('name', 'Invalid')->toString()
]
]);
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertEquals('Invalid `queries` param: Invalid query: Attribute not found in schema: name', $response['body']['message']);
}
/**
2026-01-05 21:51:03 +00:00
* @group abuseEnabled
*/
public function testGetProjectDevKey(): void
{
/**
* Test for SUCCESS
*/
$projectId = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testGetProjectDevKey',
'region' => System::getEnv('_APP_REGION', 'default')
]);
$devKey = $this->setupDevKey([
'projectId' => $projectId,
'name' => 'Dev Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), 36000)
]);
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/dev-keys/' . $devKey['$id'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($devKey['$id'], $response['body']['$id']);
$this->assertEquals('Dev Key Test', $response['body']['name']);
$this->assertNotEmpty($response['body']['secret']);
$this->assertArrayHasKey('accessedAt', $response['body']);
$this->assertEmpty($response['body']['accessedAt']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/dev-keys/error', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
}
/**
2026-01-05 21:51:03 +00:00
* @group abuseEnabled
*/
public function testGetDevKeyWithSdks(): void
{
/**
* Test for SUCCESS
*/
$projectId = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testGetDevKeyWithSdks',
'region' => System::getEnv('_APP_REGION', 'default')
]);
$devKey = $this->setupDevKey([
'projectId' => $projectId,
'name' => 'Dev Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), 36000)
]);
/** Use dev key with python sdk */
$res = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $devKey['secret'],
'x-sdk-name' => 'python'
], [
'email' => 'user@appwrite.io',
'password' => 'password'
]);
$this->assertEquals(401, $res['headers']['status-code']);
/** Use dev key with php sdk */
$res = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $devKey['secret'],
'x-sdk-name' => 'php'
], [
'email' => 'user@appwrite.io',
'password' => 'password'
]);
$this->assertEquals(401, $res['headers']['status-code']);
/** Get the dev key */
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/dev-keys/' . $devKey['$id'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertArrayHasKey('sdks', $response['body']);
$this->assertCount(2, $response['body']['sdks']);
$this->assertContains('python', $response['body']['sdks']);
$this->assertContains('php', $response['body']['sdks']);
}
/**
2026-01-05 21:51:03 +00:00
* @group abuseEnabled
*/
public function testNoHostValidationWithDevKey(): void
{
/**
* Test for SUCCESS
*/
$projectId = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testNoHostValidationWithDevKey',
'region' => System::getEnv('_APP_REGION', 'default')
]);
$devKey = $this->setupDevKey([
'projectId' => $projectId,
'name' => 'Dev Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), 36000)
]);
$provider = 'mock';
$appId = '1';
$secret = '123456';
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId . '/oauth2', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'provider' => $provider,
'appId' => $appId,
'secret' => $secret,
'enabled' => true,
]);
$this->assertEquals(200, $response['headers']['status-code']);
/** Test oauth2 and get invalid `success` URL */
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/oauth2/' . $provider, [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
], [
'success' => 'https://example.com',
'failure' => 'https://example.com'
]);
$this->assertEquals(400, $response['headers']['status-code']);
2026-02-16 16:18:58 +00:00
/** Test oauth2 with devKey and now flow works with untrusted URL too */
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/oauth2/' . $provider, [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $devKey['secret']
], [
'success' => 'https://example.com',
'failure' => 'https://example.com'
2026-02-16 16:06:11 +00:00
], followRedirects: false);
2026-02-16 16:18:58 +00:00
$this->assertEquals(301, $response['headers']['status-code']);
$this->assertArrayHasKey('location', $response['headers']);
$location = $response['headers']['location'];
$locationClient = new Client();
$locationClient->setEndpoint('');
$locationClient->addHeader('x-appwrite-dev-key', $devKey['secret']);
$response = $locationClient->call(Client::METHOD_GET, $location, followRedirects: false);
$this->assertEquals(301, $response['headers']['status-code']);
$this->assertArrayHasKey('location', $response['headers']);
$location = $response['headers']['location'];
$this->assertStringStartsWith('http://appwrite:/v1/account/sessions/oauth2/callback/mock/', $response['headers']['location']);
$response = $locationClient->call(Client::METHOD_GET, $location, followRedirects: false);
$this->assertEquals(301, $response['headers']['status-code']);
$this->assertArrayHasKey('location', $response['headers']);
$location = $response['headers']['location'];
$this->assertStringStartsWith('http://appwrite:/v1/account/sessions/oauth2/mock/redirect', $response['headers']['location']);
$response = $locationClient->call(Client::METHOD_GET, $location, followRedirects: false);
2026-02-16 16:06:11 +00:00
$this->assertEquals(301, $response['headers']['status-code']);
2026-02-16 16:18:58 +00:00
$this->assertSame('https://example.com/#', $response['headers']['location']);
2026-02-08 13:44:21 +00:00
/** Ensure any hostname is allowed */
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/oauth2/' . $provider, [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $devKey['secret'],
'origin' => '',
'referer' => 'https://domain-without-rule.com'
], [
'success' => 'https://domain-without-rule.com',
'failure' => 'https://domain-without-rule.com'
], followRedirects: false);
$this->assertEquals(301, $response['headers']['status-code']);
2026-02-08 13:47:47 +00:00
2026-02-08 13:44:21 +00:00
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/oauth2/' . $provider, [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $devKey['secret'],
'referer' => '',
'origin' => 'https://domain-without-rule.com'
], [
'success' => 'https://domain-without-rule.com',
'failure' => 'https://domain-without-rule.com'
], followRedirects: false);
$this->assertEquals(301, $response['headers']['status-code']);
/** Test hostname in Magic URL */
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
], [
'userId' => ID::unique(),
'email' => 'user@appwrite.io',
'url' => 'https://example.com',
]);
$this->assertEquals(400, $response['headers']['status-code']);
/** Test hostname in Magic URL with devKey */
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $devKey['secret']
], [
'userId' => ID::unique(),
'email' => 'user@appwrite.io',
'url' => 'https://example.com',
]);
$this->assertEquals(201, $response['headers']['status-code']);
}
public function testRuleOAuthRedirect(): void
{
// Prepare project
$projectId = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testRuleOAuthRedirect',
'region' => System::getEnv('_APP_REGION', 'default')
]);
$provider = 'mock';
$appId = '1';
$secret = '123456';
// Prepare OAuth provider
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId . '/oauth2', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'provider' => $provider,
'appId' => $appId,
'secret' => $secret,
'enabled' => true,
]);
$this->assertEquals(200, $response['headers']['status-code']);
// Prepare rule. In reality this is site rule, but for testing, API rule is enough, and faster to prepare
$domain = \uniqid() . '-with-rule.custom.localhost';
$rule = $this->client->call(Client::METHOD_POST, '/proxy/rules/api', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'domain' => $domain
]);
$this->assertEquals(201, $rule['headers']['status-code']);
// Ensure unknown domain cannot be redirect URL
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/oauth2/' . $provider, [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'referer' => 'https://' . $domain,
2026-02-08 13:44:21 +00:00
'origin' => '',
], [
'success' => 'https://domain-without-rule.com',
'failure' => 'https://domain-without-rule.com'
], followRedirects: false);
$this->assertEquals(400, $response['headers']['status-code']);
2026-02-09 12:57:19 +00:00
// Also ensure final step blocks unknown redirect URL
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/oauth2/' . $provider . '/redirect', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'origin' => '',
'referer' => 'https://mockserver.com',
], [
'code' => 'any-code',
'state' => \json_encode([
'success' => 'https://domain-without-rule.com',
'failure' => 'https://domain-without-rule.com'
]),
'error' => '',
2026-02-09 16:10:00 +00:00
'error_description' => '',
2026-02-09 12:57:19 +00:00
], followRedirects: false);
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertStringContainsString('project_invalid_success_url', $response['body']);
// Ensure rule's domain can be redirect URL
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/oauth2/' . $provider, [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'referer' => 'https://' . $domain,
2026-02-08 13:44:21 +00:00
'origin' => '',
], [
'success' => 'https://' . $domain,
'failure' => 'https://' . $domain
], followRedirects: false);
$this->assertEquals(301, $response['headers']['status-code']);
2026-02-09 12:57:19 +00:00
// Also ensure final step allows redirect URL
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/oauth2/' . $provider . '/redirect', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'origin' => '',
'referer' => 'https://mockserver.com',
], [
'code' => 'any-code',
'state' => \json_encode([
2026-02-09 13:34:52 +00:00
'success' => 'https://' . $domain,
'failure' => 'https://' . $domain
2026-02-09 12:57:19 +00:00
]),
'error' => '',
2026-02-09 16:10:00 +00:00
'error_deescription' => '',
2026-02-09 12:57:19 +00:00
], followRedirects: false);
$this->assertEquals(301, $response['headers']['status-code']);
$this->assertStringContainsString('https://' . $domain, $response['headers']['location']);
// Ensure unknown domain cannot be redirect URL
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'referer' => 'https://' . $domain,
2026-02-08 13:44:21 +00:00
'origin' => '',
], [
'userId' => ID::unique(),
'email' => 'user@appwrite.io',
'url' => 'https://domain-without-rule.com',
]);
$this->assertEquals(400, $response['headers']['status-code']);
// Ensure rule's domain can be redirect URL
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'referer' => 'https://' . $domain,
2026-02-08 13:44:21 +00:00
'origin' => '',
], [
'userId' => ID::unique(),
'email' => 'user@appwrite.io',
'url' => 'https://' . $domain,
]);
$this->assertEquals(201, $response['headers']['status-code']);
}
2026-02-11 04:41:04 +00:00
public function testOAuthRedirectWithCustomSchemeState(): void
{
// Prepare project
$projectId = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testOAuthRedirectWithCustomSchemeState',
'region' => System::getEnv('_APP_REGION', 'default')
]);
$provider = 'mock';
$appId = '1';
$secret = '123456';
// Prepare OAuth provider
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId . '/oauth2', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'provider' => $provider,
'appId' => $appId,
'secret' => $secret,
'enabled' => true,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$scheme = 'appwrite-callback-' . $projectId;
$state = \json_encode([
'success' => $scheme . ':///',
'failure' => $scheme . ':///'
]);
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/oauth2/' . $provider . '/redirect', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'origin' => '',
'referer' => '',
], [
'code' => 'any-code',
'state' => $state,
'error' => 'access_denied',
'error_description' => 'test',
], followRedirects: false);
$this->assertEquals(301, $response['headers']['status-code']);
$this->assertStringStartsWith($scheme . '://', $response['headers']['location']);
$this->assertStringContainsString('error=', $response['headers']['location']);
}
/**
2026-01-05 21:51:03 +00:00
* @group abuseEnabled
*/
public function testCorsWithDevKey(): void
{
/**
* Test for SUCCESS
*/
$projectId = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testCorsWithDevKey',
'region' => System::getEnv('_APP_REGION', 'default')
]);
$devKey = $this->setupDevKey([
'projectId' => $projectId,
'name' => 'Dev Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), 36000)
]);
$origin = 'http://example.com';
/**
* Test CORS without Dev Key (should fail due to origin)
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'origin' => $origin,
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
], [
'email' => 'user@appwrite.io',
'password' => 'password'
]);
$this->assertEquals(403, $response['headers']['status-code']);
$this->assertNotEquals($origin, $response['headers']['access-control-allow-origin'] ?? null);
2025-12-07 20:29:45 +00:00
// you should not return a fallback origin for a disallowed host
$this->assertNull($response['headers']['access-control-allow-origin'] ?? null);
/**
* Test CORS with Dev Key (should bypass origin check)
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'origin' => $origin,
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $devKey['secret']
], [
'email' => 'user@appwrite.io',
'password' => 'password'
]);
$this->assertEquals(401, $response['headers']['status-code']);
2025-12-07 20:29:45 +00:00
$this->assertEquals($origin, $response['headers']['access-control-allow-origin'] ?? null);
}
2026-02-04 13:45:38 +00:00
public function testConsoleCorsWithTrustedProject(): void
{
$trustedProjectIds = ['trusted-project', 'another-trusted-project']; // Set in env variable
$projectIds = \array_merge($trustedProjectIds, ['untrusted-project-id']);
foreach ($projectIds as $projectId) {
try {
// Create project
$this->setupProject([
'projectId' => $projectId,
'name' => 'Trusted project',
'region' => System::getEnv('_APP_REGION', 'default')
]);
// Add domain to trusted project; API for simplicity, in real work this will be site
$domain = \uniqid() . '.custom.localhost';
$rule = $this->client->call(Client::METHOD_POST, '/proxy/rules/api', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'domain' => $domain
]);
$this->assertEquals(201, $rule['headers']['status-code']);
// Talk to Console APIs from trusted project domain
$currencies = $this->client->call(
Client::METHOD_GET,
'/locale/currencies',
array_merge(
$this->getHeaders(),
[
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
'origin' => 'http://' . $domain
]
)
);
if (\in_array($projectId, $trustedProjectIds)) {
// Trusted projects can
2026-02-04 14:09:02 +00:00
$this->assertEquals(200, $currencies['headers']['status-code']);
2026-02-04 13:45:38 +00:00
$this->assertSame('http://' . $domain, $currencies['headers']['access-control-allow-origin']);
} else {
// Untrusted projects cannot
2026-02-04 14:09:02 +00:00
$this->assertEquals(403, $currencies['headers']['status-code']);
2026-02-04 13:45:38 +00:00
$this->assertArrayNotHasKey('access-control-allow-origin', $currencies['headers']);
}
} finally {
// Cleanup
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
}
}
}
/**
2026-01-05 21:51:03 +00:00
* @group abuseEnabled
*/
public function testNoRateLimitWithDevKey(): void
{
/**
* Test for SUCCESS
*/
$projectId = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testNoRateLimitWithDevKey',
'region' => System::getEnv('_APP_REGION', 'default')
]);
$devKey = $this->setupDevKey([
'projectId' => $projectId,
'name' => 'Dev Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), 36000)
]);
/**
* Test for SUCCESS
*/
for ($i = 0; $i < 10; $i++) {
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
], [
'email' => 'user@appwrite.io',
'password' => 'password'
]);
$this->assertEquals(401, $response['headers']['status-code']);
}
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
], [
'email' => 'user@appwrite.io',
'password' => 'password'
]);
$this->assertEquals(429, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $devKey['secret']
], [
'email' => 'user@appwrite.io',
'password' => 'password'
]);
$this->assertEquals(401, $response['headers']['status-code']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $projectId . '/dev-keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), -3600),
]);
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $response['body']['secret']
], [
'email' => 'user@appwrite.io',
'password' => 'password'
]);
$this->assertEquals(429, $response['headers']['status-code']);
/**
* Test for FAILURE after expire
*/
$devKey = $this->setupDevKey([
'projectId' => $projectId,
'name' => 'Dev Key Test Expire 5 seconds',
'expire' => DateTime::addSeconds(new \DateTime(), 5)
]);
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $devKey['secret']
], [
'email' => 'user@appwrite.io',
'password' => 'password'
]);
$this->assertEquals(401, $response['headers']['status-code']);
sleep(5);
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $devKey['secret']
], [
'email' => 'user@appwrite.io',
'password' => 'password'
]);
$this->assertEquals(429, $response['headers']['status-code']);
}
/**
2026-01-05 21:51:03 +00:00
* @group abuseEnabled
*/
public function testUpdateProjectDevKey(): void
{
$projectId = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testUpdateProjectDevKey',
'region' => System::getEnv('_APP_REGION', 'default')
]);
$devKey = $this->setupDevKey([
'projectId' => $projectId,
'name' => 'Dev Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), 36000)
]);
$response = $this->client->call(Client::METHOD_PUT, '/projects/' . $projectId . '/dev-keys/' . $devKey['$id'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Key Test Update',
'expire' => DateTime::addSeconds(new \DateTime(), 360),
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($devKey['$id'], $response['body']['$id']);
$this->assertEquals('Key Test Update', $response['body']['name']);
$this->assertArrayHasKey('accessedAt', $response['body']);
$this->assertEmpty($response['body']['accessedAt']);
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/dev-keys/' . $devKey['$id'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($devKey['$id'], $response['body']['$id']);
$this->assertEquals('Key Test Update', $response['body']['name']);
$this->assertArrayHasKey('accessedAt', $response['body']);
$this->assertEmpty($response['body']['accessedAt']);
}
/**
2026-01-05 21:51:03 +00:00
* @group abuseEnabled
*/
public function testDeleteProjectDevKey(): void
{
$projectId = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'testDeleteProjectDevKey',
'region' => System::getEnv('_APP_REGION', 'default')
]);
$devKey = $this->setupDevKey([
'projectId' => $projectId,
'name' => 'Dev Key Test',
'expire' => DateTime::addSeconds(new \DateTime(), 36000)
]);
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $projectId . '/dev-keys/' . $devKey['$id'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
/**
* Get rate limit trying to use the deleted key
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-dev-key' => $devKey['secret']
], [
'email' => 'user@appwrite.io',
'password' => 'password'
]);
$this->assertEquals(429, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/dev-keys/' . $devKey['$id'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $projectId . '/dev-keys/error', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(404, $response['headers']['status-code']);
}
/**
* Devkeys Tests ends here ------------------------------------------------
*/
2025-12-31 14:44:18 +00:00
public function testProjectLabels(): void
{
// Setup: Prepare team
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'teamId' => ID::unique(),
'name' => 'Query Select Test Team',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$teamId = $team['body']['$id'];
// Setup: Prepare project
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Test project - Labels 1',
'teamId' => $teamId,
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $project['headers']['status-code']);
$this->assertIsArray($project['body']['labels']);
$this->assertCount(0, $project['body']['labels']);
$projectId = $project['body']['$id'];
// Apply labels
$project = $this->client->call(Client::METHOD_PUT, '/projects/' . $projectId . '/labels', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'labels' => ['vip', 'imagine', 'blocked']
]);
$this->assertEquals(200, $project['headers']['status-code']);
$this->assertIsArray($project['body']['labels']);
$this->assertCount(3, $project['body']['labels']);
$this->assertEquals('vip', $project['body']['labels'][0]);
$this->assertEquals('imagine', $project['body']['labels'][1]);
$this->assertEquals('blocked', $project['body']['labels'][2]);
// Update labels
$project = $this->client->call(Client::METHOD_PUT, '/projects/' . $projectId . '/labels', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'labels' => ['nonvip', 'imagine']
]);
$this->assertEquals(200, $project['headers']['status-code']);
$this->assertIsArray($project['body']['labels']);
$this->assertCount(2, $project['body']['labels']);
$this->assertEquals('nonvip', $project['body']['labels'][0]);
$this->assertEquals('imagine', $project['body']['labels'][1]);
// Filter by labels
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['nonvip'])->toString(),
]
]);
2026-01-05 13:42:03 +00:00
$this->assertEquals(200, $projects['headers']['status-code']);
2025-12-31 14:44:18 +00:00
$this->assertEquals(1, $projects['body']['total']);
$this->assertEquals($projectId, $projects['body']['projects'][0]['$id']);
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['vip'])->toString(),
]
]);
2026-01-05 13:42:03 +00:00
$this->assertEquals(200, $projects['headers']['status-code']);
2025-12-31 14:44:18 +00:00
$this->assertEquals(0, $projects['body']['total']);
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['imagine'])->toString(),
]
]);
2026-01-05 13:42:03 +00:00
$this->assertEquals(200, $projects['headers']['status-code']);
2025-12-31 14:44:18 +00:00
$this->assertEquals(1, $projects['body']['total']);
$this->assertEquals($projectId, $projects['body']['projects'][0]['$id']);
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['nonvip', 'imagine'])->toString(),
]
]);
2026-01-05 13:42:03 +00:00
$this->assertEquals(200, $projects['headers']['status-code']);
2025-12-31 14:44:18 +00:00
$this->assertEquals(1, $projects['body']['total']);
$this->assertEquals($projectId, $projects['body']['projects'][0]['$id']);
// Setup: Second project with only imagine label
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Test project - Labels 2',
'teamId' => $teamId,
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $project['headers']['status-code']);
$this->assertIsArray($project['body']['labels']);
$this->assertCount(0, $project['body']['labels']);
$projectId2 = $project['body']['$id'];
$project = $this->client->call(Client::METHOD_PUT, '/projects/' . $projectId2 . '/labels', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'labels' => ['vip', 'imagine']
]);
$this->assertEquals(200, $project['headers']['status-code']);
$this->assertIsArray($project['body']['labels']);
$this->assertCount(2, $project['body']['labels']);
$this->assertEquals('vip', $project['body']['labels'][0]);
$this->assertEquals('imagine', $project['body']['labels'][1]);
// List of imagine has both
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['imagine'])->toString(),
]
]);
2026-01-05 13:42:03 +00:00
$this->assertEquals(200, $projects['headers']['status-code']);
2025-12-31 14:44:18 +00:00
$this->assertEquals(2, $projects['body']['total']);
$this->assertEquals($projectId, $projects['body']['projects'][0]['$id']);
$this->assertEquals($projectId2, $projects['body']['projects'][1]['$id']);
// List of vip only has second
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['vip'])->toString(),
]
]);
2026-01-05 13:42:03 +00:00
$this->assertEquals(200, $projects['headers']['status-code']);
2025-12-31 14:44:18 +00:00
$this->assertEquals(1, $projects['body']['total']);
$this->assertEquals($projectId2, $projects['body']['projects'][0]['$id']);
// List of vip and imagine has second
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['vip'])->toString(),
Query::contains('labels', ['imagine'])->toString(),
]
]);
2026-01-05 13:42:03 +00:00
$this->assertEquals(200, $projects['headers']['status-code']);
2025-12-31 14:44:18 +00:00
$this->assertEquals(1, $projects['body']['total']);
$this->assertEquals($projectId2, $projects['body']['projects'][0]['$id']);
// List of vip or imagine has second
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['vip', 'imagine'])->toString(),
]
]);
2026-01-05 13:42:03 +00:00
$this->assertEquals(200, $projects['headers']['status-code']);
2025-12-31 14:44:18 +00:00
$this->assertEquals(2, $projects['body']['total']);
$this->assertEquals($projectId, $projects['body']['projects'][0]['$id']);
$this->assertEquals($projectId2, $projects['body']['projects'][1]['$id']);
// Cleanup
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(204, $response['headers']['status-code']);
2026-01-05 13:42:03 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $projectId2, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(204, $response['headers']['status-code']);
2025-12-31 14:44:18 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/teams/' . $teamId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(204, $response['headers']['status-code']);
}
/**
* @group ciIgnore
*/
public function testProjectSpecificPermissionsForListProjects(): void
{
$teamId = ID::unique();
$projectIdA = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'Project Test A',
], $teamId);
$projectIdB = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'Project Test B',
], $teamId, false);
$testUserEmail = 'test-' . ID::unique() . '@localhost.test';
$testUserName = 'Test User';
[ 'membershipId' => $testUserMembershipId ] = $this->setupUserMembership([
'teamId' => $teamId,
'email' => $testUserEmail,
'name' => $testUserName,
'roles' => ["owner"],
]);
$testCases = [
[
'roles' => ["owner"],
'successProjectIds' => [$projectIdA, $projectIdB],
],
[
'roles' => ["developer"],
'successProjectIds' => [$projectIdA, $projectIdB],
],
[
'roles' => ["project-$projectIdA-owner"],
'successProjectIds' => [$projectIdA],
],
[
'roles' => ["project-$projectIdB-owner"],
'successProjectIds' => [$projectIdB],
],
[
'roles' => ["project-$projectIdA-developer"],
'successProjectIds' => [$projectIdA],
],
[
'roles' => ["project-$projectIdB-developer"],
'successProjectIds' => [$projectIdB],
],
[
'roles' => ["developer", "project-$projectIdA-owner"],
'successProjectIds' => [$projectIdA, $projectIdB],
]
];
// Setup session
$session = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], [
'email' => $testUserEmail,
'password' => 'password',
]);
$token = $session['cookies']['a_session_' . $this->getProject()['$id']];
foreach ($testCases as $testCase) {
$this->updateMembershipRole($teamId, $testUserMembershipId, $testCase['roles']);
$response = $this->client->call(Client::METHOD_GET, '/projects', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertCount(\count($testCase['successProjectIds']), $response['body']['projects']);
$returnedProjectIds = \array_column($response['body']['projects'], '$id');
foreach ($testCase['successProjectIds'] as $projectId) {
$this->assertContains($projectId, $returnedProjectIds);
}
}
}
/**
* @group ciIgnore
*/
public function testProjectSpecificPermissionsForUpdateProject(): void
{
$teamId = ID::unique();
$projectIdA = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'Project Test A',
], $teamId);
$projectIdB = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'Project Test B',
], $teamId, false);
$testUserEmail = 'test-' . ID::unique() . '@localhost.test';
$testUserName = 'Test User';
[ 'membershipId' => $testUserMembershipId ] = $this->setupUserMembership([
'teamId' => $teamId,
'email' => $testUserEmail,
'name' => $testUserName,
'roles' => ["owner"],
]);
$testCases = [
[
'roles' => ["owner"],
'successProjectIds' => [$projectIdA, $projectIdB],
'failureProjectIds' => [],
],
[
'roles' => ["developer"],
'successProjectIds' => [$projectIdA, $projectIdB],
'failureProjectIds' => [],
],
[
'roles' => ["project-$projectIdA-owner"],
'successProjectIds' => [$projectIdA],
'failureProjectIds' => [$projectIdB],
],
[
'roles' => ["project-$projectIdB-owner"],
'successProjectIds' => [$projectIdB],
'failureProjectIds' => [$projectIdA],
],
[
'roles' => ["project-$projectIdA-developer"],
'successProjectIds' => [$projectIdA],
'failureProjectIds' => [$projectIdB],
],
[
'roles' => ["project-$projectIdB-developer"],
'successProjectIds' => [$projectIdB],
'failureProjectIds' => [$projectIdA],
],
[
'roles' => ["developer", "project-$projectIdA-owner"],
'successProjectIds' => [$projectIdA, $projectIdB],
'failureProjectIds' => [],
]
];
// Setup session
$session = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], [
'email' => $testUserEmail,
'password' => 'password',
]);
$token = $session['cookies']['a_session_' . $this->getProject()['$id']];
foreach ($testCases as $testCase) {
$this->updateMembershipRole($teamId, $testUserMembershipId, $testCase['roles']);
foreach ($testCase['successProjectIds'] as $projectId) {
$newProjectName = 'Updated Project Name ' . ID::unique();
// Success: User should be able to update the project they have access to.
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId, [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
], [
'name' => $newProjectName,
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$this->assertEquals($newProjectName, $response['body']['name']);
}
foreach ($testCase['failureProjectIds'] as $projectId) {
$newProjectName = 'Updated Project Name ' . ID::unique();
// Failure: User should not be able to update the project they do not have access to.
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId, [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
], [
'name' => $newProjectName,
]);
$this->assertTrue($response['headers']['status-code'] === 401 || $response['headers']['status-code'] === 404);
}
}
}
/**
* @group ciIgnore
*/
public function testProjectSpecificPermissionsForDeleteProject(): void
{
$teamId = ID::unique();
$projectIdA = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'Project Test A',
], $teamId);
$projectIdB = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'Project Test B',
], $teamId, false);
$projectIdC = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'Project Test C',
], $teamId, false);
$projectIdD = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'Project Test D',
], $teamId, false);
$projectIdE = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'Project Test E',
], $teamId, false);
$testUserEmail = 'test-' . ID::unique() . '@localhost.test';
$testUserName = 'Test User';
[ 'membershipId' => $testUserMembershipId ] = $this->setupUserMembership([
'teamId' => $teamId,
'email' => $testUserEmail,
'name' => $testUserName,
'roles' => ["owner"],
]);
$testCases = [
[
'roles' => ["owner"],
'successProjectIds' => [$projectIdA],
'failureProjectIds' => [],
],
[
'roles' => ["developer"],
'successProjectIds' => [$projectIdB, $projectIdC],
'failureProjectIds' => [],
],
[
'roles' => ["project-$projectIdD-owner"],
'successProjectIds' => [$projectIdD],
'failureProjectIds' => [$projectIdE],
],
[
'roles' => ["project-$projectIdE-owner"],
'successProjectIds' => [$projectIdE],
'failureProjectIds' => [],
],
];
// Setup session
$session = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], [
'email' => $testUserEmail,
'password' => 'password',
]);
$token = $session['cookies']['a_session_' . $this->getProject()['$id']];
foreach ($testCases as $testCase) {
$this->updateMembershipRole($teamId, $testUserMembershipId, $testCase['roles']);
foreach ($testCase['successProjectIds'] as $projectId) {
// Success: User should be able to delete the project they have access to.
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $projectId, [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
]);
$this->assertEquals(204, $response['headers']['status-code']);
}
foreach ($testCase['failureProjectIds'] as $projectId) {
// Failure: User should not be able to delete the project they do not have access to.
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $projectId, [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
]);
$this->assertTrue($response['headers']['status-code'] === 401 || $response['headers']['status-code'] === 404);
}
}
}
/**
* @group ciIgnore
* Test project specific permissions for project resources, in this case 'function variables'.
*/
public function testProjectSpecificPermissionsForProjectResources(): void
{
$teamId = ID::unique();
$projectIdA = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'Project Test A',
], $teamId);
$projectIdB = $this->setupProject([
'projectId' => ID::unique(),
'name' => 'Project Test B',
], $teamId, false);
$testUserEmail = 'test-' . ID::unique() . '@localhost.test';
$testUserName = 'Test User';
[ 'membershipId' => $testUserMembershipId ] = $this->setupUserMembership([
'teamId' => $teamId,
'email' => $testUserEmail,
'name' => $testUserName,
'roles' => ["owner"],
]);
$testCases = [
[
'roles' => ["owner"],
'successProjectIds' => [$projectIdA, $projectIdB],
'failureProjectIds' => [],
],
[
'roles' => ["developer"],
'successProjectIds' => [$projectIdA, $projectIdB],
'failureProjectIds' => [],
],
[
'roles' => ["project-$projectIdA-owner"],
'successProjectIds' => [$projectIdA],
'failureProjectIds' => [$projectIdB],
],
[
'roles' => ["project-$projectIdB-owner"],
'successProjectIds' => [$projectIdB],
'failureProjectIds' => [$projectIdA],
],
[
'roles' => ["project-$projectIdA-developer"],
'successProjectIds' => [$projectIdA],
'failureProjectIds' => [$projectIdB],
],
[
'roles' => ["project-$projectIdB-developer"],
'successProjectIds' => [$projectIdB],
'failureProjectIds' => [$projectIdA],
],
[
'roles' => ["developer", "project-$projectIdA-owner"],
'successProjectIds' => [$projectIdA, $projectIdB],
'failureProjectIds' => [],
]
];
// Setup session
$session = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], [
'email' => $testUserEmail,
'password' => 'password',
]);
$token = $session['cookies']['a_session_' . $this->getProject()['$id']];
// Setup functions
$functionId = ID::unique();
$this->setupFunction($projectIdA, $functionId, $token);
$this->setupFunction($projectIdB, $functionId, $token);
foreach ($testCases as $testCase) {
$this->updateMembershipRole($teamId, $testUserMembershipId, $testCase['roles']);
foreach ($testCase['successProjectIds'] as $projectId) {
$variableId = ID::unique();
$response = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-mode' => 'admin',
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
], [
'key' => 'APP_TEST_' . $variableId,
'value' => 'TESTINGVALUE',
'secret' => false
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertEquals('APP_TEST_' . $variableId, $response['body']['key']);
$this->assertEquals('TESTINGVALUE', $response['body']['value']);
}
foreach ($testCase['failureProjectIds'] as $projectId) {
$variableId = ID::unique();
$response = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-mode' => 'admin',
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
], [
'key' => 'APP_TEST_' . $variableId,
'value' => 'TESTINGVALUE',
'secret' => false
]);
$this->assertTrue($response['headers']['status-code'] === 401 || $response['headers']['status-code'] === 404);
}
}
}
2020-07-11 19:40:58 +00:00
}