Merge pull request #12276 from appwrite/feat-rework-project-response-model

Feat: Rework project response model
This commit is contained in:
Matej Bačo
2026-05-12 12:57:16 +02:00
committed by GitHub
34 changed files with 813 additions and 408 deletions
-34
View File
@@ -2,9 +2,6 @@
use Appwrite\Auth\Validator\MockNumber;
use Appwrite\Extend\Exception;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response;
use Utopia\Config\Config;
use Utopia\Database\Database;
@@ -27,37 +24,6 @@ Http::init()
}
});
Http::get('/v1/projects/:projectId')
->desc('Get project')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk', new Method(
namespace: 'projects',
group: 'projects',
name: 'get',
description: '/docs/references/projects/get.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
]
))
->param('projectId', '', fn (Database $dbForPlatform) => new UID($dbForPlatform->getAdapter()->getMaxUIDLength()), 'Project unique ID.', false, ['dbForPlatform'])
->inject('response')
->inject('dbForPlatform')
->action(function (string $projectId, Response $response, Database $dbForPlatform) {
$project = $dbForPlatform->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$response->dynamic($project, Response::MODEL_PROJECT);
});
// Backwards compatibility
Http::patch('/v1/projects/:projectId/oauth2')
->desc('Update project OAuth2')
+8
View File
@@ -29,6 +29,7 @@ use Appwrite\Utopia\Request\Filters\V22 as RequestV22;
use Appwrite\Utopia\Request\Filters\V23 as RequestV23;
use Appwrite\Utopia\Request\Filters\V24 as RequestV24;
use Appwrite\Utopia\Request\Filters\V25 as RequestV25;
use Appwrite\Utopia\Request\Filters\V26 as RequestV26;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Filters\V16 as ResponseV16;
use Appwrite\Utopia\Response\Filters\V17 as ResponseV17;
@@ -40,6 +41,7 @@ use Appwrite\Utopia\Response\Filters\V22 as ResponseV22;
use Appwrite\Utopia\Response\Filters\V23 as ResponseV23;
use Appwrite\Utopia\Response\Filters\V24 as ResponseV24;
use Appwrite\Utopia\Response\Filters\V25 as ResponseV25;
use Appwrite\Utopia\Response\Filters\V26 as ResponseV26;
use Appwrite\Utopia\View;
use Executor\Exception\Timeout as ExecutorTimeout;
use Executor\Executor;
@@ -914,6 +916,9 @@ Http::init()
if (version_compare($requestFormat, '1.9.4', '<')) {
$request->addFilter(new RequestV25());
}
if (version_compare($requestFormat, '1.9.5', '<')) {
$request->addFilter(new RequestV26());
}
}
$localeParam = (string) $request->getParam('locale', $request->getHeader('x-appwrite-locale', ''));
@@ -938,6 +943,9 @@ Http::init()
*/
$responseFormat = $request->getHeader('x-appwrite-response-format', System::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', ''));
if ($responseFormat) {
if (version_compare($responseFormat, '1.9.5', '<')) {
$response->addFilter(new ResponseV26());
}
if (version_compare($responseFormat, '1.9.4', '<')) {
$response->addFilter(new ResponseV25());
}
+1 -1
View File
@@ -45,7 +45,7 @@ const APP_RESOURCE_TOKEN_ACCESS = 24 * 60 * 60; // 24 hours
const APP_FILE_ACCESS = 24 * 60 * 60; // 24 hours
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
const APP_CACHE_BUSTER = 4325;
const APP_VERSION_STABLE = '1.9.4';
const APP_VERSION_STABLE = '1.9.5';
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
const APP_DATABASE_ATTRIBUTE_IP = 'ip';
+6
View File
@@ -173,6 +173,9 @@ use Appwrite\Utopia\Response\Model\PolicySessionLimit;
use Appwrite\Utopia\Response\Model\PolicyUserLimit;
use Appwrite\Utopia\Response\Model\Preferences;
use Appwrite\Utopia\Response\Model\Project;
use Appwrite\Utopia\Response\Model\ProjectAuthMethod;
use Appwrite\Utopia\Response\Model\ProjectProtocol;
use Appwrite\Utopia\Response\Model\ProjectService;
use Appwrite\Utopia\Response\Model\Provider;
use Appwrite\Utopia\Response\Model\ProviderRepository;
use Appwrite\Utopia\Response\Model\ProviderRepositoryFramework;
@@ -397,6 +400,9 @@ Response::setModel(new FrameworkAdapter());
Response::setModel(new Deployment());
Response::setModel(new Execution());
Response::setModel(new Project());
Response::setModel(new ProjectAuthMethod());
Response::setModel(new ProjectService());
Response::setModel(new ProjectProtocol());
Response::setModel(new Webhook());
Response::setModel(new Key());
Response::setModel(new EphemeralKey());
+1 -1
View File
@@ -255,7 +255,7 @@ services:
appwrite-console:
<<: *x-logging
container_name: appwrite-console
image: appwrite/console:7.8.45
image: appwrite/console:8
restart: unless-stopped
networks:
- appwrite
+1
View File
@@ -97,6 +97,7 @@ abstract class Migration
'1.9.2' => 'V24',
'1.9.3' => 'V24',
'1.9.4' => 'V24',
'1.9.5' => 'V24',
];
/**
@@ -0,0 +1,64 @@
<?php
namespace Appwrite\Platform\Modules\Project\Http\Project;
use Appwrite\Extend\Exception;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response;
use Utopia\Database\Document;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
class Get extends Action
{
use HTTP;
public static function getName()
{
return 'getProject';
}
public function __construct()
{
$this
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
->setHttpPath('/v1/project')
->httpAlias('/v1/projects/:projectId')
->desc('Get project')
->groups(['api', 'project'])
->label('scope', 'project.read')
->label('sdk', new Method(
namespace: 'project',
group: null,
name: 'get',
description: <<<EOT
Get a project.
EOT,
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
],
contentType: ContentType::NONE
))
->inject('response')
->inject('project')
->callback($this->action(...));
}
public function action(
Response $response,
Document $project,
) {
if ($project->isEmpty()) {
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$response->dynamic($project, Response::MODEL_PROJECT);
}
}
@@ -5,6 +5,7 @@ namespace Appwrite\Platform\Modules\Project\Services;
use Appwrite\Platform\Modules\Project\Http\Init;
use Appwrite\Platform\Modules\Project\Http\Project\AuthMethods\Update as UpdateAuthMethod;
use Appwrite\Platform\Modules\Project\Http\Project\Delete as DeleteProject;
use Appwrite\Platform\Modules\Project\Http\Project\Get as GetProject;
use Appwrite\Platform\Modules\Project\Http\Project\Keys\Create as CreateKey;
use Appwrite\Platform\Modules\Project\Http\Project\Keys\Delete as DeleteKey;
use Appwrite\Platform\Modules\Project\Http\Project\Keys\Ephemeral\Create as CreateEphemeralKey;
@@ -110,6 +111,7 @@ class Http extends Service
// Project
$this->addAction(DeleteProject::getName(), new DeleteProject());
$this->addAction(GetProject::getName(), new GetProject());
$this->addAction(UpdateProjectLabels::getName(), new UpdateProjectLabels());
$this->addAction(UpdateProjectProtocol::getName(), new UpdateProjectProtocol());
$this->addAction(UpdateProjectService::getName(), new UpdateProjectService());
@@ -28,7 +28,6 @@ use Utopia\Pools\Group;
use Utopia\System\System;
use Utopia\Validator;
use Utopia\Validator\Text;
use Utopia\Validator\URL;
use Utopia\Validator\WhiteList;
class Create extends Action
@@ -72,15 +71,6 @@ class Create extends Action
->param('name', null, new Text(128), 'Project name. Max length: 128 chars.')
->param('teamId', '', new UID(), 'Team unique ID.')
->param('region', System::getEnv('_APP_REGION', 'default'), new WhiteList(array_keys(array_filter(Config::getParam('regions'), fn ($config) => !$config['disabled']))), 'Project Region.', true)
->param('description', '', new Text(256), 'Project description. Max length: 256 chars.', true)
->param('logo', '', new Text(1024), 'Project logo.', true)
->param('url', '', new URL(), 'Project URL.', true)
->param('legalName', '', new Text(256), 'Project legal Name. Max length: 256 chars.', true)
->param('legalCountry', '', new Text(256), 'Project legal Country. Max length: 256 chars.', true)
->param('legalState', '', new Text(256), 'Project legal State. Max length: 256 chars.', true)
->param('legalCity', '', new Text(256), 'Project legal City. Max length: 256 chars.', true)
->param('legalAddress', '', new Text(256), 'Project legal Address. Max length: 256 chars.', true)
->param('legalTaxId', '', new Text(256), 'Project legal Tax ID. Max length: 256 chars.', true)
->inject('request')
->inject('response')
->inject('dbForPlatform')
@@ -90,7 +80,7 @@ class Create extends Action
->callback($this->action(...));
}
public function action(string $projectId, string $name, string $teamId, string $region, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Request $request, Response $response, Database $dbForPlatform, Cache $cache, Group $pools, Hooks $hooks)
public function action(string $projectId, string $name, string $teamId, string $region, Request $request, Response $response, Database $dbForPlatform, Cache $cache, Group $pools, Hooks $hooks)
{
$team = $dbForPlatform->getDocument('teams', $teamId);
@@ -175,16 +165,7 @@ class Create extends Action
'teamInternalId' => $team->getSequence(),
'teamId' => $team->getId(),
'region' => $region,
'description' => $description,
'logo' => $logo,
'url' => $url,
'version' => APP_VERSION_STABLE,
'legalName' => $legalName,
'legalCountry' => $legalCountry,
'legalState' => $legalState,
'legalCity' => $legalCity,
'legalAddress' => $legalAddress,
'legalTaxId' => ID::custom($legalTaxId),
'services' => new \stdClass(),
'platforms' => null,
'oAuthProviders' => [],
@@ -0,0 +1,37 @@
<?php
namespace Appwrite\Utopia\Request\Filters;
use Appwrite\Utopia\Request\Filter;
class V26 extends Filter
{
// Convert 1.9.4 params to 1.9.5
public function parse(array $content, string $model): array
{
switch ($model) {
case 'projects.create':
$content = $this->stripProjectMetadata($content);
break;
}
return $content;
}
protected function stripProjectMetadata(array $content): array
{
unset(
$content['description'],
$content['logo'],
$content['url'],
$content['legalName'],
$content['legalCountry'],
$content['legalState'],
$content['legalCity'],
$content['legalAddress'],
$content['legalTaxId'],
);
return $content;
}
}
+6 -2
View File
@@ -249,6 +249,9 @@ class Response extends SwooleResponse
// Project
public const MODEL_PROJECT = 'project';
public const MODEL_PROJECT_LIST = 'projectList';
public const MODEL_PROJECT_AUTH_METHOD = 'projectAuthMethod';
public const MODEL_PROJECT_SERVICE = 'projectService';
public const MODEL_PROJECT_PROTOCOL = 'projectProtocol';
public const MODEL_WEBHOOK = 'webhook';
public const MODEL_WEBHOOK_LIST = 'webhookList';
public const MODEL_KEY = 'key';
@@ -435,9 +438,10 @@ class Response extends SwooleResponse
return isset(self::$models[$key]);
}
public function applyFilters(array $data, string $model): array
public function applyFilters(array $data, string $model, Document $raw): array
{
foreach ($this->filters as $filter) {
$filter->setRawContent($raw);
$data = $filter->parse($data, $model);
}
@@ -457,7 +461,7 @@ class Response extends SwooleResponse
public function dynamic(Document $document, string $model): void
{
$output = $this->output(clone $document, $model);
$output = $this->applyFilters($output, $model);
$output = $this->applyFilters($output, $model, raw: clone $document);
switch ($this->getContentType()) {
case self::CONTENT_TYPE_JSON:
+11
View File
@@ -2,8 +2,15 @@
namespace Appwrite\Utopia\Response;
use Utopia\Database\Document;
abstract class Filter
{
/**
* @var ?Document $rawContent
*/
protected ?Document $rawContent = null;
/**
* Parse the content to another format.
*
@@ -14,6 +21,10 @@ abstract class Filter
*/
abstract public function parse(array $content, string $model): array;
public function setRawContent(Document $rawContent): void
{
$this->rawContent = $rawContent;
}
/**
* Handle list
@@ -0,0 +1,227 @@
<?php
namespace Appwrite\Utopia\Response\Filters;
use Appwrite\Network\Platform;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Filter;
use Utopia\Config\Config;
use Utopia\Database\Document;
// Convert 1.9.5 Data format to 1.9.4 format
class V26 extends Filter
{
public function parse(array $content, string $model): array
{
return match ($model) {
Response::MODEL_PROJECT => $this->parseProject($content, $this->rawContent),
Response::MODEL_PROJECT_LIST => $this->handleList($content, 'projects', function ($item) {
$projectId = $item['$id'] ?? '';
$rawProjects = $this->rawContent->getAttribute('projects', []);
$rawProject = new Document();
foreach ($rawProjects as $rawItem) {
if ($rawItem->getId() === $projectId) {
$rawProject = $rawItem;
break;
}
}
return $this->parseProject($item, $rawProject);
}),
default => $content,
};
}
private function parseProject(array $content, Document $raw): array
{
$this->expandAuthMethods($content);
$this->expandServices($content);
$this->expandProtocols($content);
unset($content['authMethods'], $content['services'], $content['protocols']);
$auths = new Document($raw->getAttribute('auths', []));
$content['authLimit'] = $auths->getAttribute('limit', 0);
$content['authDuration'] = $auths->getAttribute('duration', TOKEN_EXPIRATION_LOGIN_LONG);
$content['authSessionsLimit'] = $auths->getAttribute('maxSessions', 0);
$content['authPasswordHistory'] = $auths->getAttribute('passwordHistory', 0);
$content['authPasswordDictionary'] = $auths->getAttribute('passwordDictionary', false);
$content['authPersonalDataCheck'] = $auths->getAttribute('personalDataCheck', false);
$content['authDisposableEmails'] = $auths->getAttribute('disposableEmails', false);
$content['authCanonicalEmails'] = $auths->getAttribute('canonicalEmails', false);
$content['authFreeEmails'] = $auths->getAttribute('freeEmails', false);
$content['authMockNumbers'] = $auths->getAttribute('mockNumbers', []);
$content['authSessionAlerts'] = $auths->getAttribute('sessionAlerts', false);
$content['authMembershipsUserName'] = $auths->getAttribute('membershipsUserName', false);
$content['authMembershipsUserEmail'] = $auths->getAttribute('membershipsUserEmail', false);
$content['authMembershipsMfa'] = $auths->getAttribute('membershipsMfa', false);
$content['authMembershipsUserId'] = $auths->getAttribute('membershipsUserId', false);
$content['authMembershipsUserPhone'] = $auths->getAttribute('membershipsUserPhone', false);
$content['authInvalidateSessions'] = $auths->getAttribute('invalidateSessions', false);
$content['description'] = $raw->getAttribute('description', '');
$content['logo'] = $raw->getAttribute('logo', '');
$content['url'] = $raw->getAttribute('url', '');
$content['legalName'] = $raw->getAttribute('legalName', '');
$content['legalCountry'] = $raw->getAttribute('legalCountry', '');
$content['legalState'] = $raw->getAttribute('legalState', '');
$content['legalCity'] = $raw->getAttribute('legalCity', '');
$content['legalAddress'] = $raw->getAttribute('legalAddress', '');
$content['legalTaxId'] = $raw->getAttribute('legalTaxId', '');
$content['oAuthProviders'] = $this->expandOAuthProviders($raw);
$content['platforms'] = [];
foreach ($raw->getAttribute('platforms', []) as $platform) {
$content['platforms'][] = $this->parsePlatform($platform);
}
$content['webhooks'] = [];
foreach ($raw->getAttribute('webhooks', []) as $webhook) {
$content['webhooks'][] = $this->parseWebhook($webhook);
}
$content['keys'] = [];
foreach ($raw->getAttribute('keys', []) as $key) {
$content['keys'][] = $this->parseKey($key);
}
return $content;
}
private function parsePlatform(Document $platform): array
{
$type = $platform->getAttribute('type', '');
$key = $platform->getAttribute('key', '');
$result = [
'$id' => $platform->getAttribute('$id', ''),
'$createdAt' => $platform->getAttribute('$createdAt', ''),
'$updatedAt' => $platform->getAttribute('$updatedAt', ''),
'name' => $platform->getAttribute('name', ''),
'type' => $type,
];
switch ($type) {
case Platform::TYPE_ANDROID:
$result['applicationId'] = $key;
break;
case Platform::TYPE_APPLE:
$result['bundleIdentifier'] = $key;
break;
case Platform::TYPE_LINUX:
$result['packageName'] = $key;
break;
case Platform::TYPE_WINDOWS:
$result['packageIdentifierName'] = $key;
break;
default:
// Web and backwards-compatibility types are mapped to web
$result['hostname'] = $platform->getAttribute('hostname', '');
$result['key'] = $key;
break;
}
return $result;
}
private function parseWebhook(Document $webhook): array
{
return [
'$id' => $webhook->getAttribute('$id', ''),
'$createdAt' => $webhook->getAttribute('$createdAt', ''),
'$updatedAt' => $webhook->getAttribute('$updatedAt', ''),
'name' => $webhook->getAttribute('name', ''),
'url' => $webhook->getAttribute('url', ''),
'events' => $webhook->getAttribute('events', []),
'tls' => $webhook->getAttribute('security', true),
'authUsername' => $webhook->getAttribute('httpUser', ''),
'authPassword' => $webhook->getAttribute('httpPass', ''),
'secret' => $webhook->getAttribute('signatureKey', ''),
'enabled' => $webhook->getAttribute('enabled', true),
'logs' => $webhook->getAttribute('logs', ''),
'attempts' => $webhook->getAttribute('attempts', 0),
];
}
private function parseKey(Document $key): array
{
return [
'$id' => $key->getAttribute('$id', ''),
'$createdAt' => $key->getAttribute('$createdAt', ''),
'$updatedAt' => $key->getAttribute('$updatedAt', ''),
'name' => $key->getAttribute('name', ''),
'expire' => $key->getAttribute('expire', ''),
'scopes' => $key->getAttribute('scopes', []),
'secret' => $key->getAttribute('secret', ''),
'accessedAt' => $key->getAttribute('accessedAt', ''),
'sdks' => $key->getAttribute('sdks', []),
];
}
private function expandAuthMethods(array &$content): void
{
$authMethods = [];
foreach ($content['authMethods'] ?? [] as $method) {
$authMethods[$method['$id'] ?? ''] = $method['enabled'] ?? true;
}
foreach (Config::getParam('auth', []) as $id => $method) {
$key = $method['key'] ?? '';
$content['auth' . ucfirst($key)] = $authMethods[$id] ?? true;
}
}
private function expandServices(array &$content): void
{
$services = [];
foreach ($content['services'] ?? [] as $service) {
$services[$service['$id'] ?? ''] = $service['enabled'] ?? true;
}
foreach (Config::getParam('services', []) as $id => $service) {
if (!($service['optional'] ?? false)) {
continue;
}
$key = $service['key'] ?? '';
$content['serviceStatusFor' . ucfirst($key)] = $services[$id] ?? true;
}
}
private function expandProtocols(array &$content): void
{
$protocols = [];
foreach ($content['protocols'] ?? [] as $protocol) {
$protocols[$protocol['$id'] ?? ''] = $protocol['enabled'] ?? true;
}
foreach (Config::getParam('protocols', []) as $id => $api) {
$key = $api['key'] ?? '';
$content['protocolStatusFor' . ucfirst($key)] = $protocols[$id] ?? true;
}
}
private function expandOAuthProviders(Document $raw): array
{
$providers = Config::getParam('oAuthProviders', []);
$providerValues = $raw->getAttribute('oAuthProviders', []);
$projectProviders = [];
foreach ($providers as $key => $provider) {
if (!($provider['enabled'] ?? false)) {
continue;
}
$projectProviders[] = [
'key' => $key,
'name' => $provider['name'] ?? '',
'appId' => $providerValues[$key . 'Appid'] ?? '',
'secret' => '',
'enabled' => $providerValues[$key . 'Enabled'] ?? false,
];
}
return $projectProviders;
}
}
+80 -333
View File
@@ -12,6 +12,7 @@ class Project extends Model
public function __construct()
{
$this
// Basic project information
->addRule('$id', [
'type' => self::TYPE_STRING,
'description' => 'Project ID.',
@@ -36,210 +37,23 @@ class Project extends Model
'default' => '',
'example' => 'New Project',
])
->addRule('description', [
'type' => self::TYPE_STRING,
'description' => 'Project description.',
'default' => '',
'example' => 'This is a new project.',
])
->addRule('teamId', [
'type' => self::TYPE_STRING,
'description' => 'Project team ID.',
'default' => '',
'example' => '1592981250',
])
->addRule('logo', [
'type' => self::TYPE_STRING,
'description' => 'Project logo file ID.',
'default' => '',
'example' => '5f5c451b403cb',
])
->addRule('url', [
'type' => self::TYPE_STRING,
'description' => 'Project website URL.',
'default' => '',
'example' => '5f5c451b403cb',
])
->addRule('legalName', [
'type' => self::TYPE_STRING,
'description' => 'Company legal name.',
'default' => '',
'example' => 'Company LTD.',
])
->addRule('legalCountry', [
'type' => self::TYPE_STRING,
'description' => 'Country code in [ISO 3166-1](http://en.wikipedia.org/wiki/ISO_3166-1) two-character format.',
'default' => '',
'example' => 'US',
])
->addRule('legalState', [
'type' => self::TYPE_STRING,
'description' => 'State name.',
'default' => '',
'example' => 'New York',
])
->addRule('legalCity', [
'type' => self::TYPE_STRING,
'description' => 'City name.',
'default' => '',
'example' => 'New York City.',
])
->addRule('legalAddress', [
'type' => self::TYPE_STRING,
'description' => 'Company Address.',
'default' => '',
'example' => '620 Eighth Avenue, New York, NY 10018',
])
->addRule('legalTaxId', [
'type' => self::TYPE_STRING,
'description' => 'Company Tax ID.',
'default' => '',
'example' => '131102020',
])
->addRule('authDuration', [
'type' => self::TYPE_INTEGER,
'description' => 'Session duration in seconds.',
'default' => TOKEN_EXPIRATION_LOGIN_LONG,
'example' => 60,
])
->addRule('authLimit', [
'type' => self::TYPE_INTEGER,
'description' => 'Max users allowed. 0 is unlimited.',
'default' => 0,
'example' => 100,
])
->addRule('authSessionsLimit', [
'type' => self::TYPE_INTEGER,
'description' => 'Max sessions allowed per user. 100 maximum.',
'default' => 10,
'example' => 10,
])
->addRule('authPasswordHistory', [
'type' => self::TYPE_INTEGER,
'description' => 'Max allowed passwords in the history list per user. Max passwords limit allowed in history is 20. Use 0 for disabling password history.',
'default' => 0,
'example' => 5,
])
->addRule('authPasswordDictionary', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not to check user\'s password against most commonly used passwords.',
'default' => false,
'example' => true,
])
->addRule('authPersonalDataCheck', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not to check the user password for similarity with their personal data.',
'default' => false,
'example' => true,
])
->addRule('authDisposableEmails', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not to disallow disposable email addresses during signup and email updates.',
'default' => false,
'example' => true,
])
->addRule('authCanonicalEmails', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not to require canonical email addresses during signup and email updates.',
'default' => false,
'example' => true,
])
->addRule('authFreeEmails', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not to disallow free email addresses during signup and email updates.',
'default' => false,
'example' => true,
])
->addRule('authMockNumbers', [
'type' => Response::MODEL_MOCK_NUMBER,
'description' => 'An array of mock numbers and their corresponding verification codes (OTPs).',
'default' => [],
'array' => true,
'example' => [new \stdClass()],
])
->addRule('authSessionAlerts', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not to send session alert emails to users.',
'default' => false,
'example' => true,
])
->addRule('authMembershipsUserName', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not to show user names in the teams membership response.',
'default' => false,
'example' => true,
])
->addRule('authMembershipsUserEmail', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not to show user emails in the teams membership response.',
'default' => false,
'example' => true,
])
->addRule('authMembershipsMfa', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not to show user MFA status in the teams membership response.',
'default' => false,
'example' => true,
])
->addRule('authMembershipsUserId', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not to show user IDs in the teams membership response.',
'default' => false,
'example' => true,
])
->addRule('authMembershipsUserPhone', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not to show user phone numbers in the teams membership response.',
'default' => false,
'example' => true,
])
->addRule('authInvalidateSessions', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether or not all existing sessions should be invalidated on password change',
'default' => false,
'example' => true,
])
->addRule('oAuthProviders', [
'type' => Response::MODEL_AUTH_PROVIDER,
'description' => 'List of Auth Providers.',
'default' => [],
'example' => [new \stdClass()],
'array' => true,
])
->addRule('platforms', [
'type' => [
Response::MODEL_PLATFORM_WEB,
Response::MODEL_PLATFORM_APPLE,
Response::MODEL_PLATFORM_ANDROID,
Response::MODEL_PLATFORM_WINDOWS,
Response::MODEL_PLATFORM_LINUX,
],
'description' => 'List of Platforms.',
'default' => [],
'example' => new \stdClass(),
'array' => true,
])
->addRule('webhooks', [
'type' => Response::MODEL_WEBHOOK,
'description' => 'List of Webhooks.',
'default' => [],
'example' => new \stdClass(),
'array' => true,
])
->addRule('keys', [
'type' => Response::MODEL_KEY,
'description' => 'List of API Keys.',
'default' => [],
'example' => new \stdClass(),
'array' => true,
])
// Resource: Dev Keys
->addRule('devKeys', [
'type' => Response::MODEL_DEV_KEY,
'description' => 'List of dev keys.',
'description' => 'Deprecated since 1.9.5: List of dev keys.',
'default' => [],
'example' => new \stdClass(),
'array' => true,
])
// Resource: SMTP
->addRule('smtpEnabled', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Status for custom SMTP',
@@ -301,6 +115,8 @@ class Project extends Model
'default' => '',
'example' => 'tls',
])
// Resource: Ping
->addRule('pingCount', [
'type' => self::TYPE_INTEGER,
'description' => 'Number of times the ping was received for this project.',
@@ -313,6 +129,8 @@ class Project extends Model
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
])
// Resource: Labels
->addRule('labels', [
'type' => self::TYPE_STRING,
'description' => 'Labels for the project.',
@@ -320,64 +138,42 @@ class Project extends Model
'example' => ['vip'],
'array' => true,
])
// Resource: Billing
->addRule('status', [
'type' => self::TYPE_STRING,
'description' => 'Project status.',
'default' => 'active',
'example' => 'active',
])
// Resource: Auth methods
->addRule('authMethods', [
'type' => Response::MODEL_PROJECT_AUTH_METHOD,
'description' => 'List of auth methods.',
'default' => [],
'example' => new \stdClass(),
'array' => true,
])
// Resource: Services
->addRule('services', [
'type' => Response::MODEL_PROJECT_SERVICE,
'description' => 'List of services.',
'default' => [],
'example' => new \stdClass(),
'array' => true,
])
// Resource: Protocols
->addRule('protocols', [
'type' => Response::MODEL_PROJECT_PROTOCOL,
'description' => 'List of protocols.',
'default' => [],
'example' => new \stdClass(),
'array' => true,
])
;
$services = Config::getParam('services', []);
$auth = Config::getParam('auth', []);
foreach ($auth as $index => $method) {
$name = $method['name'] ?? '';
$key = $method['key'] ?? '';
$this
->addRule('auth' . ucfirst($key), [
'type' => self::TYPE_BOOLEAN,
'description' => $name . ' auth method status',
'example' => true,
'default' => true,
])
;
}
foreach ($services as $service) {
if (!$service['optional']) {
continue;
}
$name = $service['name'] ?? '';
$key = $service['key'] ?? '';
$this
->addRule('serviceStatusFor' . ucfirst($key), [
'type' => self::TYPE_BOOLEAN,
'description' => $name . ' service status',
'example' => true,
'default' => true,
])
;
}
$apis = Config::getParam('protocols', []);
foreach ($apis as $api) {
$name = $api['name'] ?? '';
$key = $api['key'] ?? '';
$this
->addRule('protocolStatusFor' . ucfirst($key), [
'type' => self::TYPE_BOOLEAN,
'description' => $name . ' protocol status',
'example' => true,
'default' => true,
])
;
}
}
/**
@@ -408,10 +204,9 @@ class Project extends Model
public function filter(Document $document): Document
{
$this->expandSmtpFields($document);
$this->expandServiceFields($document);
$this->expandApiFields($document);
$this->expandAuthFields($document);
$this->expandOAuthProviders($document);
$this->expandServices($document);
$this->expandProtocols($document);
$this->expandAuthMethods($document);
return $document;
}
@@ -422,8 +217,8 @@ class Project extends Model
return;
}
// SMTP
$smtp = $document->getAttribute('smtp', []);
$document->setAttribute('smtpEnabled', $smtp['enabled'] ?? false);
$document->setAttribute('smtpSenderEmail', $smtp['senderEmail'] ?? '');
$document->setAttribute('smtpSenderName', $smtp['senderName'] ?? '');
@@ -436,100 +231,52 @@ class Project extends Model
$document->setAttribute('smtpSecure', $smtp['secure'] ?? '');
}
private function expandServiceFields(Document $document): void
private function expandServices(Document $document): void
{
if (!$document->isSet('services')) {
return;
}
$values = $document->getAttribute('services', []);
$services = Config::getParam('services', []);
$services = [];
foreach ($services as $service) {
foreach (Config::getParam('services', []) as $id => $service) {
if (!$service['optional']) {
continue;
}
$key = $service['key'] ?? '';
$value = $values[$key] ?? true;
$document->setAttribute('serviceStatusFor' . ucfirst($key), $value);
}
}
private function expandApiFields(Document $document): void
{
if (!$document->isSet('apis')) {
return;
}
$values = $document->getAttribute('apis', []);
$apis = Config::getParam('protocols', []);
foreach ($apis as $api) {
$key = $api['key'] ?? '';
$value = $values[$key] ?? true;
$document->setAttribute('protocolStatusFor' . ucfirst($key), $value);
}
}
private function expandAuthFields(Document $document): void
{
if (!$document->isSet('auths')) {
return;
}
$authValues = $document->getAttribute('auths', []);
$auth = Config::getParam('auth', []);
$document->setAttribute('authLimit', $authValues['limit'] ?? 0);
$document->setAttribute('authDuration', $authValues['duration'] ?? TOKEN_EXPIRATION_LOGIN_LONG);
$document->setAttribute('authSessionsLimit', $authValues['maxSessions'] ?? 0);
$document->setAttribute('authPasswordHistory', $authValues['passwordHistory'] ?? 0);
$document->setAttribute('authPasswordDictionary', $authValues['passwordDictionary'] ?? false);
$document->setAttribute('authPersonalDataCheck', $authValues['personalDataCheck'] ?? false);
$document->setAttribute('authDisposableEmails', $authValues['disposableEmails'] ?? false);
$document->setAttribute('authCanonicalEmails', $authValues['canonicalEmails'] ?? false);
$document->setAttribute('authFreeEmails', $authValues['freeEmails'] ?? false);
$document->setAttribute('authMockNumbers', $authValues['mockNumbers'] ?? []);
$document->setAttribute('authSessionAlerts', $authValues['sessionAlerts'] ?? false);
$document->setAttribute('authMembershipsUserName', $authValues['membershipsUserName'] ?? false);
$document->setAttribute('authMembershipsUserEmail', $authValues['membershipsUserEmail'] ?? false);
$document->setAttribute('authMembershipsMfa', $authValues['membershipsMfa'] ?? false);
$document->setAttribute('authMembershipsUserId', $authValues['membershipsUserId'] ?? false);
$document->setAttribute('authMembershipsUserPhone', $authValues['membershipsUserPhone'] ?? false);
$document->setAttribute('authInvalidateSessions', $authValues['invalidateSessions'] ?? false);
foreach ($auth as $method) {
$key = $method['key'];
$value = $authValues[$key] ?? true;
$document->setAttribute('auth' . ucfirst($key), $value);
}
}
private function expandOAuthProviders(Document $document): void
{
if (!$document->isSet('oAuthProviders')) {
return;
}
$providers = Config::getParam('oAuthProviders', []);
$providerValues = $document->getAttribute('oAuthProviders', []);
$projectProviders = [];
foreach ($providers as $key => $provider) {
if (!$provider['enabled']) {
// Disabled by Appwrite configuration, exclude from response
continue;
}
$projectProviders[] = new Document([
'key' => $key,
'name' => $provider['name'] ?? '',
'appId' => $providerValues[$key . 'Appid'] ?? '',
'secret' => '', // Write-only: never expose the stored value
'enabled' => $providerValues[$key . 'Enabled'] ?? false,
$services[] = new Document([
'$id' => $id,
'enabled' => $values[$service['key']] ?? true,
]);
}
$document->setAttribute('oAuthProviders', $projectProviders);
$document->setAttribute('services', $services);
}
private function expandProtocols(Document $document): void
{
$values = $document->getAttribute('apis', []);
$protocols = [];
foreach (Config::getParam('protocols', []) as $id => $api) {
$protocols[] = new Document([
'$id' => $id,
'enabled' => $values[$api['key']] ?? true,
]);
}
$document->setAttribute('protocols', $protocols);
}
private function expandAuthMethods(Document $document): void
{
$values = $document->getAttribute('auths', []);
$authMethods = [];
foreach (Config::getParam('auth', []) as $id => $method) {
$authMethods[] = new Document([
'$id' => $id,
'enabled' => $values[$method['key']] ?? true
]);
}
$document->setAttribute('authMethods', $authMethods);
}
}
@@ -0,0 +1,49 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
use Utopia\Config\Config;
class ProjectAuthMethod extends Model
{
public function __construct()
{
$this
->addRule('$id', [
'type' => self::TYPE_ENUM,
'description' => 'Auth method ID.',
'default' => '',
'example' => 'email-password',
'enum' => \array_keys(Config::getParam('auth', [])),
])
->addRule('enabled', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Auth method status.',
'example' => false,
'default' => true,
])
;
}
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ProjectAuthMethod';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_PROJECT_AUTH_METHOD;
}
}
@@ -0,0 +1,49 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
use Utopia\Config\Config;
class ProjectProtocol extends Model
{
public function __construct()
{
$this
->addRule('$id', [
'type' => self::TYPE_ENUM,
'description' => 'Protocol ID.',
'default' => '',
'example' => 'graphql',
'enum' => \array_keys(Config::getParam('protocols', [])),
])
->addRule('enabled', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Protocol status.',
'example' => false,
'default' => true,
])
;
}
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ProjectProtocol';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_PROJECT_PROTOCOL;
}
}
@@ -0,0 +1,49 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
use Utopia\Config\Config;
class ProjectService extends Model
{
public function __construct()
{
$this
->addRule('$id', [
'type' => self::TYPE_ENUM,
'description' => 'Service ID.',
'default' => '',
'example' => 'sites',
'enum' => \array_keys(\array_filter(Config::getParam('services', []), fn ($element) => $element['optional'])),
])
->addRule('enabled', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Service status.',
'example' => false,
'default' => true,
])
;
}
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ProjectService';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_PROJECT_SERVICE;
}
}
@@ -212,6 +212,7 @@ trait AuthMethodsBase
$headers = \array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders());
$projectId = $this->getProject()['$id'];
@@ -322,7 +323,9 @@ trait AuthMethodsBase
];
if ($authenticated) {
$headers = \array_merge($headers, $this->getHeaders());
$headers = \array_merge($headers, $this->getHeaders(), [
'x-appwrite-response-format' => '1.9.4',
]);
}
return $this->client->call(
@@ -28,6 +28,7 @@ class OAuthGitHubIntegrationTest extends Scope
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
'x-appwrite-project' => 'console',
'x-appwrite-response-format' => '1.9.4',
];
// Step 1: Create new organization (team)
+4 -1
View File
@@ -1082,7 +1082,9 @@ trait PoliciesBase
];
if ($authenticated) {
$headers = array_merge($headers, $this->getHeaders());
$headers = array_merge($headers, $this->getHeaders(), [
'x-appwrite-response-format' => '1.9.4',
]);
}
return $headers;
@@ -1094,6 +1096,7 @@ trait PoliciesBase
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
'x-appwrite-response-format' => '1.9.4',
]);
}
@@ -22,6 +22,7 @@ class PoliciesMembershipPrivacyIntegrationTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apiKey,
'x-appwrite-response-format' => '1.9.4',
];
// Step 1: Configure privacy to false
@@ -22,6 +22,7 @@ class PoliciesPasswordDictionaryIntegrationTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apiKey,
'x-appwrite-response-format' => '1.9.4',
];
// "password" is the top entry in the common-passwords dictionary and is 8 chars (min length).
@@ -22,6 +22,7 @@ class PoliciesPasswordHistoryIntegrationTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apiKey,
'x-appwrite-response-format' => '1.9.4',
];
// Step 1: Enable password history policy with limit 3
@@ -21,6 +21,7 @@ class PoliciesPasswordPersonalDataIntegrationTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apiKey,
'x-appwrite-response-format' => '1.9.4',
];
$setPersonalData = function (bool $enabled) use ($serverHeaders): void {
@@ -23,6 +23,7 @@ class PoliciesSessionAlertIntegrationTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apiKey,
'x-appwrite-response-format' => '1.9.4',
];
$publicHeaders = [
@@ -22,6 +22,7 @@ class PoliciesSessionDurationIntegrationTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apiKey,
'x-appwrite-response-format' => '1.9.4',
];
$publicHeaders = [
@@ -22,6 +22,7 @@ class PoliciesSessionInvalidationIntegrationTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apiKey,
'x-appwrite-response-format' => '1.9.4',
];
$publicHeaders = [
@@ -22,6 +22,7 @@ class PoliciesUserLimitIntegrationTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apiKey,
'x-appwrite-response-format' => '1.9.4',
];
$signupHeaders = [
@@ -51,6 +51,88 @@ class ProjectConsoleClientTest extends Scope
$this->assertSame(404, $getProject['headers']['status-code']);
}
public function testGetProject(): void
{
$team = $this->createTeam('Get Project Team');
$project = $this->createProject($team['body']['$id'], 'Get Project');
$response = $this->client->call(Client::METHOD_GET, '/project', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $project['body']['$id'],
], $this->getHeaders()));
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame($project['body']['$id'], $response['body']['$id']);
$this->assertNotEmpty($response['body']['$createdAt']);
$this->assertNotEmpty($response['body']['$updatedAt']);
$this->assertSame('Get Project', $response['body']['name']);
$this->assertSame($team['body']['$id'], $response['body']['teamId']);
$this->assertSame('active', $response['body']['status']);
// Auth methods
$this->assertIsArray($response['body']['authMethods']);
$this->assertNotEmpty($response['body']['authMethods']);
foreach ($response['body']['authMethods'] as $authMethod) {
$this->assertArrayHasKey('$id', $authMethod);
$this->assertArrayHasKey('enabled', $authMethod);
$this->assertIsBool($authMethod['enabled']);
}
// Services
$this->assertIsArray($response['body']['services']);
$this->assertNotEmpty($response['body']['services']);
foreach ($response['body']['services'] as $service) {
$this->assertArrayHasKey('$id', $service);
$this->assertArrayHasKey('enabled', $service);
$this->assertIsBool($service['enabled']);
}
// Protocols
$this->assertIsArray($response['body']['protocols']);
$this->assertNotEmpty($response['body']['protocols']);
foreach ($response['body']['protocols'] as $protocol) {
$this->assertArrayHasKey('$id', $protocol);
$this->assertArrayHasKey('enabled', $protocol);
$this->assertIsBool($protocol['enabled']);
}
// SMTP defaults
$this->assertFalse($response['body']['smtpEnabled']);
$this->assertSame('', $response['body']['smtpSenderEmail']);
$this->assertSame('', $response['body']['smtpSenderName']);
$this->assertSame('', $response['body']['smtpReplyToEmail']);
$this->assertSame('', $response['body']['smtpReplyToName']);
$this->assertSame('', $response['body']['smtpHost']);
$this->assertSame('', $response['body']['smtpPort']);
$this->assertSame('', $response['body']['smtpUsername']);
$this->assertSame('', $response['body']['smtpPassword']);
$this->assertSame('', $response['body']['smtpSecure']);
// Other fields
$this->assertIsArray($response['body']['labels']);
$this->assertIsArray($response['body']['devKeys']);
$this->assertSame(0, $response['body']['pingCount']);
$this->assertSame('', $response['body']['pingedAt']);
// Ensure old flattened fields are not present
$this->assertArrayNotHasKey('description', $response['body']);
$this->assertArrayNotHasKey('logo', $response['body']);
$this->assertArrayNotHasKey('url', $response['body']);
$this->assertArrayNotHasKey('authDuration', $response['body']);
$this->assertArrayNotHasKey('authLimit', $response['body']);
$this->assertArrayNotHasKey('authSessionsLimit', $response['body']);
$this->assertArrayNotHasKey('authPasswordHistory', $response['body']);
$this->assertArrayNotHasKey('authPasswordDictionary', $response['body']);
$this->assertArrayNotHasKey('authPersonalDataCheck', $response['body']);
$this->assertArrayNotHasKey('authDisposableEmails', $response['body']);
$this->assertArrayNotHasKey('authCanonicalEmails', $response['body']);
$this->assertArrayNotHasKey('authFreeEmails', $response['body']);
$this->assertArrayNotHasKey('oAuthProviders', $response['body']);
$this->assertArrayNotHasKey('platforms', $response['body']);
$this->assertArrayNotHasKey('webhooks', $response['body']);
$this->assertArrayNotHasKey('keys', $response['body']);
}
protected function createTeam(string $name): array
{
$response = $this->client->call(Client::METHOD_POST, '/teams', $this->getConsoleSessionHeaders(), [
+4 -1
View File
@@ -248,6 +248,7 @@ trait ProtocolsBase
$headers = array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders());
// Disable via the legacy `/status` alias
@@ -278,7 +279,9 @@ trait ProtocolsBase
];
if ($authenticated) {
$headers = array_merge($headers, $this->getHeaders());
$headers = array_merge($headers, $this->getHeaders(), [
'x-appwrite-response-format' => '1.9.4',
]);
}
return $this->client->call(Client::METHOD_PATCH, '/project/protocols/' . $protocolId, $headers, [
+4 -1
View File
@@ -246,6 +246,7 @@ trait ServicesBase
$headers = array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders());
// Disable via the legacy `/status` alias
@@ -276,7 +277,9 @@ trait ServicesBase
];
if ($authenticated) {
$headers = array_merge($headers, $this->getHeaders());
$headers = array_merge($headers, $this->getHeaders(), [
'x-appwrite-response-format' => '1.9.4',
]);
}
return $this->client->call(Client::METHOD_PATCH, '/project/services/' . $serviceId, $headers, [
@@ -46,6 +46,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4'
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
@@ -68,6 +69,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
@@ -89,6 +91,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => '',
@@ -101,6 +104,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
@@ -127,6 +131,7 @@ class ProjectsConsoleClientTest extends Scope
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'MultiDB Project',
@@ -210,6 +215,7 @@ class ProjectsConsoleClientTest extends Scope
$getProject = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(404, $getProject['headers']['status-code']);
@@ -234,6 +240,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => $projectId,
'name' => 'Original Project',
@@ -249,6 +256,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => $projectId,
'name' => 'Project Duplicate',
@@ -298,6 +306,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Team 1 Project',
@@ -318,6 +327,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId . '/team', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'teamId' => $team2,
]);
@@ -341,6 +351,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -353,6 +364,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders(), [
'search' => $id
]));
@@ -364,6 +376,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders(), [
'search' => 'Project Test'
]));
@@ -390,6 +403,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test 2',
@@ -408,6 +422,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::equal('teamId', [$team['body']['$id']])->toString(),
@@ -422,6 +437,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::limit(1)->toString(),
@@ -435,6 +451,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::offset(1)->toString(),
@@ -447,6 +464,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::equal('name', ['Project Test 2'])->toString(),
@@ -461,6 +479,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::orderDesc()->toString(),
@@ -474,6 +493,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -483,6 +503,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::cursorAfter(new Document(['$id' => $response['body']['projects'][0]['$id']]))->toString(),
@@ -498,6 +519,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::cursorAfter(new Document(['$id' => 'unknown']))->toString(),
@@ -524,6 +546,7 @@ class ProjectsConsoleClientTest extends Scope
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Query Select Test Project',
@@ -540,6 +563,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name'])->toString(),
@@ -569,6 +593,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4'
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name', 'teamId', 'description', '$createdAt', '$updatedAt'])->toString(),
@@ -600,6 +625,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name', 'teamId'])->toString(),
@@ -631,6 +657,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name'])->toString(),
@@ -661,6 +688,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name', 'platforms'])->toString(),
@@ -690,6 +718,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'name', 'webhooks', 'keys'])->toString(),
@@ -719,6 +748,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::select(['*'])->toString(),
@@ -749,6 +779,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::select(['$id', 'invalidAttribute'])->toString(),
@@ -783,6 +814,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
@@ -1027,6 +1059,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -1041,17 +1074,17 @@ class ProjectsConsoleClientTest extends Scope
$this->assertNotEmpty($response['body']['$updatedAt']);
$this->assertNotFalse(\strtotime($response['body']['$updatedAt']));
$this->assertEquals('My description', $response['body']['description']);
// $this->assertEquals('My description', $response['body']['description']); // No longer supported
$this->assertEquals($team['body']['$id'], $response['body']['teamId']);
$this->assertEquals('active', $response['body']['status']);
$this->assertEquals('https://google.com/logo.png', $response['body']['logo']);
$this->assertEquals('https://myapp.com/', $response['body']['url']);
$this->assertEquals('Legal company', $response['body']['legalName']);
$this->assertEquals('Slovakia', $response['body']['legalCountry']);
$this->assertEquals('Custom state', $response['body']['legalState']);
$this->assertEquals('Košice', $response['body']['legalCity']);
$this->assertEquals('Main street 32', $response['body']['legalAddress']);
$this->assertEquals('TAXID_123456', $response['body']['legalTaxId']);
// $this->assertEquals('https://google.com/logo.png', $response['body']['logo']); // No longer supported
// $this->assertEquals('https://myapp.com/', $response['body']['url']); // No longer supported
// $this->assertEquals('Legal company', $response['body']['legalName']); // No longer supported
// $this->assertEquals('Slovakia', $response['body']['legalCountry']); // No longer supported
// $this->assertEquals('Custom state', $response['body']['legalState']); // No longer supported
// $this->assertEquals('Košice', $response['body']['legalCity']); // No longer supported
// $this->assertEquals('Main street 32', $response['body']['legalAddress']); // No longer supported
// $this->assertEquals('TAXID_123456', $response['body']['legalTaxId']); // No longer supported
$this->assertEquals(135, $response['body']['authDuration']);
$this->assertEquals(54, $response['body']['authLimit']);
$this->assertEquals(7, $response['body']['authSessionsLimit']);
@@ -1411,6 +1444,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -1482,6 +1516,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/empty', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(404, $response['headers']['status-code']);
@@ -1490,9 +1525,10 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/'.$projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertEquals(404, $response['headers']['status-code']);
}
public function testGetProjectUsage(): void
@@ -1520,6 +1556,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
@@ -1536,6 +1573,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test 2',
@@ -1556,6 +1594,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => '',
@@ -1580,6 +1619,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'enabled' => true,
'senderEmail' => 'mailer@appwrite.io',
@@ -1605,6 +1645,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -1624,6 +1665,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'enabled' => true,
'senderEmail' => 'fail@appwrite.io',
@@ -1663,6 +1705,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
@@ -1851,6 +1894,7 @@ class ProjectsConsoleClientTest extends Scope
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Session Alert Locale Fallback Test',
@@ -1864,6 +1908,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId . '/smtp', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'enabled' => true,
'senderEmail' => 'mailer@appwrite.io',
@@ -1932,6 +1977,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertTrue($response['body']['authSessionAlerts']);
@@ -2054,6 +2100,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -2166,6 +2213,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -2189,6 +2237,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Session Invalidation Test Project',
@@ -2203,6 +2252,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -2220,6 +2270,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -2237,6 +2288,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -2261,6 +2313,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
@@ -2280,6 +2333,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/oauth2', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'provider' => $key,
'appId' => 'AppId-' . ucfirst($key),
@@ -2293,6 +2347,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -2320,6 +2375,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/oauth2', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'provider' => $key,
'enabled' => $i === 0 ? false : true // On first provider, test enabled=false
@@ -2334,6 +2390,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -2363,6 +2420,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/oauth2', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'provider' => 'unknown',
'appId' => 'AppId',
@@ -2390,6 +2448,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test',
@@ -2445,6 +2504,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
@@ -2855,6 +2915,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), []);
$this->assertEquals(400, $response['headers']['status-code']);
@@ -2864,6 +2925,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'numbers' => [
'phone' => '+1655513432',
@@ -2877,6 +2939,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'numbers' => [
[
@@ -2892,6 +2955,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'numbers' => [
[
@@ -2907,6 +2971,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'numbers' => [
[
@@ -2922,6 +2987,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'numbers' => [
[
@@ -2937,6 +3003,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'numbers' => [
[
@@ -2952,6 +3019,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'numbers' => [
[
@@ -2979,6 +3047,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'numbers' => $numbers
]);
@@ -2992,6 +3061,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'numbers' => []
]);
@@ -3000,6 +3070,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'numbers' => [
[
@@ -3323,6 +3394,7 @@ class ProjectsConsoleClientTest extends Scope
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
'projectId' => ID::unique(),
@@ -3358,6 +3430,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
@@ -3387,6 +3460,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
@@ -3412,6 +3486,7 @@ class ProjectsConsoleClientTest extends Scope
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
'projectId' => ID::unique(),
@@ -3442,6 +3517,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
@@ -3464,6 +3540,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
@@ -3487,6 +3564,7 @@ class ProjectsConsoleClientTest extends Scope
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]), [
'projectId' => ID::unique(),
@@ -3527,6 +3605,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
@@ -3603,6 +3682,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
@@ -3679,6 +3759,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]));
@@ -4437,6 +4518,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test 2',
@@ -5485,6 +5567,7 @@ class ProjectsConsoleClientTest extends Scope
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Amazing Project',
@@ -5510,6 +5593,7 @@ class ProjectsConsoleClientTest extends Scope
$project = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(200, $project['headers']['status-code']);
@@ -5533,6 +5617,7 @@ class ProjectsConsoleClientTest extends Scope
$project = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()));
$this->assertEquals(404, $project['headers']['status-code']);
@@ -5556,6 +5641,7 @@ class ProjectsConsoleClientTest extends Scope
$project1 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Amazing Project 1',
@@ -5566,6 +5652,7 @@ class ProjectsConsoleClientTest extends Scope
$project2 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Amazing Project 2',
@@ -6908,6 +6995,7 @@ class ProjectsConsoleClientTest extends Scope
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Test project - Labels 1',
@@ -6952,6 +7040,7 @@ class ProjectsConsoleClientTest extends Scope
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['nonvip'])->toString(),
@@ -6964,6 +7053,7 @@ class ProjectsConsoleClientTest extends Scope
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['vip'])->toString(),
@@ -6975,6 +7065,7 @@ class ProjectsConsoleClientTest extends Scope
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['imagine'])->toString(),
@@ -6987,6 +7078,7 @@ class ProjectsConsoleClientTest extends Scope
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['nonvip', 'imagine'])->toString(),
@@ -7000,6 +7092,7 @@ class ProjectsConsoleClientTest extends Scope
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Test project - Labels 2',
@@ -7028,6 +7121,7 @@ class ProjectsConsoleClientTest extends Scope
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['imagine'])->toString(),
@@ -7042,6 +7136,7 @@ class ProjectsConsoleClientTest extends Scope
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['vip'])->toString(),
@@ -7055,6 +7150,7 @@ class ProjectsConsoleClientTest extends Scope
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['vip'])->toString(),
@@ -7069,6 +7165,7 @@ class ProjectsConsoleClientTest extends Scope
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
], $this->getHeaders()), [
'queries' => [
Query::contains('labels', ['vip', 'imagine'])->toString(),
@@ -7174,6 +7271,7 @@ class ProjectsConsoleClientTest extends Scope
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
]);
@@ -7270,6 +7368,7 @@ class ProjectsConsoleClientTest extends Scope
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
], [
'name' => $newProjectName,
@@ -7286,6 +7385,7 @@ class ProjectsConsoleClientTest extends Scope
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.9.4',
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
], [
'name' => $newProjectName,
+1 -1
View File
@@ -209,8 +209,8 @@ trait ProxyBase
$this->assertEquals(200, $rules['headers']['status-code']);
$this->assertEquals(2, $rules['body']['total']);
$this->cleanupSite($siteId);
$this->cleanupRule($ruleId);
$this->cleanupSite($siteId);
}
public function testCreateFunctionRule(): void
+3 -2
View File
@@ -34,10 +34,11 @@ class ResponseTest extends TestCase
$this->assertTrue($this->response->hasFilters());
$this->assertCount(2, $this->response->getFilters());
$output = $this->response->applyFilters([
$content = [
'initial' => true,
'first' => false
], 'test');
];
$output = $this->response->applyFilters($content, 'test', raw: new Document($content));
$this->assertArrayHasKey('initial', $output);
$this->assertTrue($output['initial']);