diff --git a/tests/Integration/Api/Client/Server/PowerControllerTest.php b/tests/Integration/Api/Client/Server/PowerControllerTest.php new file mode 100644 index 000000000..80f58010a --- /dev/null +++ b/tests/Integration/Api/Client/Server/PowerControllerTest.php @@ -0,0 +1,107 @@ +generateTestAccount($permissions); + + $this->actingAs($user) + ->postJson("/api/client/servers/{$server->uuid}/power", ['signal' => $action]) + ->assertStatus(Response::HTTP_FORBIDDEN); + } + + /** + * Test that sending an invalid power signal returns an error. + */ + public function testInvalidPowerSignalResultsInError() + { + [$user, $server] = $this->generateTestAccount(); + + $response = $this->actingAs($user)->postJson("/api/client/servers/{$server->uuid}/power", [ + 'signal' => 'invalid', + ]); + + $response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY); + $response->assertJsonPath('errors.0.code', 'in'); + $response->assertJsonPath('errors.0.detail', 'The selected signal is invalid.'); + } + + /** + * Test that sending a valid power actions works. + * + * @param string $action + * @param string $permission + * @dataProvider validPowerActionDataProvider + */ + public function testActionCanBeSentToServer(string $action, string $permission) + { + $service = Mockery::mock(DaemonPowerRepository::class); + $this->app->instance(DaemonPowerRepository::class, $service); + + [$user, $server] = $this->generateTestAccount([$permission]); + + $service->expects('setServer') + ->with(Mockery::on(function ($value) use ($server) { + return $server->uuid === $value->uuid; + })) + ->andReturnSelf() + ->getMock() + ->expects('send') + ->with(trim($action)); + + $this->actingAs($user) + ->postJson("/api/client/servers/{$server->uuid}/power", ['signal' => $action]) + ->assertStatus(Response::HTTP_NO_CONTENT); + } + + /** + * Returns invalid permission combinations for a given power action. + * + * @return array + */ + public function invalidPermissionDataProvider(): array + { + return [ + ['start', [Permission::ACTION_CONTROL_STOP, Permission::ACTION_CONTROL_RESTART]], + ['stop', [Permission::ACTION_CONTROL_START]], + ['kill', [Permission::ACTION_CONTROL_START, Permission::ACTION_CONTROL_RESTART]], + ['restart', [Permission::ACTION_CONTROL_STOP, Permission::ACTION_CONTROL_START]], + ['random', [Permission::ACTION_CONTROL_START]], + ]; + } + + /** + * @return array + */ + public function validPowerActionDataProvider(): array + { + return [ + ['start', Permission::ACTION_CONTROL_START], + ['stop', Permission::ACTION_CONTROL_STOP], + ['restart', Permission::ACTION_CONTROL_RESTART], + ['kill', Permission::ACTION_CONTROL_STOP], + // Yes, these spaces are intentional. You should be able to send values with or without + // a space on the start/end since we should be trimming the values. + [' restart', Permission::ACTION_CONTROL_RESTART], + ['kill ', Permission::ACTION_CONTROL_STOP], + ]; + } +}