mirror of
https://github.com/appwrite/appwrite
synced 2026-05-23 08:58:35 +00:00
Merge pull request #8904 from appwrite/1.6.x
Merge 1.6.x into feat-custom-cf-hostnames
This commit is contained in:
commit
75e8635563
20 changed files with 1038 additions and 133 deletions
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
|
|
@ -125,6 +125,7 @@ jobs:
|
|||
Webhooks,
|
||||
VCS,
|
||||
Messaging,
|
||||
Migrations
|
||||
]
|
||||
|
||||
steps:
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ App::post('/v1/account')
|
|||
$identityWithMatchingEmail = $dbForProject->findOne('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
}
|
||||
|
||||
|
|
@ -395,7 +395,7 @@ App::post('/v1/account')
|
|||
$existingTarget = $dbForProject->findOne('targets', [
|
||||
Query::equal('identifier', [$email]),
|
||||
]);
|
||||
if ($existingTarget) {
|
||||
if (!$existingTarget->isEmpty()) {
|
||||
$user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND);
|
||||
}
|
||||
}
|
||||
|
|
@ -834,7 +834,7 @@ App::post('/v1/account/sessions/email')
|
|||
Query::equal('email', [$email]),
|
||||
]);
|
||||
|
||||
if (!$profile || empty($profile->getAttribute('passwordUpdate')) || !Auth::passwordVerify($password, $profile->getAttribute('password'), $profile->getAttribute('hash'), $profile->getAttribute('hashOptions'))) {
|
||||
if ($profile->isEmpty() || empty($profile->getAttribute('passwordUpdate')) || !Auth::passwordVerify($password, $profile->getAttribute('password'), $profile->getAttribute('hash'), $profile->getAttribute('hashOptions'))) {
|
||||
throw new Exception(Exception::USER_INVALID_CREDENTIALS);
|
||||
}
|
||||
|
||||
|
|
@ -1374,7 +1374,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
Query::equal('providerEmail', [$email]),
|
||||
Query::notEqual('userInternalId', $user->getInternalId()),
|
||||
]);
|
||||
if (!empty($identityWithMatchingEmail)) {
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::USER_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
|
|
@ -1405,7 +1405,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
Query::equal('provider', [$provider]),
|
||||
Query::equal('providerUid', [$oauth2ID]),
|
||||
]);
|
||||
if ($session !== false && !$session->isEmpty()) {
|
||||
if (!$session->isEmpty()) {
|
||||
$user->setAttributes($dbForProject->getDocument('users', $session->getAttribute('userId'))->getArrayCopy());
|
||||
}
|
||||
}
|
||||
|
|
@ -1423,7 +1423,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
$userWithEmail = $dbForProject->findOne('users', [
|
||||
Query::equal('email', [$email]),
|
||||
]);
|
||||
if ($userWithEmail !== false && !$userWithEmail->isEmpty()) {
|
||||
if (!$userWithEmail->isEmpty()) {
|
||||
$user->setAttributes($userWithEmail->getArrayCopy());
|
||||
}
|
||||
|
||||
|
|
@ -1434,7 +1434,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
Query::equal('providerUid', [$oauth2ID]),
|
||||
]);
|
||||
|
||||
if ($identity !== false && !$identity->isEmpty()) {
|
||||
if (!$identity->isEmpty()) {
|
||||
$user = $dbForProject->getDocument('users', $identity->getAttribute('userId'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1454,7 +1454,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
$identityWithMatchingEmail = $dbForProject->findOne('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
}
|
||||
|
||||
|
|
@ -1517,7 +1517,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
Query::equal('provider', [$provider]),
|
||||
Query::equal('providerUid', [$oauth2ID]),
|
||||
]);
|
||||
if ($identity === false || $identity->isEmpty()) {
|
||||
if ($identity->isEmpty()) {
|
||||
// Before creating the identity, check if the email is already associated with another user
|
||||
$userId = $user->getId();
|
||||
|
||||
|
|
@ -1801,7 +1801,7 @@ App::post('/v1/account/tokens/magic-url')
|
|||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
$result = $dbForProject->findOne('users', [Query::equal('email', [$email])]);
|
||||
if ($result !== false && !$result->isEmpty()) {
|
||||
if (!$result->isEmpty()) {
|
||||
$user->setAttributes($result->getArrayCopy());
|
||||
} else {
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
|
@ -1818,7 +1818,7 @@ App::post('/v1/account/tokens/magic-url')
|
|||
$identityWithMatchingEmail = $dbForProject->findOne('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
|
|
@ -2042,7 +2042,7 @@ App::post('/v1/account/tokens/email')
|
|||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
$result = $dbForProject->findOne('users', [Query::equal('email', [$email])]);
|
||||
if ($result !== false && !$result->isEmpty()) {
|
||||
if (!$result->isEmpty()) {
|
||||
$user->setAttributes($result->getArrayCopy());
|
||||
} else {
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
|
@ -2059,7 +2059,7 @@ App::post('/v1/account/tokens/email')
|
|||
$identityWithMatchingEmail = $dbForProject->findOne('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
}
|
||||
|
||||
|
|
@ -2329,7 +2329,7 @@ App::post('/v1/account/tokens/phone')
|
|||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
$result = $dbForProject->findOne('users', [Query::equal('phone', [$phone])]);
|
||||
if ($result !== false && !$result->isEmpty()) {
|
||||
if (!$result->isEmpty()) {
|
||||
$user->setAttributes($result->getArrayCopy());
|
||||
} else {
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
|
@ -2386,7 +2386,7 @@ App::post('/v1/account/tokens/phone')
|
|||
$existingTarget = $dbForProject->findOne('targets', [
|
||||
Query::equal('identifier', [$phone]),
|
||||
]);
|
||||
$user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]);
|
||||
$user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget->isEmpty() ? false : $existingTarget]);
|
||||
}
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
}
|
||||
|
|
@ -2753,7 +2753,7 @@ App::patch('/v1/account/email')
|
|||
Query::equal('providerEmail', [$email]),
|
||||
Query::notEqual('userInternalId', $user->getInternalId()),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
}
|
||||
|
||||
|
|
@ -2774,7 +2774,7 @@ App::patch('/v1/account/email')
|
|||
Query::equal('identifier', [$email]),
|
||||
]));
|
||||
|
||||
if ($target instanceof Document && !$target->isEmpty()) {
|
||||
if (!$target->isEmpty()) {
|
||||
throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
|
|
@ -2840,7 +2840,7 @@ App::patch('/v1/account/phone')
|
|||
Query::equal('identifier', [$phone]),
|
||||
]));
|
||||
|
||||
if ($target instanceof Document && !$target->isEmpty()) {
|
||||
if (!$target->isEmpty()) {
|
||||
throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
|
|
@ -2999,7 +2999,7 @@ App::post('/v1/account/recovery')
|
|||
Query::equal('email', [$email]),
|
||||
]);
|
||||
|
||||
if (!$profile) {
|
||||
if ($profile->isEmpty()) {
|
||||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2324,7 +2324,7 @@ App::delete('/v1/functions/:functionId/executions/:executionId')
|
|||
Query::equal('active', [true]),
|
||||
]);
|
||||
|
||||
if ($schedule && !$schedule->isEmpty()) {
|
||||
if (!$schedule->isEmpty()) {
|
||||
$schedule
|
||||
->setAttribute('resourceUpdatedAt', DateTime::now())
|
||||
->setAttribute('active', false);
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ App::post('/v1/migrations/firebase/oauth')
|
|||
Query::equal('provider', ['firebase']),
|
||||
Query::equal('userInternalId', [$user->getInternalId()]),
|
||||
]);
|
||||
if ($identity === false || $identity->isEmpty()) {
|
||||
if ($identity->isEmpty()) {
|
||||
throw new Exception(Exception::USER_IDENTITY_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -576,7 +576,7 @@ App::get('/v1/migrations/firebase/report/oauth')
|
|||
Query::equal('userInternalId', [$user->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($identity === false || $identity->isEmpty()) {
|
||||
if ($identity->isEmpty()) {
|
||||
throw new Exception(Exception::USER_IDENTITY_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -751,13 +751,13 @@ App::get('/v1/migrations/firebase/redirect')
|
|||
Query::equal('providerEmail', [$email]),
|
||||
]);
|
||||
|
||||
if ($identity !== false && !$identity->isEmpty()) {
|
||||
if (!$identity->isEmpty()) {
|
||||
if ($identity->getAttribute('userInternalId', '') !== $user->getInternalId()) {
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
if ($identity !== false && !$identity->isEmpty()) {
|
||||
if (!$identity->isEmpty()) {
|
||||
$identity = $identity
|
||||
->setAttribute('providerAccessToken', $accessToken)
|
||||
->setAttribute('providerRefreshToken', $refreshToken)
|
||||
|
|
@ -820,7 +820,7 @@ App::get('/v1/migrations/firebase/projects')
|
|||
Query::equal('userInternalId', [$user->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($identity === false || $identity->isEmpty()) {
|
||||
if ($identity->isEmpty()) {
|
||||
throw new Exception(Exception::USER_IDENTITY_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -900,7 +900,7 @@ App::get('/v1/migrations/firebase/deauthorize')
|
|||
Query::equal('userInternalId', [$user->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($identity === false || $identity->isEmpty()) {
|
||||
if ($identity->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_ACCESS_FORBIDDEN, 'Not authenticated with Firebase'); //TODO: Replace with USER_IDENTITY_NOT_FOUND
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1060,7 +1060,7 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
if ($webhook->isEmpty()) {
|
||||
throw new Exception(Exception::WEBHOOK_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1103,7 +1103,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
if ($webhook->isEmpty()) {
|
||||
throw new Exception(Exception::WEBHOOK_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1153,7 +1153,7 @@ App::patch('/v1/projects/:projectId/webhooks/:webhookId/signature')
|
|||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
if ($webhook->isEmpty()) {
|
||||
throw new Exception(Exception::WEBHOOK_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1191,7 +1191,7 @@ App::delete('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
if ($webhook->isEmpty()) {
|
||||
throw new Exception(Exception::WEBHOOK_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1313,7 +1313,7 @@ App::get('/v1/projects/:projectId/keys/:keyId')
|
|||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($key === false || $key->isEmpty()) {
|
||||
if ($key->isEmpty()) {
|
||||
throw new Exception(Exception::KEY_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1350,7 +1350,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
|
|||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($key === false || $key->isEmpty()) {
|
||||
if ($key->isEmpty()) {
|
||||
throw new Exception(Exception::KEY_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1392,7 +1392,7 @@ App::delete('/v1/projects/:projectId/keys/:keyId')
|
|||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($key === false || $key->isEmpty()) {
|
||||
if ($key->isEmpty()) {
|
||||
throw new Exception(Exception::KEY_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1550,7 +1550,7 @@ App::get('/v1/projects/:projectId/platforms/:platformId')
|
|||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
if ($platform->isEmpty()) {
|
||||
throw new Exception(Exception::PLATFORM_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1587,7 +1587,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
|
|||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
if ($platform->isEmpty()) {
|
||||
throw new Exception(Exception::PLATFORM_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1631,7 +1631,7 @@ App::delete('/v1/projects/:projectId/platforms/:platformId')
|
|||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
if ($platform->isEmpty()) {
|
||||
throw new Exception(Exception::PLATFORM_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ App::post('/v1/proxy/rules')
|
|||
Query::equal('domain', [$domain]),
|
||||
]);
|
||||
|
||||
if ($document && !$document->isEmpty()) {
|
||||
if (!$document->isEmpty()) {
|
||||
if ($document->getAttribute('projectId') === $project->getId()) {
|
||||
$resourceType = $document->getAttribute('resourceType');
|
||||
$resourceId = $document->getAttribute('resourceId');
|
||||
|
|
|
|||
|
|
@ -467,17 +467,17 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
$name = empty($name) ? $invitee->getAttribute('name', '') : $name;
|
||||
} elseif (!empty($email)) {
|
||||
$invitee = $dbForProject->findOne('users', [Query::equal('email', [$email])]); // Get user by email address
|
||||
if (!empty($invitee) && !empty($phone) && $invitee->getAttribute('phone', '') !== $phone) {
|
||||
if (!$invitee->isEmpty() && !empty($phone) && $invitee->getAttribute('phone', '') !== $phone) {
|
||||
throw new Exception(Exception::USER_ALREADY_EXISTS, 'Given email and phone doesn\'t match', 409);
|
||||
}
|
||||
} elseif (!empty($phone)) {
|
||||
$invitee = $dbForProject->findOne('users', [Query::equal('phone', [$phone])]);
|
||||
if (!empty($invitee) && !empty($email) && $invitee->getAttribute('email', '') !== $email) {
|
||||
if (!$invitee->isEmpty() && !empty($email) && $invitee->getAttribute('email', '') !== $email) {
|
||||
throw new Exception(Exception::USER_ALREADY_EXISTS, 'Given phone and email doesn\'t match', 409);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($invitee)) { // Create new user if no user with same email found
|
||||
if ($invitee->isEmpty()) { // Create new user if no user with same email found
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
||||
if (!$isPrivilegedUser && !$isAppUser && $limit !== 0 && $project->getId() !== 'console') { // check users limit, console invites are allways allowed.
|
||||
|
|
@ -492,7 +492,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
$identityWithMatchingEmail = $dbForProject->findOne('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e
|
|||
$identityWithMatchingEmail = $dbForProject->findOne('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e
|
|||
$existingTarget = $dbForProject->findOne('targets', [
|
||||
Query::equal('identifier', [$email]),
|
||||
]);
|
||||
if ($existingTarget) {
|
||||
if (!$existingTarget->isEmpty()) {
|
||||
$user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND);
|
||||
}
|
||||
}
|
||||
|
|
@ -165,7 +165,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e
|
|||
$existingTarget = $dbForProject->findOne('targets', [
|
||||
Query::equal('identifier', [$phone]),
|
||||
]);
|
||||
if ($existingTarget) {
|
||||
if (!$existingTarget->isEmpty()) {
|
||||
$user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND);
|
||||
}
|
||||
}
|
||||
|
|
@ -1232,7 +1232,7 @@ App::patch('/v1/users/:userId/email')
|
|||
Query::equal('providerEmail', [$email]),
|
||||
Query::notEqual('userInternalId', $user->getInternalId()),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
|||
Query::orderDesc('$createdAt'),
|
||||
]));
|
||||
|
||||
if ($latestComment !== false && !$latestComment->isEmpty()) {
|
||||
if (!$latestComment->isEmpty()) {
|
||||
$latestCommentId = $latestComment->getAttribute('providerCommentId', '');
|
||||
$comment = new Comment();
|
||||
$comment->parseComment($github->getComment($owner, $repositoryName, $latestCommentId));
|
||||
|
|
@ -371,13 +371,11 @@ App::get('/v1/vcs/github/callback')
|
|||
$identity = $dbForConsole->findOne('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
]);
|
||||
if ($identity !== false && !$identity->isEmpty()) {
|
||||
if (!$identity->isEmpty()) {
|
||||
if ($identity->getAttribute('userInternalId', '') !== $user->getInternalId()) {
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
if ($identity !== false && !$identity->isEmpty()) {
|
||||
$identity = $identity
|
||||
->setAttribute('providerAccessToken', $accessToken)
|
||||
->setAttribute('providerRefreshToken', $refreshToken)
|
||||
|
|
@ -418,7 +416,7 @@ App::get('/v1/vcs/github/callback')
|
|||
Query::equal('projectInternalId', [$projectInternalId])
|
||||
]);
|
||||
|
||||
if ($installation === false || $installation->isEmpty()) {
|
||||
if ($installation->isEmpty()) {
|
||||
$teamId = $project->getAttribute('teamId', '');
|
||||
|
||||
$installation = new Document([
|
||||
|
|
@ -726,7 +724,7 @@ App::post('/v1/vcs/github/installations/:installationId/providerRepositories')
|
|||
Query::equal('provider', ['github']),
|
||||
Query::equal('userInternalId', [$user->getInternalId()]),
|
||||
]);
|
||||
if ($identity === false || $identity->isEmpty()) {
|
||||
if ($identity->isEmpty()) {
|
||||
throw new Exception(Exception::USER_IDENTITY_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@ App::init()
|
|||
$mainDomain = $envDomain;
|
||||
} else {
|
||||
$domainDocument = $dbForConsole->findOne('rules', [Query::orderAsc('$id')]);
|
||||
$mainDomain = $domainDocument ? $domainDocument->getAttribute('domain') : $domain->get();
|
||||
$mainDomain = !$domainDocument->isEmpty() ? $domainDocument->getAttribute('domain') : $domain->get();
|
||||
}
|
||||
|
||||
if ($mainDomain !== $domain->get()) {
|
||||
|
|
@ -529,7 +529,7 @@ App::init()
|
|||
Query::equal('domain', [$domain->get()])
|
||||
]);
|
||||
|
||||
if (!$domainDocument) {
|
||||
if ($domainDocument->isEmpty()) {
|
||||
$domainDocument = new Document([
|
||||
'domain' => $domain->get(),
|
||||
'resourceType' => 'api',
|
||||
|
|
|
|||
|
|
@ -1812,9 +1812,6 @@ App::setResource('team', function (Document $project, Database $dbForConsole, Ap
|
|||
]);
|
||||
});
|
||||
|
||||
if (!$team) {
|
||||
$team = new Document([]);
|
||||
}
|
||||
return $team;
|
||||
}, ['project', 'dbForConsole', 'utopia', 'request']);
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
"utopia-php/cache": "0.10.*",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/database": "0.53.8",
|
||||
"utopia-php/database": "0.53.9",
|
||||
"utopia-php/domains": "0.5.*",
|
||||
"utopia-php/dsn": "0.2.1",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
|
|
|
|||
126
composer.lock
generated
126
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": "18505aa5baca1170e7cbdbb2a355b173",
|
||||
"content-hash": "1529d4abfe0432b2d9c838705220ed4a",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
|
@ -157,16 +157,16 @@
|
|||
},
|
||||
{
|
||||
"name": "appwrite/php-runtimes",
|
||||
"version": "0.16.2",
|
||||
"version": "0.16.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/runtimes.git",
|
||||
"reference": "c33005e3eaaf2d427e9fd1077d5335e31f4d36f9"
|
||||
"reference": "7e4741337b9373f77210396e68eca539018cabd1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/runtimes/zipball/c33005e3eaaf2d427e9fd1077d5335e31f4d36f9",
|
||||
"reference": "c33005e3eaaf2d427e9fd1077d5335e31f4d36f9",
|
||||
"url": "https://api.github.com/repos/appwrite/runtimes/zipball/7e4741337b9373f77210396e68eca539018cabd1",
|
||||
"reference": "7e4741337b9373f77210396e68eca539018cabd1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -206,22 +206,22 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/runtimes/issues",
|
||||
"source": "https://github.com/appwrite/runtimes/tree/0.16.2"
|
||||
"source": "https://github.com/appwrite/runtimes/tree/0.16.4"
|
||||
},
|
||||
"time": "2024-10-09T15:02:52+00:00"
|
||||
"time": "2024-10-26T10:39:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "beberlei/assert",
|
||||
"version": "v3.3.2",
|
||||
"version": "v3.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/beberlei/assert.git",
|
||||
"reference": "cb70015c04be1baee6f5f5c953703347c0ac1655"
|
||||
"reference": "b5fd8eacd8915a1b627b8bfc027803f1939734dd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/beberlei/assert/zipball/cb70015c04be1baee6f5f5c953703347c0ac1655",
|
||||
"reference": "cb70015c04be1baee6f5f5c953703347c0ac1655",
|
||||
"url": "https://api.github.com/repos/beberlei/assert/zipball/b5fd8eacd8915a1b627b8bfc027803f1939734dd",
|
||||
"reference": "b5fd8eacd8915a1b627b8bfc027803f1939734dd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -229,7 +229,7 @@
|
|||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-simplexml": "*",
|
||||
"php": "^7.0 || ^8.0"
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "*",
|
||||
|
|
@ -273,9 +273,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/beberlei/assert/issues",
|
||||
"source": "https://github.com/beberlei/assert/tree/v3.3.2"
|
||||
"source": "https://github.com/beberlei/assert/tree/v3.3.3"
|
||||
},
|
||||
"time": "2021-12-16T21:41:27+00:00"
|
||||
"time": "2024-07-15T13:18:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "chillerlan/php-qrcode",
|
||||
|
|
@ -1724,16 +1724,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.53.8",
|
||||
"version": "0.53.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "f4f9297d633b9f8407c6261535549bfd6024a468"
|
||||
"reference": "19969d2c6d29b5d1cbf4cb1a33e18017a54f30e3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/f4f9297d633b9f8407c6261535549bfd6024a468",
|
||||
"reference": "f4f9297d633b9f8407c6261535549bfd6024a468",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/19969d2c6d29b5d1cbf4cb1a33e18017a54f30e3",
|
||||
"reference": "19969d2c6d29b5d1cbf4cb1a33e18017a54f30e3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1774,9 +1774,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.53.8"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.53.9"
|
||||
},
|
||||
"time": "2024-10-16T08:16:33+00:00"
|
||||
"time": "2024-10-31T08:18:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
|
|
@ -2175,16 +2175,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
"version": "0.6.9",
|
||||
"version": "0.6.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/migration.git",
|
||||
"reference": "ce97cdf2ca82e7cec78e2ed484ef2c71ebe8744b"
|
||||
"reference": "4d167914d3f7fa1fe816b2b2c6f221e70166bfd7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/ce97cdf2ca82e7cec78e2ed484ef2c71ebe8744b",
|
||||
"reference": "ce97cdf2ca82e7cec78e2ed484ef2c71ebe8744b",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/4d167914d3f7fa1fe816b2b2c6f221e70166bfd7",
|
||||
"reference": "4d167914d3f7fa1fe816b2b2c6f221e70166bfd7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2225,9 +2225,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/migration/issues",
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.6.9"
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.6.11"
|
||||
},
|
||||
"time": "2024-10-16T08:33:21+00:00"
|
||||
"time": "2024-10-31T06:19:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/mongo",
|
||||
|
|
@ -5875,16 +5875,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.1.5",
|
||||
"version": "v7.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee"
|
||||
"reference": "bb5192af6edc797cbab5c8e8ecfea2fe5f421e57"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee",
|
||||
"reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/bb5192af6edc797cbab5c8e8ecfea2fe5f421e57",
|
||||
"reference": "bb5192af6edc797cbab5c8e8ecfea2fe5f421e57",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -5948,7 +5948,7 @@
|
|||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.1.5"
|
||||
"source": "https://github.com/symfony/console/tree/v7.1.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -5964,7 +5964,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-20T08:28:38+00:00"
|
||||
"time": "2024-10-09T08:46:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
|
|
@ -6035,16 +6035,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v7.1.5",
|
||||
"version": "v7.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a"
|
||||
"reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/61fe0566189bf32e8cfee78335d8776f64a66f5a",
|
||||
"reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/c835867b3c62bb05c7fe3d637c871c7ae52024d4",
|
||||
"reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -6081,7 +6081,7 @@
|
|||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v7.1.5"
|
||||
"source": "https://github.com/symfony/filesystem/tree/v7.1.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -6097,20 +6097,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-17T09:16:35+00:00"
|
||||
"time": "2024-10-25T15:11:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v7.1.4",
|
||||
"version": "v7.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "d95bbf319f7d052082fb7af147e0f835a695e823"
|
||||
"reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823",
|
||||
"reference": "d95bbf319f7d052082fb7af147e0f835a695e823",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/2cb89664897be33f78c65d3d2845954c8d7a43b8",
|
||||
"reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -6145,7 +6145,7 @@
|
|||
"description": "Finds files and directories via an intuitive fluent interface",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/finder/tree/v7.1.4"
|
||||
"source": "https://github.com/symfony/finder/tree/v7.1.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -6161,20 +6161,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-08-13T14:28:19+00:00"
|
||||
"time": "2024-10-01T08:31:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v7.1.1",
|
||||
"version": "v7.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/options-resolver.git",
|
||||
"reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55"
|
||||
"reference": "85e95eeede2d41cd146146e98c9c81d9214cae85"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/47aa818121ed3950acd2b58d1d37d08a94f9bf55",
|
||||
"reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/85e95eeede2d41cd146146e98c9c81d9214cae85",
|
||||
"reference": "85e95eeede2d41cd146146e98c9c81d9214cae85",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -6212,7 +6212,7 @@
|
|||
"options"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.1.1"
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.1.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -6228,7 +6228,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-05-31T14:57:53+00:00"
|
||||
"time": "2024-09-25T14:20:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
|
|
@ -6546,16 +6546,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v7.1.5",
|
||||
"version": "v7.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "5c03ee6369281177f07f7c68252a280beccba847"
|
||||
"reference": "6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847",
|
||||
"reference": "5c03ee6369281177f07f7c68252a280beccba847",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e",
|
||||
"reference": "6aaa189ddb4ff6b5de8fa3210f2fb42c87b4d12e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -6587,7 +6587,7 @@
|
|||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v7.1.5"
|
||||
"source": "https://github.com/symfony/process/tree/v7.1.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -6603,7 +6603,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-19T21:48:23+00:00"
|
||||
"time": "2024-09-25T14:20:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
|
|
@ -6690,16 +6690,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v7.1.5",
|
||||
"version": "v7.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "d66f9c343fa894ec2037cc928381df90a7ad4306"
|
||||
"reference": "61b72d66bf96c360a727ae6232df5ac83c71f626"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306",
|
||||
"reference": "d66f9c343fa894ec2037cc928381df90a7ad4306",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/61b72d66bf96c360a727ae6232df5ac83c71f626",
|
||||
"reference": "61b72d66bf96c360a727ae6232df5ac83c71f626",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -6757,7 +6757,7 @@
|
|||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v7.1.5"
|
||||
"source": "https://github.com/symfony/string/tree/v7.1.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -6773,7 +6773,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-20T08:28:38+00:00"
|
||||
"time": "2024-09-25T14:20:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "textalk/websocket",
|
||||
|
|
@ -7005,7 +7005,7 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
<directory>./tests/e2e/Services/Storage</directory>
|
||||
<directory>./tests/e2e/Services/Webhooks</directory>
|
||||
<directory>./tests/e2e/Services/Messaging</directory>
|
||||
<directory>./tests/e2e/Services/Migrations</directory>
|
||||
<file>./tests/e2e/Services/Functions/FunctionsBase.php</file>
|
||||
<file>./tests/e2e/Services/Functions/FunctionsCustomServerTest.php</file>
|
||||
<file>./tests/e2e/Services/Functions/FunctionsCustomClientTest.php</file>
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ class Certificates extends Action
|
|||
$certificate = $dbForConsole->findOne('certificates', [Query::equal('domain', [$domain->get()])]);
|
||||
|
||||
// If we don't have certificate for domain yet, let's create new document. At the end we save it
|
||||
if (!$certificate) {
|
||||
if ($certificate->isEmpty()) {
|
||||
$certificate = new Document();
|
||||
$certificate->setAttribute('domain', $domain->get());
|
||||
}
|
||||
|
|
@ -258,7 +258,7 @@ class Certificates extends Action
|
|||
{
|
||||
// Check if update or insert required
|
||||
$certificateDocument = $dbForConsole->findOne('certificates', [Query::equal('domain', [$domain])]);
|
||||
if (!empty($certificateDocument) && !$certificateDocument->isEmpty()) {
|
||||
if (!$certificateDocument->isEmpty()) {
|
||||
// Merge new data with current data
|
||||
$certificate = new Document(\array_merge($certificateDocument->getArrayCopy(), $certificate->getArrayCopy()));
|
||||
$certificate = $dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate);
|
||||
|
|
@ -524,7 +524,7 @@ class Certificates extends Action
|
|||
Query::equal('domain', [$domain]),
|
||||
]);
|
||||
|
||||
if ($rule !== false && !$rule->isEmpty()) {
|
||||
if (!$rule->isEmpty()) {
|
||||
$rule->setAttribute('certificateId', $certificateId);
|
||||
$rule->setAttribute('status', $success ? 'verified' : 'unverified');
|
||||
$dbForConsole->updateDocument('rules', $rule->getId(), $rule);
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ class Messaging extends Action
|
|||
Query::equal('type', [$providerType]),
|
||||
]);
|
||||
|
||||
if ($default === false || $default->isEmpty()) {
|
||||
if ($default->isEmpty()) {
|
||||
$dbForProject->updateDocument('messages', $message->getId(), $message->setAttributes([
|
||||
'status' => MessageStatus::FAILED,
|
||||
'deliveryErrors' => ['No enabled provider found.']
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ class Migrations extends Action
|
|||
),
|
||||
SourceAppwrite::getName() => new SourceAppwrite(
|
||||
$credentials['projectId'],
|
||||
$credentials['endpoint'],
|
||||
$credentials['endpoint'] === 'http://localhost/v1' ? 'http://appwrite/v1' : $credentials['endpoint'],
|
||||
$credentials['apiKey'],
|
||||
),
|
||||
default => throw new \Exception('Invalid source type'),
|
||||
|
|
@ -134,16 +134,15 @@ class Migrations extends Action
|
|||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function processDestination(Document $migration): Destination
|
||||
protected function processDestination(Document $migration, string $apiKey): Destination
|
||||
{
|
||||
$destination = $migration->getAttribute('destination');
|
||||
$credentials = $migration->getAttribute('credentials');
|
||||
|
||||
return match ($destination) {
|
||||
DestinationAppwrite::getName() => new DestinationAppwrite(
|
||||
$credentials['projectId'],
|
||||
$credentials['endpoint'],
|
||||
$credentials['apiKey'],
|
||||
$this->project->getId(),
|
||||
'http://appwrite/v1',
|
||||
$apiKey,
|
||||
$this->dbForProject,
|
||||
Config::getParam('collections', [])['databases']['collections'],
|
||||
),
|
||||
|
|
@ -272,8 +271,8 @@ class Migrations extends Action
|
|||
$migration = $this->dbForProject->getDocument('migrations', $migration->getId());
|
||||
|
||||
if (
|
||||
$migration->getAttribute('source') === SourceAppwrite::getName() ||
|
||||
$migration->getAttribute('destination') === DestinationAppwrite::getName()
|
||||
$migration->getAttribute('source') === SourceAppwrite::getName() &&
|
||||
empty($migration->getAttribute('credentials', []))
|
||||
) {
|
||||
$credentials = $migration->getAttribute('credentials', []);
|
||||
|
||||
|
|
@ -291,7 +290,7 @@ class Migrations extends Action
|
|||
$log->addTag('type', $migration->getAttribute('source'));
|
||||
|
||||
$source = $this->processSource($migration);
|
||||
$destination = $this->processDestination($migration);
|
||||
$destination = $this->processDestination($migration, $tempAPIKey->getAttribute('secret'));
|
||||
|
||||
$source->report();
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ trait ProjectCustom
|
|||
'topics.read',
|
||||
'subscribers.write',
|
||||
'subscribers.read',
|
||||
'migrations.write',
|
||||
'migrations.read'
|
||||
],
|
||||
]);
|
||||
|
||||
|
|
|
|||
895
tests/e2e/Services/Migrations/MigrationsBase.php
Normal file
895
tests/e2e/Services/Migrations/MigrationsBase.php
Normal file
|
|
@ -0,0 +1,895 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\E2E\Services\Migrations;
|
||||
|
||||
use CURLFile;
|
||||
use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Services\Functions\FunctionsBase;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Migration\Resource;
|
||||
use Utopia\Migration\Sources\Appwrite;
|
||||
|
||||
trait MigrationsBase
|
||||
{
|
||||
use ProjectCustom;
|
||||
use FunctionsBase;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $destinationProject = [];
|
||||
|
||||
/**
|
||||
* @param bool $fresh
|
||||
* @return array
|
||||
*/
|
||||
public function getDesintationProject(bool $fresh = false): array
|
||||
{
|
||||
if (!empty(self::$destinationProject) && !$fresh) {
|
||||
return self::$destinationProject;
|
||||
}
|
||||
|
||||
$projectBackup = self::$project;
|
||||
|
||||
self::$destinationProject = $this->getProject(true);
|
||||
self::$project = $projectBackup;
|
||||
|
||||
return self::$destinationProject;
|
||||
}
|
||||
|
||||
public function performMigrationSync(
|
||||
array $body,
|
||||
): array {
|
||||
$migration = $this->client->call(Client::METHOD_POST, '/migrations/appwrite', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
], $body);
|
||||
|
||||
$this->assertEquals(202, $migration['headers']['status-code']);
|
||||
$this->assertNotEmpty($migration['body']);
|
||||
$this->assertNotEmpty($migration['body']['$id']);
|
||||
|
||||
$attempts = 0;
|
||||
while ($attempts < 5) {
|
||||
$response = $this->client->call(Client::METHOD_GET, '/migrations/' . $migration['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
|
||||
if ($response['body']['status'] === 'failed') {
|
||||
$this->fail('Migration failed', json_encode($response['body'], JSON_PRETTY_PRINT));
|
||||
}
|
||||
|
||||
$this->assertNotEquals('failed', $response['body']['status']);
|
||||
|
||||
if ($response['body']['status'] === 'completed') {
|
||||
return $response['body'];
|
||||
}
|
||||
|
||||
if ($attempts === 4) {
|
||||
$this->assertEquals('completed', $response['body']['status']);
|
||||
}
|
||||
|
||||
$attempts++;
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appwrite E2E Migration Tests
|
||||
*/
|
||||
public function testCreateAppwriteMigration()
|
||||
{
|
||||
$response = $this->performMigrationSync([
|
||||
'resources' => Appwrite::getSupportedResources(),
|
||||
'endpoint' => 'http://localhost/v1',
|
||||
'projectId' => $this->getProject()['$id'],
|
||||
'apiKey' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(Appwrite::getSupportedResources(), $response['resources']);
|
||||
$this->assertEquals('Appwrite', $response['source']);
|
||||
$this->assertEquals('Appwrite', $response['destination']);
|
||||
$this->assertEmpty($response['statusCounters']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auth
|
||||
*/
|
||||
public function testAppwriteMigrationAuthUserPassword()
|
||||
{
|
||||
$response = $this->client->call(Client::METHOD_POST, '/users', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'userId' => ID::unique(),
|
||||
'email' => 'test@test.com',
|
||||
'password' => 'password',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertEquals('test@test.com', $response['body']['email']);
|
||||
|
||||
$user = $response['body'];
|
||||
|
||||
$result = $this->performMigrationSync([
|
||||
'resources' => [
|
||||
Resource::TYPE_USER,
|
||||
],
|
||||
'endpoint' => 'http://localhost/v1',
|
||||
'projectId' => $this->getProject()['$id'],
|
||||
'apiKey' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals('completed', $result['status']);
|
||||
$this->assertEquals([Resource::TYPE_USER], $result['resources']);
|
||||
$this->assertArrayHasKey(Resource::TYPE_USER, $result['statusCounters']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][Resource::TYPE_USER]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['warning']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users/' . $user['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertEquals($user['email'], $response['body']['email']);
|
||||
$this->assertEquals($user['password'], $response['body']['password']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/users/' . $user['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/users/' . $user['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testAppwriteMigrationAuthUserPhone()
|
||||
{
|
||||
$response = $this->client->call(Client::METHOD_POST, '/users', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'userId' => ID::unique(),
|
||||
'phone' => '+12065550100',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertEquals('+12065550100', $response['body']['phone']);
|
||||
|
||||
$user = $response['body'];
|
||||
|
||||
$result = $this->performMigrationSync([
|
||||
'resources' => [
|
||||
Resource::TYPE_USER,
|
||||
],
|
||||
'endpoint' => 'http://localhost/v1',
|
||||
'projectId' => $this->getProject()['$id'],
|
||||
'apiKey' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals('completed', $result['status']);
|
||||
$this->assertEquals([Resource::TYPE_USER], $result['resources']);
|
||||
$this->assertArrayHasKey(Resource::TYPE_USER, $result['statusCounters']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][Resource::TYPE_USER]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['warning']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users/' . $user['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertEquals($user['phone'], $response['body']['phone']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/users/' . $user['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/users/' . $user['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testAppwriteMigrationAuthTeam()
|
||||
{
|
||||
$user = $this->client->call(Client::METHOD_POST, '/users', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'userId' => ID::unique(),
|
||||
'email' => 'test@test.com',
|
||||
'password' => 'password',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $user['headers']['status-code']);
|
||||
$this->assertNotEmpty($user['body']);
|
||||
$this->assertNotEmpty($user['body']['$id']);
|
||||
$this->assertEquals('test@test.com', $user['body']['email']);
|
||||
|
||||
$team = $this->client->call(Client::METHOD_POST, '/teams', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'teamId' => ID::unique(),
|
||||
'name' => 'Test Team',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $team['headers']['status-code']);
|
||||
$this->assertNotEmpty($team['body']);
|
||||
$this->assertNotEmpty($team['body']['$id']);
|
||||
|
||||
$membership = $this->client->call(Client::METHOD_POST, '/teams/' . $team['body']['$id'] . '/memberships', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'teamId' => $team['body']['$id'],
|
||||
'userId' => $user['body']['$id'],
|
||||
'roles' => ['owner'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $membership['headers']['status-code']);
|
||||
$this->assertNotEmpty($membership['body']);
|
||||
$this->assertNotEmpty($membership['body']['$id']);
|
||||
|
||||
$result = $this->performMigrationSync([
|
||||
'resources' => [
|
||||
Resource::TYPE_USER,
|
||||
Resource::TYPE_TEAM,
|
||||
Resource::TYPE_MEMBERSHIP,
|
||||
],
|
||||
'endpoint' => 'http://localhost/v1',
|
||||
'projectId' => $this->getProject()['$id'],
|
||||
'apiKey' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals('completed', $result['status']);
|
||||
$this->assertEquals([Resource::TYPE_USER, Resource::TYPE_TEAM, Resource::TYPE_MEMBERSHIP], $result['resources']);
|
||||
$this->assertArrayHasKey(Resource::TYPE_USER, $result['statusCounters']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][Resource::TYPE_USER]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['warning']);
|
||||
|
||||
$this->assertArrayHasKey(Resource::TYPE_TEAM, $result['statusCounters']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_TEAM]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_TEAM]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][Resource::TYPE_TEAM]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_TEAM]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_TEAM]['warning']);
|
||||
|
||||
$this->assertArrayHasKey(Resource::TYPE_MEMBERSHIP, $result['statusCounters']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_MEMBERSHIP]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_MEMBERSHIP]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][Resource::TYPE_MEMBERSHIP]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_MEMBERSHIP]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_MEMBERSHIP]['warning']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/teams/' . $team['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertEquals($team['body']['name'], $response['body']['name']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/teams/' . $team['body']['$id'] . '/memberships', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
|
||||
$membership = $response['body']['memberships'][0];
|
||||
|
||||
$this->assertEquals($user['body']['$id'], $membership['userId']);
|
||||
$this->assertEquals($team['body']['$id'], $membership['teamId']);
|
||||
$this->assertEquals(['owner'], $membership['roles']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/teams/' . $team['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/teams/' . $team['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/users/' . $user['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/users/' . $user['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/teams/' . $team['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/teams/' . $team['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Databases
|
||||
*/
|
||||
public function testAppwriteMigrationDatabase()
|
||||
{
|
||||
$response = $this->client->call(Client::METHOD_POST, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Test Database'
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
|
||||
$databaseId = $response['body']['$id'];
|
||||
|
||||
$result = $this->performMigrationSync([
|
||||
'resources' => [
|
||||
Resource::TYPE_DATABASE,
|
||||
],
|
||||
'endpoint' => 'http://localhost/v1',
|
||||
'projectId' => $this->getProject()['$id'],
|
||||
'apiKey' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
|
||||
$this->assertEquals('completed', $result['status']);
|
||||
$this->assertEquals([Resource::TYPE_DATABASE], $result['resources']);
|
||||
$this->assertArrayHasKey(Resource::TYPE_DATABASE, $result['statusCounters']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][Resource::TYPE_DATABASE]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['warning']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
|
||||
$this->assertEquals($databaseId, $response['body']['$id']);
|
||||
$this->assertEquals('Test Database', $response['body']['name']);
|
||||
|
||||
// Cleanup on destination
|
||||
$this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
return [
|
||||
'databaseId' => $databaseId,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testAppwriteMigrationDatabase
|
||||
*/
|
||||
public function testAppwriteMigrationDatabasesCollection(array $data)
|
||||
{
|
||||
$databaseId = $data['databaseId'];
|
||||
|
||||
$collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'collectionId' => ID::unique(),
|
||||
'name' => 'Test Collection',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $collection['headers']['status-code']);
|
||||
|
||||
$collectionId = $collection['body']['$id'];
|
||||
|
||||
// Create Attribute
|
||||
$response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'key' => 'name',
|
||||
'size' => 100,
|
||||
'encrypt' => false,
|
||||
'required' => true
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $response['headers']['status-code']);
|
||||
|
||||
// Wait for attribute to be ready
|
||||
$this->assertEventually(function () use ($databaseId, $collectionId) {
|
||||
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/name', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals('available', $response['body']['status']);
|
||||
}, 5000, 500);
|
||||
|
||||
$result = $this->performMigrationSync([
|
||||
'resources' => [
|
||||
Resource::TYPE_DATABASE,
|
||||
Resource::TYPE_COLLECTION,
|
||||
Resource::TYPE_ATTRIBUTE,
|
||||
],
|
||||
'endpoint' => 'http://localhost/v1',
|
||||
'projectId' => $this->getProject()['$id'],
|
||||
'apiKey' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals('completed', $result['status']);
|
||||
$this->assertEquals([Resource::TYPE_DATABASE, Resource::TYPE_COLLECTION, Resource::TYPE_ATTRIBUTE], $result['resources']);
|
||||
|
||||
foreach ([Resource::TYPE_DATABASE, Resource::TYPE_COLLECTION, Resource::TYPE_ATTRIBUTE] as $resource) {
|
||||
$this->assertArrayHasKey($resource, $result['statusCounters']);
|
||||
$this->assertEquals(0, $result['statusCounters'][$resource]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][$resource]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][$resource]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][$resource]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][$resource]['warning']);
|
||||
}
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
|
||||
$this->assertEquals($collectionId, $response['body']['$id']);
|
||||
$this->assertEquals('Test Collection', $response['body']['name']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/name', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
|
||||
$this->assertEquals('name', $response['body']['key']);
|
||||
$this->assertEquals(100, $response['body']['size']);
|
||||
$this->assertEquals(true, $response['body']['required']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
return [
|
||||
'databaseId' => $databaseId,
|
||||
'collectionId' => $collectionId,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testAppwriteMigrationDatabasesCollection
|
||||
*/
|
||||
public function testAppwriteMigrationDatabasesDocument(array $data)
|
||||
{
|
||||
$databaseId = $data['databaseId'];
|
||||
$collectionId = $data['collectionId'];
|
||||
|
||||
$document = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'documentId' => ID::unique(),
|
||||
'data' => [
|
||||
'name' => 'Test Document',
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $document['headers']['status-code']);
|
||||
$this->assertNotEmpty($document['body']);
|
||||
$this->assertNotEmpty($document['body']['$id']);
|
||||
|
||||
$documentId = $document['body']['$id'];
|
||||
|
||||
$result = $this->performMigrationSync([
|
||||
'resources' => [
|
||||
Resource::TYPE_DATABASE,
|
||||
Resource::TYPE_COLLECTION,
|
||||
Resource::TYPE_ATTRIBUTE,
|
||||
Resource::TYPE_DOCUMENT,
|
||||
],
|
||||
'endpoint' => 'http://localhost/v1',
|
||||
'projectId' => $this->getProject()['$id'],
|
||||
'apiKey' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals('completed', $result['status']);
|
||||
$this->assertEquals([Resource::TYPE_DATABASE, Resource::TYPE_COLLECTION, Resource::TYPE_ATTRIBUTE, Resource::TYPE_DOCUMENT], $result['resources']);
|
||||
|
||||
//TODO: Add TYPE_DOCUMENT to the migration status counters once pending issue is resolved
|
||||
foreach ([Resource::TYPE_DATABASE, Resource::TYPE_COLLECTION, Resource::TYPE_ATTRIBUTE] as $resource) {
|
||||
$this->assertArrayHasKey($resource, $result['statusCounters']);
|
||||
$this->assertEquals(0, $result['statusCounters'][$resource]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][$resource]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][$resource]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][$resource]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][$resource]['warning']);
|
||||
}
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
|
||||
$this->assertEquals($documentId, $response['body']['$id']);
|
||||
$this->assertEquals('Test Document', $response['body']['name']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Storage
|
||||
*/
|
||||
public function testAppwriteMigrationStorageBucket()
|
||||
{
|
||||
$bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'bucketId' => ID::unique(),
|
||||
'name' => 'Test Bucket',
|
||||
'permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::create(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'maximumFileSize' => 1000000,
|
||||
'allowedFileExtensions' => ['pdf'],
|
||||
'compression' => 'gzip',
|
||||
'encryption' => false,
|
||||
'antivirus' => false
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $bucket['headers']['status-code']);
|
||||
$this->assertNotEmpty($bucket['body']);
|
||||
$this->assertNotEmpty($bucket['body']['$id']);
|
||||
$this->assertEquals('Test Bucket', $bucket['body']['name']);
|
||||
|
||||
$result = $this->performMigrationSync([
|
||||
'resources' => [
|
||||
Resource::TYPE_BUCKET
|
||||
],
|
||||
'endpoint' => 'http://localhost/v1',
|
||||
'projectId' => $this->getProject()['$id'],
|
||||
'apiKey' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals('completed', $result['status']);
|
||||
$this->assertEquals([Resource::TYPE_BUCKET], $result['resources']);
|
||||
$this->assertArrayHasKey(Resource::TYPE_BUCKET, $result['statusCounters']);
|
||||
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][Resource::TYPE_BUCKET]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['warning']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucket['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
|
||||
$this->assertEquals($bucket['body']['$id'], $response['body']['$id']);
|
||||
$this->assertEquals($bucket['body']['name'], $response['body']['name']);
|
||||
$this->assertEquals($bucket['body']['$permissions'], $response['body']['$permissions']);
|
||||
$this->assertEquals($bucket['body']['maximumFileSize'], $response['body']['maximumFileSize']);
|
||||
$this->assertEquals($bucket['body']['allowedFileExtensions'], $response['body']['allowedFileExtensions']);
|
||||
$this->assertEquals($bucket['body']['compression'], $response['body']['compression']);
|
||||
$this->assertEquals($bucket['body']['encryption'], $response['body']['encryption']);
|
||||
$this->assertEquals($bucket['body']['antivirus'], $response['body']['antivirus']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $bucket['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $bucket['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testAppwriteMigrationStorageFiles()
|
||||
{
|
||||
$bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'bucketId' => ID::unique(),
|
||||
'name' => 'Test Bucket',
|
||||
'fileSecurity' => true,
|
||||
'maximumFileSize' => 2000000, //2MB
|
||||
'allowedFileExtensions' => ['jpg', 'png', 'jfif'],
|
||||
'permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::create(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(201, $bucket['headers']['status-code']);
|
||||
$this->assertNotEmpty($bucket['body']['$id']);
|
||||
|
||||
$bucketId = $bucket['body']['$id'];
|
||||
|
||||
$file = $this->client->call(Client::METHOD_POST, '/storage/buckets/' . $bucketId . '/files', [
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'fileId' => ID::unique(),
|
||||
'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'),
|
||||
'permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $file['headers']['status-code']);
|
||||
$this->assertNotEmpty($file['body']['$id']);
|
||||
|
||||
$fileId = $file['body']['$id'];
|
||||
|
||||
$result = $this->performMigrationSync([
|
||||
'resources' => [
|
||||
Resource::TYPE_BUCKET,
|
||||
Resource::TYPE_FILE
|
||||
],
|
||||
'endpoint' => 'http://localhost/v1',
|
||||
'projectId' => $this->getProject()['$id'],
|
||||
'apiKey' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals('completed', $result['status']);
|
||||
$this->assertEquals([Resource::TYPE_BUCKET, Resource::TYPE_FILE], $result['resources']);
|
||||
$this->assertArrayHasKey(Resource::TYPE_BUCKET, $result['statusCounters']);
|
||||
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][Resource::TYPE_BUCKET]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['warning']);
|
||||
|
||||
$this->assertArrayHasKey(Resource::TYPE_FILE, $result['statusCounters']);
|
||||
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FILE]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FILE]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][Resource::TYPE_FILE]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FILE]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FILE]['warning']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucketId . '/files/' . $fileId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
|
||||
$this->assertEquals($fileId, $response['body']['$id']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $bucketId . '/files/' . $fileId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $bucketId . '/files/' . $fileId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions
|
||||
*/
|
||||
public function testAppwriteMigrationFunction()
|
||||
{
|
||||
$functionId = $this->setupFunction([
|
||||
'functionId' => ID::unique(),
|
||||
'name' => 'Test',
|
||||
'runtime' => 'php-8.0',
|
||||
'entrypoint' => 'index.php'
|
||||
]);
|
||||
|
||||
$deploymentId = $this->setupDeployment($functionId, [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => $this->packageFunction('php'),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$result = $this->performMigrationSync([
|
||||
'resources' => [
|
||||
Resource::TYPE_FUNCTION,
|
||||
Resource::TYPE_DEPLOYMENT
|
||||
],
|
||||
'endpoint' => 'http://localhost/v1',
|
||||
'projectId' => $this->getProject()['$id'],
|
||||
'apiKey' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals('completed', $result['status']);
|
||||
$this->assertEquals([Resource::TYPE_FUNCTION, Resource::TYPE_DEPLOYMENT], $result['resources']);
|
||||
$this->assertArrayHasKey(Resource::TYPE_FUNCTION, $result['statusCounters']);
|
||||
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FUNCTION]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FUNCTION]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][Resource::TYPE_FUNCTION]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FUNCTION]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FUNCTION]['warning']);
|
||||
|
||||
$this->assertArrayHasKey(Resource::TYPE_DEPLOYMENT, $result['statusCounters']);
|
||||
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DEPLOYMENT]['error']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DEPLOYMENT]['pending']);
|
||||
$this->assertEquals(1, $result['statusCounters'][Resource::TYPE_DEPLOYMENT]['success']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DEPLOYMENT]['processing']);
|
||||
$this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DEPLOYMENT]['warning']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
|
||||
$this->assertEquals($functionId, $response['body']['$id']);
|
||||
$this->assertEquals('Test', $response['body']['name']);
|
||||
$this->assertEquals('php-8.0', $response['body']['runtime']);
|
||||
$this->assertEquals('index.php', $response['body']['entrypoint']);
|
||||
|
||||
|
||||
$this->assertEventually(function () use ($functionId) {
|
||||
$deployments = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]));
|
||||
|
||||
$this->assertEquals(200, $deployments['headers']['status-code']);
|
||||
$this->assertNotEmpty($deployments['body']);
|
||||
$this->assertEquals(1, $deployments['body']['total']);
|
||||
|
||||
$this->assertEquals('ready', $deployments['body']['deployments'][0]['status'], 'Deployment status is not ready, deployment: ' . json_encode($deployments['body']['deployments'][0], JSON_PRETTY_PRINT));
|
||||
}, 50000, 500);
|
||||
|
||||
// Attempt execution
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
], [
|
||||
'body' => 'test'
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
$this->assertStringContainsString('body-is-test', $execution['body']['logs']);
|
||||
|
||||
// Cleanup
|
||||
$this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getDesintationProject()['$id'],
|
||||
'x-appwrite-key' => $this->getDesintationProject()['apiKey'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\E2E\Services\Migrations;
|
||||
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideConsole;
|
||||
|
||||
class MigrationsConsoleClientTest extends Scope
|
||||
{
|
||||
use MigrationsBase;
|
||||
use SideConsole;
|
||||
}
|
||||
Loading…
Reference in a new issue