Merge branch 'feat-database-update-attribute' of github.com:appwrite/appwrite into feat-relations-2
Conflicts: app/controllers/api/databases.php composer.json composer.lock
This commit is contained in:
commit
79bfa025cb
35 changed files with 2934 additions and 272 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -48,6 +48,7 @@ use Appwrite\Utopia\Database\Validator\Queries\Databases;
|
|||
use Appwrite\Utopia\Database\Validator\Queries\Documents;
|
||||
use Utopia\Config\Config;
|
||||
use MaxMind\Db\Reader;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
/**
|
||||
* Create attribute of varying type
|
||||
|
@ -156,6 +157,163 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
|
|||
return $attribute;
|
||||
}
|
||||
|
||||
function updateAttribute(
|
||||
string $databaseId,
|
||||
string $collectionId,
|
||||
string $key,
|
||||
Database $dbForProject,
|
||||
Event $events,
|
||||
string $type,
|
||||
string $filter = null,
|
||||
string|bool|int|float $default = null,
|
||||
bool $required = null,
|
||||
int|float $min = null,
|
||||
int|float $max = null,
|
||||
array $elements = null
|
||||
): Document {
|
||||
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
|
||||
if ($db->isEmpty()) {
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$attribute = $dbForProject->getDocument('attributes', ID::custom($db->getInternalId() . '_' . $collection->getInternalId() . '_' . $key));
|
||||
|
||||
if ($attribute->isEmpty()) {
|
||||
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($attribute->getAttribute('status') !== 'available') {
|
||||
throw new Exception(Exception::ATTRIBUTE_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
if ($attribute->getAttribute(('type') !== $type)) {
|
||||
throw new Exception(Exception::ATTRIBUTE_TYPE_INVALID);
|
||||
}
|
||||
|
||||
if ($attribute->getAttribute('type') === Database::VAR_STRING && $attribute->getAttribute(('filter') !== $filter)) {
|
||||
throw new Exception(Exception::ATTRIBUTE_TYPE_INVALID);
|
||||
}
|
||||
|
||||
if ($required && isset($default)) {
|
||||
throw new Exception(Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED, 'Cannot set default value for required attribute');
|
||||
}
|
||||
|
||||
if ($attribute->getAttribute('array', false) && isset($default)) {
|
||||
throw new Exception(Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED, 'Cannot set default value for array attributes');
|
||||
}
|
||||
|
||||
$collectionId = 'database_' . $db->getInternalId() . '_collection_' . $collection->getInternalId();
|
||||
|
||||
$attribute
|
||||
->setAttribute('default', $default)
|
||||
->setAttribute('required', $required);
|
||||
|
||||
$formatOptions = $attribute->getAttribute('formatOptions');
|
||||
|
||||
switch ($attribute->getAttribute('format')) {
|
||||
case APP_DATABASE_ATTRIBUTE_INT_RANGE:
|
||||
if ($min === $formatOptions['min'] && $max === $formatOptions['max']) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($min > $max) {
|
||||
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
|
||||
}
|
||||
|
||||
$validator = new Range($min, $max, Database::VAR_INTEGER);
|
||||
|
||||
if (!is_null($default) && !$validator->isValid($default)) {
|
||||
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, $validator->getDescription());
|
||||
}
|
||||
|
||||
$options = [
|
||||
'min' => $min,
|
||||
'max' => $max
|
||||
];
|
||||
$attribute->setAttribute('formatOptions', $options);
|
||||
|
||||
break;
|
||||
case APP_DATABASE_ATTRIBUTE_FLOAT_RANGE:
|
||||
if ($min === $formatOptions['min'] && $max === $formatOptions['max']) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($min > $max) {
|
||||
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
|
||||
}
|
||||
|
||||
if (!is_null($default)) {
|
||||
$default = \floatval($default);
|
||||
}
|
||||
|
||||
$validator = new Range($min, $max, Database::VAR_FLOAT);
|
||||
|
||||
if (!is_null($default) && !$validator->isValid($default)) {
|
||||
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, $validator->getDescription());
|
||||
}
|
||||
|
||||
$options = [
|
||||
'min' => $min,
|
||||
'max' => $max
|
||||
];
|
||||
$attribute->setAttribute('formatOptions', $options);
|
||||
|
||||
break;
|
||||
case APP_DATABASE_ATTRIBUTE_ENUM:
|
||||
if (empty($elements)) {
|
||||
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Enum elements must not be empty');
|
||||
}
|
||||
|
||||
//TODO: before merging - this iteration is kinda hard to follow because of the $size variable?
|
||||
$size = 0;
|
||||
foreach ($elements as $element) {
|
||||
$length = \strlen($element);
|
||||
if ($length === 0) {
|
||||
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Each enum element must not be empty');
|
||||
}
|
||||
$size = ($length > $size) ? $length : $size;
|
||||
}
|
||||
|
||||
if (!is_null($default) && !in_array($default, $elements)) {
|
||||
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Default value not found in elements');
|
||||
}
|
||||
|
||||
$options = [
|
||||
'elements' => $elements
|
||||
];
|
||||
$attribute->setAttribute('formatOptions', $options);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$dbForProject->updateAttribute(
|
||||
collection: $collectionId,
|
||||
id: $key,
|
||||
required: $required,
|
||||
default: $default,
|
||||
formatOptions: $options ?? null
|
||||
);
|
||||
|
||||
$dbForProject->updateDocument('attributes', $db->getInternalId() . '_' . $collection->getInternalId() . '_' . $key, $attribute);
|
||||
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
|
||||
$events
|
||||
->setContext('collection', $collection)
|
||||
->setContext('database', $db)
|
||||
->setParam('databaseId', $databaseId)
|
||||
->setParam('collectionId', $collection->getId())
|
||||
->setParam('attributeId', $attribute->getId());
|
||||
|
||||
return $attribute;
|
||||
}
|
||||
|
||||
App::post('/v1/databases')
|
||||
->desc('Create Database')
|
||||
->groups(['api', 'database'])
|
||||
|
@ -973,7 +1131,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum')
|
|||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('elements', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of elements in enumerated type. Uses length of longest element to determine size. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' elements are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.')
|
||||
->param('elements', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE, min: 0), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of elements in enumerated type. Uses length of longest element to determine size. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' elements are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Text(0), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
|
||||
->param('array', false, new Boolean(), 'Is attribute an array?', true)
|
||||
|
@ -1534,6 +1692,394 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key')
|
|||
$response->dynamic($attribute, $model);
|
||||
});
|
||||
|
||||
App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/string')
|
||||
->desc('Update String Attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('usage.metric', 'collections.{scope}.requests.update')
|
||||
->label('usage.params', ['databaseId:{request.databaseId}'])
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'databases')
|
||||
->label('sdk.method', 'updateStringAttribute')
|
||||
->label('sdk.description', '/docs/references/databases/update-string-attribute.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_STRING)
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Nullable(new Text(0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $events) {
|
||||
$attribute = updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
events: $events,
|
||||
type: Database::VAR_STRING,
|
||||
default: $default,
|
||||
required: $required
|
||||
);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->dynamic($attribute, Response::MODEL_ATTRIBUTE_STRING);
|
||||
});
|
||||
|
||||
App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/email')
|
||||
->desc('Update Email Attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('usage.metric', 'collections.{scope}.requests.update')
|
||||
->label('usage.params', ['databaseId:{request.databaseId}'])
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'databases')
|
||||
->label('sdk.method', 'updateEmailAttribute')
|
||||
->label('sdk.description', '/docs/references/databases/update-email-attribute.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_EMAIL)
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Nullable(new Email()), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $events) {
|
||||
$attribute = updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
events: $events,
|
||||
type: Database::VAR_STRING,
|
||||
filter: APP_DATABASE_ATTRIBUTE_EMAIL,
|
||||
default: $default,
|
||||
required: $required
|
||||
);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->dynamic($attribute, Response::MODEL_ATTRIBUTE_EMAIL);
|
||||
});
|
||||
|
||||
App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/enum')
|
||||
->desc('Update Enum Attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('usage.metric', 'collections.{scope}.requests.update')
|
||||
->label('usage.params', ['databaseId:{request.databaseId}'])
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'databases')
|
||||
->label('sdk.method', 'updateEnumAttribute')
|
||||
->label('sdk.description', '/docs/references/databases/update-enum-attribute.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_ENUM)
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('elements', null, new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of elements in enumerated type. Uses length of longest element to determine size. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' elements are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Nullable(new Text(0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, ?array $elements, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $events) {
|
||||
$attribute = updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
events: $events,
|
||||
type: Database::VAR_STRING,
|
||||
filter: APP_DATABASE_ATTRIBUTE_ENUM,
|
||||
default: $default,
|
||||
required: $required,
|
||||
elements: $elements
|
||||
);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->dynamic($attribute, Response::MODEL_ATTRIBUTE_ENUM);
|
||||
});
|
||||
|
||||
App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/ip')
|
||||
->desc('Update IP Address Attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('usage.metric', 'collections.{scope}.requests.update')
|
||||
->label('usage.params', ['databaseId:{request.databaseId}'])
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'databases')
|
||||
->label('sdk.method', 'updateIpAttribute')
|
||||
->label('sdk.description', '/docs/references/databases/update-ip-attribute.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_IP)
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Nullable(new IP()), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $events) {
|
||||
$attribute = updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
events: $events,
|
||||
type: Database::VAR_STRING,
|
||||
filter: APP_DATABASE_ATTRIBUTE_IP,
|
||||
default: $default,
|
||||
required: $required
|
||||
);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->dynamic($attribute, Response::MODEL_ATTRIBUTE_IP);
|
||||
});
|
||||
|
||||
App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/url')
|
||||
->desc('Update URL Attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('usage.metric', 'collections.{scope}.requests.update')
|
||||
->label('usage.params', ['databaseId:{request.databaseId}'])
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'databases')
|
||||
->label('sdk.method', 'updateUrlAttribute')
|
||||
->label('sdk.description', '/docs/references/databases/update-url-attribute.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_URL)
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Nullable(new URL()), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $events) {
|
||||
$attribute = updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
events: $events,
|
||||
type: Database::VAR_STRING,
|
||||
filter: APP_DATABASE_ATTRIBUTE_URL,
|
||||
default: $default,
|
||||
required: $required
|
||||
);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->dynamic($attribute, Response::MODEL_ATTRIBUTE_URL);
|
||||
});
|
||||
|
||||
App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/integer')
|
||||
->desc('Update Integer Attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('usage.metric', 'collections.{scope}.requests.update')
|
||||
->label('usage.params', ['databaseId:{request.databaseId}'])
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'databases')
|
||||
->label('sdk.method', 'updateIntegerAttribute')
|
||||
->label('sdk.description', '/docs/references/databases/update-integer-attribute.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_INTEGER)
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('min', null, new Integer(), 'Minimum value to enforce on new documents')
|
||||
->param('max', null, new Integer(), 'Maximum value to enforce on new documents')
|
||||
->param('default', null, new Nullable(new Integer()), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, Response $response, Database $dbForProject, Event $events) {
|
||||
$attribute = updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
events: $events,
|
||||
type: Database::VAR_INTEGER,
|
||||
default: $default,
|
||||
required: $required,
|
||||
min: $min,
|
||||
max: $max
|
||||
);
|
||||
|
||||
$formatOptions = $attribute->getAttribute('formatOptions', []);
|
||||
|
||||
if (!empty($formatOptions)) {
|
||||
$attribute->setAttribute('min', \intval($formatOptions['min']));
|
||||
$attribute->setAttribute('max', \intval($formatOptions['max']));
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->dynamic($attribute, Response::MODEL_ATTRIBUTE_INTEGER);
|
||||
});
|
||||
|
||||
App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/float')
|
||||
->desc('Update Float Attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('usage.metric', 'collections.{scope}.requests.update')
|
||||
->label('usage.params', ['databaseId:{request.databaseId}'])
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'databases')
|
||||
->label('sdk.method', 'updateFloatAttribute')
|
||||
->label('sdk.description', '/docs/references/databases/update-float-attribute.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_FLOAT)
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('min', null, new FloatValidator(), 'Minimum value to enforce on new documents')
|
||||
->param('max', null, new FloatValidator(), 'Maximum value to enforce on new documents')
|
||||
->param('default', null, new Nullable(new FloatValidator()), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, Response $response, Database $dbForProject, Event $events) {
|
||||
$attribute = updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
events: $events,
|
||||
type: Database::VAR_FLOAT,
|
||||
default: $default,
|
||||
required: $required,
|
||||
min: $min,
|
||||
max: $max
|
||||
);
|
||||
|
||||
$formatOptions = $attribute->getAttribute('formatOptions', []);
|
||||
|
||||
if (!empty($formatOptions)) {
|
||||
$attribute->setAttribute('min', \floatval($formatOptions['min']));
|
||||
$attribute->setAttribute('max', \floatval($formatOptions['max']));
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->dynamic($attribute, Response::MODEL_ATTRIBUTE_FLOAT);
|
||||
});
|
||||
|
||||
App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/boolean')
|
||||
->desc('Update Boolean Attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('usage.metric', 'collections.{scope}.requests.update')
|
||||
->label('usage.params', ['databaseId:{request.databaseId}'])
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'databases')
|
||||
->label('sdk.method', 'updateBooleanAttribute')
|
||||
->label('sdk.description', '/docs/references/databases/update-boolean-attribute.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_BOOLEAN)
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Nullable(new Boolean()), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?bool $default, Response $response, Database $dbForProject, Event $events) {
|
||||
$attribute = updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
events: $events,
|
||||
type: Database::VAR_BOOLEAN,
|
||||
default: $default,
|
||||
required: $required
|
||||
);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->dynamic($attribute, Response::MODEL_ATTRIBUTE_BOOLEAN);
|
||||
});
|
||||
|
||||
App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/datetime')
|
||||
->desc('Update DateTime Attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('usage.metric', 'collections.{scope}.requests.update')
|
||||
->label('usage.params', ['databaseId:{request.databaseId}'])
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'databases')
|
||||
->label('sdk.method', 'updateDatetimeAttribute')
|
||||
->label('sdk.description', '/docs/references/databases/update-datetime-attribute.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_DATETIME)
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Nullable(new DatetimeValidator()), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $events) {
|
||||
$attribute = updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
events: $events,
|
||||
type: Database::VAR_DATETIME,
|
||||
default: $default,
|
||||
required: $required
|
||||
);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->dynamic($attribute, Response::MODEL_ATTRIBUTE_DATETIME);
|
||||
});
|
||||
|
||||
App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key')
|
||||
->alias('/v1/database/collections/:collectionId/attributes/:key', ['databaseId' => 'default'])
|
||||
->desc('Delete Attribute')
|
||||
|
@ -1577,7 +2123,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key
|
|||
}
|
||||
|
||||
// Only update status if removing available attribute
|
||||
if ($attribute->getAttribute('status' === 'available')) {
|
||||
if ($attribute->getAttribute('status') === 'available') {
|
||||
$attribute = $dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'deleting'));
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ use Appwrite\Task\Validator\Cron;
|
|||
use Appwrite\Utopia\Database\Validator\Queries\Deployments;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Executions;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Functions;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Variables;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
|
@ -33,7 +32,6 @@ use Utopia\Database\DateTime;
|
|||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Assoc;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
@ -63,7 +61,7 @@ App::post('/v1/functions')
|
|||
->label('sdk.response.model', Response::MODEL_FUNCTION)
|
||||
->param('functionId', '', new CustomId(), 'Function ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
|
||||
->param('name', '', new Text(128), 'Function name. Max length: 128 chars.')
|
||||
->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with execution roles. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 64 characters long.')
|
||||
->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with execution roles. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 64 characters long.', true)
|
||||
->param('runtime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution runtime.')
|
||||
->param('events', [], new ArrayList(new ValidatorEvent(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Events list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.', true)
|
||||
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
|
||||
|
@ -440,7 +438,7 @@ App::put('/v1/functions/:functionId')
|
|||
->label('sdk.response.model', Response::MODEL_FUNCTION)
|
||||
->param('functionId', '', new UID(), 'Function ID.')
|
||||
->param('name', '', new Text(128), 'Function name. Max length: 128 chars.')
|
||||
->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with execution roles. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 64 characters long.')
|
||||
->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with execution roles. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 64 characters long.', true)
|
||||
->param('events', [], new ArrayList(new ValidatorEvent(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Events list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.', true)
|
||||
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
|
||||
->param('timeout', 15, new Range(1, (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)), 'Maximum execution time in seconds.', true)
|
||||
|
@ -601,8 +599,8 @@ App::post('/v1/functions/:functionId/deployments')
|
|||
->label('sdk.response.model', Response::MODEL_DEPLOYMENT)
|
||||
->param('functionId', '', new UID(), 'Function ID.')
|
||||
->param('entrypoint', '', new Text('1028'), 'Entrypoint File.')
|
||||
->param('code', [], new File(), 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', false)
|
||||
->param('activate', false, new Boolean(true), 'Automatically activate the deployment when it is finished building.', false)
|
||||
->param('code', [], new File(), 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', skipValidation: true)
|
||||
->param('activate', false, new Boolean(true), 'Automatically activate the deployment when it is finished building.')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
|
@ -1348,7 +1346,7 @@ App::post('/v1/functions/:functionId/variables')
|
|||
->label('sdk.response.model', Response::MODEL_VARIABLE)
|
||||
->param('functionId', '', new UID(), 'Function unique ID.', false)
|
||||
->param('key', null, new Text(Database::LENGTH_KEY), 'Variable key. Max length: ' . Database::LENGTH_KEY . ' chars.', false)
|
||||
->param('value', null, new Text(8192), 'Variable value. Max length: 8192 chars.', false)
|
||||
->param('value', null, new Text(8192, 0), 'Variable value. Max length: 8192 chars.', false)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(function (string $functionId, string $key, string $value, Response $response, Database $dbForProject) {
|
||||
|
@ -1464,7 +1462,7 @@ App::put('/v1/functions/:functionId/variables/:variableId')
|
|||
->param('functionId', '', new UID(), 'Function unique ID.', false)
|
||||
->param('variableId', '', new UID(), 'Variable unique ID.', false)
|
||||
->param('key', null, new Text(255), 'Variable key. Max length: 255 chars.', false)
|
||||
->param('value', null, new Text(8192), 'Variable value. Max length: 8192 chars.', true)
|
||||
->param('value', null, new Text(8192, 0), 'Variable value. Max length: 8192 chars.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(function (string $functionId, string $variableId, string $key, ?string $value, Response $response, Database $dbForProject) {
|
||||
|
|
|
@ -30,7 +30,7 @@ App::get('/v1/graphql')
|
|||
->label('sdk.response.model', Response::MODEL_ANY)
|
||||
->label('abuse-limit', 60)
|
||||
->label('abuse-time', 60)
|
||||
->param('query', '', new Text(0), 'The query to execute.')
|
||||
->param('query', '', new Text(0, 0), 'The query to execute.')
|
||||
->param('operationName', '', new Text(256), 'The name of the operation to execute.', true)
|
||||
->param('variables', '', new Text(0), 'The JSON encoded variables to use in the query.', true)
|
||||
->inject('request')
|
||||
|
|
|
@ -348,7 +348,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
->label('sdk.response.model', Response::MODEL_FILE)
|
||||
->param('bucketId', '', new UID(), 'Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](/docs/server/storage#createBucket).')
|
||||
->param('fileId', '', new CustomId(), 'File ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
|
||||
->param('file', [], new File(), 'Binary file.', false)
|
||||
->param('file', [], new File(), 'Binary file.', skipValidation: true)
|
||||
->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permission strings. By default, only the current user is granted all permissions. [Learn more about permissions](/docs/permissions).', true)
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
|
|
|
@ -594,7 +594,7 @@ App::get('/.well-known/acme-challenge')
|
|||
$uriChunks = \explode('/', $request->getURI());
|
||||
$token = $uriChunks[\count($uriChunks) - 1];
|
||||
|
||||
$validator = new Text(100, [
|
||||
$validator = new Text(100, allowList: [
|
||||
...Text::NUMBERS,
|
||||
...Text::ALPHABET_LOWER,
|
||||
...Text::ALPHABET_UPPER,
|
||||
|
|
|
@ -165,14 +165,14 @@ App::post('/v1/runtimes')
|
|||
->desc("Create a new runtime server")
|
||||
->param('runtimeId', '', new Text(64), 'Unique runtime ID.')
|
||||
->param('source', '', new Text(0), 'Path to source files.')
|
||||
->param('destination', '', new Text(0), 'Destination folder to store build files into.', true)
|
||||
->param('destination', '', new Text(0, 0), 'Destination folder to store build files into.', true)
|
||||
->param('vars', [], new Assoc(), 'Environment Variables required for the build.')
|
||||
->param('commands', [], new ArrayList(new Text(1024), 100), 'Commands required to build the container. Maximum of 100 commands are allowed, each 1024 characters long.')
|
||||
->param('runtime', '', new Text(128), 'Runtime for the cloud function.')
|
||||
->param('baseImage', '', new Text(128), 'Base image name of the runtime.')
|
||||
->param('entrypoint', '', new Text(256), 'Entrypoint of the code file.', true)
|
||||
->param('remove', false, new Boolean(), 'Remove a runtime after execution.')
|
||||
->param('workdir', '', new Text(256), 'Working directory.', true)
|
||||
->param('workdir', '', new Text(256, 0), 'Working directory.', true)
|
||||
->inject('orchestrationPool')
|
||||
->inject('activeRuntimes')
|
||||
->inject('response')
|
||||
|
@ -459,7 +459,7 @@ App::post('/v1/execution')
|
|||
->desc('Create an execution')
|
||||
->param('runtimeId', '', new Text(64), 'The runtimeID to execute.')
|
||||
->param('vars', [], new Assoc(), 'Environment variables required for the build.')
|
||||
->param('data', '', new Text(8192), 'Data to be forwarded to the function, this is user specified.', true)
|
||||
->param('data', '', new Text(8192, 0), 'Data to be forwarded to the function, this is user specified.', true)
|
||||
->param('timeout', 15, new Range(1, (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)), 'Function maximum execution time in seconds.')
|
||||
->inject('activeRuntimes')
|
||||
->inject('response')
|
||||
|
|
39
composer.lock
generated
39
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "65ec111f49af9c148eb69dc16aec7a10",
|
||||
"content-hash": "db9e7adb4caf775eaa200d3888b65579",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
@ -2113,20 +2113,19 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "dev-feat-relationships",
|
||||
"version": "0.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "dc842d7c1c209ef55c7ce84c056efbc1dcd24283"
|
||||
"reference": "7453256728053cddfb0c872ac8ca60157c4d8a11"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/dc842d7c1c209ef55c7ce84c056efbc1dcd24283",
|
||||
"reference": "dc842d7c1c209ef55c7ce84c056efbc1dcd24283",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/7453256728053cddfb0c872ac8ca60157c4d8a11",
|
||||
"reference": "7453256728053cddfb0c872ac8ca60157c4d8a11",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pdo": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/cache": "0.8.*",
|
||||
"utopia-php/framework": "0.*.*",
|
||||
|
@ -2136,14 +2135,11 @@
|
|||
"ext-mongodb": "*",
|
||||
"ext-redis": "*",
|
||||
"fakerphp/faker": "^1.14",
|
||||
"laravel/pint": "1.4.*",
|
||||
"mongodb/mongodb": "1.8.0",
|
||||
"pcov/clobber": "^2.0",
|
||||
"phpstan/phpstan": "1.9.*",
|
||||
"phpunit/phpunit": "^9.4",
|
||||
"rregeer/phpunit-coverage-check": "^0.3.1",
|
||||
"swoole/ide-helper": "4.8.0",
|
||||
"utopia-php/cli": "^0.14.0"
|
||||
"utopia-php/cli": "^0.14.0",
|
||||
"vimeo/psalm": "4.0.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -2155,7 +2151,7 @@
|
|||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "A simple library to manage application persistence using multiple database adapters",
|
||||
"description": "A simple library to manage application persistency using multiple database adapters",
|
||||
"keywords": [
|
||||
"database",
|
||||
"framework",
|
||||
|
@ -2165,9 +2161,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/feat-relationships"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.33.0"
|
||||
},
|
||||
"time": "2023-03-15T07:38:26+00:00"
|
||||
"time": "2023-03-08T08:46:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
|
@ -5567,18 +5563,9 @@
|
|||
"time": "2023-02-08T07:49:20+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"package": "utopia-php/database",
|
||||
"version": "dev-feat-relationships",
|
||||
"alias": "0.33.0",
|
||||
"alias_normalized": "0.33.0.0"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"utopia-php/database": 20
|
||||
},
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
@ -5602,5 +5589,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "8.0"
|
||||
},
|
||||
"plugin-api-version": "2.2.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
|
1
docs/references/databases/update-email-attribute.md
Normal file
1
docs/references/databases/update-email-attribute.md
Normal file
|
@ -0,0 +1 @@
|
|||
Update an email attribute. Changing the `default` value will not update already existing documents.
|
1
docs/references/databases/update-enum-attribute.md
Normal file
1
docs/references/databases/update-enum-attribute.md
Normal file
|
@ -0,0 +1 @@
|
|||
Update an enum attribute. Changing the `default` value will not update already existing documents.
|
1
docs/references/databases/update-float-attribute.md
Normal file
1
docs/references/databases/update-float-attribute.md
Normal file
|
@ -0,0 +1 @@
|
|||
Update a float attribute. Changing the `default` value will not update already existing documents.
|
1
docs/references/databases/update-integer-attribute.md
Normal file
1
docs/references/databases/update-integer-attribute.md
Normal file
|
@ -0,0 +1 @@
|
|||
Update an integer attribute. Changing the `default` value will not update already existing documents.
|
1
docs/references/databases/update-ip-attribute.md
Normal file
1
docs/references/databases/update-ip-attribute.md
Normal file
|
@ -0,0 +1 @@
|
|||
Update an ip attribute. Changing the `default` value will not update already existing documents.
|
1
docs/references/databases/update-string-attribute.md
Normal file
1
docs/references/databases/update-string-attribute.md
Normal file
|
@ -0,0 +1 @@
|
|||
Update a string attribute. Changing the `default` value will not update already existing documents.
|
1
docs/references/databases/update-url-attribute.md
Normal file
1
docs/references/databases/update-url-attribute.md
Normal file
|
@ -0,0 +1 @@
|
|||
Update an url attribute. Changing the `default` value will not update already existing documents.
|
|
@ -146,6 +146,7 @@ class Exception extends \Exception
|
|||
public const ATTRIBUTE_ALREADY_EXISTS = 'attribute_already_exists';
|
||||
public const ATTRIBUTE_LIMIT_EXCEEDED = 'attribute_limit_exceeded';
|
||||
public const ATTRIBUTE_VALUE_INVALID = 'attribute_value_invalid';
|
||||
public const ATTRIBUTE_TYPE_INVALID = 'attribute_type_invalid';
|
||||
|
||||
/** Indexes */
|
||||
public const INDEX_NOT_FOUND = 'index_not_found';
|
||||
|
|
|
@ -11,6 +11,7 @@ use GraphQL\Type\Definition\UnionType;
|
|||
use Utopia\App;
|
||||
use Utopia\Route;
|
||||
use Utopia\Validator;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Mapper
|
||||
{
|
||||
|
@ -109,9 +110,6 @@ class Mapper
|
|||
'type' => $parameterType,
|
||||
'description' => $parameter['description'],
|
||||
];
|
||||
if ($parameter['optional']) {
|
||||
$params[$name]['defaultValue'] = $parameter['default'];
|
||||
}
|
||||
}
|
||||
|
||||
$field = [
|
||||
|
@ -224,6 +222,12 @@ class Mapper
|
|||
? \call_user_func_array($validator, $utopia->getResources($injections))
|
||||
: $validator;
|
||||
|
||||
$isNullable = $validator instanceof Nullable;
|
||||
|
||||
if ($isNullable) {
|
||||
$validator = $validator->getValidator();
|
||||
}
|
||||
|
||||
switch ((!empty($validator)) ? $validator::class : '') {
|
||||
case 'Appwrite\Network\Validator\CNAME':
|
||||
case 'Appwrite\Task\Validator\Cron':
|
||||
|
@ -294,7 +298,7 @@ class Mapper
|
|||
break;
|
||||
}
|
||||
|
||||
if ($required) {
|
||||
if ($required && !$isNullable) {
|
||||
$type = Type::nonNull($type);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ use Appwrite\Utopia\Response\Model;
|
|||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Validator;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class OpenAPI3 extends Format
|
||||
{
|
||||
|
@ -284,6 +285,13 @@ class OpenAPI3 extends Format
|
|||
}
|
||||
}
|
||||
|
||||
$isNullable = $validator instanceof Nullable;
|
||||
|
||||
if ($isNullable) {
|
||||
/** @var Nullable $validator */
|
||||
$validator = $validator->getValidator();
|
||||
}
|
||||
|
||||
switch ((!empty($validator)) ? \get_class($validator) : '') {
|
||||
case 'Utopia\Validator\Text':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
|
@ -449,6 +457,10 @@ class OpenAPI3 extends Format
|
|||
if ($node['x-global'] ?? false) {
|
||||
$body['content'][$consumes[0]]['schema']['properties'][$name]['x-global'] = true;
|
||||
}
|
||||
|
||||
if ($isNullable) {
|
||||
$body['content'][$consumes[0]]['schema']['properties'][$name]['x-nullable'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$url = \str_replace(':' . $name, '{' . $name . '}', $url);
|
||||
|
|
|
@ -8,6 +8,7 @@ use Appwrite\Utopia\Response\Model;
|
|||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Validator;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Swagger2 extends Format
|
||||
{
|
||||
|
@ -285,6 +286,13 @@ class Swagger2 extends Format
|
|||
}
|
||||
}
|
||||
|
||||
$isNullable = $validator instanceof Nullable;
|
||||
|
||||
if ($isNullable) {
|
||||
/** @var Nullable $validator */
|
||||
$validator = $validator->getValidator();
|
||||
}
|
||||
|
||||
switch ((!empty($validator)) ? \get_class($validator) : '') {
|
||||
case 'Utopia\Validator\Text':
|
||||
$node['type'] = $validator->getType();
|
||||
|
@ -448,6 +456,10 @@ class Swagger2 extends Format
|
|||
$body['schema']['properties'][$name]['x-global'] = true;
|
||||
}
|
||||
|
||||
if ($isNullable) {
|
||||
$body['schema']['properties'][$name]['x-nullable'] = true;
|
||||
}
|
||||
|
||||
if (\array_key_exists('items', $node)) {
|
||||
$body['schema']['properties'][$name]['items'] = $node['items'];
|
||||
}
|
||||
|
|
|
@ -46,14 +46,7 @@ trait ProjectCustom
|
|||
'name' => 'Demo Project',
|
||||
'teamId' => $team['body']['$id'],
|
||||
'description' => 'Demo Project Description',
|
||||
'logo' => '',
|
||||
'url' => 'https://appwrite.io',
|
||||
'legalName' => '',
|
||||
'legalCountry' => '',
|
||||
'legalState' => '',
|
||||
'legalCity' => '',
|
||||
'legalAddress' => '',
|
||||
'legalTaxId' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $project['headers']['status-code']);
|
||||
|
@ -111,8 +104,6 @@ trait ProjectCustom
|
|||
],
|
||||
'url' => 'http://request-catcher:5000/webhook',
|
||||
'security' => false,
|
||||
'httpUser' => '',
|
||||
'httpPass' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $webhook['headers']['status-code']);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -109,6 +109,7 @@ class FunctionsCustomClientTest extends Scope
|
|||
], [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
@ -223,6 +224,7 @@ class FunctionsCustomClientTest extends Scope
|
|||
], [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), //different tarball names intentional
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
@ -321,6 +323,7 @@ class FunctionsCustomClientTest extends Scope
|
|||
], [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), //different tarball names intentional
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
@ -549,6 +552,7 @@ class FunctionsCustomClientTest extends Scope
|
|||
], [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), //different tarball names intentional
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
|
|
@ -363,6 +363,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
@ -411,6 +412,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$largeTag = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/deployments', array_merge($headers, $this->getHeaders()), [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => $curlFile,
|
||||
'activate' => true
|
||||
]);
|
||||
$counter++;
|
||||
$id = $largeTag['body']['$id'];
|
||||
|
@ -741,7 +743,6 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
@ -752,7 +753,6 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
|
||||
$this->assertEquals('completed', $execution['body']['status']);
|
||||
$this->assertStringContainsString($data['deploymentId'], $execution['body']['response']);
|
||||
$this->assertStringContainsString('Test1', $execution['body']['response']);
|
||||
$this->assertStringContainsString('http', $execution['body']['response']);
|
||||
$this->assertStringContainsString('PHP', $execution['body']['response']);
|
||||
|
@ -869,7 +869,6 @@ class FunctionsCustomServerTest extends Scope
|
|||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'events' => [],
|
||||
'schedule' => '',
|
||||
'timeout' => $timeout,
|
||||
]);
|
||||
|
||||
|
@ -953,7 +952,6 @@ class FunctionsCustomServerTest extends Scope
|
|||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'events' => [],
|
||||
'schedule' => '',
|
||||
'timeout' => $timeout,
|
||||
]);
|
||||
|
||||
|
@ -967,6 +965,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'entrypoint' => $entrypoint,
|
||||
'code' => new CURLFile($code, 'application/x-gzip', basename($code)),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
@ -1063,7 +1062,6 @@ class FunctionsCustomServerTest extends Scope
|
|||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'events' => [],
|
||||
'schedule' => '',
|
||||
'timeout' => $timeout,
|
||||
]);
|
||||
|
||||
|
@ -1176,7 +1174,6 @@ class FunctionsCustomServerTest extends Scope
|
|||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'events' => [],
|
||||
'schedule' => '',
|
||||
'timeout' => $timeout,
|
||||
]);
|
||||
|
||||
|
@ -1290,7 +1287,6 @@ class FunctionsCustomServerTest extends Scope
|
|||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'events' => [],
|
||||
'schedule' => '',
|
||||
'timeout' => $timeout,
|
||||
]);
|
||||
|
||||
|
@ -1404,7 +1400,6 @@ class FunctionsCustomServerTest extends Scope
|
|||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'events' => [],
|
||||
'schedule' => '',
|
||||
'timeout' => $timeout,
|
||||
]);
|
||||
|
||||
|
|
|
@ -26,6 +26,15 @@ trait Base
|
|||
public static string $CREATE_IP_ATTRIBUTE = 'create_ip_attribute';
|
||||
public static string $CREATE_ENUM_ATTRIBUTE = 'create_enum_attribute';
|
||||
public static string $CREATE_DATETIME_ATTRIBUTE = 'create_datetime_attribute';
|
||||
public static string $UPDATE_STRING_ATTRIBUTE = 'update_string_attribute';
|
||||
public static string $UPDATE_INTEGER_ATTRIBUTE = 'update_integer_attribute';
|
||||
public static string $UPDATE_FLOAT_ATTRIBUTE = 'update_float_attribute';
|
||||
public static string $UPDATE_BOOLEAN_ATTRIBUTE = 'update_boolean_attribute';
|
||||
public static string $UPDATE_URL_ATTRIBUTE = 'update_url_attribute';
|
||||
public static string $UPDATE_EMAIL_ATTRIBUTE = 'update_email_attribute';
|
||||
public static string $UPDATE_IP_ATTRIBUTE = 'update_ip_attribute';
|
||||
public static string $UPDATE_ENUM_ATTRIBUTE = 'update_enum_attribute';
|
||||
public static string $UPDATE_DATETIME_ATTRIBUTE = 'update_datetime_attribute';
|
||||
public static string $GET_ATTRIBUTES = 'get_attributes';
|
||||
public static string $GET_ATTRIBUTE = 'get_attribute';
|
||||
public static string $DELETE_ATTRIBUTE = 'delete_attribute';
|
||||
|
@ -451,6 +460,74 @@ trait Base
|
|||
array
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_STRING_ATTRIBUTE:
|
||||
return 'mutation updateStringAttribute($databaseId: String!, $collectionId: String!, $key: String!, $required: Boolean!, $default: String){
|
||||
databasesUpdateStringAttribute(databaseId: $databaseId, collectionId: $collectionId, key: $key, required: $required, default: $default) {
|
||||
required
|
||||
default
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_INTEGER_ATTRIBUTE:
|
||||
return 'mutation updateIntegerAttribute($databaseId: String!, $collectionId: String!, $key: String!, $required: Boolean!, $min: Int!, $max: Int!, $default: Int){
|
||||
databasesUpdateIntegerAttribute(databaseId: $databaseId, collectionId: $collectionId, key: $key, required: $required, min: $min, max: $max, default: $default) {
|
||||
required
|
||||
min
|
||||
max
|
||||
default
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_FLOAT_ATTRIBUTE:
|
||||
return 'mutation updateFloatAttribute($databaseId: String!, $collectionId: String!, $key: String!, $required: Boolean!, $min: Float!, $max: Float!, $default: Float){
|
||||
databasesUpdateFloatAttribute(databaseId: $databaseId, collectionId: $collectionId, key: $key, min: $min, max: $max, required: $required, default: $default) {
|
||||
required
|
||||
min
|
||||
max
|
||||
default
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_BOOLEAN_ATTRIBUTE:
|
||||
return 'mutation updateBooleanAttribute($databaseId: String!, $collectionId: String!, $key: String!, $required: Boolean!, $default: Boolean){
|
||||
databasesUpdateBooleanAttribute(databaseId: $databaseId, collectionId: $collectionId, key: $key, required: $required, default: $default) {
|
||||
required
|
||||
default
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_URL_ATTRIBUTE:
|
||||
return 'mutation updateUrlAttribute($databaseId: String!, $collectionId: String!, $key: String!, $required: Boolean!, $default: String){
|
||||
databasesUpdateUrlAttribute(databaseId: $databaseId, collectionId: $collectionId, key: $key, required: $required, default: $default) {
|
||||
required
|
||||
default
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_EMAIL_ATTRIBUTE:
|
||||
return 'mutation updateEmailAttribute($databaseId: String!, $collectionId: String!, $key: String!, $required: Boolean!, $default: String){
|
||||
databasesUpdateEmailAttribute(databaseId: $databaseId, collectionId: $collectionId, key: $key, required: $required, default: $default) {
|
||||
required
|
||||
default
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_IP_ATTRIBUTE:
|
||||
return 'mutation updateIpAttribute($databaseId: String!, $collectionId: String!, $key: String!, $required: Boolean!, $default: String){
|
||||
databasesUpdateIpAttribute(databaseId: $databaseId, collectionId: $collectionId, key: $key, required: $required, default: $default) {
|
||||
required
|
||||
default
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_ENUM_ATTRIBUTE:
|
||||
return 'mutation updateEnumAttribute($databaseId: String!, $collectionId: String!, $key: String!, $elements: [String!]!, $required: Boolean!, $default: String){
|
||||
databasesUpdateEnumAttribute(databaseId: $databaseId, collectionId: $collectionId, key: $key, elements: $elements, required: $required, default: $default) {
|
||||
elements
|
||||
required
|
||||
default
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_DATETIME_ATTRIBUTE:
|
||||
return 'mutation updateDatetimeAttribute($databaseId: String!, $collectionId: String!, $key: String!, $required: Boolean!, $default: String){
|
||||
databasesUpdateDatetimeAttribute(databaseId: $databaseId, collectionId: $collectionId, key: $key, required: $required, default: $default) {
|
||||
required
|
||||
default
|
||||
}
|
||||
}';
|
||||
case self::$CREATE_INDEX:
|
||||
return 'mutation createIndex($databaseId: String!, $collectionId: String!, $key: String!, $type: String!, $attributes: [String!]!, $orders: [String!]){
|
||||
databasesCreateIndex(databaseId: $databaseId, collectionId: $collectionId, key: $key, type: $type, attributes: $attributes, orders: $orders) {
|
||||
|
|
|
@ -112,6 +112,42 @@ class DatabaseServerTest extends Scope
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateStringAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testUpdateStringAttribute($data): array
|
||||
{
|
||||
// Wait for attributes to be available
|
||||
sleep(3);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$UPDATE_STRING_ATTRIBUTE);
|
||||
$gqlPayload = [
|
||||
'query' => $query,
|
||||
'variables' => [
|
||||
'databaseId' => $data['database']['_id'],
|
||||
'collectionId' => $data['collection']['_id'],
|
||||
'key' => 'name',
|
||||
'required' => false,
|
||||
'default' => 'Default Value',
|
||||
]
|
||||
];
|
||||
|
||||
$attribute = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $gqlPayload);
|
||||
|
||||
$this->assertIsArray($attribute['body']['data']);
|
||||
$this->assertIsArray($attribute['body']['data']['databasesUpdateStringAttribute']);
|
||||
$this->assertFalse($attribute['body']['data']['databasesUpdateStringAttribute']['required']);
|
||||
$this->assertEquals('Default Value', $attribute['body']['data']['databasesUpdateStringAttribute']['default']);
|
||||
$this->assertEquals(200, $attribute['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateCollection
|
||||
* @throws Exception
|
||||
|
@ -144,6 +180,46 @@ class DatabaseServerTest extends Scope
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateIntegerAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testUpdateIntegerAttribute($data): array
|
||||
{
|
||||
// Wait for attributes to be available
|
||||
sleep(3);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$UPDATE_INTEGER_ATTRIBUTE);
|
||||
$gqlPayload = [
|
||||
'query' => $query,
|
||||
'variables' => [
|
||||
'databaseId' => $data['database']['_id'],
|
||||
'collectionId' => $data['collection']['_id'],
|
||||
'key' => 'age',
|
||||
'required' => false,
|
||||
'min' => 12,
|
||||
'max' => 160,
|
||||
'default' => 50
|
||||
]
|
||||
];
|
||||
|
||||
$attribute = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $gqlPayload);
|
||||
|
||||
$this->assertIsArray($attribute['body']['data']);
|
||||
$this->assertIsArray($attribute['body']['data']['databasesUpdateIntegerAttribute']);
|
||||
$this->assertFalse($attribute['body']['data']['databasesUpdateIntegerAttribute']['required']);
|
||||
$this->assertEquals(12, $attribute['body']['data']['databasesUpdateIntegerAttribute']['min']);
|
||||
$this->assertEquals(160, $attribute['body']['data']['databasesUpdateIntegerAttribute']['max']);
|
||||
$this->assertEquals(50, $attribute['body']['data']['databasesUpdateIntegerAttribute']['default']);
|
||||
$this->assertEquals(200, $attribute['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateCollection
|
||||
* @throws Exception
|
||||
|
@ -174,6 +250,42 @@ class DatabaseServerTest extends Scope
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateBooleanAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testUpdateBooleanAttribute($data): array
|
||||
{
|
||||
// Wait for attributes to be available
|
||||
sleep(3);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$UPDATE_BOOLEAN_ATTRIBUTE);
|
||||
$gqlPayload = [
|
||||
'query' => $query,
|
||||
'variables' => [
|
||||
'databaseId' => $data['database']['_id'],
|
||||
'collectionId' => $data['collection']['_id'],
|
||||
'key' => 'alive',
|
||||
'required' => false,
|
||||
'default' => true
|
||||
]
|
||||
];
|
||||
|
||||
$attribute = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $gqlPayload);
|
||||
|
||||
$this->assertIsArray($attribute['body']['data']);
|
||||
$this->assertIsArray($attribute['body']['data']['databasesUpdateBooleanAttribute']);
|
||||
$this->assertFalse($attribute['body']['data']['databasesUpdateBooleanAttribute']['required']);
|
||||
$this->assertTrue($attribute['body']['data']['databasesUpdateBooleanAttribute']['default']);
|
||||
$this->assertEquals(200, $attribute['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateCollection
|
||||
* @throws Exception
|
||||
|
@ -207,6 +319,46 @@ class DatabaseServerTest extends Scope
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateFloatAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testUpdateFloatAttribute($data): array
|
||||
{
|
||||
// Wait for attributes to be available
|
||||
sleep(3);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$UPDATE_FLOAT_ATTRIBUTE);
|
||||
$gqlPayload = [
|
||||
'query' => $query,
|
||||
'variables' => [
|
||||
'databaseId' => $data['database']['_id'],
|
||||
'collectionId' => $data['collection']['_id'],
|
||||
'key' => 'salary',
|
||||
'required' => false,
|
||||
'min' => 100.0,
|
||||
'max' => 1000000.0,
|
||||
'default' => 2500.0
|
||||
]
|
||||
];
|
||||
|
||||
$attribute = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $gqlPayload);
|
||||
|
||||
$this->assertIsArray($attribute['body']['data']);
|
||||
$this->assertIsArray($attribute['body']['data']['databasesUpdateFloatAttribute']);
|
||||
$this->assertFalse($attribute['body']['data']['databasesUpdateFloatAttribute']['required']);
|
||||
$this->assertEquals(100.0, $attribute['body']['data']['databasesUpdateFloatAttribute']['min']);
|
||||
$this->assertEquals(1000000.0, $attribute['body']['data']['databasesUpdateFloatAttribute']['max']);
|
||||
$this->assertEquals(2500.0, $attribute['body']['data']['databasesUpdateFloatAttribute']['default']);
|
||||
$this->assertEquals(200, $attribute['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateCollection
|
||||
* @throws Exception
|
||||
|
@ -237,6 +389,42 @@ class DatabaseServerTest extends Scope
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateEmailAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testUpdateEmailAttribute($data): array
|
||||
{
|
||||
// Wait for attributes to be available
|
||||
sleep(3);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$UPDATE_EMAIL_ATTRIBUTE);
|
||||
$gqlPayload = [
|
||||
'query' => $query,
|
||||
'variables' => [
|
||||
'databaseId' => $data['database']['_id'],
|
||||
'collectionId' => $data['collection']['_id'],
|
||||
'key' => 'email',
|
||||
'required' => false,
|
||||
'default' => 'torsten@appwrite.io',
|
||||
]
|
||||
];
|
||||
|
||||
$attribute = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $gqlPayload);
|
||||
|
||||
$this->assertIsArray($attribute['body']['data']);
|
||||
$this->assertIsArray($attribute['body']['data']['databasesUpdateEmailAttribute']);
|
||||
$this->assertFalse($attribute['body']['data']['databasesUpdateEmailAttribute']['required']);
|
||||
$this->assertEquals('torsten@appwrite.io', $attribute['body']['data']['databasesUpdateEmailAttribute']['default']);
|
||||
$this->assertEquals(200, $attribute['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateCollection
|
||||
* @throws Exception
|
||||
|
@ -272,6 +460,50 @@ class DatabaseServerTest extends Scope
|
|||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @depends testCreateEnumAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testUpdateEnumAttribute($data): array
|
||||
{
|
||||
// Wait for attributes to be available
|
||||
sleep(3);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$UPDATE_ENUM_ATTRIBUTE);
|
||||
$gqlPayload = [
|
||||
'query' => $query,
|
||||
'variables' => [
|
||||
'databaseId' => $data['database']['_id'],
|
||||
'collectionId' => $data['collection']['_id'],
|
||||
'key' => 'role',
|
||||
'required' => false,
|
||||
'elements' => [
|
||||
'crew',
|
||||
'tech',
|
||||
'actor'
|
||||
],
|
||||
'default' => 'tech'
|
||||
]
|
||||
];
|
||||
|
||||
$attribute = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $gqlPayload);
|
||||
|
||||
$this->assertIsArray($attribute['body']['data']);
|
||||
$this->assertIsArray($attribute['body']['data']['databasesUpdateEnumAttribute']);
|
||||
$this->assertFalse($attribute['body']['data']['databasesUpdateEnumAttribute']['required']);
|
||||
$this->assertEquals('tech', $attribute['body']['data']['databasesUpdateEnumAttribute']['default']);
|
||||
$this->assertContains('tech', $attribute['body']['data']['databasesUpdateEnumAttribute']['elements']);
|
||||
$this->assertNotContains('guest', $attribute['body']['data']['databasesUpdateEnumAttribute']['elements']);
|
||||
$this->assertEquals(200, $attribute['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateCollection
|
||||
* @throws Exception
|
||||
|
@ -302,6 +534,42 @@ class DatabaseServerTest extends Scope
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateDatetimeAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testUpdateDatetimeAttribute($data): array
|
||||
{
|
||||
// Wait for attributes to be available
|
||||
sleep(3);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$UPDATE_DATETIME_ATTRIBUTE);
|
||||
$gqlPayload = [
|
||||
'query' => $query,
|
||||
'variables' => [
|
||||
'databaseId' => $data['database']['_id'],
|
||||
'collectionId' => $data['collection']['_id'],
|
||||
'key' => 'dob',
|
||||
'required' => false,
|
||||
'default' => '2000-01-01T00:00:00Z'
|
||||
]
|
||||
];
|
||||
|
||||
$attribute = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $gqlPayload);
|
||||
|
||||
$this->assertIsArray($attribute['body']['data']);
|
||||
$this->assertIsArray($attribute['body']['data']['databasesUpdateDatetimeAttribute']);
|
||||
$this->assertFalse($attribute['body']['data']['databasesUpdateDatetimeAttribute']['required']);
|
||||
$this->assertEquals('2000-01-01T00:00:00Z', $attribute['body']['data']['databasesUpdateDatetimeAttribute']['default']);
|
||||
$this->assertEquals(200, $attribute['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateCollection
|
||||
* @throws Exception
|
||||
|
@ -333,6 +601,42 @@ class DatabaseServerTest extends Scope
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateIPAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testUpdateIPAttribute($data): array
|
||||
{
|
||||
// Wait for attributes to be available
|
||||
sleep(3);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$UPDATE_IP_ATTRIBUTE);
|
||||
$gqlPayload = [
|
||||
'query' => $query,
|
||||
'variables' => [
|
||||
'databaseId' => $data['database']['_id'],
|
||||
'collectionId' => $data['collection']['_id'],
|
||||
'key' => 'ip',
|
||||
'required' => false,
|
||||
'default' => '127.0.0.1'
|
||||
]
|
||||
];
|
||||
|
||||
$attribute = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $gqlPayload);
|
||||
|
||||
$this->assertIsArray($attribute['body']['data']);
|
||||
$this->assertIsArray($attribute['body']['data']['databasesUpdateIpAttribute']);
|
||||
$this->assertFalse($attribute['body']['data']['databasesUpdateIpAttribute']['required']);
|
||||
$this->assertEquals('127.0.0.1', $attribute['body']['data']['databasesUpdateIpAttribute']['default']);
|
||||
$this->assertEquals(200, $attribute['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateCollection
|
||||
* @throws Exception
|
||||
|
@ -365,15 +669,46 @@ class DatabaseServerTest extends Scope
|
|||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateStringAttribute
|
||||
* @depends testCreateIntegerAttribute
|
||||
* @depends testCreateURLAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testCreateIndex($data): array
|
||||
public function testUpdateURLAttribute($data): void
|
||||
{
|
||||
// Wait for attributes to be available
|
||||
sleep(3);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$UPDATE_URL_ATTRIBUTE);
|
||||
$gqlPayload = [
|
||||
'query' => $query,
|
||||
'variables' => [
|
||||
'databaseId' => $data['database']['_id'],
|
||||
'collectionId' => $data['collection']['_id'],
|
||||
'key' => 'url',
|
||||
'required' => false,
|
||||
'default' => 'https://cloud.appwrite.io'
|
||||
]
|
||||
];
|
||||
|
||||
$attribute = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $gqlPayload);
|
||||
|
||||
$this->assertIsArray($attribute['body']['data']);
|
||||
$this->assertIsArray($attribute['body']['data']['databasesUpdateUrlAttribute']);
|
||||
$this->assertFalse($attribute['body']['data']['databasesUpdateUrlAttribute']['required']);
|
||||
$this->assertEquals('https://cloud.appwrite.io', $attribute['body']['data']['databasesUpdateUrlAttribute']['default']);
|
||||
$this->assertEquals(200, $attribute['headers']['status-code']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testUpdateStringAttribute
|
||||
* @depends testUpdateIntegerAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testCreateIndex($data): array
|
||||
{
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$CREATE_INDEX);
|
||||
$gqlPayload = [
|
||||
|
@ -407,10 +742,10 @@ class DatabaseServerTest extends Scope
|
|||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateStringAttribute
|
||||
* @depends testCreateIntegerAttribute
|
||||
* @depends testCreateBooleanAttribute
|
||||
* @depends testCreateEnumAttribute
|
||||
* @depends testUpdateStringAttribute
|
||||
* @depends testUpdateIntegerAttribute
|
||||
* @depends testUpdateBooleanAttribute
|
||||
* @depends testUpdateEnumAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testCreateDocument($data): array
|
||||
|
@ -458,45 +793,45 @@ class DatabaseServerTest extends Scope
|
|||
];
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @depends testCreateStringAttribute
|
||||
// * @depends testCreateIntegerAttribute
|
||||
// * @depends testCreateBooleanAttribute
|
||||
// * @depends testCreateFloatAttribute
|
||||
// * @depends testCreateEmailAttribute
|
||||
// * @depends testCreateEnumAttribute
|
||||
// * @depends testCreateDatetimeAttribute
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public function testCreateCustomEntity(): array
|
||||
// {
|
||||
// $projectId = $this->getProject()['$id'];
|
||||
// $query = $this->getQuery(self::$CREATE_CUSTOM_ENTITY);
|
||||
// $gqlPayload = [
|
||||
// 'query' => $query,
|
||||
// 'variables' => [
|
||||
// 'name' => 'John Doe',
|
||||
// 'age' => 35,
|
||||
// 'alive' => true,
|
||||
// 'salary' => 9999.9,
|
||||
// 'email' => 'johndoe@appwrite.io',
|
||||
// 'role' => 'crew',
|
||||
// 'dob' => '2000-01-01T00:00:00Z',
|
||||
// ]
|
||||
// ];
|
||||
//
|
||||
// $actor = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $projectId,
|
||||
// ], $this->getHeaders()), $gqlPayload);
|
||||
//
|
||||
// $this->assertArrayNotHasKey('errors', $actor['body']);
|
||||
// $this->assertIsArray($actor['body']['data']);
|
||||
// $actor = $actor['body']['data']['actorsCreate'];
|
||||
// $this->assertIsArray($actor);
|
||||
//
|
||||
// return $actor;
|
||||
// }
|
||||
// /**
|
||||
// * @depends testCreateStringAttribute
|
||||
// * @depends testCreateIntegerAttribute
|
||||
// * @depends testCreateBooleanAttribute
|
||||
// * @depends testCreateFloatAttribute
|
||||
// * @depends testCreateEmailAttribute
|
||||
// * @depends testCreateEnumAttribute
|
||||
// * @depends testCreateDatetimeAttribute
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public function testCreateCustomEntity(): array
|
||||
// {
|
||||
// $projectId = $this->getProject()['$id'];
|
||||
// $query = $this->getQuery(self::$CREATE_CUSTOM_ENTITY);
|
||||
// $gqlPayload = [
|
||||
// 'query' => $query,
|
||||
// 'variables' => [
|
||||
// 'name' => 'John Doe',
|
||||
// 'age' => 35,
|
||||
// 'alive' => true,
|
||||
// 'salary' => 9999.9,
|
||||
// 'email' => 'johndoe@appwrite.io',
|
||||
// 'role' => 'crew',
|
||||
// 'dob' => '2000-01-01T00:00:00Z',
|
||||
// ]
|
||||
// ];
|
||||
//
|
||||
// $actor = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $projectId,
|
||||
// ], $this->getHeaders()), $gqlPayload);
|
||||
//
|
||||
// $this->assertArrayNotHasKey('errors', $actor['body']);
|
||||
// $this->assertIsArray($actor['body']['data']);
|
||||
// $actor = $actor['body']['data']['actorsCreate'];
|
||||
// $this->assertIsArray($actor);
|
||||
//
|
||||
// return $actor;
|
||||
// }
|
||||
|
||||
public function testGetDatabases(): void
|
||||
{
|
||||
|
@ -593,8 +928,8 @@ class DatabaseServerTest extends Scope
|
|||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateStringAttribute
|
||||
* @depends testCreateIntegerAttribute
|
||||
* @depends testUpdateStringAttribute
|
||||
* @depends testUpdateIntegerAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testGetAttributes($data): void
|
||||
|
@ -752,52 +1087,52 @@ class DatabaseServerTest extends Scope
|
|||
$this->assertIsArray($document['body']['data']['databasesGetDocument']);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @depends testCreateCustomEntity
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public function testGetCustomEntities($data)
|
||||
// {
|
||||
// $projectId = $this->getProject()['$id'];
|
||||
// $query = $this->getQuery(self::$GET_CUSTOM_ENTITIES);
|
||||
// $gqlPayload = [
|
||||
// 'query' => $query,
|
||||
// ];
|
||||
//
|
||||
// $customEntities = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $projectId,
|
||||
// ], $this->getHeaders()), $gqlPayload);
|
||||
//
|
||||
// $this->assertArrayNotHasKey('errors', $customEntities['body']);
|
||||
// $this->assertIsArray($customEntities['body']['data']);
|
||||
// $this->assertIsArray($customEntities['body']['data']['actorsList']);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @depends testCreateCustomEntity
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public function testGetCustomEntity($data)
|
||||
// {
|
||||
// $projectId = $this->getProject()['$id'];
|
||||
// $query = $this->getQuery(self::$GET_CUSTOM_ENTITY);
|
||||
// $gqlPayload = [
|
||||
// 'query' => $query,
|
||||
// 'variables' => [
|
||||
// 'id' => $data['id'],
|
||||
// ]
|
||||
// ];
|
||||
//
|
||||
// $entity = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $projectId,
|
||||
// ], $this->getHeaders()), $gqlPayload);
|
||||
//
|
||||
// $this->assertArrayNotHasKey('errors', $entity['body']);
|
||||
// $this->assertIsArray($entity['body']['data']);
|
||||
// $this->assertIsArray($entity['body']['data']['actorsGet']);
|
||||
// }
|
||||
// /**
|
||||
// * @depends testCreateCustomEntity
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public function testGetCustomEntities($data)
|
||||
// {
|
||||
// $projectId = $this->getProject()['$id'];
|
||||
// $query = $this->getQuery(self::$GET_CUSTOM_ENTITIES);
|
||||
// $gqlPayload = [
|
||||
// 'query' => $query,
|
||||
// ];
|
||||
//
|
||||
// $customEntities = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $projectId,
|
||||
// ], $this->getHeaders()), $gqlPayload);
|
||||
//
|
||||
// $this->assertArrayNotHasKey('errors', $customEntities['body']);
|
||||
// $this->assertIsArray($customEntities['body']['data']);
|
||||
// $this->assertIsArray($customEntities['body']['data']['actorsList']);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @depends testCreateCustomEntity
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public function testGetCustomEntity($data)
|
||||
// {
|
||||
// $projectId = $this->getProject()['$id'];
|
||||
// $query = $this->getQuery(self::$GET_CUSTOM_ENTITY);
|
||||
// $gqlPayload = [
|
||||
// 'query' => $query,
|
||||
// 'variables' => [
|
||||
// 'id' => $data['id'],
|
||||
// ]
|
||||
// ];
|
||||
//
|
||||
// $entity = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $projectId,
|
||||
// ], $this->getHeaders()), $gqlPayload);
|
||||
//
|
||||
// $this->assertArrayNotHasKey('errors', $entity['body']);
|
||||
// $this->assertIsArray($entity['body']['data']);
|
||||
// $this->assertIsArray($entity['body']['data']['actorsGet']);
|
||||
// }
|
||||
|
||||
/**
|
||||
* @depends testCreateDatabase
|
||||
|
@ -885,33 +1220,33 @@ class DatabaseServerTest extends Scope
|
|||
$this->assertStringContainsString('New Document Name', $document['data']);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @depends testCreateCustomEntity
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public function testUpdateCustomEntity(array $data)
|
||||
// {
|
||||
// $projectId = $this->getProject()['$id'];
|
||||
// $query = $this->getQuery(self::$UPDATE_CUSTOM_ENTITY);
|
||||
// $gqlPayload = [
|
||||
// 'query' => $query,
|
||||
// 'variables' => [
|
||||
// 'id' => $data['id'],
|
||||
// 'name' => 'New Custom Entity Name',
|
||||
// ]
|
||||
// ];
|
||||
//
|
||||
// $entity = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $projectId,
|
||||
// ], $this->getHeaders()), $gqlPayload);
|
||||
//
|
||||
// $this->assertArrayNotHasKey('errors', $entity['body']);
|
||||
// $this->assertIsArray($entity['body']['data']);
|
||||
// $entity = $entity['body']['data']['actorsUpdate'];
|
||||
// $this->assertIsArray($entity);
|
||||
// $this->assertStringContainsString('New Custom Entity Name', $entity['name']);
|
||||
// }
|
||||
// /**
|
||||
// * @depends testCreateCustomEntity
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public function testUpdateCustomEntity(array $data)
|
||||
// {
|
||||
// $projectId = $this->getProject()['$id'];
|
||||
// $query = $this->getQuery(self::$UPDATE_CUSTOM_ENTITY);
|
||||
// $gqlPayload = [
|
||||
// 'query' => $query,
|
||||
// 'variables' => [
|
||||
// 'id' => $data['id'],
|
||||
// 'name' => 'New Custom Entity Name',
|
||||
// ]
|
||||
// ];
|
||||
//
|
||||
// $entity = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $projectId,
|
||||
// ], $this->getHeaders()), $gqlPayload);
|
||||
//
|
||||
// $this->assertArrayNotHasKey('errors', $entity['body']);
|
||||
// $this->assertIsArray($entity['body']['data']);
|
||||
// $entity = $entity['body']['data']['actorsUpdate'];
|
||||
// $this->assertIsArray($entity);
|
||||
// $this->assertStringContainsString('New Custom Entity Name', $entity['name']);
|
||||
// }
|
||||
|
||||
/**
|
||||
* @depends testCreateDocument
|
||||
|
@ -939,32 +1274,32 @@ class DatabaseServerTest extends Scope
|
|||
$this->assertEquals(204, $document['headers']['status-code']);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @depends testCreateCustomEntity
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public function testDeleteCustomEntity(array $data)
|
||||
// {
|
||||
// $projectId = $this->getProject()['$id'];
|
||||
// $query = $this->getQuery(self::$DELETE_CUSTOM_ENTITY);
|
||||
// $gqlPayload = [
|
||||
// 'query' => $query,
|
||||
// 'variables' => [
|
||||
// 'id' => $data['id'],
|
||||
// ]
|
||||
// ];
|
||||
//
|
||||
// $entity = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $projectId,
|
||||
// ], $this->getHeaders()), $gqlPayload);
|
||||
//
|
||||
// $this->assertIsNotArray($entity['body']);
|
||||
// $this->assertEquals(204, $entity['headers']['status-code']);
|
||||
// }
|
||||
// /**
|
||||
// * @depends testCreateCustomEntity
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public function testDeleteCustomEntity(array $data)
|
||||
// {
|
||||
// $projectId = $this->getProject()['$id'];
|
||||
// $query = $this->getQuery(self::$DELETE_CUSTOM_ENTITY);
|
||||
// $gqlPayload = [
|
||||
// 'query' => $query,
|
||||
// 'variables' => [
|
||||
// 'id' => $data['id'],
|
||||
// ]
|
||||
// ];
|
||||
//
|
||||
// $entity = $this->client->call(Client::METHOD_POST, '/graphql', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $projectId,
|
||||
// ], $this->getHeaders()), $gqlPayload);
|
||||
//
|
||||
// $this->assertIsNotArray($entity['body']);
|
||||
// $this->assertEquals(204, $entity['headers']['status-code']);
|
||||
// }
|
||||
|
||||
/**
|
||||
* @depends testCreateStringAttribute
|
||||
* @depends testUpdateStringAttribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testDeleteAttribute($data): void
|
||||
|
|
|
@ -1655,8 +1655,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'events' => ['users.*.delete', 'users.*.sessions.*.delete', 'buckets.*.files.*.create'],
|
||||
'url' => 'https://appwrite.io/new',
|
||||
'security' => false,
|
||||
'httpUser' => '',
|
||||
'httpPass' => ''
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
@ -1703,8 +1701,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'events' => ['users.*.delete', 'users.*.sessions.*.delete', 'buckets.*.files.*.unknown'],
|
||||
'url' => 'https://appwrite.io/new',
|
||||
'security' => false,
|
||||
'httpUser' => '',
|
||||
'httpPass' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
@ -1717,8 +1713,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'events' => ['users.*.delete', 'users.*.sessions.*.delete', 'buckets.*.files.*.create'],
|
||||
'url' => 'appwrite.io/new',
|
||||
'security' => false,
|
||||
'httpUser' => '',
|
||||
'httpPass' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
@ -2090,8 +2084,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'type' => 'web',
|
||||
'name' => 'Web App',
|
||||
'key' => '',
|
||||
'store' => '',
|
||||
'hostname' => 'localhost',
|
||||
]);
|
||||
|
||||
|
@ -2112,8 +2104,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'type' => 'flutter-ios',
|
||||
'name' => 'Flutter App (iOS)',
|
||||
'key' => 'com.example.ios',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
@ -2133,8 +2123,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'type' => 'flutter-android',
|
||||
'name' => 'Flutter App (Android)',
|
||||
'key' => 'com.example.android',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
@ -2153,8 +2141,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'type' => 'flutter-web',
|
||||
'name' => 'Flutter App (Web)',
|
||||
'key' => '',
|
||||
'store' => '',
|
||||
'hostname' => 'flutter.appwrite.io',
|
||||
]);
|
||||
|
||||
|
@ -2175,8 +2161,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'type' => 'apple-ios',
|
||||
'name' => 'iOS App',
|
||||
'key' => 'com.example.ios',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
@ -2196,8 +2180,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'type' => 'apple-macos',
|
||||
'name' => 'macOS App',
|
||||
'key' => 'com.example.macos',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
@ -2217,8 +2199,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'type' => 'apple-watchos',
|
||||
'name' => 'watchOS App',
|
||||
'key' => 'com.example.watchos',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
@ -2238,8 +2218,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'type' => 'apple-tvos',
|
||||
'name' => 'tvOS App',
|
||||
'key' => 'com.example.tvos',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
@ -2261,8 +2239,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'type' => 'unknown',
|
||||
'name' => 'Web App',
|
||||
'key' => '',
|
||||
'store' => '',
|
||||
'hostname' => 'localhost',
|
||||
]);
|
||||
|
||||
|
@ -2457,8 +2433,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Web App 2',
|
||||
'key' => '',
|
||||
'store' => '',
|
||||
'hostname' => 'localhost-new',
|
||||
]);
|
||||
|
||||
|
@ -2479,8 +2453,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'name' => 'Flutter App (iOS) 2',
|
||||
'key' => 'com.example.ios2',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
@ -2500,8 +2472,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'name' => 'Flutter App (Android) 2',
|
||||
'key' => 'com.example.android2',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
@ -2520,8 +2490,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Flutter App (Web) 2',
|
||||
'key' => '',
|
||||
'store' => '',
|
||||
'hostname' => 'flutter2.appwrite.io',
|
||||
]);
|
||||
|
||||
|
@ -2542,8 +2510,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'name' => 'iOS App 2',
|
||||
'key' => 'com.example.ios2',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
@ -2563,8 +2529,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'name' => 'macOS App 2',
|
||||
'key' => 'com.example.macos2',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
@ -2584,8 +2548,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'name' => 'watchOS App 2',
|
||||
'key' => 'com.example.watchos2',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
@ -2605,8 +2567,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'name' => 'tvOS App 2',
|
||||
'key' => 'com.example.tvos2',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
@ -2627,8 +2587,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'name' => 'Flutter App (Android) 2',
|
||||
'key' => 'com.example.android2',
|
||||
'store' => '',
|
||||
'hostname' => '',
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
|
@ -2836,8 +2794,6 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'type' => 'web',
|
||||
'name' => 'Too Long Hostname',
|
||||
'key' => '',
|
||||
'store' => '',
|
||||
'hostname' => \str_repeat("bestdomain", 25) . '.com' // 250 + 4 chars total (exactly above limit)
|
||||
]);
|
||||
|
||||
|
|
|
@ -443,7 +443,7 @@ class RealtimeConsoleClientTest extends Scope
|
|||
'users.*.delete',
|
||||
],
|
||||
'schedule' => '0 0 1 1 *',
|
||||
'timeout' => 10,
|
||||
'timeout' => 10
|
||||
]);
|
||||
|
||||
$functionId = $response1['body']['$id'] ?? '';
|
||||
|
@ -482,6 +482,7 @@ class RealtimeConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
|
|
@ -1284,7 +1284,8 @@ class RealtimeCustomClientTest extends Scope
|
|||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile($code, 'application/x-gzip', basename($code))
|
||||
'code' => new CURLFile($code, 'application/x-gzip', basename($code)),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
|
|
@ -517,11 +517,22 @@ trait TeamsBaseClient
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
]), [
|
||||
'secret' => $secret,
|
||||
'userId' => ID::custom(''),
|
||||
'userId' => ID::custom('$notallowed'),
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/' . $teamUid . '/memberships/' . $membershipUid . '/status', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
]), [
|
||||
'secret' => $secret,
|
||||
'userId' => ID::custom(''),
|
||||
]);
|
||||
|
||||
$this->assertEquals(401, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/' . $teamUid . '/memberships/' . $membershipUid . '/status', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
|
|
|
@ -484,16 +484,6 @@ class WebhooksCustomServerTest extends Scope
|
|||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
|
||||
|
||||
$function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Test Failure',
|
||||
'execute' => [ 'not-valid-permission' ]
|
||||
]);
|
||||
|
||||
$this->assertEquals($function['headers']['status-code'], 400);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
@ -516,7 +506,8 @@ class WebhooksCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code))
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$id = $data['functionId'] ?? '';
|
||||
|
|
Loading…
Reference in a new issue