mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Move schedule endpoints to projects group (/v1/projects/:projectId/schedules)
This commit is contained in:
committed by
premtsd-code
parent
3fde05e024
commit
63d2efdaac
@@ -32,18 +32,18 @@ class Create extends Action
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/schedules')
|
||||
->setHttpPath('/v1/projects/:projectId/schedules')
|
||||
->desc('Create schedule')
|
||||
->groups(['api', 'schedules'])
|
||||
->groups(['api', 'projects'])
|
||||
->label('scope', 'schedules.write')
|
||||
->label('audits.event', 'schedule.create')
|
||||
->label('audits.resource', 'schedule/{response.$id}')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'schedules',
|
||||
namespace: 'projects',
|
||||
group: 'schedules',
|
||||
name: 'create',
|
||||
name: 'createSchedule',
|
||||
description: '/docs/references/schedules/create.md',
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
auth: [AuthType::ADMIN],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_CREATED,
|
||||
@@ -51,29 +51,37 @@ class Create extends Action
|
||||
)
|
||||
],
|
||||
))
|
||||
->param('projectId', '', new UID(), 'Project unique ID.')
|
||||
->param('resourceType', '', new WhiteList([SCHEDULE_RESOURCE_TYPE_FUNCTION, SCHEDULE_RESOURCE_TYPE_EXECUTION, SCHEDULE_RESOURCE_TYPE_MESSAGE], true), 'The resource type for the schedule. Possible values: ' . implode(', ', [SCHEDULE_RESOURCE_TYPE_FUNCTION, SCHEDULE_RESOURCE_TYPE_EXECUTION, SCHEDULE_RESOURCE_TYPE_MESSAGE]) . '.')
|
||||
->param('resourceId', '', new UID(), 'The resource ID to associate with this schedule.')
|
||||
->param('schedule', '', new Cron(), 'Schedule CRON expression.')
|
||||
->param('active', false, new Boolean(), 'Whether the schedule is active.', true)
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('getProjectDB')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(
|
||||
string $projectId,
|
||||
string $resourceType,
|
||||
string $resourceId,
|
||||
string $schedule,
|
||||
bool $active,
|
||||
Response $response,
|
||||
Document $project,
|
||||
Database $dbForProject,
|
||||
Database $dbForPlatform,
|
||||
callable $getProjectDB,
|
||||
Authorization $authorization,
|
||||
): void {
|
||||
$project = $dbForPlatform->getDocument('projects', $projectId);
|
||||
|
||||
if ($project->isEmpty()) {
|
||||
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
||||
$collection = match ($resourceType) {
|
||||
SCHEDULE_RESOURCE_TYPE_FUNCTION => 'functions',
|
||||
SCHEDULE_RESOURCE_TYPE_EXECUTION => 'executions',
|
||||
|
||||
@@ -8,7 +8,6 @@ use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Platform\Action;
|
||||
@@ -27,16 +26,16 @@ class Get extends Action
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/schedules/:scheduleId')
|
||||
->setHttpPath('/v1/projects/:projectId/schedules/:scheduleId')
|
||||
->desc('Get schedule')
|
||||
->groups(['api', 'schedules'])
|
||||
->groups(['api', 'projects'])
|
||||
->label('scope', 'schedules.read')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'schedules',
|
||||
namespace: 'projects',
|
||||
group: 'schedules',
|
||||
name: 'get',
|
||||
name: 'getSchedule',
|
||||
description: '/docs/references/schedules/get.md',
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
auth: [AuthType::ADMIN],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
@@ -44,21 +43,27 @@ class Get extends Action
|
||||
)
|
||||
]
|
||||
))
|
||||
->param('projectId', '', new UID(), 'Project unique ID.')
|
||||
->param('scheduleId', '', new UID(), 'Schedule ID.')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForPlatform')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(
|
||||
string $projectId,
|
||||
string $scheduleId,
|
||||
Response $response,
|
||||
Document $project,
|
||||
Database $dbForPlatform,
|
||||
Authorization $authorization,
|
||||
): void {
|
||||
$project = $dbForPlatform->getDocument('projects', $projectId);
|
||||
|
||||
if ($project->isEmpty()) {
|
||||
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$schedule = $authorization->skip(
|
||||
fn () => $dbForPlatform->getDocument('schedules', $scheduleId)
|
||||
);
|
||||
|
||||
@@ -15,6 +15,7 @@ use Utopia\Database\Exception\Query as QueryException;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\Query\Cursor;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\Boolean;
|
||||
@@ -32,16 +33,16 @@ class XList extends Action
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/schedules')
|
||||
->setHttpPath('/v1/projects/:projectId/schedules')
|
||||
->desc('List schedules')
|
||||
->groups(['api', 'schedules'])
|
||||
->groups(['api', 'projects'])
|
||||
->label('scope', 'schedules.read')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'schedules',
|
||||
namespace: 'projects',
|
||||
group: 'schedules',
|
||||
name: 'list',
|
||||
name: 'listSchedules',
|
||||
description: '/docs/references/schedules/list.md',
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
auth: [AuthType::ADMIN],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
@@ -49,30 +50,35 @@ class XList extends Action
|
||||
)
|
||||
]
|
||||
))
|
||||
->param('projectId', '', new UID(), 'Project unique ID.')
|
||||
->param('queries', [], new Schedules(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Schedules::ALLOWED_ATTRIBUTES), true)
|
||||
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForPlatform')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(
|
||||
string $projectId,
|
||||
array $queries,
|
||||
bool $includeTotal,
|
||||
Response $response,
|
||||
Document $project,
|
||||
Database $dbForPlatform,
|
||||
Authorization $authorization,
|
||||
): void {
|
||||
$project = $dbForPlatform->getDocument('projects', $projectId);
|
||||
|
||||
if ($project->isEmpty()) {
|
||||
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
try {
|
||||
$queries = Query::parseQueries($queries);
|
||||
} catch (QueryException $e) {
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
// Always scope to the current project
|
||||
$queries[] = Query::equal('projectId', [$project->getId()]);
|
||||
|
||||
$cursor = Query::getCursorQueries($queries, false);
|
||||
|
||||
@@ -109,8 +109,6 @@ trait ProjectCustom
|
||||
'subscribers.read',
|
||||
'migrations.write',
|
||||
'migrations.read',
|
||||
'schedules.read',
|
||||
'schedules.write',
|
||||
'tokens.read',
|
||||
'tokens.write',
|
||||
],
|
||||
|
||||
@@ -4,44 +4,57 @@ namespace Tests\E2E\Services\Schedules;
|
||||
|
||||
use Tests\E2E\Client;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\System\System;
|
||||
|
||||
trait SchedulesBase
|
||||
{
|
||||
protected function createSchedule(array $params = []): array
|
||||
public function testCreateProject(): array
|
||||
{
|
||||
return $this->client->call(Client::METHOD_POST, '/schedules', array_merge([
|
||||
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), $params);
|
||||
}
|
||||
], $this->getHeaders()), [
|
||||
'teamId' => ID::unique(),
|
||||
'name' => 'Schedule Test Team',
|
||||
]);
|
||||
|
||||
protected function getSchedule(string $scheduleId): array
|
||||
{
|
||||
return $this->client->call(Client::METHOD_GET, '/schedules/' . $scheduleId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
}
|
||||
$this->assertEquals(201, $team['headers']['status-code']);
|
||||
|
||||
protected function listSchedules(array $params = []): array
|
||||
{
|
||||
return $this->client->call(Client::METHOD_GET, '/schedules', array_merge([
|
||||
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), $params);
|
||||
}
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Schedule Test Project',
|
||||
'teamId' => $team['body']['$id'],
|
||||
'region' => System::getEnv('_APP_REGION', 'default'),
|
||||
]);
|
||||
|
||||
protected function createFunction(array $params = []): array
|
||||
{
|
||||
return $this->client->call(Client::METHOD_POST, '/functions', array_merge([
|
||||
$this->assertEquals(201, $project['headers']['status-code']);
|
||||
|
||||
$projectId = $project['body']['$id'];
|
||||
|
||||
$key = $this->client->call(Client::METHOD_POST, '/projects/' . $projectId . '/keys', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), array_merge([
|
||||
'functionId' => ID::unique(),
|
||||
'name' => 'Test Schedule Function',
|
||||
'runtime' => 'node-22',
|
||||
'entrypoint' => 'index.js',
|
||||
'execute' => ['any'],
|
||||
], $params));
|
||||
], $this->getHeaders()), [
|
||||
'keyId' => ID::unique(),
|
||||
'name' => 'Schedule Test Key',
|
||||
'scopes' => [
|
||||
'functions.read',
|
||||
'functions.write',
|
||||
'execution.read',
|
||||
'execution.write',
|
||||
'messages.read',
|
||||
'messages.write',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $key['headers']['status-code']);
|
||||
|
||||
return [
|
||||
'projectId' => $projectId,
|
||||
'apiKey' => $key['body']['secret'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,28 +2,50 @@
|
||||
|
||||
namespace Tests\E2E\Services\Schedules;
|
||||
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectConsole;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideServer;
|
||||
use Tests\E2E\Scopes\SideClient;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\System\System;
|
||||
|
||||
class SchedulesCustomServerTest extends Scope
|
||||
{
|
||||
use SchedulesBase;
|
||||
use ProjectCustom;
|
||||
use SideServer;
|
||||
use ProjectConsole;
|
||||
use SideClient;
|
||||
|
||||
public function testCreateSchedule(): array
|
||||
/**
|
||||
* @depends testCreateProject
|
||||
*/
|
||||
public function testCreateSchedule($data): array
|
||||
{
|
||||
$id = $data['projectId'] ?? '';
|
||||
$apiKey = $data['apiKey'] ?? '';
|
||||
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$function = $this->createFunction();
|
||||
$function = $this->client->call(Client::METHOD_POST, '/functions', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $id,
|
||||
'x-appwrite-key' => $apiKey,
|
||||
], [
|
||||
'functionId' => ID::unique(),
|
||||
'name' => 'Test Schedule Function',
|
||||
'runtime' => 'node-22',
|
||||
'entrypoint' => 'index.js',
|
||||
'execute' => ['any'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
$functionId = $function['body']['$id'];
|
||||
|
||||
$response = $this->createSchedule([
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => $functionId,
|
||||
'schedule' => '0 0 * * *',
|
||||
@@ -42,13 +64,20 @@ class SchedulesCustomServerTest extends Scope
|
||||
$this->assertTrue($response['body']['active']);
|
||||
$this->assertNotEmpty($response['body']['region']);
|
||||
|
||||
return ['scheduleId' => $response['body']['$id'], 'functionId' => $functionId];
|
||||
}
|
||||
$data = array_merge($data, [
|
||||
'scheduleId' => $response['body']['$id'],
|
||||
'functionId' => $functionId,
|
||||
]);
|
||||
|
||||
public function testCreateScheduleResourceNotFound(): void
|
||||
{
|
||||
// Function not found
|
||||
$response = $this->createSchedule([
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
||||
// Resource not found
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => ID::unique(),
|
||||
'schedule' => '0 0 * * *',
|
||||
@@ -56,51 +85,35 @@ class SchedulesCustomServerTest extends Scope
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
|
||||
// Execution not found
|
||||
$response = $this->createSchedule([
|
||||
'resourceType' => 'execution',
|
||||
'resourceId' => ID::unique(),
|
||||
'schedule' => '*/10 * * * *',
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
|
||||
// Message not found
|
||||
$response = $this->createSchedule([
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => ID::unique(),
|
||||
'schedule' => '0 9 * * 1',
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testCreateScheduleInvalidResourceType(): void
|
||||
{
|
||||
$response = $this->createSchedule([
|
||||
// Invalid resource type
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'resourceType' => 'invalid',
|
||||
'resourceId' => ID::unique(),
|
||||
'schedule' => '0 0 * * *',
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testCreateScheduleInvalidCron(): void
|
||||
{
|
||||
$response = $this->createSchedule([
|
||||
// Invalid cron
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => ID::unique(),
|
||||
'schedule' => 'not-a-cron',
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testCreateScheduleMissingRequired(): void
|
||||
{
|
||||
// Missing resourceType
|
||||
$response = $this->createSchedule([
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'resourceId' => ID::unique(),
|
||||
'schedule' => '0 0 * * *',
|
||||
]);
|
||||
@@ -108,7 +121,10 @@ class SchedulesCustomServerTest extends Scope
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Missing resourceId
|
||||
$response = $this->createSchedule([
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'resourceType' => 'function',
|
||||
'schedule' => '0 0 * * *',
|
||||
]);
|
||||
@@ -116,49 +132,69 @@ class SchedulesCustomServerTest extends Scope
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Missing schedule
|
||||
$response = $this->createSchedule([
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => ID::unique(),
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateSchedule
|
||||
*/
|
||||
public function testGetSchedule(array $data): void
|
||||
public function testGetSchedule($data): array
|
||||
{
|
||||
$scheduleId = $data['scheduleId'];
|
||||
$id = $data['projectId'] ?? '';
|
||||
$scheduleId = $data['scheduleId'] ?? '';
|
||||
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$response = $this->getSchedule($scheduleId);
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/schedules/' . $scheduleId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertEquals($scheduleId, $response['body']['$id']);
|
||||
$this->assertEquals('function', $response['body']['resourceType']);
|
||||
$this->assertEquals('0 0 * * *', $response['body']['schedule']);
|
||||
$this->assertTrue($response['body']['active']);
|
||||
}
|
||||
|
||||
public function testGetScheduleNotFound(): void
|
||||
{
|
||||
$response = $this->getSchedule('nonexistent');
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/schedules/error', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateSchedule
|
||||
*/
|
||||
public function testListSchedules(array $data): void
|
||||
public function testListSchedules($data): array
|
||||
{
|
||||
$id = $data['projectId'] ?? '';
|
||||
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$response = $this->listSchedules();
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertIsArray($response['body']['schedules']);
|
||||
@@ -176,15 +212,12 @@ class SchedulesCustomServerTest extends Scope
|
||||
$this->assertArrayHasKey('schedule', $schedule);
|
||||
$this->assertArrayHasKey('active', $schedule);
|
||||
$this->assertArrayHasKey('region', $schedule);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateSchedule
|
||||
*/
|
||||
public function testListSchedulesWithQuery(array $data): void
|
||||
{
|
||||
// Filter by resourceType
|
||||
$response = $this->listSchedules([
|
||||
/** Filter by resourceType */
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::equal('resourceType', ['function'])->toString()],
|
||||
]);
|
||||
|
||||
@@ -195,8 +228,11 @@ class SchedulesCustomServerTest extends Scope
|
||||
$this->assertEquals('function', $schedule['resourceType']);
|
||||
}
|
||||
|
||||
// Filter by active status
|
||||
$response = $this->listSchedules([
|
||||
/** Filter by active status */
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::equal('active', [true])->toString()],
|
||||
]);
|
||||
|
||||
@@ -205,61 +241,78 @@ class SchedulesCustomServerTest extends Scope
|
||||
foreach ($response['body']['schedules'] as $schedule) {
|
||||
$this->assertTrue($schedule['active']);
|
||||
}
|
||||
}
|
||||
|
||||
public function testListSchedulesWithTotalDisabled(): void
|
||||
{
|
||||
$response = $this->listSchedules([
|
||||
/** List with total disabled */
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'total' => false,
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(0, $response['body']['total']);
|
||||
$this->assertIsArray($response['body']['schedules']);
|
||||
}
|
||||
|
||||
public function testListSchedulesInvalidQuery(): void
|
||||
{
|
||||
$response = $this->listSchedules([
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::equal('nonexistent', ['value'])->toString()],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function testScheduleProjectIsolation(): void
|
||||
/**
|
||||
* @depends testCreateSchedule
|
||||
*/
|
||||
public function testScheduleProjectIsolation($data): void
|
||||
{
|
||||
// Create a function and schedule in the current project
|
||||
$function = $this->createFunction();
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
$scheduleId = $data['scheduleId'] ?? '';
|
||||
|
||||
$response = $this->createSchedule([
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => $function['body']['$id'],
|
||||
'schedule' => '0 12 * * *',
|
||||
// Create a second project
|
||||
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'teamId' => ID::unique(),
|
||||
'name' => 'Isolation Test Team',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$scheduleId = $response['body']['$id'];
|
||||
$this->assertEquals(201, $team['headers']['status-code']);
|
||||
|
||||
// Create a fresh project with its own key
|
||||
$freshProject = $this->getProject(true);
|
||||
$otherProject = $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' => 'Isolation Test Project',
|
||||
'teamId' => $team['body']['$id'],
|
||||
'region' => System::getEnv('_APP_REGION', 'default'),
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $otherProject['headers']['status-code']);
|
||||
$otherProjectId = $otherProject['body']['$id'];
|
||||
|
||||
// Try to get the schedule from the other project
|
||||
$response = $this->client->call(\Tests\E2E\Client::METHOD_GET, '/schedules/' . $scheduleId, [
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $otherProjectId . '/schedules/' . $scheduleId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $freshProject['$id'],
|
||||
'x-appwrite-key' => $freshProject['apiKey'],
|
||||
]);
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
|
||||
// List should not include schedules from other projects
|
||||
$response = $this->client->call(\Tests\E2E\Client::METHOD_GET, '/schedules', [
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $otherProjectId . '/schedules', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $freshProject['$id'],
|
||||
'x-appwrite-key' => $freshProject['apiKey'],
|
||||
]);
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user