mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Add resource validation, admin scopes, and events for schedules
This commit is contained in:
committed by
premtsd-code
parent
9b72b78338
commit
3fde05e024
@@ -405,6 +405,20 @@ return [
|
||||
'$description' => 'This event triggers when a provider is deleted.'
|
||||
],
|
||||
],
|
||||
'schedules' => [
|
||||
'$model' => Response::MODEL_SCHEDULE,
|
||||
'$resource' => true,
|
||||
'$description' => 'This event triggers on any schedule event.',
|
||||
'create' => [
|
||||
'$description' => 'This event triggers when a schedule is created.',
|
||||
],
|
||||
'update' => [
|
||||
'$description' => 'This event triggers when a schedule is updated.',
|
||||
],
|
||||
'delete' => [
|
||||
'$description' => 'This event triggers when a schedule is deleted.',
|
||||
],
|
||||
],
|
||||
'rules' => [
|
||||
'$model' => Response::MODEL_PROXY_RULE,
|
||||
'$resource' => true,
|
||||
|
||||
@@ -91,6 +91,8 @@ $admins = [
|
||||
'subscribers.read',
|
||||
'tokens.read',
|
||||
'tokens.write',
|
||||
'schedules.read',
|
||||
'schedules.write',
|
||||
];
|
||||
|
||||
return [
|
||||
|
||||
@@ -57,6 +57,7 @@ class Create extends Action
|
||||
->param('active', false, new Boolean(), 'Whether the schedule is active.', true)
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
@@ -69,16 +70,33 @@ class Create extends Action
|
||||
bool $active,
|
||||
Response $response,
|
||||
Document $project,
|
||||
Database $dbForProject,
|
||||
Database $dbForPlatform,
|
||||
Authorization $authorization,
|
||||
): void {
|
||||
$collection = match ($resourceType) {
|
||||
SCHEDULE_RESOURCE_TYPE_FUNCTION => 'functions',
|
||||
SCHEDULE_RESOURCE_TYPE_EXECUTION => 'executions',
|
||||
SCHEDULE_RESOURCE_TYPE_MESSAGE => 'messages',
|
||||
};
|
||||
|
||||
$resource = $dbForProject->getDocument($collection, $resourceId);
|
||||
|
||||
if ($resource->isEmpty()) {
|
||||
throw new Exception(match ($resourceType) {
|
||||
SCHEDULE_RESOURCE_TYPE_FUNCTION => Exception::FUNCTION_NOT_FOUND,
|
||||
SCHEDULE_RESOURCE_TYPE_EXECUTION => Exception::EXECUTION_NOT_FOUND,
|
||||
SCHEDULE_RESOURCE_TYPE_MESSAGE => Exception::MESSAGE_NOT_FOUND,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
$doc = $authorization->skip(
|
||||
fn () => $dbForPlatform->createDocument('schedules', new Document([
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => $resourceType,
|
||||
'resourceId' => $resourceId,
|
||||
'resourceInternalId' => '',
|
||||
'resourceInternalId' => $resource->getSequence(),
|
||||
'resourceUpdatedAt' => DateTime::now(),
|
||||
'projectId' => $project->getId(),
|
||||
'schedule' => $schedule,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Tests\E2E\Services\Schedules;
|
||||
|
||||
use Tests\E2E\Client;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
|
||||
trait SchedulesBase
|
||||
{
|
||||
@@ -29,4 +30,18 @@ trait SchedulesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), $params);
|
||||
}
|
||||
|
||||
protected function createFunction(array $params = []): array
|
||||
{
|
||||
return $this->client->call(Client::METHOD_POST, '/functions', 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,13 @@ class SchedulesCustomServerTest extends Scope
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$function = $this->createFunction();
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
$functionId = $function['body']['$id'];
|
||||
|
||||
$response = $this->createSchedule([
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => ID::unique(),
|
||||
'resourceId' => $functionId,
|
||||
'schedule' => '0 0 * * *',
|
||||
'active' => true,
|
||||
]);
|
||||
@@ -31,39 +35,44 @@ class SchedulesCustomServerTest extends Scope
|
||||
$this->assertNotEmpty($response['body']['$createdAt']);
|
||||
$this->assertNotEmpty($response['body']['$updatedAt']);
|
||||
$this->assertEquals('function', $response['body']['resourceType']);
|
||||
$this->assertNotEmpty($response['body']['resourceId']);
|
||||
$this->assertEquals($functionId, $response['body']['resourceId']);
|
||||
$this->assertNotEmpty($response['body']['resourceUpdatedAt']);
|
||||
$this->assertNotEmpty($response['body']['projectId']);
|
||||
$this->assertEquals('0 0 * * *', $response['body']['schedule']);
|
||||
$this->assertTrue($response['body']['active']);
|
||||
$this->assertNotEmpty($response['body']['region']);
|
||||
|
||||
return ['scheduleId' => $response['body']['$id']];
|
||||
return ['scheduleId' => $response['body']['$id'], 'functionId' => $functionId];
|
||||
}
|
||||
|
||||
public function testCreateScheduleExecutionType(): void
|
||||
public function testCreateScheduleResourceNotFound(): void
|
||||
{
|
||||
// Function not found
|
||||
$response = $this->createSchedule([
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => ID::unique(),
|
||||
'schedule' => '0 0 * * *',
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
|
||||
// Execution not found
|
||||
$response = $this->createSchedule([
|
||||
'resourceType' => 'execution',
|
||||
'resourceId' => ID::unique(),
|
||||
'schedule' => '*/10 * * * *',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals('execution', $response['body']['resourceType']);
|
||||
$this->assertFalse($response['body']['active']);
|
||||
}
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
|
||||
public function testCreateScheduleMessageType(): void
|
||||
{
|
||||
// Message not found
|
||||
$response = $this->createSchedule([
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => ID::unique(),
|
||||
'schedule' => '0 9 * * 1',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals('message', $response['body']['resourceType']);
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testCreateScheduleInvalidResourceType(): void
|
||||
@@ -220,10 +229,13 @@ class SchedulesCustomServerTest extends Scope
|
||||
|
||||
public function testScheduleProjectIsolation(): void
|
||||
{
|
||||
// Create a schedule in the current project
|
||||
// Create a function and schedule in the current project
|
||||
$function = $this->createFunction();
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$response = $this->createSchedule([
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => ID::unique(),
|
||||
'resourceId' => $function['body']['$id'],
|
||||
'schedule' => '0 12 * * *',
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user