mirror of
https://github.com/appwrite/appwrite
synced 2026-04-21 21:47:16 +00:00
611 lines
24 KiB
PHP
611 lines
24 KiB
PHP
<?php
|
|
|
|
namespace Tests\E2E\Services\Projects;
|
|
|
|
use Tests\E2E\Client;
|
|
use Utopia\Database\Helpers\ID;
|
|
use Utopia\Database\Helpers\Role;
|
|
use Utopia\System\System;
|
|
|
|
trait ProjectsBase
|
|
{
|
|
private static array $cachedProjectData = [];
|
|
private static array $cachedProjectWithWebhook = [];
|
|
private static array $cachedProjectWithKey = [];
|
|
private static array $cachedProjectWithPlatform = [];
|
|
private static array $cachedProjectWithVariable = [];
|
|
private static array $cachedProjectWithAuthLimit = [];
|
|
private static array $cachedProjectWithServicesDisabled = [];
|
|
|
|
/**
|
|
* Setup and cache a basic project with team
|
|
*/
|
|
protected function setupProjectData(): array
|
|
{
|
|
if (!empty(self::$cachedProjectData)) {
|
|
return self::$cachedProjectData;
|
|
}
|
|
|
|
$teamId = ID::unique();
|
|
$team = null;
|
|
for ($i = 0; $i < 3; $i++) {
|
|
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
], $this->getHeaders()), [
|
|
'teamId' => $teamId,
|
|
'name' => 'Project Test',
|
|
]);
|
|
if (\in_array($team['headers']['status-code'], [201, 409])) {
|
|
break;
|
|
}
|
|
\usleep(500000);
|
|
}
|
|
$this->assertContains($team['headers']['status-code'], [201, 409]);
|
|
|
|
$project = null;
|
|
for ($i = 0; $i < 3; $i++) {
|
|
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
], $this->getHeaders()), [
|
|
'projectId' => ID::unique(),
|
|
'name' => 'Project Test',
|
|
'teamId' => $team['body']['$id'] ?? $teamId,
|
|
'region' => System::getEnv('_APP_REGION', 'default')
|
|
]);
|
|
if ($project['headers']['status-code'] === 201) {
|
|
break;
|
|
}
|
|
\usleep(500000);
|
|
}
|
|
$this->assertEquals(201, $project['headers']['status-code']);
|
|
|
|
self::$cachedProjectData = [
|
|
'projectId' => $project['body']['$id'],
|
|
'teamId' => $team['body']['$id']
|
|
];
|
|
|
|
return self::$cachedProjectData;
|
|
}
|
|
|
|
/**
|
|
* Setup and cache a project with a webhook
|
|
*/
|
|
protected function setupProjectWithWebhook(): array
|
|
{
|
|
if (!empty(self::$cachedProjectWithWebhook)) {
|
|
return self::$cachedProjectWithWebhook;
|
|
}
|
|
|
|
$projectData = $this->setupProjectData();
|
|
$id = $projectData['projectId'];
|
|
|
|
$response = $this->client->call(Client::METHOD_POST, '/webhooks', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $id,
|
|
'x-appwrite-mode' => 'admin',
|
|
], $this->getHeaders()), [
|
|
'webhookId' => 'unique()',
|
|
'name' => 'Webhook Test',
|
|
'events' => ['users.*.create', 'users.*.update.email'],
|
|
'url' => 'https://appwrite.io',
|
|
'tls' => true,
|
|
'authUsername' => 'username',
|
|
'authPassword' => 'password',
|
|
]);
|
|
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
|
|
self::$cachedProjectWithWebhook = array_merge($projectData, [
|
|
'webhookId' => $response['body']['$id'],
|
|
'signatureKey' => $response['body']['secret']
|
|
]);
|
|
|
|
return self::$cachedProjectWithWebhook;
|
|
}
|
|
|
|
/**
|
|
* Setup and cache a project with an API key
|
|
*/
|
|
protected function setupProjectWithKey(): array
|
|
{
|
|
if (!empty(self::$cachedProjectWithKey)) {
|
|
return self::$cachedProjectWithKey;
|
|
}
|
|
|
|
$projectData = $this->setupProjectData();
|
|
$id = $projectData['projectId'];
|
|
|
|
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'x-appwrite-response-format' => '1.8.0',
|
|
], $this->getHeaders()), [
|
|
'name' => 'Key Test',
|
|
'scopes' => ['teams.read', 'teams.write'],
|
|
]);
|
|
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
|
|
self::$cachedProjectWithKey = array_merge($projectData, [
|
|
'keyId' => $response['body']['$id'],
|
|
'secret' => $response['body']['secret']
|
|
]);
|
|
|
|
return self::$cachedProjectWithKey;
|
|
}
|
|
|
|
/**
|
|
* Setup and cache a project with platforms
|
|
*/
|
|
protected function setupProjectWithPlatform(): array
|
|
{
|
|
if (!empty(self::$cachedProjectWithPlatform)) {
|
|
return self::$cachedProjectWithPlatform;
|
|
}
|
|
|
|
$projectData = $this->setupProjectData();
|
|
$id = $projectData['projectId'];
|
|
|
|
// Create web platform
|
|
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'x-appwrite-response-format' => '1.8.0',
|
|
], $this->getHeaders()), [
|
|
'type' => 'web',
|
|
'name' => 'Web App',
|
|
'hostname' => 'localhost',
|
|
]);
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
$platformWebId = $response['body']['$id'];
|
|
|
|
// Create flutter-ios platform
|
|
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'x-appwrite-response-format' => '1.8.0',
|
|
], $this->getHeaders()), [
|
|
'type' => 'flutter-ios',
|
|
'name' => 'Flutter App (iOS)',
|
|
'key' => 'com.example.ios',
|
|
]);
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
$platformFultteriOSId = $response['body']['$id'];
|
|
|
|
// Create flutter-android platform
|
|
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'x-appwrite-response-format' => '1.8.0',
|
|
], $this->getHeaders()), [
|
|
'type' => 'flutter-android',
|
|
'name' => 'Flutter App (Android)',
|
|
'key' => 'com.example.android',
|
|
]);
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
$platformFultterAndroidId = $response['body']['$id'];
|
|
|
|
// Create flutter-web platform
|
|
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'x-appwrite-response-format' => '1.8.0',
|
|
], $this->getHeaders()), [
|
|
'type' => 'flutter-web',
|
|
'name' => 'Flutter App (Web)',
|
|
'hostname' => 'flutter.appwrite.io',
|
|
]);
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
$platformFultterWebId = $response['body']['$id'];
|
|
|
|
// Create apple-ios platform
|
|
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'x-appwrite-response-format' => '1.8.0',
|
|
], $this->getHeaders()), [
|
|
'type' => 'apple-ios',
|
|
'name' => 'iOS App',
|
|
'key' => 'com.example.ios',
|
|
]);
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
$platformAppleIosId = $response['body']['$id'];
|
|
|
|
// Create apple-macos platform
|
|
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'x-appwrite-response-format' => '1.8.0',
|
|
], $this->getHeaders()), [
|
|
'type' => 'apple-macos',
|
|
'name' => 'macOS App',
|
|
'key' => 'com.example.macos',
|
|
]);
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
$platformAppleMacOsId = $response['body']['$id'];
|
|
|
|
// Create apple-watchos platform
|
|
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'x-appwrite-response-format' => '1.8.0',
|
|
], $this->getHeaders()), [
|
|
'type' => 'apple-watchos',
|
|
'name' => 'watchOS App',
|
|
'key' => 'com.example.watchos',
|
|
]);
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
$platformAppleWatchOsId = $response['body']['$id'];
|
|
|
|
// Create apple-tvos platform
|
|
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/platforms', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'x-appwrite-response-format' => '1.8.0',
|
|
], $this->getHeaders()), [
|
|
'type' => 'apple-tvos',
|
|
'name' => 'tvOS App',
|
|
'key' => 'com.example.tvos',
|
|
]);
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
$platformAppleTvOsId = $response['body']['$id'];
|
|
|
|
self::$cachedProjectWithPlatform = array_merge($projectData, [
|
|
'platformWebId' => $platformWebId,
|
|
'platformFultteriOSId' => $platformFultteriOSId,
|
|
'platformFultterAndroidId' => $platformFultterAndroidId,
|
|
'platformFultterWebId' => $platformFultterWebId,
|
|
'platformAppleIosId' => $platformAppleIosId,
|
|
'platformAppleMacOsId' => $platformAppleMacOsId,
|
|
'platformAppleWatchOsId' => $platformAppleWatchOsId,
|
|
'platformAppleTvOsId' => $platformAppleTvOsId,
|
|
]);
|
|
|
|
return self::$cachedProjectWithPlatform;
|
|
}
|
|
|
|
/**
|
|
* Setup and cache a project with variables
|
|
*/
|
|
protected function setupProjectWithVariable(): array
|
|
{
|
|
if (!empty(self::$cachedProjectWithVariable)) {
|
|
return self::$cachedProjectWithVariable;
|
|
}
|
|
|
|
$projectData = $this->setupProjectData();
|
|
|
|
// Create a non-secret variable
|
|
$variable = $this->client->call(Client::METHOD_POST, '/project/variables', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $projectData['projectId'],
|
|
'x-appwrite-mode' => 'admin',
|
|
], $this->getHeaders()), [
|
|
'variableId' => 'unique()',
|
|
'key' => 'APP_TEST',
|
|
'value' => 'TESTINGVALUE',
|
|
'secret' => false
|
|
]);
|
|
|
|
$this->assertEquals(201, $variable['headers']['status-code']);
|
|
$variableId = $variable['body']['$id'];
|
|
|
|
// Create a secret variable
|
|
$variable = $this->client->call(Client::METHOD_POST, '/project/variables', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $projectData['projectId'],
|
|
'x-appwrite-mode' => 'admin',
|
|
], $this->getHeaders()), [
|
|
'variableId' => 'unique()',
|
|
'key' => 'APP_TEST_1',
|
|
'value' => 'TESTINGVALUE_1',
|
|
'secret' => true
|
|
]);
|
|
|
|
$this->assertEquals(201, $variable['headers']['status-code']);
|
|
$secretVariableId = $variable['body']['$id'];
|
|
|
|
self::$cachedProjectWithVariable = array_merge($projectData, [
|
|
'variableId' => $variableId,
|
|
'secretVariableId' => $secretVariableId
|
|
]);
|
|
|
|
return self::$cachedProjectWithVariable;
|
|
}
|
|
|
|
/**
|
|
* Setup and cache a project with auth limit configured
|
|
*/
|
|
protected function setupProjectWithAuthLimit(): array
|
|
{
|
|
if (!empty(self::$cachedProjectWithAuthLimit)) {
|
|
return self::$cachedProjectWithAuthLimit;
|
|
}
|
|
|
|
$projectData = $this->setupProjectData();
|
|
$id = $projectData['projectId'];
|
|
|
|
// Set auth limit to 0 (unlimited) for the base setup
|
|
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/limit', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
], $this->getHeaders()), [
|
|
'limit' => 0,
|
|
]);
|
|
|
|
$this->assertEquals(200, $response['headers']['status-code']);
|
|
|
|
self::$cachedProjectWithAuthLimit = $projectData;
|
|
|
|
return self::$cachedProjectWithAuthLimit;
|
|
}
|
|
|
|
/**
|
|
* Setup and cache a project with services disabled
|
|
*/
|
|
protected function setupProjectWithServicesDisabled(): array
|
|
{
|
|
if (!empty(self::$cachedProjectWithServicesDisabled)) {
|
|
return self::$cachedProjectWithServicesDisabled;
|
|
}
|
|
|
|
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
|
]), [
|
|
'teamId' => ID::unique(),
|
|
'name' => 'Project Test',
|
|
]);
|
|
$this->assertEquals(201, $team['headers']['status-code']);
|
|
|
|
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
|
]), [
|
|
'projectId' => ID::unique(),
|
|
'name' => 'Project Test',
|
|
'teamId' => $team['body']['$id'],
|
|
'region' => System::getEnv('_APP_REGION', 'default')
|
|
]);
|
|
|
|
$this->assertEquals(201, $project['headers']['status-code']);
|
|
|
|
$id = $project['body']['$id'];
|
|
$services = require(__DIR__ . '/../../../../app/config/services.php');
|
|
|
|
// Disable all optional services
|
|
foreach ($services as $service) {
|
|
if (!$service['optional']) {
|
|
continue;
|
|
}
|
|
|
|
$key = $service['key'] ?? '';
|
|
|
|
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
'x-appwrite-response-format' => '1.9.0',
|
|
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
|
]), [
|
|
'service' => $key,
|
|
'status' => false,
|
|
]);
|
|
|
|
$this->assertEquals(200, $response['headers']['status-code']);
|
|
}
|
|
|
|
// Re-enable all services for the cached project
|
|
foreach ($services as $service) {
|
|
if (!$service['optional']) {
|
|
continue;
|
|
}
|
|
|
|
$key = $service['key'] ?? '';
|
|
|
|
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service/', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
], $this->getHeaders()), [
|
|
'service' => $key,
|
|
'status' => true,
|
|
]);
|
|
}
|
|
|
|
self::$cachedProjectWithServicesDisabled = ['projectId' => $id];
|
|
|
|
return self::$cachedProjectWithServicesDisabled;
|
|
}
|
|
|
|
protected function setupProject(mixed $params, ?string $teamId = null, bool $newTeam = true): string
|
|
{
|
|
if ($newTeam) {
|
|
$generatedTeamId = $teamId ?? ID::unique();
|
|
$team = null;
|
|
for ($i = 0; $i < 3; $i++) {
|
|
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
], $this->getHeaders()), [
|
|
'teamId' => $generatedTeamId,
|
|
'name' => 'Project Test',
|
|
]);
|
|
if (\in_array($team['headers']['status-code'], [201, 409])) {
|
|
break;
|
|
}
|
|
\usleep(500000);
|
|
}
|
|
|
|
$this->assertContains($team['headers']['status-code'], [201, 409], 'Setup team failed with status code: ' . $team['headers']['status-code'] . ' and response: ' . json_encode($team['body'], JSON_PRETTY_PRINT));
|
|
|
|
$teamId = $team['body']['$id'] ?? $generatedTeamId;
|
|
}
|
|
|
|
$project = null;
|
|
for ($i = 0; $i < 3; $i++) {
|
|
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
], $this->getHeaders()), [
|
|
...$params,
|
|
'teamId' => $teamId,
|
|
]);
|
|
if ($project['headers']['status-code'] === 201) {
|
|
break;
|
|
}
|
|
\usleep(500000);
|
|
}
|
|
|
|
$this->assertEquals(201, $project['headers']['status-code'], 'Setup project failed with status code: ' . $project['headers']['status-code'] . ' and response: ' . json_encode($project['body'], JSON_PRETTY_PRINT));
|
|
|
|
return $project['body']['$id'];
|
|
}
|
|
|
|
protected function setupDevKey(mixed $params): array
|
|
{
|
|
$devKey = $this->client->call(Client::METHOD_POST, '/projects/' . $params['projectId'] . '/dev-keys', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
], $this->getHeaders()), $params);
|
|
|
|
$this->assertEquals(201, $devKey['headers']['status-code'], 'Setup devKey failed with status code: ' . $devKey['headers']['status-code'] . ' and response: ' . json_encode($devKey['body'], JSON_PRETTY_PRINT));
|
|
|
|
return [
|
|
'$id' => $devKey['body']['$id'],
|
|
'secret' => $devKey['body']['secret'],
|
|
];
|
|
}
|
|
|
|
protected function setupUserMembership(mixed $params): array
|
|
{
|
|
// Create membership
|
|
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $params['teamId'] . '/memberships', array_merge([
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
], $this->getHeaders()), [
|
|
'email' => $params['email'],
|
|
'name' => $params['name'],
|
|
'roles' => $params['roles'],
|
|
'url' => 'http://localhost:5000/join-us#title'
|
|
]);
|
|
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
$this->assertNotEmpty($response['body']['$id']);
|
|
$this->assertNotEmpty($response['body']['userId']);
|
|
$this->assertEquals($params['name'], $response['body']['userName']);
|
|
$this->assertEquals($params['email'], $response['body']['userEmail']);
|
|
$this->assertNotEmpty($response['body']['teamId']);
|
|
$this->assertCount(count($params['roles']), $response['body']['roles']);
|
|
$this->assertEquals(false, $response['body']['confirm']);
|
|
|
|
$userId = $response['body']['userId'];
|
|
$membershipId = $response['body']['$id'];
|
|
|
|
|
|
$lastEmail = $this->getLastEmailByAddress($params['email'], function ($email) {
|
|
$this->assertStringContainsString('/join-us', $email['html'] ?? '');
|
|
});
|
|
$tokens = $this->extractQueryParamsFromEmailLink($lastEmail['html']);
|
|
$userId = $tokens['userId'];
|
|
$secret = $tokens['secret'];
|
|
// Confirm membership
|
|
$response = $this->client->call(Client::METHOD_PATCH, '/teams/' . $params['teamId'] . '/memberships/' . $membershipId . '/status', array_merge([
|
|
'origin' => 'http://localhost',
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
]), [
|
|
'userId' => $userId,
|
|
'secret' => $secret,
|
|
]);
|
|
|
|
$this->assertEquals(200, $response['headers']['status-code']);
|
|
$this->assertNotEmpty($response['body']['$id']);
|
|
$this->assertNotEmpty($response['body']['userId']);
|
|
$this->assertNotEmpty($response['body']['teamId']);
|
|
$this->assertCount(count($params['roles']), $response['body']['roles']);
|
|
$this->assertEquals(true, $response['body']['confirm']);
|
|
|
|
// Simulate password recovery flow to reset password for the created user (useful when creating session for this user)
|
|
$response = $this->client->call(Client::METHOD_POST, '/account/recovery', array_merge([
|
|
'origin' => 'http://localhost',
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
]), [
|
|
'email' => $params['email'],
|
|
'url' => 'http://localhost/recovery',
|
|
]);
|
|
|
|
$this->assertEquals(201, $response['headers']['status-code']);
|
|
$this->assertNotEmpty($response['body']['$id']);
|
|
$this->assertEmpty($response['body']['secret']);
|
|
|
|
$lastEmail = $this->getLastEmailByAddress($params['email'], function ($email) {
|
|
$this->assertStringContainsString('Password Reset', $email['subject']);
|
|
});
|
|
$this->assertEquals($params['email'], $lastEmail['to'][0]['address']);
|
|
$this->assertEquals($params['name'], $lastEmail['to'][0]['name']);
|
|
$this->assertEquals('Password Reset for ' . $this->getProject()['name'], $lastEmail['subject']);
|
|
$this->assertStringContainsStringIgnoringCase('Reset your ' . $this->getProject()['name'] . ' password using the link.', $lastEmail['text']);
|
|
|
|
$tokens = $this->extractQueryParamsFromEmailLink($lastEmail['html']);
|
|
$secret = $tokens['secret'];
|
|
|
|
$response = $this->client->call(Client::METHOD_PUT, '/account/recovery', array_merge([
|
|
'origin' => 'http://localhost',
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
]), [
|
|
'userId' => $userId,
|
|
'secret' => $secret,
|
|
'password' => 'password',
|
|
]);
|
|
|
|
$this->assertEquals(200, $response['headers']['status-code']);
|
|
|
|
return [
|
|
'userId' => $userId,
|
|
'membershipId' => $membershipId,
|
|
];
|
|
}
|
|
|
|
protected function updateMembershipRole(string $teamId, string $membershipId, array $roles): void
|
|
{
|
|
$response = $this->client->call(Client::METHOD_PATCH, '/teams/' . $teamId . '/memberships/' . $membershipId, array_merge([
|
|
'origin' => 'http://localhost',
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $this->getProject()['$id'],
|
|
], $this->getHeaders()), [
|
|
'roles' => $roles,
|
|
]);
|
|
|
|
$this->assertEquals(200, $response['headers']['status-code']);
|
|
}
|
|
|
|
protected function setupFunction(string $projectId, string $functionId, string $token): void
|
|
{
|
|
$function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([
|
|
'origin' => 'http://localhost',
|
|
'content-type' => 'application/json',
|
|
'x-appwrite-project' => $projectId,
|
|
'x-appwrite-mode' => 'admin',
|
|
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
|
|
]), [
|
|
'functionId' => $functionId,
|
|
'name' => 'Test function',
|
|
'execute' => [Role::any()->toString()],
|
|
'runtime' => 'node-22',
|
|
'entrypoint' => 'index.js',
|
|
'events' => [
|
|
'users.*.create',
|
|
'users.*.delete',
|
|
],
|
|
'schedule' => '0 0 1 1 *',
|
|
'timeout' => 10,
|
|
]);
|
|
$this->assertEquals(201, $function['headers']['status-code']);
|
|
$this->assertNotEmpty($function['body']['$id']);
|
|
}
|
|
}
|