Add test coverage for startup modification
This commit is contained in:
parent
d087bebc93
commit
7a643beee0
3 changed files with 148 additions and 19 deletions
|
@ -89,22 +89,21 @@ class StartupModificationService
|
||||||
*/
|
*/
|
||||||
protected function updateAdministrativeSettings(array $data, Server &$server)
|
protected function updateAdministrativeSettings(array $data, Server &$server)
|
||||||
{
|
{
|
||||||
if (
|
$eggId = Arr::get($data, 'egg_id');
|
||||||
is_digit(Arr::get($data, 'egg_id'))
|
|
||||||
&& $data['egg_id'] != $server->egg_id
|
|
||||||
&& is_null(Arr::get($data, 'nest_id'))
|
|
||||||
) {
|
|
||||||
/** @var \Pterodactyl\Models\Egg $egg */
|
|
||||||
$egg = Egg::query()->select(['nest_id'])->findOrFail($data['egg_id']);
|
|
||||||
|
|
||||||
$data['nest_id'] = $egg->nest_id;
|
if (is_digit($eggId) && $server->egg_id !== (int)$eggId) {
|
||||||
|
/** @var \Pterodactyl\Models\Egg $egg */
|
||||||
|
$egg = Egg::query()->findOrFail($data['egg_id']);
|
||||||
|
|
||||||
|
$server = $server->forceFill([
|
||||||
|
'egg_id' => $egg->id,
|
||||||
|
'nest_id' => $egg->nest_id,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$server->forceFill([
|
$server->forceFill([
|
||||||
'installed' => 0,
|
'installed' => 0,
|
||||||
'startup' => $data['startup'] ?? $server->startup,
|
'startup' => $data['startup'] ?? $server->startup,
|
||||||
'nest_id' => $data['nest_id'] ?? $server->nest_id,
|
|
||||||
'egg_id' => $data['egg_id'] ?? $server->egg_id,
|
|
||||||
'skip_scripts' => $data['skip_scripts'] ?? isset($data['skip_scripts']),
|
'skip_scripts' => $data['skip_scripts'] ?? isset($data['skip_scripts']),
|
||||||
'image' => $data['docker_image'] ?? $server->image,
|
'image' => $data['docker_image'] ?? $server->image,
|
||||||
])->save();
|
])->save();
|
||||||
|
|
|
@ -3,10 +3,15 @@
|
||||||
namespace Pterodactyl\Tests\Integration\Services\Servers;
|
namespace Pterodactyl\Tests\Integration\Services\Servers;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Ramsey\Uuid\Uuid;
|
||||||
|
use Pterodactyl\Models\Egg;
|
||||||
|
use Pterodactyl\Models\User;
|
||||||
|
use Pterodactyl\Models\Nest;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Models\ServerVariable;
|
use Pterodactyl\Models\ServerVariable;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Pterodactyl\Tests\Integration\IntegrationTestCase;
|
use Pterodactyl\Tests\Integration\IntegrationTestCase;
|
||||||
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||||
use Pterodactyl\Services\Servers\StartupModificationService;
|
use Pterodactyl\Services\Servers\StartupModificationService;
|
||||||
|
|
||||||
class StartupModificationServiceTest extends IntegrationTestCase
|
class StartupModificationServiceTest extends IntegrationTestCase
|
||||||
|
@ -46,15 +51,15 @@ class StartupModificationServiceTest extends IntegrationTestCase
|
||||||
|
|
||||||
ServerVariable::query()->where('variable_id', $server->variables[1]->id)->delete();
|
ServerVariable::query()->where('variable_id', $server->variables[1]->id)->delete();
|
||||||
|
|
||||||
/** @var \Pterodactyl\Models\Server $result */
|
$result = $this->getService()
|
||||||
$result = $this->app->make(StartupModificationService::class)->handle($server, [
|
->handle($server, [
|
||||||
'egg_id' => $server->egg_id + 1,
|
'egg_id' => $server->egg_id + 1,
|
||||||
'startup' => 'random gibberish',
|
'startup' => 'random gibberish',
|
||||||
'environment' => [
|
'environment' => [
|
||||||
'BUNGEE_VERSION' => '1234',
|
'BUNGEE_VERSION' => '1234',
|
||||||
'SERVER_JARFILE' => 'test.jar',
|
'SERVER_JARFILE' => 'test.jar',
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertInstanceOf(Server::class, $result);
|
$this->assertInstanceOf(Server::class, $result);
|
||||||
$this->assertCount(2, $result->variables);
|
$this->assertCount(2, $result->variables);
|
||||||
|
@ -62,4 +67,105 @@ class StartupModificationServiceTest extends IntegrationTestCase
|
||||||
$this->assertSame('1234', $result->variables[0]->server_value);
|
$this->assertSame('1234', $result->variables[0]->server_value);
|
||||||
$this->assertSame('test.jar', $result->variables[1]->server_value);
|
$this->assertSame('test.jar', $result->variables[1]->server_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that modifying an egg as an admin properly updates the data for the server.
|
||||||
|
*/
|
||||||
|
public function testServerIsProperlyModifiedAsAdminUser()
|
||||||
|
{
|
||||||
|
/** @var \Pterodactyl\Models\Egg $nextEgg */
|
||||||
|
$nextEgg = Nest::query()->findOrFail(2)->eggs()->firstOrFail();
|
||||||
|
|
||||||
|
$server = $this->createServerModel(['egg_id' => 1]);
|
||||||
|
|
||||||
|
$this->assertNotSame($nextEgg->id, $server->egg_id);
|
||||||
|
$this->assertNotSame($nextEgg->nest_id, $server->nest_id);
|
||||||
|
|
||||||
|
$response = $this->getService()
|
||||||
|
->setUserLevel(User::USER_LEVEL_ADMIN)
|
||||||
|
->handle($server, [
|
||||||
|
'egg_id' => $nextEgg->id,
|
||||||
|
'startup' => 'sample startup',
|
||||||
|
'skip_scripts' => true,
|
||||||
|
'docker_image' => 'docker/hodor',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Server::class, $response);
|
||||||
|
$this->assertSame($nextEgg->id, $response->egg_id);
|
||||||
|
$this->assertSame($nextEgg->nest_id, $response->nest_id);
|
||||||
|
$this->assertSame('sample startup', $response->startup);
|
||||||
|
$this->assertSame('docker/hodor', $response->image);
|
||||||
|
$this->assertTrue($response->skip_scripts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that hidden variables can be updated by an admin but are not affected by a
|
||||||
|
* regular user who attempts to pass them through.
|
||||||
|
*/
|
||||||
|
public function testEnvironmentVariablesCanBeUpdatedByAdmin()
|
||||||
|
{
|
||||||
|
$server = $this->createServerModel();
|
||||||
|
$server->loadMissing(['egg', 'variables']);
|
||||||
|
|
||||||
|
$clone = $this->cloneEggAndVariables($server->egg);
|
||||||
|
// This makes the BUNGEE_VERSION variable not user editable.
|
||||||
|
$clone->variables()->first()->update([
|
||||||
|
'user_editable' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$server->fill(['egg_id' => $clone->id])->saveOrFail();
|
||||||
|
$server->refresh();
|
||||||
|
|
||||||
|
ServerVariable::query()->updateOrCreate([
|
||||||
|
'server_id' => $server->id,
|
||||||
|
'variable_id' => $server->variables[0]->id,
|
||||||
|
], ['variable_value' => 'EXIST']);
|
||||||
|
|
||||||
|
$response = $this->getService()->handle($server, [
|
||||||
|
'environment' => [
|
||||||
|
'BUNGEE_VERSION' => '1234',
|
||||||
|
'SERVER_JARFILE' => 'test.jar',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertCount(2, $response->variables);
|
||||||
|
$this->assertSame('EXIST', $response->variables[0]->server_value);
|
||||||
|
$this->assertSame('test.jar', $response->variables[1]->server_value);
|
||||||
|
|
||||||
|
$response = $this->getService()
|
||||||
|
->setUserLevel(User::USER_LEVEL_ADMIN)
|
||||||
|
->handle($server, [
|
||||||
|
'environment' => [
|
||||||
|
'BUNGEE_VERSION' => '1234',
|
||||||
|
'SERVER_JARFILE' => 'test.jar',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertCount(2, $response->variables);
|
||||||
|
$this->assertSame('1234', $response->variables[0]->server_value);
|
||||||
|
$this->assertSame('test.jar', $response->variables[1]->server_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that passing an invalid egg ID into the function throws an exception
|
||||||
|
* rather than silently failing or skipping.
|
||||||
|
*/
|
||||||
|
public function testInvalidEggIdTriggersException()
|
||||||
|
{
|
||||||
|
$server = $this->createServerModel();
|
||||||
|
|
||||||
|
$this->expectException(ModelNotFoundException::class);
|
||||||
|
|
||||||
|
$this->getService()
|
||||||
|
->setUserLevel(User::USER_LEVEL_ADMIN)
|
||||||
|
->handle($server, ['egg_id' => 123456789]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Pterodactyl\Services\Servers\StartupModificationService
|
||||||
|
*/
|
||||||
|
private function getService()
|
||||||
|
{
|
||||||
|
return $this->app->make(StartupModificationService::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Tests\Traits\Integration;
|
namespace Tests\Traits\Integration;
|
||||||
|
|
||||||
|
use Ramsey\Uuid\Uuid;
|
||||||
use Pterodactyl\Models\Egg;
|
use Pterodactyl\Models\Egg;
|
||||||
use Pterodactyl\Models\Nest;
|
use Pterodactyl\Models\Nest;
|
||||||
use Pterodactyl\Models\Node;
|
use Pterodactyl\Models\Node;
|
||||||
|
@ -74,4 +75,27 @@ trait CreatesTestModels
|
||||||
'location', 'user', 'node', 'allocation', 'nest', 'egg',
|
'location', 'user', 'node', 'allocation', 'nest', 'egg',
|
||||||
])->findOrFail($server->id);
|
])->findOrFail($server->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clones a given egg allowing us to make modifications that don't affect other
|
||||||
|
* tests that rely on the egg existing in the correct state.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\Egg $egg
|
||||||
|
* @return \Pterodactyl\Models\Egg
|
||||||
|
*/
|
||||||
|
protected function cloneEggAndVariables(Egg $egg): Egg
|
||||||
|
{
|
||||||
|
$model = $egg->replicate(['id', 'uuid']);
|
||||||
|
$model->uuid = Uuid::uuid4()->toString();
|
||||||
|
$model->push();
|
||||||
|
|
||||||
|
/** @var \Pterodactyl\Models\Egg $model */
|
||||||
|
$model = $model->fresh();
|
||||||
|
|
||||||
|
foreach ($egg->variables as $variable) {
|
||||||
|
$variable->replicate(['id', 'egg_id'])->forceFill(['egg_id' => $model->id])->push();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model->fresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue