Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/tests/Integration/Api/Client/Server/ScheduleTask/CreateServerScheduleTaskTest.php
7461 views
1
<?php
2
3
namespace Pterodactyl\Tests\Integration\Api\Client\Server\ScheduleTask;
4
5
use Pterodactyl\Models\Task;
6
use Illuminate\Http\Response;
7
use Pterodactyl\Models\Schedule;
8
use Pterodactyl\Models\Permission;
9
use Pterodactyl\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
10
11
class CreateServerScheduleTaskTest extends ClientApiIntegrationTestCase
12
{
13
/**
14
* Test that a task can be created.
15
*/
16
#[\PHPUnit\Framework\Attributes\DataProvider('permissionsDataProvider')]
17
public function testTaskCanBeCreated(array $permissions)
18
{
19
[$user, $server] = $this->generateTestAccount($permissions);
20
21
/** @var Schedule $schedule */
22
$schedule = Schedule::factory()->create(['server_id' => $server->id]);
23
$this->assertEmpty($schedule->tasks);
24
25
$response = $this->actingAs($user)->postJson($this->link($schedule, '/tasks'), [
26
'action' => 'command',
27
'payload' => 'say Test',
28
'time_offset' => 10,
29
'sequence_id' => 1,
30
]);
31
32
$response->assertOk();
33
/** @var Task $task */
34
$task = Task::query()->findOrFail($response->json('attributes.id'));
35
36
$this->assertSame($schedule->id, $task->schedule_id);
37
$this->assertSame(1, $task->sequence_id);
38
$this->assertSame('command', $task->action);
39
$this->assertSame('say Test', $task->payload);
40
$this->assertSame(10, $task->time_offset);
41
$this->assertJsonTransformedWith($response->json('attributes'), $task);
42
}
43
44
/**
45
* Test that validation errors are returned correctly if bad data is passed into the API.
46
*/
47
public function testValidationErrorsAreReturned()
48
{
49
[$user, $server] = $this->generateTestAccount();
50
51
/** @var Schedule $schedule */
52
$schedule = Schedule::factory()->create(['server_id' => $server->id]);
53
54
$response = $this->actingAs($user)->postJson($this->link($schedule, '/tasks'))->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY);
55
56
foreach (['action', 'payload', 'time_offset'] as $i => $field) {
57
$response->assertJsonPath("errors.$i.meta.rule", $field === 'payload' ? 'required_unless' : 'required');
58
$response->assertJsonPath("errors.$i.meta.source_field", $field);
59
}
60
61
$this->actingAs($user)->postJson($this->link($schedule, '/tasks'), [
62
'action' => 'hodor',
63
'payload' => 'say Test',
64
'time_offset' => 0,
65
])
66
->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY)
67
->assertJsonPath('errors.0.meta.rule', 'in')
68
->assertJsonPath('errors.0.meta.source_field', 'action');
69
70
$this->actingAs($user)->postJson($this->link($schedule, '/tasks'), [
71
'action' => 'command',
72
'time_offset' => 0,
73
])
74
->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY)
75
->assertJsonPath('errors.0.meta.rule', 'required_unless')
76
->assertJsonPath('errors.0.meta.source_field', 'payload');
77
78
$this->actingAs($user)->postJson($this->link($schedule, '/tasks'), [
79
'action' => 'command',
80
'payload' => 'say Test',
81
'time_offset' => 0,
82
'sequence_id' => 'hodor',
83
])
84
->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY)
85
->assertJsonPath('errors.0.meta.rule', 'numeric')
86
->assertJsonPath('errors.0.meta.source_field', 'sequence_id');
87
}
88
89
/**
90
* Test that backups can not be tasked when the backup limit is 0.
91
*/
92
public function testBackupsCanNotBeTaskedIfLimit0()
93
{
94
[$user, $server] = $this->generateTestAccount();
95
96
/** @var Schedule $schedule */
97
$schedule = Schedule::factory()->create(['server_id' => $server->id]);
98
99
$this->actingAs($user)->postJson($this->link($schedule, '/tasks'), [
100
'action' => 'backup',
101
'time_offset' => 0,
102
])
103
->assertStatus(Response::HTTP_FORBIDDEN)
104
->assertJsonPath('errors.0.detail', 'A backup task cannot be created when the server\'s backup limit is set to 0.');
105
106
$this->actingAs($user)->postJson($this->link($schedule, '/tasks'), [
107
'action' => 'backup',
108
'payload' => "file.txt\nfile2.log",
109
'time_offset' => 0,
110
])
111
->assertStatus(Response::HTTP_FORBIDDEN)
112
->assertJsonPath('errors.0.detail', 'A backup task cannot be created when the server\'s backup limit is set to 0.');
113
}
114
115
/**
116
* Test that an error is returned if the user attempts to create an additional task that
117
* would put the schedule over the task limit.
118
*/
119
public function testErrorIsReturnedIfTooManyTasksExistForSchedule()
120
{
121
config()->set('pterodactyl.client_features.schedules.per_schedule_task_limit', 2);
122
123
[$user, $server] = $this->generateTestAccount();
124
125
/** @var Schedule $schedule */
126
$schedule = Schedule::factory()->create(['server_id' => $server->id]);
127
Task::factory()->times(2)->create(['schedule_id' => $schedule->id]);
128
129
$this->actingAs($user)->postJson($this->link($schedule, '/tasks'), [
130
'action' => 'command',
131
'payload' => 'say test',
132
'time_offset' => 0,
133
])
134
->assertStatus(Response::HTTP_BAD_REQUEST)
135
->assertJsonPath('errors.0.code', 'ServiceLimitExceededException')
136
->assertJsonPath('errors.0.detail', 'Schedules may not have more than 2 tasks associated with them. Creating this task would put this schedule over the limit.');
137
}
138
139
/**
140
* Test that an error is returned if the targeted schedule does not belong to the server
141
* in the request.
142
*/
143
public function testErrorIsReturnedIfScheduleDoesNotBelongToServer()
144
{
145
[$user, $server] = $this->generateTestAccount();
146
$server2 = $this->createServerModel(['owner_id' => $user->id]);
147
148
/** @var Schedule $schedule */
149
$schedule = Schedule::factory()->create(['server_id' => $server2->id]);
150
151
$this->actingAs($user)
152
->postJson("/api/client/servers/$server->uuid/schedules/$schedule->id/tasks")
153
->assertNotFound();
154
}
155
156
/**
157
* Test that an error is returned if the subuser making the request does not have permission
158
* to update a schedule.
159
*/
160
public function testErrorIsReturnedIfSubuserDoesNotHaveScheduleUpdatePermissions()
161
{
162
[$user, $server] = $this->generateTestAccount([Permission::ACTION_SCHEDULE_CREATE]);
163
164
/** @var Schedule $schedule */
165
$schedule = Schedule::factory()->create(['server_id' => $server->id]);
166
167
$this->actingAs($user)
168
->postJson($this->link($schedule, '/tasks'))
169
->assertForbidden();
170
}
171
172
public static function permissionsDataProvider(): array
173
{
174
return [[[]], [[Permission::ACTION_SCHEDULE_UPDATE]]];
175
}
176
}
177
178