Merge branch 'develop' into matthewpi/security-keys-backport

This commit is contained in:
Matthew Penner 2023-01-17 15:33:53 -07:00
commit f631ac1946
No known key found for this signature in database
1153 changed files with 25099 additions and 37002 deletions

View file

@ -2,16 +2,12 @@
namespace Pterodactyl\Tests\Integration\Api\Application;
use Illuminate\Http\Request;
use Pterodactyl\Models\User;
use PHPUnit\Framework\Assert;
use Pterodactyl\Models\ApiKey;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Tests\Integration\IntegrationTestCase;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Pterodactyl\Tests\Traits\Integration\CreatesTestModels;
use Pterodactyl\Transformers\Api\Application\BaseTransformer;
use Pterodactyl\Transformers\Api\Client\BaseClientTransformer;
use Pterodactyl\Tests\Traits\Http\IntegrationJsonRequestAssertions;
abstract class ApplicationApiIntegrationTestCase extends IntegrationTestCase
@ -91,22 +87,4 @@ abstract class ApplicationApiIntegrationTestCase extends IntegrationTestCase
'r_server_databases' => AdminAcl::READ | AdminAcl::WRITE,
], $permissions));
}
/**
* Return a transformer that can be used for testing purposes.
*/
protected function getTransformer(string $abstract): BaseTransformer
{
$request = Request::createFromGlobals();
$request->setUserResolver(function () {
return $this->getApiKey()->user;
});
$transformer = $abstract::fromRequest($request);
Assert::assertInstanceOf(BaseTransformer::class, $transformer);
Assert::assertNotInstanceOf(BaseClientTransformer::class, $transformer);
return $transformer;
}
}

View file

