Skip to content

Commit 6312b62

Browse files
committed
Add test coverage for power toggling
1 parent 8cfdb3a commit 6312b62

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
namespace Pterodactyl\Tests\Integration\Api\Client\Server;
4+
5+
use Mockery;
6+
use Illuminate\Http\Response;
7+
use Pterodactyl\Models\Permission;
8+
use Pterodactyl\Repositories\Wings\DaemonPowerRepository;
9+
use Pterodactyl\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
10+
11+
class PowerControllerTest extends ClientApiIntegrationTestCase
12+
{
13+
/**
14+
* Test that a subuser without permission to send a command to the server receives
15+
* an error in response. This checks against the specific permission needed to send
16+
* the command to the server.
17+
*
18+
* @param string $action
19+
* @param string[] $permissions
20+
* @dataProvider invalidPermissionDataProvider
21+
*/
22+
public function testSubuserWithoutPermissionsReceivesError(string $action, array $permissions)
23+
{
24+
[$user, $server] = $this->generateTestAccount($permissions);
25+
26+
$this->actingAs($user)
27+
->postJson("/api/client/servers/{$server->uuid}/power", ['signal' => $action])
28+
->assertStatus(Response::HTTP_FORBIDDEN);
29+
}
30+
31+
/**
32+
* Test that sending an invalid power signal returns an error.
33+
*/
34+
public function testInvalidPowerSignalResultsInError()
35+
{
36+
[$user, $server] = $this->generateTestAccount();
37+
38+
$response = $this->actingAs($user)->postJson("/api/client/servers/{$server->uuid}/power", [
39+
'signal' => 'invalid',
40+
]);
41+
42+
$response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY);
43+
$response->assertJsonPath('errors.0.code', 'in');
44+
$response->assertJsonPath('errors.0.detail', 'The selected signal is invalid.');
45+
}
46+
47+
/**
48+
* Test that sending a valid power actions works.
49+
*
50+
* @param string $action
51+
* @param string $permission
52+
* @dataProvider validPowerActionDataProvider
53+
*/
54+
public function testActionCanBeSentToServer(string $action, string $permission)
55+
{
56+
$service = Mockery::mock(DaemonPowerRepository::class);
57+
$this->app->instance(DaemonPowerRepository::class, $service);
58+
59+
[$user, $server] = $this->generateTestAccount([$permission]);
60+
61+
$service->expects('setServer')
62+
->with(Mockery::on(function ($value) use ($server) {
63+
return $server->uuid === $value->uuid;
64+
}))
65+
->andReturnSelf()
66+
->getMock()
67+
->expects('send')
68+
->with(trim($action));
69+
70+
$this->actingAs($user)
71+
->postJson("/api/client/servers/{$server->uuid}/power", ['signal' => $action])
72+
->assertStatus(Response::HTTP_NO_CONTENT);
73+
}
74+
75+
/**
76+
* Returns invalid permission combinations for a given power action.
77+
*
78+
* @return array
79+
*/
80+
public function invalidPermissionDataProvider(): array
81+
{
82+
return [
83+
['start', [Permission::ACTION_CONTROL_STOP, Permission::ACTION_CONTROL_RESTART]],
84+
['stop', [Permission::ACTION_CONTROL_START]],
85+
['kill', [Permission::ACTION_CONTROL_START, Permission::ACTION_CONTROL_RESTART]],
86+
['restart', [Permission::ACTION_CONTROL_STOP, Permission::ACTION_CONTROL_START]],
87+
['random', [Permission::ACTION_CONTROL_START]],
88+
];
89+
}
90+
91+
/**
92+
* @return array
93+
*/
94+
public function validPowerActionDataProvider(): array
95+
{
96+
return [
97+
['start', Permission::ACTION_CONTROL_START],
98+
['stop', Permission::ACTION_CONTROL_STOP],
99+
['restart', Permission::ACTION_CONTROL_RESTART],
100+
['kill', Permission::ACTION_CONTROL_STOP],
101+
// Yes, these spaces are intentional. You should be able to send values with or without
102+
// a space on the start/end since we should be trimming the values.
103+
[' restart', Permission::ACTION_CONTROL_RESTART],
104+
['kill ', Permission::ACTION_CONTROL_STOP],
105+
];
106+
}
107+
}

0 commit comments

Comments
 (0)