From a430ebb89e9d73815b3d66f1113caf372e2b9b4d Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Fri, 10 Jul 2020 21:17:28 -0700 Subject: [PATCH] Add test coverage for allocation routes --- .../Network/UpdateAllocationRequest.php | 4 +- .../Client/ClientApiIntegrationTestCase.php | 6 +- .../NetworkAllocationControllerTest.php | 212 ++++++++++++++++++ 3 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 tests/Integration/Api/Client/Server/NetworkAllocationControllerTest.php diff --git a/app/Http/Requests/Api/Client/Servers/Network/UpdateAllocationRequest.php b/app/Http/Requests/Api/Client/Servers/Network/UpdateAllocationRequest.php index 1424cad14..766a66b78 100644 --- a/app/Http/Requests/Api/Client/Servers/Network/UpdateAllocationRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Network/UpdateAllocationRequest.php @@ -21,8 +21,10 @@ class UpdateAllocationRequest extends ClientApiRequest */ public function rules(): array { + $rules = Allocation::getRules(); + return [ - 'notes' => Allocation::$validationRules['notes'], + 'notes' => array_merge($rules['notes'], ['present']), ]; } } diff --git a/tests/Integration/Api/Client/ClientApiIntegrationTestCase.php b/tests/Integration/Api/Client/ClientApiIntegrationTestCase.php index e6dbf0974..e893c17b9 100644 --- a/tests/Integration/Api/Client/ClientApiIntegrationTestCase.php +++ b/tests/Integration/Api/Client/ClientApiIntegrationTestCase.php @@ -15,6 +15,7 @@ use Pterodactyl\Models\Subuser; use Pterodactyl\Models\Location; use Pterodactyl\Models\Schedule; use Illuminate\Support\Collection; +use Pterodactyl\Models\Allocation; use Pterodactyl\Tests\Integration\IntegrationTestCase; use Pterodactyl\Transformers\Api\Client\BaseClientTransformer; @@ -53,7 +54,7 @@ abstract class ClientApiIntegrationTestCase extends IntegrationTestCase */ protected function link($model, $append = null): string { - Assert::isInstanceOfAny($model, [Server::class, Schedule::class, Task::class]); + Assert::isInstanceOfAny($model, [Server::class, Schedule::class, Task::class, Allocation::class]); $link = ''; switch (get_class($model)) { @@ -66,6 +67,9 @@ abstract class ClientApiIntegrationTestCase extends IntegrationTestCase case Task::class: $link = "/api/client/servers/{$model->schedule->server->uuid}/schedules/{$model->schedule->id}/tasks/{$model->id}"; break; + case Allocation::class: + $link = "/api/client/servers/{$model->server->uuid}/network/allocations/{$model->id}"; + break; } return $link . ($append ? '/' . ltrim($append, '/') : ''); diff --git a/tests/Integration/Api/Client/Server/NetworkAllocationControllerTest.php b/tests/Integration/Api/Client/Server/NetworkAllocationControllerTest.php new file mode 100644 index 000000000..b019b3e62 --- /dev/null +++ b/tests/Integration/Api/Client/Server/NetworkAllocationControllerTest.php @@ -0,0 +1,212 @@ +generateTestAccount(); + $allocation = $this->getAllocation($server); + + $response = $this->actingAs($user)->getJson($this->link($server, '/network/allocations')); + + $response->assertOk(); + $response->assertJsonPath('object', 'list'); + $response->assertJsonCount(1, 'data'); + + $this->assertJsonTransformedWith($response->json('data.0.attributes'), $allocation); + } + + /** + * Test that allocations cannot be returned without the required user permissions. + */ + public function testServerAllocationsAreNotReturnedWithoutPermission() + { + [$user, $server] = $this->generateTestAccount(); + $user2 = factory(User::class)->create(); + + $server->owner_id = $user2->id; + $server->save(); + + $this->actingAs($user)->getJson($this->link($server, '/network/allocations')) + ->assertNotFound(); + + [$user, $server] = $this->generateTestAccount([Permission::ACTION_ALLOCATION_CREATE]); + + $this->actingAs($user)->getJson($this->link($server, '/network/allocations')) + ->assertForbidden(); + } + + /** + * Tests that notes on an allocation can be set correctly. + * + * @param array $permissions + * @dataProvider updatePermissionsDataProvider + */ + public function testAllocationNotesCanBeUpdated(array $permissions) + { + [$user, $server] = $this->generateTestAccount($permissions); + $allocation = $this->getAllocation($server); + + $this->assertNull($allocation->notes); + + $this->actingAs($user)->postJson($this->link($allocation), []) + ->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY) + ->assertJsonPath('errors.0.code', 'present'); + + $this->actingAs($user)->postJson($this->link($allocation), ['notes' => 'Test notes']) + ->assertOk() + ->assertJsonPath('object', Allocation::RESOURCE_NAME) + ->assertJsonPath('attributes.notes', 'Test notes'); + + $allocation = $allocation->refresh(); + + $this->assertSame('Test notes', $allocation->notes); + + $this->actingAs($user)->postJson($this->link($allocation), ['notes' => null]) + ->assertOk() + ->assertJsonPath('object', Allocation::RESOURCE_NAME) + ->assertJsonPath('attributes.notes', null); + + $allocation = $allocation->refresh(); + + $this->assertNull($allocation->notes); + } + + public function testAllocationNotesCannotBeUpdatedByInvalidUsers() + { + [$user, $server] = $this->generateTestAccount(); + $user2 = factory(User::class)->create(); + + $server->owner_id = $user2->id; + $server->save(); + + $this->actingAs($user)->postJson($this->link($this->getAllocation($server))) + ->assertNotFound(); + + [$user, $server] = $this->generateTestAccount([Permission::ACTION_ALLOCATION_CREATE]); + + $this->actingAs($user)->postJson($this->link($this->getAllocation($server))) + ->assertForbidden(); + } + + /** + * @param array $permissions + * @dataProvider updatePermissionsDataProvider + */ + public function testPrimaryAllocationCanBeModified(array $permissions) + { + [$user, $server] = $this->generateTestAccount($permissions); + $allocation = $this->getAllocation($server); + $allocation2 = $this->getAllocation($server); + + $server->allocation_id = $allocation->id; + $server->save(); + + $this->actingAs($user)->postJson($this->link($allocation2, '/primary')) + ->assertOk(); + + $server = $server->refresh(); + + $this->assertSame($allocation2->id, $server->allocation_id); + } + + public function testPrimaryAllocationCannotBeModifiedByInvalidUser() + { + [$user, $server] = $this->generateTestAccount(); + $user2 = factory(User::class)->create(); + + $server->owner_id = $user2->id; + $server->save(); + + $this->actingAs($user)->postJson($this->link($this->getAllocation($server), '/primary')) + ->assertNotFound(); + + [$user, $server] = $this->generateTestAccount([Permission::ACTION_ALLOCATION_CREATE]); + + $this->actingAs($user)->postJson($this->link($this->getAllocation($server), '/primary')) + ->assertForbidden(); + } + + /** + * @param array $permissions + * @dataProvider deletePermissionsDataProvider + */ + public function testAllocationCanBeDeleted(array $permissions) + { + [$user, $server] = $this->generateTestAccount($permissions); + $allocation = $this->getAllocation($server); + $allocation2 = $this->getAllocation($server); + + $allocation2->notes = 'Filled notes'; + $allocation2->save(); + + $server->allocation_id = $allocation->id; + $server->save(); + + $this->actingAs($user)->deleteJson($this->link($allocation)) + ->assertStatus(Response::HTTP_BAD_REQUEST) + ->assertJsonPath('errors.0.code', 'DisplayException') + ->assertJsonPath('errors.0.detail', 'Cannot delete the primary allocation for a server.'); + + $this->actingAs($user)->deleteJson($this->link($allocation2)) + ->assertStatus(Response::HTTP_NO_CONTENT); + + $server = $server->refresh(); + $allocation2 = $allocation2->refresh(); + + $this->assertSame($allocation->id, $server->allocation_id); + $this->assertNull($allocation2->server_id); + $this->assertNull($allocation2->notes); + } + + public function testAllocationCannotBeDeletedByInvalidUser() + { + [$user, $server] = $this->generateTestAccount(); + $user2 = factory(User::class)->create(); + + $server->owner_id = $user2->id; + $server->save(); + + $this->actingAs($user)->deleteJson($this->link($this->getAllocation($server))) + ->assertNotFound(); + + [$user, $server] = $this->generateTestAccount([Permission::ACTION_ALLOCATION_CREATE]); + + $this->actingAs($user)->deleteJson($this->link($this->getAllocation($server))) + ->assertForbidden(); + } + + public function updatePermissionsDataProvider() + { + return [[[]], [[Permission::ACTION_ALLOCATION_UPDATE]]]; + } + + public function deletePermissionsDataProvider() + { + return [[[]], [[Permission::ACTION_ALLOCATION_DELETE]]]; + } + + /** + * @param \Pterodactyl\Models\Server $server + * @return \Pterodactyl\Models\Allocation + */ + protected function getAllocation(Server $server): Allocation + { + return factory(Allocation::class)->create([ + 'server_id' => $server->id, + 'node_id' => $server->node_id, + ]); + } +}