@ -1,21 +1,33 @@
<?php
namespace Pterodactyl\Tests\Integration\Api\Application\Nests;
namespace Pterodactyl\Tests\Integration\Api\Application\Eggs;
use Illuminate\Support\Arr;
use Pterodactyl\Models\Egg;
use Illuminate\Http\Response;
use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
use Pterodactyl\Transformers\Api\Application\EggTransformer;
use Pterodactyl\Tests\Integration\Api\Application\ApplicationApiIntegrationTestCase;
class EggControllerTest extends ApplicationApiIntegrationTestCase
{
private EggRepositoryInterface $repository;
/**
* Setup tests.
*/
public function setUp(): void
{
parent::setUp();
$this->repository = $this->app->make(EggRepositoryInterface::class);
}
/**
* Test that all the eggs belonging to a given nest can be returned.
*/
public function testListAllEggsInNest()
{
$eggs = Egg::query()->where('nest_id', 1)->get();
$eggs = $this->repository->findWhere([['nest_id', '=', 1]]);
$response = $this->getJson('/api/application/nests/' . $eggs->first()->nest_id . '/eggs');
$response->assertStatus(Response::HTTP_OK);
@ -26,13 +38,12 @@ class EggControllerTest extends ApplicationApiIntegrationTestCase
[
'object',
'attributes' => [
'id', 'uuid', 'nest', 'author', 'description', 'docker_image', 'startup', 'created_at', 'updated_at',
'id', 'uuid', 'nest_id', 'author', 'description', 'docker_images', 'startup', 'created_at', 'updated_at',
'script' => ['privileged', 'install', 'entry', 'container', 'extends'],
'config' => [
'files' => [],
'startup' => ['done'],
'stop',
'logs' => [],
'extends',
],
],
@ -44,12 +55,12 @@ class EggControllerTest extends ApplicationApiIntegrationTestCase
$egg = $eggs->where('id', '=', $datum['attributes']['id'])->first();
$expected = json_encode(Arr::sortRecursive($datum['attributes']));
$actual = json_encode(Arr::sortRecursive($this->getTransformer(EggTransformer::class)->transform($egg)));
$actual = json_encode(Arr::sortRecursive((new EggTransformer())->transform($egg)));
$this->assertSame(
$this->assertJsonStringEqualsJsonString(
$expected,
$actual,
'Unable to find JSON fragment: ' . PHP_EOL . PHP_EOL . "[$expected]" . PHP_EOL . PHP_EOL . 'within' . PHP_EOL . PHP_EOL . "[$actual]."
'Unable to find JSON fragment: ' . PHP_EOL . PHP_EOL . "[{$expected}]" . PHP_EOL . PHP_EOL . 'within' . PHP_EOL . PHP_EOL . "[{$actual}]."
);
}
}
@ -59,20 +70,20 @@ class EggControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testReturnSingleEgg()
{
$egg = Egg::query()->findOrFail(1);
$egg = $this->repository->find(1);
$response = $this->getJson('/api/application/nests/' . $egg->nest_id . '/eggs/' . $egg->id);
$response = $this->getJson('/api/application/eggs/' . $egg->id);
$response->assertStatus(Response::HTTP_OK);
$response->assertJsonStructure([
'object',
'attributes' => [
'id', 'uuid', 'nest', 'author', 'description', 'docker_image', 'startup', 'script' => [], 'config' => [], 'created_at', 'updated_at',
'id', 'uuid', 'nest_id', 'author', 'description', 'docker_images', 'startup', 'script' => [], 'config' => [], 'created_at', 'updated_at',
],
]);
$response->assertJson([
'object' => 'egg',
'attributes' => $this->getTransformer(EggTransformer::class)->transform($egg),
'attributes' => json_decode(json_encode((new EggTransformer())->transform($egg)), true),
], true);
}
@ -81,9 +92,9 @@ class EggControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testReturnSingleEggWithRelationships()
{
$egg = Egg::query()->findOrFail(1);
$egg = $this->repository->find(1);
$response = $this->getJson('/api/application/nests/' . $egg->nest_id . '/eggs/' . $egg->id . '?include=servers,variables,nest');
$response = $this->getJson('/api/application/eggs/' . $egg->id . '?include=servers,variables,nest');
$response->assertStatus(Response::HTTP_OK);
$response->assertJsonStructure([
'object',
@ -102,9 +113,7 @@ class EggControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testGetMissingEgg()
{
$egg = Egg::query()->findOrFail(1);
$response = $this->getJson('/api/application/nests/' . $egg->nest_id . '/eggs/nil');
$response = $this->getJson('/api/application/eggs/0');
$this->assertNotFoundJson($response);
}
@ -114,10 +123,6 @@ class EggControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testErrorReturnedIfNoPermission()
{
$egg = Egg::query()->findOrFail(1);
$this->createNewDefaultApiKey($this->getApiUser(), ['r_eggs' => 0]);
$response = $this->getJson('/api/application/nests/' . $egg->nest_id . '/eggs');
$this->assertAccessDeniedJson($response);
$this->markTestSkipped('todo: implement proper admin api key permissions system');
}
}

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Integration\Api\Application\Location;
use Pterodactyl\Models\Node;
use Illuminate\Http\Response;
use Pterodactyl\Models\Location;
use Pterodactyl\Transformers\Api\Application\NodeTransformer;
@ -100,11 +99,10 @@ class LocationControllerTest extends ApplicationApiIntegrationTestCase
]);
$response->assertStatus(Response::HTTP_CREATED);
$response->assertJsonCount(3);
$response->assertJsonCount(2);
$response->assertJsonStructure([
'object',
'attributes' => ['id', 'short', 'long', 'created_at', 'updated_at'],
'meta' => ['resource'],
]);
$this->assertDatabaseHas('locations', ['short' => 'inhouse', 'long' => 'This is my inhouse location']);
@ -112,10 +110,7 @@ class LocationControllerTest extends ApplicationApiIntegrationTestCase
$location = Location::where('short', 'inhouse')->first();
$response->assertJson([
'object' => 'location',
'attributes' => $this->getTransformer(LocationTransformer::class)->transform($location),
'meta' => [
'resource' => route('api.application.locations.view', $location->id),
],
'attributes' => (new LocationTransformer())->transform($location),
], true);
}
@ -142,7 +137,7 @@ class LocationControllerTest extends ApplicationApiIntegrationTestCase
$response->assertJson([
'object' => 'location',
'attributes' => $this->getTransformer(LocationTransformer::class)->transform($location),
'attributes' => (new LocationTransformer())->transform($location),
]);
}
@ -189,7 +184,7 @@ class LocationControllerTest extends ApplicationApiIntegrationTestCase
'data' => [
[
'object' => 'node',
'attributes' => $this->getTransformer(NodeTransformer::class)->transform($server->getRelation('node')),
'attributes' => (new NodeTransformer())->transform($server->getRelation('node')),
],
],
],
@ -198,7 +193,7 @@ class LocationControllerTest extends ApplicationApiIntegrationTestCase
'data' => [
[
'object' => 'server',
'attributes' => $this->getTransformer(ServerTransformer::class)->transform($server),
'attributes' => (new ServerTransformer())->transform($server),
],
],
],
@ -213,33 +208,7 @@ class LocationControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testKeyWithoutPermissionCannotLoadRelationship()
{
$this->createNewDefaultApiKey($this->getApiUser(), ['r_nodes' => 0]);
$location = Location::factory()->create();
Node::factory()->create(['location_id' => $location->id]);
$response = $this->getJson('/api/application/locations/' . $location->id . '?include=nodes');
$response->assertStatus(Response::HTTP_OK);
$response->assertJsonCount(2)->assertJsonCount(1, 'attributes.relationships');
$response->assertJsonStructure([
'attributes' => [
'relationships' => [
'nodes' => ['object', 'attributes'],
],
],
]);
// Just assert that we see the expected relationship IDs in the response.
$response->assertJson([
'attributes' => [
'relationships' => [
'nodes' => [
'object' => 'null_resource',
'attributes' => null,
],
],
],
]);
$this->markTestSkipped('todo: implement proper admin api key permissions system');
}
/**
@ -249,7 +218,7 @@ class LocationControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testGetMissingLocation()
{
$response = $this->getJson('/api/application/locations/nil');
$response = $this->getJson('/api/application/locations/0');
$this->assertNotFoundJson($response);
}
@ -259,10 +228,6 @@ class LocationControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testErrorReturnedIfNoPermission()
{
$location = Location::factory()->create();
$this->createNewDefaultApiKey($this->getApiUser(), ['r_locations' => 0]);
$response = $this->getJson('/api/application/locations/' . $location->id);
$this->assertAccessDeniedJson($response);
$this->markTestSkipped('todo: implement proper admin api key permissions system');
}
}

View file

@ -45,7 +45,7 @@ class NestControllerTest extends ApplicationApiIntegrationTestCase
'pagination' => [
'total' => 4,
'count' => 4,
'per_page' => 50,
'per_page' => 10,
'current_page' => 1,
'total_pages' => 1,
],
@ -55,7 +55,7 @@ class NestControllerTest extends ApplicationApiIntegrationTestCase
foreach ($nests as $nest) {
$response->assertJsonFragment([
'object' => 'nest',
'attributes' => $this->getTransformer(NestTransformer::class)->transform($nest),
'attributes' => (new NestTransformer())->transform($nest),
]);
}
}
@ -76,7 +76,7 @@ class NestControllerTest extends ApplicationApiIntegrationTestCase
$response->assertJson([
'object' => 'nest',
'attributes' => $this->getTransformer(NestTransformer::class)->transform($nest),
'attributes' => (new NestTransformer())->transform($nest),
]);
}
@ -108,7 +108,7 @@ class NestControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testGetMissingNest()
{
$response = $this->getJson('/api/application/nests/nil');
$response = $this->getJson('/api/application/nests/0');
$this->assertNotFoundJson($response);
}
@ -118,10 +118,6 @@ class NestControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testErrorReturnedIfNoPermission()
{
$nest = $this->repository->find(1);
$this->createNewDefaultApiKey($this->getApiUser(), ['r_nests' => 0]);
$response = $this->getJson('/api/application/nests/' . $nest->id);
$this->assertAccessDeniedJson($response);
$this->markTestSkipped('todo: implement proper admin api key permissions system');
}
}

View file

@ -22,7 +22,7 @@ class ExternalUserControllerTest extends ApplicationApiIntegrationTestCase
$response->assertJsonStructure([
'object',
'attributes' => [
'id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name',
'id', 'external_id', 'uuid', 'username', 'email',
'language', 'root_admin', '2fa', 'created_at', 'updated_at',
],
]);
@ -35,11 +35,9 @@ class ExternalUserControllerTest extends ApplicationApiIntegrationTestCase
'uuid' => $user->uuid,
'username' => $user->username,
'email' => $user->email,
'first_name' => $user->name_first,
'last_name' => $user->name_last,
'language' => $user->language,
'root_admin' => (bool) $user->root_admin,
'2fa' => (bool) $user->totp_enabled,
'2fa' => (bool) $user->use_totp,
'created_at' => $this->formatTimestamp($user->created_at),
'updated_at' => $this->formatTimestamp($user->updated_at),
],
@ -51,7 +49,7 @@ class ExternalUserControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testGetMissingUser()
{
$response = $this->getJson('/api/application/users/external/nil');
$response = $this->getJson('/api/application/users/external/0');
$this->assertNotFoundJson($response);
}
@ -61,10 +59,6 @@ class ExternalUserControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testErrorReturnedIfNoPermission()
{
$user = User::factory()->create(['external_id' => Str::random()]);
$this->createNewDefaultApiKey($this->getApiUser(), ['r_users' => 0]);
$response = $this->getJson('/api/application/users/external/' . $user->external_id);
$this->assertAccessDeniedJson($response);
$this->markTestSkipped('todo: implement proper admin api key permissions system');
}
}

View file

@ -4,7 +4,6 @@ namespace Pterodactyl\Tests\Integration\Api\Application\Users;
use Pterodactyl\Models\User;
use Illuminate\Http\Response;
use Pterodactyl\Services\Acl\Api\AdminAcl;
use Pterodactyl\Transformers\Api\Application\UserTransformer;
use Pterodactyl\Transformers\Api\Application\ServerTransformer;
use Pterodactyl\Tests\Integration\Api\Application\ApplicationApiIntegrationTestCase;
@ -24,8 +23,8 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
$response->assertJsonStructure([
'object',
'data' => [
['object', 'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at']],
['object', 'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at']],
['object', 'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'language', 'admin_role_id', 'root_admin', '2fa', 'avatar_url', 'role_name', 'created_at', 'updated_at']],
['object', 'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'language', 'admin_role_id', 'root_admin', '2fa', 'avatar_url', 'role_name', 'created_at', 'updated_at']],
],
'meta' => ['pagination' => ['total', 'count', 'per_page', 'current_page', 'total_pages']],
]);
@ -52,11 +51,12 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
'uuid' => $this->getApiUser()->uuid,
'username' => $this->getApiUser()->username,
'email' => $this->getApiUser()->email,
'first_name' => $this->getApiUser()->name_first,
'last_name' => $this->getApiUser()->name_last,
'language' => $this->getApiUser()->language,
'admin_role_id' => $this->getApiUser()->admin_role_id,
'root_admin' => $this->getApiUser()->root_admin,
'2fa' => (bool) $this->getApiUser()->totp_enabled,
'2fa' => $this->getApiUser()->use_totp,
'avatar_url' => $this->getApiUser()->avatar_url,
'role_name' => $this->getApiUser()->admin_role_name,
'created_at' => $this->formatTimestamp($this->getApiUser()->created_at),
'updated_at' => $this->formatTimestamp($this->getApiUser()->updated_at),
],
@ -69,11 +69,12 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
'uuid' => $user->uuid,
'username' => $user->username,
'email' => $user->email,
'first_name' => $user->name_first,
'last_name' => $user->name_last,
'language' => $user->language,
'admin_role_id' => $user->admin_role_id,
'root_admin' => (bool) $user->root_admin,
'2fa' => (bool) $user->totp_enabled,
'2fa' => (bool) $user->use_totp,
'avatar_url' => $user->avatar_url,
'role_name' => $user->admin_role_name,
'created_at' => $this->formatTimestamp($user->created_at),
'updated_at' => $this->formatTimestamp($user->updated_at),
],
@ -92,7 +93,7 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
$response->assertJsonCount(2);
$response->assertJsonStructure([
'object',
'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at'],
'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'language', 'admin_role_id', 'root_admin', '2fa', 'avatar_url', 'role_name', 'created_at', 'updated_at'],
]);
$response->assertJson([
@ -103,11 +104,12 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
'uuid' => $user->uuid,
'username' => $user->username,
'email' => $user->email,
'first_name' => $user->name_first,
'last_name' => $user->name_last,
'language' => $user->language,
'admin_role_id' => $user->admin_role_id,
'root_admin' => (bool) $user->root_admin,
'2fa' => (bool) $user->totp_enabled,
'2fa' => (bool) $user->use_totp,
'avatar_url' => $user->avatar_url,
'role_name' => $user->admin_role_name,
'created_at' => $this->formatTimestamp($user->created_at),
'updated_at' => $this->formatTimestamp($user->updated_at),
],
@ -128,7 +130,7 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
$response->assertJsonStructure([
'object',
'attributes' => [
'id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at',
'id', 'external_id', 'uuid', 'username', 'email', 'language', 'admin_role_id', 'root_admin', '2fa', 'avatar_url', 'role_name', 'created_at', 'updated_at',
'relationships' => ['servers' => ['object', 'data' => [['object', 'attributes' => []]]]],
],
]);
@ -138,7 +140,7 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
'data' => [
[
'object' => 'server',
'attributes' => $this->getTransformer(ServerTransformer::class)->transform($server),
'attributes' => (new ServerTransformer())->transform($server),
],
],
]);
@ -150,33 +152,7 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testKeyWithoutPermissionCannotLoadRelationship()
{
$this->createNewDefaultApiKey($this->getApiUser(), ['r_servers' => 0]);
$user = User::factory()->create();
$this->createServerModel(['user_id' => $user->id]);
$response = $this->getJson('/api/application/users/' . $user->id . '?include=servers');
$response->assertStatus(Response::HTTP_OK);
$response->assertJsonCount(2)->assertJsonCount(1, 'attributes.relationships');
$response->assertJsonStructure([
'attributes' => [
'relationships' => [
'servers' => ['object', 'attributes'],
],
],
]);
// Just assert that we see the expected relationship IDs in the response.
$response->assertJson([
'attributes' => [
'relationships' => [
'servers' => [
'object' => 'null_resource',
'attributes' => null,
],
],
],
]);
$this->markTestSkipped('todo: implement proper admin api key permissions system');
}
/**
@ -184,7 +160,7 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testGetMissingUser()
{
$response = $this->getJson('/api/application/users/nil');
$response = $this->getJson('/api/application/users/0');
$this->assertNotFoundJson($response);
}
@ -194,11 +170,7 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testErrorReturnedIfNoPermission()
{
$user = User::factory()->create();
$this->createNewDefaultApiKey($this->getApiUser(), ['r_users' => 0]);
$response = $this->getJson('/api/application/users/' . $user->id);
$this->assertAccessDeniedJson($response);
$this->markTestSkipped('todo: implement proper admin api key permissions system');
}
/**
@ -209,16 +181,13 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
$response = $this->postJson('/api/application/users', [
'username' => 'testuser',
'email' => 'test@example.com',
'first_name' => 'Test',
'last_name' => 'User',
]);
$response->assertStatus(Response::HTTP_CREATED);
$response->assertJsonCount(3);
$response->assertJsonCount(2);
$response->assertJsonStructure([
'object',
'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at'],
'meta' => ['resource'],
'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'language', 'admin_role_id', 'root_admin', '2fa', 'avatar_url', 'role_name', 'created_at', 'updated_at'],
]);
$this->assertDatabaseHas('users', ['username' => 'testuser', 'email' => 'test@example.com']);
@ -226,10 +195,7 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
$user = User::where('username', 'testuser')->first();
$response->assertJson([
'object' => 'user',
'attributes' => $this->getTransformer(UserTransformer::class)->transform($user),
'meta' => [
'resource' => route('api.application.users.view', $user->id),
],
'attributes' => (new UserTransformer())->transform($user),
], true);
}
@ -243,14 +209,12 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
$response = $this->patchJson('/api/application/users/' . $user->id, [
'username' => 'new.test.name',
'email' => 'new@emailtest.com',
'first_name' => $user->name_first,
'last_name' => $user->name_last,
]);
$response->assertStatus(Response::HTTP_OK);
$response->assertJsonCount(2);
$response->assertJsonStructure([
'object',
'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at'],
'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'language', 'admin_role_id', 'root_admin', '2fa', 'avatar_url', 'role_name', 'created_at', 'updated_at'],
]);
$this->assertDatabaseHas('users', ['username' => 'new.test.name', 'email' => 'new@emailtest.com']);
@ -258,7 +222,7 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
$response->assertJson([
'object' => 'user',
'attributes' => $this->getTransformer(UserTransformer::class)->transform($user),
'attributes' => (new UserTransformer())->transform($user),
]);
}
@ -284,15 +248,7 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
*/
public function testApiKeyWithoutWritePermissions(string $method, string $url)
{
$this->createNewDefaultApiKey($this->getApiUser(), ['r_users' => AdminAcl::READ]);
if (str_contains($url, '{id}')) {
$user = User::factory()->create();
$url = str_replace('{id}', $user->id, $url);
}
$response = $this->$method($url);
$this->assertAccessDeniedJson($response);
$this->markTestSkipped('todo: implement proper admin api key permissions system');
}
/**

View file

@ -26,8 +26,6 @@ class AccountControllerTest extends ClientApiIntegrationTestCase
'admin' => false,
'username' => $user->username,
'email' => $user->email,
'first_name' => $user->name_first,
'last_name' => $user->name_last,
'language' => $user->language,
],
]);

View file

@ -2,11 +2,9 @@
namespace Pterodactyl\Tests\Integration\Api\Client;
use ReflectionClass;
use Pterodactyl\Models\Node;
use Pterodactyl\Models\Task;
use Pterodactyl\Models\User;
use InvalidArgumentException;
use Pterodactyl\Models\Model;
use Pterodactyl\Models\Backup;
use Pterodactyl\Models\Server;
@ -16,10 +14,10 @@ use Pterodactyl\Models\Schedule;
use Illuminate\Support\Collection;
use Pterodactyl\Models\Allocation;
use Pterodactyl\Models\DatabaseHost;
use Pterodactyl\Transformers\Api\Transformer;
use Pterodactyl\Tests\Integration\TestResponse;
use Pterodactyl\Tests\Integration\IntegrationTestCase;
use Illuminate\Database\Eloquent\Model as EloquentModel;
use Pterodactyl\Transformers\Api\Client\BaseClientTransformer;
abstract class ClientApiIntegrationTestCase extends IntegrationTestCase
{
@ -75,7 +73,7 @@ abstract class ClientApiIntegrationTestCase extends IntegrationTestCase
$link = "/api/client/servers/{$model->server->uuid}/backups/$model->uuid";
break;
default:
throw new InvalidArgumentException(sprintf('Cannot create link for Model of type %s', class_basename($model)));
throw new \InvalidArgumentException(sprintf('Cannot create link for Model of type %s', class_basename($model)));
}
return $link . ($append ? '/' . ltrim($append, '/') : '');
@ -87,11 +85,11 @@ abstract class ClientApiIntegrationTestCase extends IntegrationTestCase
*/
protected function assertJsonTransformedWith(array $data, Model|EloquentModel $model)
{
$reflect = new ReflectionClass($model);
$reflect = new \ReflectionClass($model);
$transformer = sprintf('\\Pterodactyl\\Transformers\\Api\\Client\\%sTransformer', $reflect->getShortName());
$transformer = new $transformer();
$this->assertInstanceOf(BaseClientTransformer::class, $transformer);
$this->assertInstanceOf(Transformer::class, $transformer);
$this->assertSame(
$transformer->transform($model),

View file

@ -18,10 +18,10 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
*/
public function testOnlyLoggedInUsersServersAreReturned()
{
/** @var \Pterodactyl\Models\User[] $users */
/** @var User[] $users */
$users = User::factory()->times(3)->create();
/** @var \Pterodactyl\Models\Server[] $servers */
/** @var Server[] $servers */
$servers = [
$this->createServerModel(['user_id' => $users[0]->id]),
$this->createServerModel(['user_id' => $users[1]->id]),
@ -45,11 +45,11 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
*/
public function testServersAreFilteredUsingNameAndUuidInformation()
{
/** @var \Pterodactyl\Models\User[] $users */
/** @var User[] $users */
$users = User::factory()->times(2)->create();
$users[0]->update(['root_admin' => true]);
/** @var \Pterodactyl\Models\Server[] $servers */
/** @var Server[] $servers */
$servers = [
$this->createServerModel(['user_id' => $users[0]->id, 'name' => 'Julia']),
$this->createServerModel(['user_id' => $users[1]->id, 'uuidShort' => '12121212', 'name' => 'Janice']),
@ -101,8 +101,8 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
*/
public function testServersAreFilteredUsingAllocationInformation()
{
/** @var \Pterodactyl\Models\User $user */
/** @var \Pterodactyl\Models\Server $server */
/** @var User $user */
/** @var Server $server */
[$user, $server] = $this->generateTestAccount();
$server2 = $this->createServerModel(['user_id' => $user->id, 'node_id' => $server->node_id]);
@ -143,7 +143,7 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
*/
public function testServersUserIsASubuserOfAreReturned()
{
/** @var \Pterodactyl\Models\User[] $users */
/** @var User[] $users */
$users = User::factory()->times(3)->create();
$servers = [
$this->createServerModel(['user_id' => $users[0]->id]),
@ -174,7 +174,7 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
*/
public function testFilterOnlyOwnerServers()
{
/** @var \Pterodactyl\Models\User[] $users */
/** @var User[] $users */
$users = User::factory()->times(3)->create();
$servers = [
$this->createServerModel(['user_id' => $users[0]->id]),
@ -203,7 +203,7 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
*/
public function testPermissionsAreReturned()
{
/** @var \Pterodactyl\Models\User $user */
/** @var User $user */
$user = User::factory()->create();
$this->actingAs($user)
@ -223,7 +223,7 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
*/
public function testOnlyAdminLevelServersAreReturned()
{
/** @var \Pterodactyl\Models\User[] $users */
/** @var User[] $users */
$users = User::factory()->times(4)->create();
$users[0]->update(['root_admin' => true]);
@ -258,7 +258,7 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
*/
public function testAllServersAreReturnedToAdmin()
{
/** @var \Pterodactyl\Models\User[] $users */
/** @var User[] $users */
$users = User::factory()->times(4)->create();
$users[0]->update(['root_admin' => true]);
@ -290,7 +290,7 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
*/
public function testNoServersAreReturnedIfAdminFilterIsPassedByRegularUser(string $type)
{
/** @var \Pterodactyl\Models\User[] $users */
/** @var User[] $users */
$users = User::factory()->times(3)->create();
$this->createServerModel(['user_id' => $users[0]->id]);
@ -309,7 +309,7 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
*/
public function testOnlyPrimaryAllocationIsReturnedToSubuser()
{
/** @var \Pterodactyl\Models\Server $server */
/** @var Server $server */
[$user, $server] = $this->generateTestAccount([Permission::ACTION_WEBSOCKET_CONNECT]);
$server->allocation->notes = 'Test notes';
$server->allocation->save();

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Integration\Api\Client\Server\Backup;
use Mockery;
use Carbon\CarbonImmutable;
use Pterodactyl\Models\Backup;
use Pterodactyl\Models\Subuser;
@ -31,7 +30,7 @@ class BackupAuthorizationTest extends ClientApiIntegrationTestCase
$backup2 = Backup::factory()->create(['server_id' => $server2->id, 'completed_at' => CarbonImmutable::now()]);
$backup3 = Backup::factory()->create(['server_id' => $server3->id, 'completed_at' => CarbonImmutable::now()]);
$this->instance(DeleteBackupService::class, $mock = Mockery::mock(DeleteBackupService::class));
$this->instance(DeleteBackupService::class, $mock = \Mockery::mock(DeleteBackupService::class));
if ($method === 'DELETE') {
$mock->expects('handle')->andReturnUndefined();

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Integration\Api\Client\Server\Backup;
use Mockery;
use Mockery\MockInterface;
use Illuminate\Http\Response;
use Pterodactyl\Models\Backup;
@ -48,7 +47,7 @@ class DeleteBackupTest extends ClientApiIntegrationTestCase
$backup = Backup::factory()->create(['server_id' => $server->id]);
$this->repository->expects('setServer->delete')->with(
Mockery::on(function ($value) use ($backup) {
\Mockery::on(function ($value) use ($backup) {
return $value instanceof Backup && $value->uuid === $backup->uuid;
})
)->andReturn(new Response());

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Integration\Api\Client\Server;
use Mockery;
use GuzzleHttp\Psr7\Request;
use Illuminate\Http\Response;
use Pterodactyl\Models\Server;
@ -55,7 +54,7 @@ class CommandControllerTest extends ClientApiIntegrationTestCase
$mock = $this->mock(DaemonCommandRepository::class);
$mock->expects('setServer')
->with(Mockery::on(fn (Server $value) => $value->is($server)))
->with(\Mockery::on(fn (Server $value) => $value->is($server)))
->andReturnSelf();
$mock->expects('send')->with('say Test')->andReturn(new GuzzleResponse());

View file

@ -24,7 +24,7 @@ class DatabaseAuthorizationTest extends ClientApiIntegrationTestCase
// And as no access to $server3.
$server3 = $this->createServerModel();
$host = DatabaseHost::factory()->create([]);
$host = DatabaseHost::factory()->create();
// Set the API $user as a subuser of server 2, but with no permissions
// to do anything with the databases for that server.

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Integration\Api\Client\Server;
use Mockery;
use Illuminate\Http\Response;
use Pterodactyl\Models\Permission;
use Pterodactyl\Repositories\Wings\DaemonPowerRepository;
@ -51,13 +50,13 @@ class PowerControllerTest extends ClientApiIntegrationTestCase
*/
public function testActionCanBeSentToServer(string $action, string $permission)
{
$service = Mockery::mock(DaemonPowerRepository::class);
$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) {
->with(\Mockery::on(function ($value) use ($server) {
return $server->uuid === $value->uuid;
}))
->andReturnSelf()

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Integration\Api\Client\Server;
use Mockery;
use Pterodactyl\Models\Permission;
use Pterodactyl\Repositories\Wings\DaemonServerRepository;
use Pterodactyl\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
@ -14,12 +13,12 @@ class ResourceUtilizationControllerTest extends ClientApiIntegrationTestCase
*/
public function testServerResourceUtilizationIsReturned()
{
$service = Mockery::mock(DaemonServerRepository::class);
$service = \Mockery::mock(DaemonServerRepository::class);
$this->app->instance(DaemonServerRepository::class, $service);
[$user, $server] = $this->generateTestAccount([Permission::ACTION_WEBSOCKET_CONNECT]);
$service->expects('setServer')->with(Mockery::on(function ($value) use ($server) {
$service->expects('setServer')->with(\Mockery::on(function ($value) use ($server) {
return $server->uuid === $value->uuid;
}))->andReturnSelf()->getMock()->expects('getDetails')->andReturns([]);

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Integration\Api\Client\Server;
use Mockery;
use Illuminate\Http\Response;
use Pterodactyl\Models\Server;
use Pterodactyl\Models\Permission;
@ -78,11 +77,11 @@ class SettingsControllerTest extends ClientApiIntegrationTestCase
[$user, $server] = $this->generateTestAccount($permissions);
$this->assertTrue($server->isInstalled());
$service = Mockery::mock(DaemonServerRepository::class);
$service = \Mockery::mock(DaemonServerRepository::class);
$this->app->instance(DaemonServerRepository::class, $service);
$service->expects('setServer')
->with(Mockery::on(function ($value) use ($server) {
->with(\Mockery::on(function ($value) use ($server) {
return $value->uuid === $server->uuid;
}))
->andReturnSelf()

View file

@ -42,7 +42,7 @@ class GetStartupAndVariablesTest extends ClientApiIntegrationTestCase
$response->assertJsonPath('object', 'list');
$response->assertJsonCount(1, 'data');
$response->assertJsonPath('data.0.object', EggVariable::RESOURCE_NAME);
$this->assertJsonTransformedWith($response->json('data.0.attributes'), $egg->variables[1]);
$this->assertJsonTransformedWith($response->json('data.0.attributes'), $egg->variables()->orderBy('id', 'desc')->first());
}
/**

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Integration\Api\Client\Server\Subuser;
use Mockery;
use Ramsey\Uuid\Uuid;
use Pterodactyl\Models\User;
use Pterodactyl\Models\Subuser;
@ -25,7 +24,7 @@ class DeleteSubuserTest extends ClientApiIntegrationTestCase
*/
public function testCorrectSubuserIsDeletedFromServer()
{
$this->swap(DaemonServerRepository::class, $mock = Mockery::mock(DaemonServerRepository::class));
$this->swap(DaemonServerRepository::class, $mock = \Mockery::mock(DaemonServerRepository::class));
[$user, $server] = $this->generateTestAccount();

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Integration\Api\Client\Server\Subuser;
use Mockery;
use Pterodactyl\Models\User;
use Pterodactyl\Models\Subuser;
use Pterodactyl\Repositories\Wings\DaemonServerRepository;
@ -36,7 +35,7 @@ class SubuserAuthorizationTest extends ClientApiIntegrationTestCase
Subuser::factory()->create(['server_id' => $server2->id, 'user_id' => $internal->id]);
Subuser::factory()->create(['server_id' => $server3->id, 'user_id' => $internal->id]);
$this->instance(DaemonServerRepository::class, $mock = Mockery::mock(DaemonServerRepository::class));
$this->instance(DaemonServerRepository::class, $mock = \Mockery::mock(DaemonServerRepository::class));
if ($method === 'DELETE') {
$mock->expects('setServer->revokeUserJTI')->with($internal->id)->andReturnUndefined();
}

View file

@ -1,59 +0,0 @@
<?php
namespace Pterodactyl\Tests\Integration\Http\Controllers\Admin;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Pterodactyl\Models\User;
use Pterodactyl\Models\Subuser;
use Illuminate\Pagination\LengthAwarePaginator;
use Pterodactyl\Http\Controllers\Admin\UserController;
use Pterodactyl\Tests\Integration\IntegrationTestCase;
class UserControllerTest extends IntegrationTestCase
{
/**
* Test that the index route controller for the user listing returns the expected user
* data with the number of servers they are assigned to, and the number of servers they
* are a subuser of.
*
* @see https://github.com/pterodactyl/panel/issues/2469
*/
public function testIndexReturnsExpectedData()
{
$unique = Str::random();
$users = [
User::factory()->create(['username' => $unique . '_1']),
User::factory()->create(['username' => $unique . '_2']),
];
$servers = [
$this->createServerModel(['owner_id' => $users[0]->id]),
$this->createServerModel(['owner_id' => $users[0]->id]),
$this->createServerModel(['owner_id' => $users[0]->id]),
$this->createServerModel(['owner_id' => $users[1]->id]),
];
Subuser::query()->forceCreate(['server_id' => $servers[0]->id, 'user_id' => $users[1]->id]);
Subuser::query()->forceCreate(['server_id' => $servers[1]->id, 'user_id' => $users[1]->id]);
/** @var \Pterodactyl\Http\Controllers\Admin\UserController $controller */
$controller = $this->app->make(UserController::class);
$request = Request::create('/admin/users?filter[username]=' . $unique);
$this->app->instance(Request::class, $request);
$data = $controller->index($request)->getData();
$this->assertArrayHasKey('users', $data);
$this->assertInstanceOf(LengthAwarePaginator::class, $data['users']);
/** @var \Pterodactyl\Models\User[] $response */
$response = $data['users']->items();
$this->assertCount(2, $response);
$this->assertInstanceOf(User::class, $response[0]);
$this->assertSame(3, (int) $response[0]->servers_count);
$this->assertSame(0, (int) $response[0]->subuser_of_count);
$this->assertSame(1, (int) $response[1]->servers_count);
$this->assertSame(2, (int) $response[1]->subuser_of_count);
}
}

View file

@ -9,15 +9,12 @@ use Illuminate\Support\Facades\Event;
use Pterodactyl\Events\ActivityLogged;
use Pterodactyl\Tests\Assertions\AssertsActivityLogged;
use Pterodactyl\Tests\Traits\Integration\CreatesTestModels;
use Pterodactyl\Transformers\Api\Application\BaseTransformer;
abstract class IntegrationTestCase extends TestCase
{
use CreatesTestModels;
use AssertsActivityLogged;
protected array $connectionsToTransact = ['mysql'];
protected $defaultHeaders = [
'Accept' => 'application/json',
];
@ -35,7 +32,7 @@ abstract class IntegrationTestCase extends TestCase
protected function formatTimestamp(string $timestamp): string
{
return CarbonImmutable::createFromFormat(CarbonInterface::DEFAULT_TO_STRING_FORMAT, $timestamp)
->setTimezone(BaseTransformer::RESPONSE_TIMEZONE)
->setTimezone('UTC')
->toAtomString();
}
}

View file

@ -2,14 +2,11 @@
namespace Pterodactyl\Tests\Integration\Jobs\Schedule;
use Mockery;
use Carbon\Carbon;
use DateTimeInterface;
use Carbon\CarbonImmutable;
use GuzzleHttp\Psr7\Request;
use Pterodactyl\Models\Task;
use GuzzleHttp\Psr7\Response;
use InvalidArgumentException;
use Pterodactyl\Models\Server;
use Pterodactyl\Models\Schedule;
use Illuminate\Support\Facades\Bus;
@ -48,7 +45,7 @@ class RunTaskJobTest extends IntegrationTestCase
$this->assertFalse($task->is_queued);
$this->assertFalse($schedule->is_processing);
$this->assertFalse($schedule->is_active);
$this->assertTrue(CarbonImmutable::now()->isSameAs(DateTimeInterface::ATOM, $schedule->last_run_at));
$this->assertTrue(CarbonImmutable::now()->isSameAs(\DateTimeInterface::ATOM, $schedule->last_run_at));
}
public function testJobWithInvalidActionThrowsException()
@ -62,7 +59,7 @@ class RunTaskJobTest extends IntegrationTestCase
$job = new RunTaskJob($task);
$this->expectException(InvalidArgumentException::class);
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid task action provided: foobar');
Bus::dispatchNow($job);
}
@ -90,10 +87,10 @@ class RunTaskJobTest extends IntegrationTestCase
'continue_on_failure' => false,
]);
$mock = Mockery::mock(DaemonPowerRepository::class);
$mock = \Mockery::mock(DaemonPowerRepository::class);
$this->instance(DaemonPowerRepository::class, $mock);
$mock->expects('setServer')->with(Mockery::on(function ($value) use ($server) {
$mock->expects('setServer')->with(\Mockery::on(function ($value) use ($server) {
return $value instanceof Server && $value->id === $server->id;
}))->andReturnSelf();
$mock->expects('send')->with('start')->andReturn(new Response());
@ -105,7 +102,7 @@ class RunTaskJobTest extends IntegrationTestCase
$this->assertFalse($task->is_queued);
$this->assertFalse($schedule->is_processing);
$this->assertTrue(CarbonImmutable::now()->isSameAs(DateTimeInterface::ATOM, $schedule->last_run_at));
$this->assertTrue(CarbonImmutable::now()->isSameAs(\DateTimeInterface::ATOM, $schedule->last_run_at));
}
/**
@ -125,7 +122,7 @@ class RunTaskJobTest extends IntegrationTestCase
'continue_on_failure' => $continueOnFailure,
]);
$mock = Mockery::mock(DaemonPowerRepository::class);
$mock = \Mockery::mock(DaemonPowerRepository::class);
$this->instance(DaemonPowerRepository::class, $mock);
$mock->expects('setServer->send')->andThrow(
@ -144,7 +141,7 @@ class RunTaskJobTest extends IntegrationTestCase
$this->assertFalse($task->is_queued);
$this->assertFalse($schedule->is_processing);
$this->assertTrue(CarbonImmutable::now()->isSameAs(DateTimeInterface::ATOM, $schedule->last_run_at));
$this->assertTrue(CarbonImmutable::now()->isSameAs(\DateTimeInterface::ATOM, $schedule->last_run_at));
}
}
@ -175,7 +172,7 @@ class RunTaskJobTest extends IntegrationTestCase
$this->assertFalse($task->is_queued);
$this->assertFalse($schedule->is_processing);
$this->assertTrue(Carbon::now()->isSameAs(DateTimeInterface::ATOM, $schedule->last_run_at));
$this->assertTrue(Carbon::now()->isSameAs(\DateTimeInterface::ATOM, $schedule->last_run_at));
}
public function isManualRunDataProvider(): array

View file

@ -2,8 +2,6 @@
namespace Pterodactyl\Tests\Integration\Services\Allocations;
use Exception;
use InvalidArgumentException;
use Pterodactyl\Models\Allocation;
use Pterodactyl\Tests\Integration\IntegrationTestCase;
use Pterodactyl\Services\Allocations\FindAssignableAllocationService;
@ -142,8 +140,8 @@ class FindAssignableAllocationServiceTest extends IntegrationTestCase
try {
$this->getService()->handle($server);
$this->fail('This assertion should not be reached.');
} catch (Exception $exception) {
$this->assertInstanceOf(InvalidArgumentException::class, $exception);
} catch (\Exception $exception) {
$this->assertInstanceOf(\InvalidArgumentException::class, $exception);
$this->assertSame('Expected an integerish value. Got: string', $exception->getMessage());
}
@ -153,8 +151,8 @@ class FindAssignableAllocationServiceTest extends IntegrationTestCase
try {
$this->getService()->handle($server);
$this->fail('This assertion should not be reached.');
} catch (Exception $exception) {
$this->assertInstanceOf(InvalidArgumentException::class, $exception);
} catch (\Exception $exception) {
$this->assertInstanceOf(\InvalidArgumentException::class, $exception);
$this->assertSame('Expected an integerish value. Got: string', $exception->getMessage());
}
}

View file

@ -2,10 +2,7 @@
namespace Pterodactyl\Tests\Integration\Services\Databases;
use Mockery;
use Mockery\MockInterface;
use BadMethodCallException;
use InvalidArgumentException;
use Pterodactyl\Models\Database;
use Pterodactyl\Models\DatabaseHost;
use Pterodactyl\Tests\Integration\IntegrationTestCase;
@ -61,7 +58,7 @@ class DatabaseManagementServiceTest extends IntegrationTestCase
public function testDatabaseCannotBeCreatedIfServerHasReachedLimit()
{
$server = $this->createServerModel(['database_limit' => 2]);
$host = DatabaseHost::factory()->create(['node_id' => $server->node_id]);
$host = DatabaseHost::factory()->create();
Database::factory()->times(2)->create(['server_id' => $server->id, 'database_host_id' => $host->id]);
@ -79,7 +76,7 @@ class DatabaseManagementServiceTest extends IntegrationTestCase
{
$server = $this->createServerModel();
$this->expectException(InvalidArgumentException::class);
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('The database name passed to DatabaseManagementService::handle MUST be prefixed with "s{server_id}_".');
$this->getService()->create($server, $data);
@ -91,10 +88,10 @@ class DatabaseManagementServiceTest extends IntegrationTestCase
public function testCreatingDatabaseWithIdenticalNameTriggersAnException()
{
$server = $this->createServerModel();
$name = DatabaseManagementService::generateUniqueDatabaseName('soemthing', $server->id);
$name = DatabaseManagementService::generateUniqueDatabaseName('something', $server->id);
$host = DatabaseHost::factory()->create(['node_id' => $server->node_id]);
$host2 = DatabaseHost::factory()->create(['node_id' => $server->node_id]);
$host = DatabaseHost::factory()->create();
$host2 = DatabaseHost::factory()->create();
Database::factory()->create([
'database' => $name,
'database_host_id' => $host->id,
@ -120,9 +117,9 @@ class DatabaseManagementServiceTest extends IntegrationTestCase
public function testServerDatabaseCanBeCreated()
{
$server = $this->createServerModel();
$name = DatabaseManagementService::generateUniqueDatabaseName('soemthing', $server->id);
$name = DatabaseManagementService::generateUniqueDatabaseName('something', $server->id);
$host = DatabaseHost::factory()->create(['node_id' => $server->node_id]);
$host = DatabaseHost::factory()->create();
$this->repository->expects('createDatabase')->with($name);
@ -134,13 +131,13 @@ class DatabaseManagementServiceTest extends IntegrationTestCase
// assertions that would get caught by the functions catcher and thus lead to the exception
// being swallowed incorrectly.
$this->repository->expects('createUser')->with(
Mockery::on(function ($value) use (&$username) {
\Mockery::on(function ($value) use (&$username) {
$username = $value;
return true;
}),
'%',
Mockery::on(function ($value) use (&$password) {
\Mockery::on(function ($value) use (&$password) {
$password = $value;
return true;
@ -148,7 +145,7 @@ class DatabaseManagementServiceTest extends IntegrationTestCase
null
);
$this->repository->expects('assignUserToDatabase')->with($name, Mockery::on(function ($value) use (&$secondUsername) {
$this->repository->expects('assignUserToDatabase')->with($name, \Mockery::on(function ($value) use (&$secondUsername) {
$secondUsername = $value;
return true;
@ -178,15 +175,15 @@ class DatabaseManagementServiceTest extends IntegrationTestCase
public function testExceptionEncounteredWhileCreatingDatabaseAttemptsToCleanup()
{
$server = $this->createServerModel();
$name = DatabaseManagementService::generateUniqueDatabaseName('soemthing', $server->id);
$name = DatabaseManagementService::generateUniqueDatabaseName('something', $server->id);
$host = DatabaseHost::factory()->create(['node_id' => $server->node_id]);
$host = DatabaseHost::factory()->create();
$this->repository->expects('createDatabase')->with($name)->andThrows(new BadMethodCallException());
$this->repository->expects('createDatabase')->with($name)->andThrows(new \BadMethodCallException());
$this->repository->expects('dropDatabase')->with($name);
$this->repository->expects('dropUser')->withAnyArgs()->andThrows(new InvalidArgumentException());
$this->repository->expects('dropUser')->withAnyArgs()->andThrows(new \InvalidArgumentException());
$this->expectException(BadMethodCallException::class);
$this->expectException(\BadMethodCallException::class);
$this->getService()->create($server, [
'remote' => '%',

View file

@ -2,10 +2,8 @@
namespace Pterodactyl\Tests\Integration\Services\Databases;
use Mockery;
use Mockery\MockInterface;
use Pterodactyl\Models\Node;
use InvalidArgumentException;
use Pterodactyl\Models\Database;
use Pterodactyl\Models\DatabaseHost;
use Pterodactyl\Tests\Integration\IntegrationTestCase;
@ -24,7 +22,7 @@ class DeployServerDatabaseServiceTest extends IntegrationTestCase
{
parent::setUp();
$this->managementService = Mockery::mock(DatabaseManagementService::class);
$this->managementService = \Mockery::mock(DatabaseManagementService::class);
$this->swap(DatabaseManagementService::class, $this->managementService);
}
@ -50,7 +48,7 @@ class DeployServerDatabaseServiceTest extends IntegrationTestCase
{
$server = $this->createServerModel();
$this->expectException(InvalidArgumentException::class);
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessageMatches('/^Expected a non-empty value\. Got: /');
$this->getService()->handle($server, $data);
}
@ -63,8 +61,8 @@ class DeployServerDatabaseServiceTest extends IntegrationTestCase
{
$server = $this->createServerModel();
$node = Node::factory()->create(['location_id' => $server->location->id]);
DatabaseHost::factory()->create(['node_id' => $node->id]);
$host = DatabaseHost::factory()->create();
$node = Node::factory()->create(['database_host_id' => $host->id, 'location_id' => $server->location->id]);
config()->set('pterodactyl.client_features.databases.allow_random', false);
@ -98,12 +96,13 @@ class DeployServerDatabaseServiceTest extends IntegrationTestCase
{
$server = $this->createServerModel();
$node = Node::factory()->create(['location_id' => $server->location->id]);
DatabaseHost::factory()->create(['node_id' => $node->id]);
$host = DatabaseHost::factory()->create(['node_id' => $server->node_id]);
$host1 = DatabaseHost::factory()->create();
$host2 = DatabaseHost::factory()->create();
$node = Node::factory()->create(['database_host_id' => $host2->id, 'location_id' => $server->location->id]);
$server->node->database_host_id = $host2->id;
$this->managementService->expects('create')->with($server, [
'database_host_id' => $host->id,
'database_host_id' => $host2->id,
'database' => "s{$server->id}_something",
'remote' => '%',
])->andReturns(new Database());
@ -125,8 +124,8 @@ class DeployServerDatabaseServiceTest extends IntegrationTestCase
{
$server = $this->createServerModel();
$node = Node::factory()->create(['location_id' => $server->location->id]);
$host = DatabaseHost::factory()->create(['node_id' => $node->id]);
$host = DatabaseHost::factory()->create();
$node = Node::factory()->create(['location_id' => $server->location->id, 'database_host_id' => $host->id]);
$this->managementService->expects('create')->with($server, [
'database_host_id' => $host->id,

View file

@ -2,9 +2,7 @@
namespace Pterodactyl\Tests\Integration\Services\Deployment;
use Exception;
use Pterodactyl\Models\Node;
use InvalidArgumentException;
use Pterodactyl\Models\Server;
use Pterodactyl\Models\Database;
use Pterodactyl\Models\Location;
@ -26,7 +24,7 @@ class FindViableNodesServiceTest extends IntegrationTestCase
public function testExceptionIsThrownIfNoDiskSpaceHasBeenSet()
{
$this->expectException(InvalidArgumentException::class);
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Disk space must be an int, got NULL');
$this->getService()->handle();
@ -34,7 +32,7 @@ class FindViableNodesServiceTest extends IntegrationTestCase
public function testExceptionIsThrownIfNoMemoryHasBeenSet()
{
$this->expectException(InvalidArgumentException::class);
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Memory usage must be an int, got NULL');
$this->getService()->setDisk(10)->handle();
@ -54,16 +52,16 @@ class FindViableNodesServiceTest extends IntegrationTestCase
try {
$this->getService()->setLocations(['a']);
$this->fail('This expectation should not be called.');
} catch (Exception $exception) {
$this->assertInstanceOf(InvalidArgumentException::class, $exception);
} catch (\Exception $exception) {
$this->assertInstanceOf(\InvalidArgumentException::class, $exception);
$this->assertSame('An array of location IDs should be provided when calling setLocations.', $exception->getMessage());
}
try {
$this->getService()->setLocations(['1.2', '1', 2]);
$this->fail('This expectation should not be called.');
} catch (Exception $exception) {
$this->assertInstanceOf(InvalidArgumentException::class, $exception);
} catch (\Exception $exception) {
$this->assertInstanceOf(\InvalidArgumentException::class, $exception);
$this->assertSame('An array of location IDs should be provided when calling setLocations.', $exception->getMessage());
}
}

View file

@ -2,11 +2,9 @@
namespace Pterodactyl\Tests\Integration\Services\Schedules;
use Mockery;
use Exception;
use Carbon\CarbonImmutable;
use Pterodactyl\Models\Task;
use InvalidArgumentException;
use Pterodactyl\Models\Schedule;
use Illuminate\Support\Facades\Bus;
use Illuminate\Contracts\Bus\Dispatcher;
@ -47,7 +45,7 @@ class ProcessScheduleServiceTest extends IntegrationTestCase
/** @var \Pterodactyl\Models\Task $task */
$task = Task::factory()->create(['schedule_id' => $schedule->id, 'sequence_id' => 1]);
$this->expectException(InvalidArgumentException::class);
$this->expectException(\InvalidArgumentException::class);
$this->getService()->handle($schedule);
@ -126,7 +124,7 @@ class ProcessScheduleServiceTest extends IntegrationTestCase
*/
public function testTaskDispatchedNowIsResetProperlyIfErrorIsEncountered()
{
$this->swap(Dispatcher::class, $dispatcher = Mockery::mock(Dispatcher::class));
$this->swap(Dispatcher::class, $dispatcher = \Mockery::mock(Dispatcher::class));
$server = $this->createServerModel();
/** @var \Pterodactyl\Models\Schedule $schedule */
@ -134,9 +132,9 @@ class ProcessScheduleServiceTest extends IntegrationTestCase
/** @var \Pterodactyl\Models\Task $task */
$task = Task::factory()->create(['schedule_id' => $schedule->id, 'sequence_id' => 1]);
$dispatcher->expects('dispatchNow')->andThrows(new Exception('Test thrown exception'));
$dispatcher->expects('dispatchNow')->andThrows(new \Exception('Test thrown exception'));
$this->expectException(Exception::class);
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Test thrown exception');
$this->getService()->handle($schedule, true);

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Integration\Services\Servers;
use Mockery;
use Mockery\MockInterface;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
@ -108,14 +107,14 @@ class BuildModificationServiceTest extends IntegrationTestCase
{
$server = $this->createServerModel();
$this->daemonServerRepository->expects('setServer')->with(Mockery::on(function (Server $s) use ($server) {
$this->daemonServerRepository->expects('setServer')->with(\Mockery::on(function (Server $s) use ($server) {
return $s->id === $server->id;
}))->andReturnSelf();
$this->daemonServerRepository->expects('sync')->withNoArgs()->andReturnUndefined();
$response = $this->getService()->handle($server, [
'oom_disabled' => false,
'oom_killer' => true,
'memory' => 256,
'swap' => 128,
'io' => 600,
@ -127,7 +126,7 @@ class BuildModificationServiceTest extends IntegrationTestCase
'allocation_limit' => 20,
]);
$this->assertFalse($response->oom_disabled);
$this->assertTrue($response->oom_killer);
$this->assertSame(256, $response->memory);
$this->assertSame(128, $response->swap);
$this->assertSame(600, $response->io);

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Integration\Services\Servers;
use Mockery;
use Mockery\MockInterface;
use Pterodactyl\Models\Egg;
use GuzzleHttp\Psr7\Request;
@ -42,7 +41,7 @@ class ServerCreationServiceTest extends IntegrationTestCase
->where('name', 'Bungeecord')
->firstOrFail();
$this->daemonServerRepository = Mockery::mock(DaemonServerRepository::class);
$this->daemonServerRepository = \Mockery::mock(DaemonServerRepository::class);
$this->swap(DaemonServerRepository::class, $this->daemonServerRepository);
}
@ -127,9 +126,10 @@ class ServerCreationServiceTest extends IntegrationTestCase
$this->assertNotNull($response->uuid);
$this->assertSame($response->uuidShort, substr($response->uuid, 0, 8));
$this->assertSame($egg->id, $response->egg_id);
$this->assertCount(2, $response->variables);
$this->assertSame('123', $response->variables[0]->server_value);
$this->assertSame('server2.jar', $response->variables[1]->server_value);
$variables = $response->variables->sortBy('server_value')->values();
$this->assertCount(2, $variables);
$this->assertSame('123', $variables->get(0)->server_value);
$this->assertSame('server2.jar', $variables->get(1)->server_value);
foreach ($data as $key => $value) {
if (in_array($key, ['allocation_additional', 'environment', 'start_on_completion'])) {
@ -145,7 +145,7 @@ class ServerCreationServiceTest extends IntegrationTestCase
$this->assertSame($allocations[4]->id, $response->allocations[1]->id);
$this->assertFalse($response->isSuspended());
$this->assertTrue($response->oom_disabled);
$this->assertFalse($response->oom_killer);
$this->assertSame(0, $response->database_limit);
$this->assertSame(0, $response->allocation_limit);
$this->assertSame(0, $response->backup_limit);

View file

@ -2,8 +2,6 @@
namespace Pterodactyl\Tests\Integration\Services\Servers;
use Mockery;
use Exception;
use Mockery\MockInterface;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
@ -35,8 +33,8 @@ class ServerDeletionServiceTest extends IntegrationTestCase
// There will be some log calls during this test, don't actually write to the disk.
config()->set('logging.default', 'null');
$this->daemonServerRepository = Mockery::mock(DaemonServerRepository::class);
$this->databaseManagementService = Mockery::mock(DatabaseManagementService::class);
$this->daemonServerRepository = \Mockery::mock(DaemonServerRepository::class);
$this->databaseManagementService = \Mockery::mock(DatabaseManagementService::class);
$this->app->instance(DaemonServerRepository::class, $this->daemonServerRepository);
$this->app->instance(DatabaseManagementService::class, $this->databaseManagementService);
@ -120,11 +118,11 @@ class ServerDeletionServiceTest extends IntegrationTestCase
$server->refresh();
$this->daemonServerRepository->expects('setServer->delete')->withNoArgs()->andReturnUndefined();
$this->databaseManagementService->expects('delete')->with(Mockery::on(function ($value) use ($db) {
$this->databaseManagementService->expects('delete')->with(\Mockery::on(function ($value) use ($db) {
return $value instanceof Database && $value->id === $db->id;
}))->andThrows(new Exception());
}))->andThrows(new \Exception());
$this->expectException(Exception::class);
$this->expectException(\Exception::class);
$this->getService()->handle($server);
$this->assertDatabaseHas('servers', ['id' => $server->id]);
@ -145,9 +143,9 @@ class ServerDeletionServiceTest extends IntegrationTestCase
$server->refresh();
$this->daemonServerRepository->expects('setServer->delete')->withNoArgs()->andReturnUndefined();
$this->databaseManagementService->expects('delete')->with(Mockery::on(function ($value) use ($db) {
$this->databaseManagementService->expects('delete')->with(\Mockery::on(function ($value) use ($db) {
return $value instanceof Database && $value->id === $db->id;
}))->andThrows(new Exception());
}))->andThrows(new \Exception());
$this->getService()->withForce(true)->handle($server);

View file

@ -34,7 +34,7 @@ class StartupModificationServiceTest extends IntegrationTestCase
]);
$this->fail('This assertion should not be called.');
} catch (Exception $exception) {
} catch (\Exception $exception) {
$this->assertInstanceOf(ValidationException::class, $exception);
/** @var \Illuminate\Validation\ValidationException $exception */
@ -109,7 +109,7 @@ class StartupModificationServiceTest extends IntegrationTestCase
$clone = $this->cloneEggAndVariables($server->egg);
// This makes the BUNGEE_VERSION variable not user editable.
$clone->variables()->first()->update([
$clone->variables()->orderBy('id')->first()->update([
'user_editable' => false,
]);
@ -118,7 +118,7 @@ class StartupModificationServiceTest extends IntegrationTestCase
ServerVariable::query()->updateOrCreate([
'server_id' => $server->id,
'variable_id' => $server->variables[0]->id,
'variable_id' => $server->variables()->orderBy('id')->first()->id,
], ['variable_value' => 'EXIST']);
$response = $this->getService()->handle($server, [
@ -128,9 +128,10 @@ class StartupModificationServiceTest extends IntegrationTestCase
],
]);
$this->assertCount(2, $response->variables);
$this->assertSame('EXIST', $response->variables[0]->server_value);
$this->assertSame('test.jar', $response->variables[1]->server_value);
$variables = $response->variables->sortBy('server_value')->values();
$this->assertCount(2, $variables);
$this->assertSame('EXIST', $variables->get(0)->server_value);
$this->assertSame('test.jar', $variables->get(1)->server_value);
$response = $this->getService()
->setUserLevel(User::USER_LEVEL_ADMIN)
@ -141,9 +142,11 @@ class StartupModificationServiceTest extends IntegrationTestCase
],
]);
$this->assertCount(2, $response->variables);
$this->assertSame('1234', $response->variables[0]->server_value);
$this->assertSame('test.jar', $response->variables[1]->server_value);
$variables = $response->variables->sortBy('server_value')->values();
$this->assertCount(2, $variables);
$this->assertSame('1234', $variables->get(0)->server_value);
$this->assertSame('test.jar', $variables->get(1)->server_value);
}
/**

View file

@ -2,9 +2,7 @@
namespace Pterodactyl\Tests\Integration\Services\Servers;
use Mockery;
use Mockery\MockInterface;
use InvalidArgumentException;
use Pterodactyl\Models\Server;
use Pterodactyl\Services\Servers\SuspensionService;
use Pterodactyl\Tests\Integration\IntegrationTestCase;
@ -21,7 +19,7 @@ class SuspensionServiceTest extends IntegrationTestCase
{
parent::setUp();
$this->repository = Mockery::mock(DaemonServerRepository::class);
$this->repository = \Mockery::mock(DaemonServerRepository::class);
$this->app->instance(DaemonServerRepository::class, $this->repository);
}
@ -60,7 +58,7 @@ class SuspensionServiceTest extends IntegrationTestCase
{
$server = $this->createServerModel();
$this->expectException(InvalidArgumentException::class);
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Expected one of: "suspend", "unsuspend". Got: "foo"');
$this->getService()->toggle($server, 'foo');

View file

@ -108,11 +108,12 @@ class VariableValidatorServiceTest extends IntegrationTestCase
]);
$this->assertInstanceOf(Collection::class, $response);
$this->assertCount(2, $response);
$this->assertSame('BUNGEE_VERSION', $response->get(0)->key);
$this->assertSame('123', $response->get(0)->value);
$this->assertSame('SERVER_JARFILE', $response->get(1)->key);
$this->assertSame('server.jar', $response->get(1)->value);
$variables = $response->sortBy('key')->values();
$this->assertCount(2, $variables);
$this->assertSame('BUNGEE_VERSION', $variables->get(0)->key);
$this->assertSame('123', $variables->get(0)->value);
$this->assertSame('SERVER_JARFILE', $variables->get(1)->key);
$this->assertSame('server.jar', $variables->get(1)->value);
}
public function testNullableEnvironmentVariablesCanBeUsedCorrectly()

View file

@ -4,7 +4,6 @@ namespace Pterodactyl\Tests\Traits\Http;
use Closure;
use Illuminate\Http\Request;
use BadFunctionCallException;
trait MocksMiddlewareClosure
{
@ -12,10 +11,10 @@ trait MocksMiddlewareClosure
* Provide a closure to be used when validating that the response from the middleware
* is the same request object we passed into it.
*/
protected function getClosureAssertions(): Closure
protected function getClosureAssertions(): \Closure
{
if (is_null($this->request)) {
throw new BadFunctionCallException('Calling getClosureAssertions without defining a request object is not supported.');
throw new \BadFunctionCallException('Calling getClosureAssertions without defining a request object is not supported.');
}
return function ($response) {

View file

@ -6,7 +6,6 @@ use Mockery as m;
use Mockery\Mock;
use Illuminate\Http\Request;
use Pterodactyl\Models\User;
use InvalidArgumentException;
use Symfony\Component\HttpFoundation\ParameterBag;
trait RequestMockHelpers
@ -68,7 +67,7 @@ trait RequestMockHelpers
{
$this->request = m::mock($this->requestMockClass);
if (!$this->request instanceof Request) {
throw new InvalidArgumentException('Request mock class must be an instance of ' . Request::class . ' when mocked.');
throw new \InvalidArgumentException('Request mock class must be an instance of ' . Request::class . ' when mocked.');
}
$this->request->attributes = new ParameterBag();

View file

@ -1,48 +0,0 @@
<?php
namespace Pterodactyl\Tests\Traits;
use PDO;
use Mockery;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\MySqlConnection;
use Illuminate\Database\ConnectionResolver;
use Illuminate\Database\ConnectionResolverInterface;
trait MocksPdoConnection
{
private static ?ConnectionResolverInterface $initialResolver;
/**
* Generates a mock PDO connection and injects it into the models so that any actual
* DB call can be properly intercepted.
*/
protected function mockPdoConnection(): Mockery\MockInterface
{
self::$initialResolver = Model::getConnectionResolver();
Model::unsetConnectionResolver();
$connection = new MySqlConnection($mock = Mockery::mock(PDO::class), 'testing_mock');
$resolver = new ConnectionResolver(['mocked' => $connection]);
$resolver->setDefaultConnection('mocked');
Model::setConnectionResolver($resolver);
return $mock;
}
/**
* Resets the mock state.
*/
protected function tearDownPdoMock(): void
{
if (!self::$initialResolver) {
return;
}
Model::setConnectionResolver(self::$initialResolver);
self::$initialResolver = null;
}
}

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Tests\Traits;
use Mockery;
use Mockery\Mock;
use Mockery\MockInterface;
use GuzzleHttp\Exception\RequestException;
@ -27,6 +26,6 @@ trait MocksRequestException
*/
protected function getExceptionMock(string $abstract = RequestException::class): MockInterface
{
return $this->exception ?? $this->exception = Mockery::mock($abstract);
return $this->exception ?? $this->exception = \Mockery::mock($abstract);
}
}