diff --git a/.env.example b/.env.example
index 9062de215..67d496d47 100644
--- a/.env.example
+++ b/.env.example
@@ -19,8 +19,8 @@ HASHIDS_SALT=
HASHIDS_LENGTH=8
MAIL_DRIVER=smtp
-MAIL_HOST=mailtrap.io
-MAIL_PORT=2525
+MAIL_HOST=smtp.example.com
+MAIL_PORT=25
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=tls
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index 1f83ddf93..4fa0845e5 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -25,11 +25,13 @@ class Kernel extends ConsoleKernel
// Execute scheduled commands for servers every minute, as if there was a normal cron running.
$schedule->command('p:schedule:process')->everyMinute()->withoutOverlapping();
- // Every 30 minutes, run the backup pruning command so that any abandoned backups can be removed
- // from the UI view for the server.
- $schedule->command('p:maintenance:prune-backups', [
- '--since-minutes' => '30',
- ])->everyThirtyMinutes();
+ // Every 30 minutes, run the backup pruning command so that any abandoned backups can be deleted.
+ $pruneAge = config('backups.prune_age', 360); // Defaults to 6 hours (time is in minuteS)
+ if ($pruneAge > 0) {
+ $schedule->command('p:maintenance:prune-backups', [
+ '--since-minutes' => $pruneAge,
+ ])->everyThirtyMinutes();
+ }
// Every day cleanup any internal backups of service files.
$schedule->command('p:maintenance:clean-service-backups')->daily();
diff --git a/app/Http/Controllers/Api/Client/Servers/FileController.php b/app/Http/Controllers/Api/Client/Servers/FileController.php
index 961b7cd02..317115b29 100644
--- a/app/Http/Controllers/Api/Client/Servers/FileController.php
+++ b/app/Http/Controllers/Api/Client/Servers/FileController.php
@@ -13,6 +13,7 @@ use Pterodactyl\Repositories\Wings\DaemonFileRepository;
use Pterodactyl\Transformers\Daemon\FileObjectTransformer;
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\CopyFileRequest;
+use Pterodactyl\Http\Requests\Api\Client\Servers\Files\PullFileRequest;
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\ListFilesRequest;
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\DeleteFileRequest;
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\RenameFileRequest;
@@ -143,10 +144,7 @@ class FileController extends ClientApiController
*/
public function write(WriteFileContentRequest $request, Server $server): JsonResponse
{
- $this->fileRepository->setServer($server)->putContent(
- $this->encode($request->get('file')),
- $request->getContent()
- );
+ $this->fileRepository->setServer($server)->putContent($request->get('file'), $request->getContent());
return new JsonResponse([], Response::HTTP_NO_CONTENT);
}
@@ -284,16 +282,18 @@ class FileController extends ClientApiController
}
/**
- * Encodes a given file name & path in a format that should work for a good majority
- * of file names without too much confusing logic.
+ * Requests that a file be downloaded from a remote location by Wings.
*
- * @param string $path
- * @return string
+ * @param $request
+ * @param \Pterodactyl\Models\Server $server
+ * @return \Illuminate\Http\JsonResponse
+ *
+ * @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
*/
- private function encode(string $path): string
+ public function pull(PullFileRequest $request, Server $server): JsonResponse
{
- return Collection::make(explode('/', rawurldecode($path)))->map(function ($value) {
- return rawurlencode($value);
- })->join('/');
+ $this->fileRepository->setServer($server)->pull($request->input('url'), $request->input('directory'));
+
+ return new JsonResponse([], Response::HTTP_NO_CONTENT);
}
}
diff --git a/app/Http/Controllers/Api/Remote/Backups/BackupRemoteUploadController.php b/app/Http/Controllers/Api/Remote/Backups/BackupRemoteUploadController.php
index 497d12904..6d50ad64d 100644
--- a/app/Http/Controllers/Api/Remote/Backups/BackupRemoteUploadController.php
+++ b/app/Http/Controllers/Api/Remote/Backups/BackupRemoteUploadController.php
@@ -52,7 +52,7 @@ class BackupRemoteUploadController extends Controller
public function __invoke(Request $request, string $backup)
{
// Get the size query parameter.
- $size = (int)$request->query('size');
+ $size = (int) $request->query('size');
if (empty($size)) {
throw new BadRequestHttpException('A non-empty "size" query parameter must be provided.');
}
diff --git a/app/Http/Requests/Api/Client/Servers/Files/PullFileRequest.php b/app/Http/Requests/Api/Client/Servers/Files/PullFileRequest.php
new file mode 100644
index 000000000..02a2fd376
--- /dev/null
+++ b/app/Http/Requests/Api/Client/Servers/Files/PullFileRequest.php
@@ -0,0 +1,29 @@
+ 'required|string|url',
+ 'directory' => 'sometimes|nullable|string',
+ ];
+ }
+}
diff --git a/app/Repositories/Wings/DaemonBackupRepository.php b/app/Repositories/Wings/DaemonBackupRepository.php
index 6506ac8a2..0eb9d4792 100644
--- a/app/Repositories/Wings/DaemonBackupRepository.php
+++ b/app/Repositories/Wings/DaemonBackupRepository.php
@@ -2,6 +2,7 @@
namespace Pterodactyl\Repositories\Wings;
+use Illuminate\Support\Arr;
use Webmozart\Assert\Assert;
use Pterodactyl\Models\Backup;
use Pterodactyl\Models\Server;
@@ -48,7 +49,7 @@ class DaemonBackupRepository extends DaemonRepository
'json' => [
'adapter' => $this->adapter ?? config('backups.default'),
'uuid' => $backup->uuid,
- 'ignored_files' => $backup->ignored_files,
+ 'ignore' => implode('\n', $backup->ignored_files),
],
]
);
diff --git a/app/Repositories/Wings/DaemonFileRepository.php b/app/Repositories/Wings/DaemonFileRepository.php
index c36a8abb0..da6cb7ae2 100644
--- a/app/Repositories/Wings/DaemonFileRepository.php
+++ b/app/Repositories/Wings/DaemonFileRepository.php
@@ -37,7 +37,7 @@ class DaemonFileRepository extends DaemonRepository
throw new DaemonConnectionException($exception);
}
- $length = (int) $response->getHeader('Content-Length')[0] ?? 0;
+ $length = (int)$response->getHeader('Content-Length')[0] ?? 0;
if ($notLargerThan && $length > $notLargerThan) {
throw new FileSizeTooLargeException;
@@ -297,4 +297,29 @@ class DaemonFileRepository extends DaemonRepository
throw new DaemonConnectionException($exception);
}
}
+
+ /**
+ * Pulls a file from the given URL and saves it to the disk.
+ *
+ * @param string $url
+ * @param string|null $directory
+ * @return \Psr\Http\Message\ResponseInterface
+ *
+ * @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
+ */
+ public function pull(string $url, ?string $directory): ResponseInterface
+ {
+ Assert::isInstanceOf($this->server, Server::class);
+
+ try {
+ return $this->getHttpClient()->post(
+ sprintf('/api/servers/%s/files/pull', $this->server->uuid),
+ [
+ 'json' => ['url' => $url, 'directory' => $directory ?? '/'],
+ ]
+ );
+ } catch (TransferException $exception) {
+ throw new DaemonConnectionException($exception);
+ }
+ }
}
diff --git a/app/Services/Backups/InitiateBackupService.php b/app/Services/Backups/InitiateBackupService.php
index 0857478ba..615f357ce 100644
--- a/app/Services/Backups/InitiateBackupService.php
+++ b/app/Services/Backups/InitiateBackupService.php
@@ -117,9 +117,9 @@ class InitiateBackupService
}
// Check if the server has reached or exceeded it's backup limit
- if (!$server->backup_limit || $server->backups()->where('is_successful', true)->count() >= $server->backup_limit) {
+ if (! $server->backup_limit || $server->backups()->where('is_successful', true)->count() >= $server->backup_limit) {
// Do not allow the user to continue if this server is already at its limit and can't override.
- if (!$override || $server->backup_limit <= 0) {
+ if (! $override || $server->backup_limit <= 0) {
throw new TooManyBackupsException($server->backup_limit);
}
diff --git a/config/backups.php b/config/backups.php
index 32ee1aa8a..a309a9ee6 100644
--- a/config/backups.php
+++ b/config/backups.php
@@ -12,6 +12,10 @@ return [
// uses to upload backups to S3 storage. Value is in minutes, so this would default to an hour.
'presigned_url_lifespan' => env('BACKUP_PRESIGNED_URL_LIFESPAN', 60),
+ // The time to wait before automatically failing a backup, time is in minutes and defaults
+ // to 6 hours. To disable this feature, set the value to `0`.
+ 'prune_age' => env('BACKUP_PRUNE_AGE', 360),
+
'disks' => [
// There is no configuration for the local disk for Wings. That configuration
// is determined by the Daemon configuration, and not the Panel.
diff --git a/database/seeds/eggs/minecraft/egg-sponge--sponge-vanilla.json b/database/seeds/eggs/minecraft/egg-sponge--sponge-vanilla.json
index 0a695ac2e..db3f7fc94 100644
--- a/database/seeds/eggs/minecraft/egg-sponge--sponge-vanilla.json
+++ b/database/seeds/eggs/minecraft/egg-sponge--sponge-vanilla.json
@@ -28,7 +28,7 @@
"name": "Sponge Version",
"description": "The version of SpongeVanilla to download and use.",
"env_variable": "SPONGE_VERSION",
- "default_value": "1.11.2-6.1.0-BETA-21",
+ "default_value": "1.12.2-7.3.0",
"user_viewable": true,
"user_editable": false,
"rules": "required|regex:\/^([a-zA-Z0-9.\\-_]+)$\/"
diff --git a/resources/scripts/components/server/databases/DatabaseRow.tsx b/resources/scripts/components/server/databases/DatabaseRow.tsx
index caf4a702e..148415a13 100644
--- a/resources/scripts/components/server/databases/DatabaseRow.tsx
+++ b/resources/scripts/components/server/databases/DatabaseRow.tsx
@@ -127,7 +127,7 @@ export default ({ database, className }: Props) => {
-
+
diff --git a/routes/api-client.php b/routes/api-client.php
index 320c8ec55..62cad21c1 100644
--- a/routes/api-client.php
+++ b/routes/api-client.php
@@ -66,6 +66,7 @@ Route::group(['prefix' => '/servers/{server}', 'middleware' => [AuthenticateServ
Route::post('/delete', 'Servers\FileController@delete');
Route::post('/create-folder', 'Servers\FileController@create');
Route::post('/chmod', 'Servers\FileController@chmod');
+ Route::post('/pull', 'Servers\FileController@pull');
Route::get('/upload', 'Servers\FileUploadController');
});
diff --git a/tests/Unit/Commands/CommandTestCase.php b/tests/Unit/Commands/CommandTestCase.php
deleted file mode 100644
index 7786a4dcf..000000000
--- a/tests/Unit/Commands/CommandTestCase.php
+++ /dev/null
@@ -1,59 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Commands;
-
-use Tests\TestCase;
-use Illuminate\Console\Command;
-use Illuminate\Contracts\Foundation\Application;
-use Symfony\Component\Console\Tester\CommandTester;
-
-abstract class CommandTestCase extends TestCase
-{
- /**
- * @var bool
- */
- protected $commandIsInteractive = true;
-
- /**
- * Set a command to be non-interactive for testing purposes.
- *
- * @return $this
- */
- public function withoutInteraction()
- {
- $this->commandIsInteractive = false;
-
- return $this;
- }
-
- /**
- * Return the display from running a command.
- *
- * @param \Illuminate\Console\Command $command
- * @param array $args
- * @param array $inputs
- * @param array $opts
- * @return string
- */
- protected function runCommand(Command $command, array $args = [], array $inputs = [], array $opts = [])
- {
- if (! $command->getLaravel() instanceof Application) {
- $command->setLaravel($this->app);
- }
-
- $response = new CommandTester($command);
- $response->setInputs($inputs);
-
- $opts = array_merge($opts, ['interactive' => $this->commandIsInteractive]);
- $response->execute($args, $opts);
-
- return $response->getDisplay();
- }
-}
diff --git a/tests/Unit/Commands/Environment/EmailSettingsCommandTest.php b/tests/Unit/Commands/Environment/EmailSettingsCommandTest.php
deleted file mode 100644
index 6c071124a..000000000
--- a/tests/Unit/Commands/Environment/EmailSettingsCommandTest.php
+++ /dev/null
@@ -1,275 +0,0 @@
-config = m::mock(Repository::class);
- $this->command = m::mock(EmailSettingsCommand::class . '[call, writeToEnvironment]', [$this->config]);
- $this->command->setLaravel($this->app);
- }
-
- /**
- * Test selection of the SMTP driver with no options passed.
- */
- public function testSmtpDriverSelection()
- {
- // TODO(dane): fix this
- $this->markTestSkipped('Skipped, GitHub actions cannot run successfully.');
-// $data = [
-// 'MAIL_DRIVER' => 'smtp',
-// 'MAIL_HOST' => 'mail.test.com',
-// 'MAIL_PORT' => '567',
-// 'MAIL_USERNAME' => 'username',
-// 'MAIL_PASSWORD' => 'password',
-// 'MAIL_FROM' => 'mail@from.com',
-// 'MAIL_FROM_NAME' => 'MailName',
-// 'MAIL_ENCRYPTION' => 'tls',
-// ];
-//
-// $this->setupCoreFunctions($data);
-// $display = $this->runCommand($this->command, [], array_values($data));
-//
-// $this->assertNotEmpty($display);
-// $this->assertStringContainsString('Updating stored environment configuration file.', $display);
- }
-
- /**
- * Test that the command can run when all variables are passed in as options.
- */
- public function testSmtpDriverSelectionWithOptionsPassed()
- {
- $data = [
- 'MAIL_DRIVER' => 'smtp',
- 'MAIL_HOST' => 'mail.test.com',
- 'MAIL_PORT' => '567',
- 'MAIL_USERNAME' => 'username',
- 'MAIL_PASSWORD' => 'password',
- 'MAIL_FROM' => 'mail@from.com',
- 'MAIL_FROM_NAME' => 'MailName',
- 'MAIL_ENCRYPTION' => 'tls',
- ];
-
- $this->setupCoreFunctions($data);
- $display = $this->withoutInteraction()->runCommand($this->command, [
- '--driver' => $data['MAIL_DRIVER'],
- '--email' => $data['MAIL_FROM'],
- '--from' => $data['MAIL_FROM_NAME'],
- '--encryption' => $data['MAIL_ENCRYPTION'],
- '--host' => $data['MAIL_HOST'],
- '--port' => $data['MAIL_PORT'],
- '--username' => $data['MAIL_USERNAME'],
- '--password' => $data['MAIL_PASSWORD'],
- ]);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString('Updating stored environment configuration file.', $display);
- }
-
- /**
- * Test selection of PHP mail() as the driver.
- */
- public function testPHPMailDriverSelection()
- {
- $data = [
- 'MAIL_DRIVER' => 'mail',
- 'MAIL_FROM' => 'mail@from.com',
- 'MAIL_FROM_NAME' => 'MailName',
- 'MAIL_ENCRYPTION' => 'tls',
- ];
-
- $this->setupCoreFunctions($data);
-
- // The driver flag is passed because there seems to be some issue with the command tester
- // when using a choice() method when two keys start with the same letters.
- //
- // In this case, mail and mailgun.
- unset($data['MAIL_DRIVER']);
- $display = $this->runCommand($this->command, ['--driver' => 'mail'], array_values($data));
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString('Updating stored environment configuration file.', $display);
- }
-
- /**
- * Test selection of the Mailgun driver with no options passed.
- */
- public function testMailgunDriverSelection()
- {
- $data = [
- 'MAIL_DRIVER' => 'mailgun',
- 'MAILGUN_DOMAIN' => 'domain.com',
- 'MAILGUN_SECRET' => '123456',
- 'MAIL_FROM' => 'mail@from.com',
- 'MAIL_FROM_NAME' => 'MailName',
- 'MAIL_ENCRYPTION' => 'tls',
- ];
-
- $this->setupCoreFunctions($data);
- $display = $this->runCommand($this->command, [], array_values($data));
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString('Updating stored environment configuration file.', $display);
- }
-
- /**
- * Test mailgun driver selection when variables are passed as options.
- */
- public function testMailgunDriverSelectionWithOptionsPassed()
- {
- $data = [
- 'MAIL_DRIVER' => 'mailgun',
- 'MAILGUN_DOMAIN' => 'domain.com',
- 'MAILGUN_SECRET' => '123456',
- 'MAIL_FROM' => 'mail@from.com',
- 'MAIL_FROM_NAME' => 'MailName',
- 'MAIL_ENCRYPTION' => 'tls',
- ];
-
- $this->setupCoreFunctions($data);
- $display = $this->withoutInteraction()->runCommand($this->command, [
- '--driver' => $data['MAIL_DRIVER'],
- '--email' => $data['MAIL_FROM'],
- '--from' => $data['MAIL_FROM_NAME'],
- '--encryption' => $data['MAIL_ENCRYPTION'],
- '--host' => $data['MAILGUN_DOMAIN'],
- '--password' => $data['MAILGUN_SECRET'],
- ]);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString('Updating stored environment configuration file.', $display);
- }
-
- /**
- * Test selection of the Mandrill driver with no options passed.
- */
- public function testMandrillDriverSelection()
- {
- $data = [
- 'MAIL_DRIVER' => 'mandrill',
- 'MANDRILL_SECRET' => '123456',
- 'MAIL_FROM' => 'mail@from.com',
- 'MAIL_FROM_NAME' => 'MailName',
- 'MAIL_ENCRYPTION' => 'tls',
- ];
-
- $this->setupCoreFunctions($data);
- $display = $this->runCommand($this->command, [], array_values($data));
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString('Updating stored environment configuration file.', $display);
- }
-
- /**
- * Test mandrill driver selection when variables are passed as options.
- */
- public function testMandrillDriverSelectionWithOptionsPassed()
- {
- $data = [
- 'MAIL_DRIVER' => 'mandrill',
- 'MANDRILL_SECRET' => '123456',
- 'MAIL_FROM' => 'mail@from.com',
- 'MAIL_FROM_NAME' => 'MailName',
- 'MAIL_ENCRYPTION' => 'tls',
- ];
-
- $this->setupCoreFunctions($data);
- $display = $this->withoutInteraction()->runCommand($this->command, [
- '--driver' => $data['MAIL_DRIVER'],
- '--email' => $data['MAIL_FROM'],
- '--from' => $data['MAIL_FROM_NAME'],
- '--encryption' => $data['MAIL_ENCRYPTION'],
- '--password' => $data['MANDRILL_SECRET'],
- ]);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString('Updating stored environment configuration file.', $display);
- }
-
- /**
- * Test selection of the Postmark driver with no options passed.
- */
- public function testPostmarkDriverSelection()
- {
- $data = [
- 'MAIL_DRIVER' => 'smtp',
- 'MAIL_HOST' => 'smtp.postmarkapp.com',
- 'MAIL_PORT' => '587',
- 'MAIL_USERNAME' => '123456',
- 'MAIL_PASSWORD' => '123456',
- 'MAIL_FROM' => 'mail@from.com',
- 'MAIL_FROM_NAME' => 'MailName',
- 'MAIL_ENCRYPTION' => 'tls',
- ];
-
- $this->setupCoreFunctions($data);
- $display = $this->runCommand($this->command, [], [
- 'postmark', '123456', $data['MAIL_FROM'], $data['MAIL_FROM_NAME'], $data['MAIL_ENCRYPTION'],
- ]);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString('Updating stored environment configuration file.', $display);
- }
-
- /**
- * Test postmark driver selection when variables are passed as options.
- */
- public function testPostmarkDriverSelectionWithOptionsPassed()
- {
- $data = [
- 'MAIL_DRIVER' => 'smtp',
- 'MAIL_HOST' => 'smtp.postmarkapp.com',
- 'MAIL_PORT' => '587',
- 'MAIL_USERNAME' => '123456',
- 'MAIL_PASSWORD' => '123456',
- 'MAIL_FROM' => 'mail@from.com',
- 'MAIL_FROM_NAME' => 'MailName',
- 'MAIL_ENCRYPTION' => 'tls',
- ];
-
- $this->setupCoreFunctions($data);
- $display = $this->withoutInteraction()->runCommand($this->command, [
- '--driver' => 'postmark',
- '--email' => $data['MAIL_FROM'],
- '--from' => $data['MAIL_FROM_NAME'],
- '--encryption' => $data['MAIL_ENCRYPTION'],
- '--username' => $data['MAIL_USERNAME'],
- ]);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString('Updating stored environment configuration file.', $display);
- }
-
- /**
- * Setup the core functions that are repeated across all of these tests.
- *
- * @param array $data
- */
- private function setupCoreFunctions(array $data)
- {
- $this->config->shouldReceive('get')->withAnyArgs()->zeroOrMoreTimes()->andReturnNull();
- $this->command->shouldReceive('writeToEnvironment')->with($data)->once()->andReturnNull();
- }
-}
diff --git a/tests/Unit/Commands/Location/DeleteLocationCommandTest.php b/tests/Unit/Commands/Location/DeleteLocationCommandTest.php
deleted file mode 100644
index 26bd73319..000000000
--- a/tests/Unit/Commands/Location/DeleteLocationCommandTest.php
+++ /dev/null
@@ -1,128 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Commands\Location;
-
-use Mockery as m;
-use Pterodactyl\Models\Location;
-use Tests\Unit\Commands\CommandTestCase;
-use Pterodactyl\Services\Locations\LocationDeletionService;
-use Pterodactyl\Console\Commands\Location\DeleteLocationCommand;
-use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
-
-class DeleteLocationCommandTest extends CommandTestCase
-{
- /**
- * @var \Pterodactyl\Console\Commands\Location\DeleteLocationCommand
- */
- protected $command;
-
- /**
- * @var \Pterodactyl\Services\Locations\LocationDeletionService|\Mockery\Mock
- */
- protected $deletionService;
-
- /**
- * @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface|\Mockery\Mock
- */
- protected $repository;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->deletionService = m::mock(LocationDeletionService::class);
- $this->repository = m::mock(LocationRepositoryInterface::class);
-
- $this->command = new DeleteLocationCommand($this->deletionService, $this->repository);
- $this->command->setLaravel($this->app);
- }
-
- /**
- * Test that a location can be deleted.
- */
- public function testLocationIsDeleted()
- {
- $locations = collect([
- $location1 = factory(Location::class)->make(),
- $location2 = factory(Location::class)->make(),
- ]);
-
- $this->repository->shouldReceive('all')->withNoArgs()->once()->andReturn($locations);
- $this->deletionService->shouldReceive('handle')->with($location2->id)->once()->andReturnNull();
-
- $display = $this->runCommand($this->command, [], [$location2->short]);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString(trans('command/messages.location.deleted'), $display);
- }
-
- /**
- * Test that a location is deleted if passed in as an option.
- */
- public function testLocationIsDeletedIfPassedInOption()
- {
- $locations = collect([
- $location1 = factory(Location::class)->make(),
- $location2 = factory(Location::class)->make(),
- ]);
-
- $this->repository->shouldReceive('all')->withNoArgs()->once()->andReturn($locations);
- $this->deletionService->shouldReceive('handle')->with($location2->id)->once()->andReturnNull();
-
- $display = $this->withoutInteraction()->runCommand($this->command, [
- '--short' => $location2->short,
- ]);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString(trans('command/messages.location.deleted'), $display);
- }
-
- /**
- * Test that prompt shows back up if the user enters the wrong parameters.
- */
- public function testInteractiveEnvironmentAllowsReAttemptingSearch()
- {
- $locations = collect([
- $location1 = factory(Location::class)->make(),
- $location2 = factory(Location::class)->make(),
- ]);
-
- $this->repository->shouldReceive('all')->withNoArgs()->once()->andReturn($locations);
- $this->deletionService->shouldReceive('handle')->with($location2->id)->once()->andReturnNull();
-
- $display = $this->runCommand($this->command, [], ['123_not_exist', 'another_not_exist', $location2->short]);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString(trans('command/messages.location.no_location_found'), $display);
- $this->assertStringContainsString(trans('command/messages.location.deleted'), $display);
- }
-
- /**
- * Test that no re-attempt is performed in a non-interactive environment.
- */
- public function testNonInteractiveEnvironmentThrowsErrorIfNoLocationIsFound()
- {
- $locations = collect([
- $location1 = factory(Location::class)->make(),
- $location2 = factory(Location::class)->make(),
- ]);
-
- $this->repository->shouldReceive('all')->withNoArgs()->once()->andReturn($locations);
- $this->deletionService->shouldNotReceive('handle');
-
- $display = $this->withoutInteraction()->runCommand($this->command, ['--short' => 'randomTestString']);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString(trans('command/messages.location.no_location_found'), $display);
- }
-}
diff --git a/tests/Unit/Commands/Location/MakeLocationCommandTest.php b/tests/Unit/Commands/Location/MakeLocationCommandTest.php
deleted file mode 100644
index 6b628a6f0..000000000
--- a/tests/Unit/Commands/Location/MakeLocationCommandTest.php
+++ /dev/null
@@ -1,87 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Commands\Location;
-
-use Mockery as m;
-use Pterodactyl\Models\Location;
-use Tests\Unit\Commands\CommandTestCase;
-use Pterodactyl\Services\Locations\LocationCreationService;
-use Pterodactyl\Console\Commands\Location\MakeLocationCommand;
-
-class MakeLocationCommandTest extends CommandTestCase
-{
- /**
- * @var \Pterodactyl\Console\Commands\Location\MakeLocationCommand
- */
- protected $command;
-
- /**
- * @var \Pterodactyl\Services\Locations\LocationCreationService|\Mockery\Mock
- */
- protected $creationService;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->creationService = m::mock(LocationCreationService::class);
-
- $this->command = new MakeLocationCommand($this->creationService);
- $this->command->setLaravel($this->app);
- }
-
- /**
- * Test that a location can be created when no options are passed.
- */
- public function testLocationIsCreatedWithNoOptionsPassed()
- {
- $location = factory(Location::class)->make();
-
- $this->creationService->shouldReceive('handle')->with([
- 'short' => $location->short,
- 'long' => $location->long,
- ])->once()->andReturn($location);
-
- $display = $this->runCommand($this->command, [], [$location->short, $location->long]);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString(trans('command/messages.location.created', [
- 'name' => $location->short,
- 'id' => $location->id,
- ]), $display);
- }
-
- /**
- * Test that a location is created when options are passed.
- */
- public function testLocationIsCreatedWhenOptionsArePassed()
- {
- $location = factory(Location::class)->make();
-
- $this->creationService->shouldReceive('handle')->with([
- 'short' => $location->short,
- 'long' => $location->long,
- ])->once()->andReturn($location);
-
- $display = $this->withoutInteraction()->runCommand($this->command, [
- '--short' => $location->short,
- '--long' => $location->long,
- ]);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString(trans('command/messages.location.created', [
- 'name' => $location->short,
- 'id' => $location->id,
- ]), $display);
- }
-}
diff --git a/tests/Unit/Commands/Maintenance/CleanServiceBackupFilesCommandTest.php b/tests/Unit/Commands/Maintenance/CleanServiceBackupFilesCommandTest.php
deleted file mode 100644
index ecb412e52..000000000
--- a/tests/Unit/Commands/Maintenance/CleanServiceBackupFilesCommandTest.php
+++ /dev/null
@@ -1,87 +0,0 @@
-disk = m::mock(Filesystem::class);
- $this->filesystem = m::mock(Factory::class);
- $this->filesystem->shouldReceive('disk')->withNoArgs()->once()->andReturn($this->disk);
- }
-
- /**
- * Test that a file is deleted if it is > 5min old.
- */
- public function testCommandCleansFilesMoreThan5MinutesOld()
- {
- $file = new SplFileInfo('testfile.txt');
-
- $this->disk->shouldReceive('files')->with('services/.bak')->once()->andReturn([$file]);
- $this->disk->shouldReceive('lastModified')->with($file->getPath())->once()->andReturn(Carbon::now()->subDays(100)->getTimestamp());
- $this->disk->shouldReceive('delete')->with($file->getPath())->once()->andReturnNull();
-
- $display = $this->runCommand($this->getCommand());
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString(trans('command/messages.maintenance.deleting_service_backup', ['file' => 'testfile.txt']), $display);
- }
-
- /**
- * Test that a file isn't deleted if it is < 5min old.
- */
- public function testCommandDoesNotCleanFileLessThan5MinutesOld()
- {
- $file = new SplFileInfo('testfile.txt');
-
- $this->disk->shouldReceive('files')->with('services/.bak')->once()->andReturn([$file]);
- $this->disk->shouldReceive('lastModified')->with($file->getPath())->once()->andReturn(Carbon::now()->getTimestamp());
-
- $display = $this->runCommand($this->getCommand());
-
- $this->assertEmpty($display);
- }
-
- /**
- * Return an instance of the command for testing.
- *
- * @return \Pterodactyl\Console\Commands\Maintenance\CleanServiceBackupFilesCommand
- */
- private function getCommand(): CleanServiceBackupFilesCommand
- {
- $command = new CleanServiceBackupFilesCommand($this->filesystem);
- $command->setLaravel($this->app);
-
- return $command;
- }
-}
diff --git a/tests/Unit/Commands/User/DisableTwoFactorCommandTest.php b/tests/Unit/Commands/User/DisableTwoFactorCommandTest.php
deleted file mode 100644
index f2868883d..000000000
--- a/tests/Unit/Commands/User/DisableTwoFactorCommandTest.php
+++ /dev/null
@@ -1,83 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Commands\User;
-
-use Mockery as m;
-use Pterodactyl\Models\User;
-use Tests\Unit\Commands\CommandTestCase;
-use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
-use Pterodactyl\Console\Commands\User\DisableTwoFactorCommand;
-
-class DisableTwoFactorCommandTest extends CommandTestCase
-{
- /**
- * @var \Pterodactyl\Console\Commands\User\DisableTwoFactorCommand
- */
- protected $command;
-
- /**
- * @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface|\Mockery\Mock
- */
- protected $repository;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->repository = m::mock(UserRepositoryInterface::class);
-
- $this->command = new DisableTwoFactorCommand($this->repository);
- $this->command->setLaravel($this->app);
- }
-
- /**
- * Test 2-factor auth is disabled when no option is passed.
- */
- public function testTwoFactorIsDisabledWhenNoOptionIsPassed()
- {
- $user = factory(User::class)->make();
-
- $this->repository->shouldReceive('setColumns')->with(['id', 'email'])->once()->andReturnSelf()
- ->shouldReceive('findFirstWhere')->with([['email', '=', $user->email]])->once()->andReturn($user);
- $this->repository->shouldReceive('withoutFreshModel')->withNoArgs()->once()->andReturnSelf()
- ->shouldReceive('update')->with($user->id, [
- 'use_totp' => false,
- 'totp_secret' => null,
- ])->once()->andReturnNull();
-
- $display = $this->runCommand($this->command, [], [$user->email]);
-
- $this->assertNotEmpty($display);
- $this->assertStringContainsString(trans('command/messages.user.2fa_disabled', ['email' => $user->email]), $display);
- }
-
- /**
- * Test 2-factor auth is disabled when user is passed in option.
- */
- public function testTwoFactorIsDisabledWhenOptionIsPassed()
- {
- $user = factory(User::class)->make();
-
- $this->repository->shouldReceive('setColumns')->with(['id', 'email'])->once()->andReturnSelf()
- ->shouldReceive('findFirstWhere')->with([['email', '=', $user->email]])->once()->andReturn($user);
- $this->repository->shouldReceive('withoutFreshModel')->withNoArgs()->once()->andReturnSelf()
- ->shouldReceive('update')->with($user->id, [
- 'use_totp' => false,
- 'totp_secret' => null,
- ])->once()->andReturnNull();
-
- $display = $this->withoutInteraction()->runCommand($this->command, ['--email' => $user->email]);
- $this->assertNotEmpty($display);
- $this->assertStringContainsString(trans('command/messages.user.2fa_disabled', ['email' => $user->email]), $display);
- }
-}
diff --git a/tests/Unit/Commands/User/MakeUserCommandTest.php b/tests/Unit/Commands/User/MakeUserCommandTest.php
deleted file mode 100644
index 676a3c6dc..000000000
--- a/tests/Unit/Commands/User/MakeUserCommandTest.php
+++ /dev/null
@@ -1,132 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Commands\User;
-
-use Mockery as m;
-use Pterodactyl\Models\User;
-use Tests\Unit\Commands\CommandTestCase;
-use Pterodactyl\Services\Users\UserCreationService;
-use Pterodactyl\Console\Commands\User\MakeUserCommand;
-
-class MakeUserCommandTest extends CommandTestCase
-{
- /**
- * @var \Pterodactyl\Console\Commands\User\MakeUserCommand
- */
- protected $command;
-
- /**
- * @var \Pterodactyl\Services\Users\UserCreationService
- */
- protected $creationService;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->creationService = m::mock(UserCreationService::class);
-
- $this->command = new MakeUserCommand($this->creationService);
- $this->command->setLaravel($this->app);
- }
-
- /**
- * Test that the command executes if no options are passed.
- */
- public function testCommandWithNoPassedOptions()
- {
- // TODO(dane): fix this
- $this->markTestSkipped('Skipped, GitHub actions cannot run successfully.');
-
-// $user = factory(User::class)->make(['root_admin' => true]);
-//
-// $this->creationService->shouldReceive('handle')->with([
-// 'email' => $user->email,
-// 'username' => $user->username,
-// 'name_first' => $user->name_first,
-// 'name_last' => $user->name_last,
-// 'password' => 'Password123',
-// 'root_admin' => $user->root_admin,
-// ])->once()->andReturn($user);
-//
-// $display = $this->runCommand($this->command, [], [
-// 'yes', $user->email, $user->username, $user->name_first, $user->name_last, 'Password123',
-// ]);
-//
-// $this->assertNotEmpty($display);
-// $this->assertStringContainsString(trans('command/messages.user.ask_password_help'), $display);
-// $this->assertStringContainsString($user->uuid, $display);
-// $this->assertStringContainsString($user->email, $display);
-// $this->assertStringContainsString($user->username, $display);
-// $this->assertStringContainsString($user->name, $display);
-// $this->assertStringContainsString('Yes', $display);
- }
-
- /**
- * Test that the --no-password flag works as intended.
- */
- public function testCommandWithNoPasswordOption()
- {
- $user = factory(User::class)->make(['root_admin' => true]);
-
- $this->creationService->shouldReceive('handle')->with([
- 'email' => $user->email,
- 'username' => $user->username,
- 'name_first' => $user->name_first,
- 'name_last' => $user->name_last,
- 'password' => null,
- 'root_admin' => $user->root_admin,
- ])->once()->andReturn($user);
-
- $display = $this->runCommand($this->command, ['--no-password' => true], [
- 'yes', $user->email, $user->username, $user->name_first, $user->name_last,
- ]);
-
- $this->assertNotEmpty($display);
- $this->assertStringNotContainsString(trans('command/messages.user.ask_password_help'), $display);
- }
-
- /**
- * Test command when arguments are passed as flags.
- */
- public function testCommandWithOptionsPassed()
- {
- $user = factory(User::class)->make(['root_admin' => false]);
-
- $this->creationService->shouldReceive('handle')->with([
- 'email' => $user->email,
- 'username' => $user->username,
- 'name_first' => $user->name_first,
- 'name_last' => $user->name_last,
- 'password' => 'Password123',
- 'root_admin' => $user->root_admin,
- ])->once()->andReturn($user);
-
- $display = $this->withoutInteraction()->runCommand($this->command, [
- '--email' => $user->email,
- '--username' => $user->username,
- '--name-first' => $user->name_first,
- '--name-last' => $user->name_last,
- '--password' => 'Password123',
- '--admin' => 0,
- ]);
-
- $this->assertNotEmpty($display);
- $this->assertStringNotContainsString(trans('command/messages.user.ask_password_help'), $display);
- $this->assertStringContainsString($user->uuid, $display);
- $this->assertStringContainsString($user->email, $display);
- $this->assertStringContainsString($user->username, $display);
- $this->assertStringContainsString($user->name, $display);
- $this->assertStringContainsString('No', $display);
- }
-}
diff --git a/tests/Unit/Http/Controllers/Admin/DatabaseControllerTest.php b/tests/Unit/Http/Controllers/Admin/DatabaseControllerTest.php
deleted file mode 100644
index 6188c0c33..000000000
--- a/tests/Unit/Http/Controllers/Admin/DatabaseControllerTest.php
+++ /dev/null
@@ -1,143 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Http\Controllers\Admin;
-
-use Mockery as m;
-use Tests\TestCase;
-use Pterodactyl\Models\DatabaseHost;
-use Prologue\Alerts\AlertsMessageBag;
-use Illuminate\Pagination\LengthAwarePaginator;
-use Tests\Assertions\ControllerAssertionsTrait;
-use Pterodactyl\Http\Controllers\Admin\DatabaseController;
-use Pterodactyl\Services\Databases\Hosts\HostUpdateService;
-use Pterodactyl\Services\Databases\Hosts\HostCreationService;
-use Pterodactyl\Services\Databases\Hosts\HostDeletionService;
-use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
-use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
-use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
-
-class DatabaseControllerTest extends TestCase
-{
- use ControllerAssertionsTrait;
-
- /**
- * @var \Prologue\Alerts\AlertsMessageBag|\Mockery\Mock
- */
- private $alert;
-
- /**
- * @var \Pterodactyl\Services\Databases\Hosts\HostCreationService|\Mockery\Mock
- */
- private $creationService;
-
- /**
- * @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface|\Mockery\Mock
- */
- private $databaseRepository;
-
- /**
- * @var \Pterodactyl\Services\Databases\Hosts\HostDeletionService|\Mockery\Mock
- */
- private $deletionService;
-
- /**
- * @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface|\Mockery\Mock
- */
- private $locationRepository;
-
- /**
- * @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface|\Mockery\Mock
- */
- private $repository;
-
- /**
- * @var \Pterodactyl\Services\Databases\Hosts\HostUpdateService|\Mockery\Mock
- */
- private $updateService;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->alert = m::mock(AlertsMessageBag::class);
- $this->creationService = m::mock(HostCreationService::class);
- $this->databaseRepository = m::mock(DatabaseRepositoryInterface::class);
- $this->deletionService = m::mock(HostDeletionService::class);
- $this->locationRepository = m::mock(LocationRepositoryInterface::class);
- $this->repository = m::mock(DatabaseHostRepositoryInterface::class);
- $this->updateService = m::mock(HostUpdateService::class);
- }
-
- /**
- * Test the index controller.
- */
- public function testIndexController()
- {
- $this->locationRepository->shouldReceive('getAllWithNodes')->withNoArgs()->once()->andReturn(collect(['getAllWithNodes']));
- $this->repository->shouldReceive('getWithViewDetails')->withNoArgs()->once()->andReturn(collect(['getWithViewDetails']));
-
- $response = $this->getController()->index();
-
- $this->assertIsViewResponse($response);
- $this->assertViewNameEquals('admin.databases.index', $response);
- $this->assertViewHasKey('locations', $response);
- $this->assertViewHasKey('hosts', $response);
- $this->assertViewKeyEquals('locations', collect(['getAllWithNodes']), $response);
- $this->assertViewKeyEquals('hosts', collect(['getWithViewDetails']), $response);
- }
-
- /**
- * Test the view controller for displaying a specific database host.
- */
- public function testViewController()
- {
- $model = factory(DatabaseHost::class)->make();
- $paginator = new LengthAwarePaginator([], 1, 1);
-
- $this->locationRepository->shouldReceive('getAllWithNodes')->withNoArgs()->once()->andReturn(collect(['getAllWithNodes']));
- $this->repository->shouldReceive('find')->with(1)->once()->andReturn($model);
- $this->databaseRepository->shouldReceive('getDatabasesForHost')
- ->once()
- ->with(1)
- ->andReturn($paginator);
-
- $response = $this->getController()->view(1);
-
- $this->assertIsViewResponse($response);
- $this->assertViewNameEquals('admin.databases.view', $response);
- $this->assertViewHasKey('locations', $response);
- $this->assertViewHasKey('host', $response);
- $this->assertViewHasKey('databases', $response);
- $this->assertViewKeyEquals('locations', collect(['getAllWithNodes']), $response);
- $this->assertViewKeyEquals('host', $model, $response);
- $this->assertViewKeyEquals('databases', $paginator, $response);
- }
-
- /**
- * Return an instance of the DatabaseController with mock dependencies.
- *
- * @return \Pterodactyl\Http\Controllers\Admin\DatabaseController
- */
- private function getController(): DatabaseController
- {
- return new DatabaseController(
- $this->alert,
- $this->repository,
- $this->databaseRepository,
- $this->creationService,
- $this->deletionService,
- $this->updateService,
- $this->locationRepository
- );
- }
-}
diff --git a/tests/Unit/Http/Controllers/Admin/MailControllerTest.php b/tests/Unit/Http/Controllers/Admin/MailControllerTest.php
deleted file mode 100644
index ecd5258e6..000000000
--- a/tests/Unit/Http/Controllers/Admin/MailControllerTest.php
+++ /dev/null
@@ -1,82 +0,0 @@
-alert = m::mock(AlertsMessageBag::class);
- $this->configRepository = m::mock(ConfigRepository::class);
- $this->encrypter = m::mock(Encrypter::class);
- $this->kernel = m::mock(Kernel::class);
- $this->settingsRepositoryInterface = m::mock(SettingsRepositoryInterface::class);
- }
-
- /**
- * Test the mail controller for viewing mail settings page.
- */
- public function testIndex()
- {
- $this->configRepository->shouldReceive('get');
-
- $response = $this->getController()->index();
-
- $this->assertIsViewResponse($response);
- $this->assertViewNameEquals('admin.settings.mail', $response);
- }
-
- /**
- * Prepare a MailController using our mocks.
- *
- * @return MailController
- */
- public function getController()
- {
- return new MailController(
- $this->alert,
- $this->configRepository,
- $this->encrypter,
- $this->kernel,
- $this->settingsRepositoryInterface
- );
- }
-}
diff --git a/tests/Unit/Http/Controllers/ControllerTestCase.php b/tests/Unit/Http/Controllers/ControllerTestCase.php
deleted file mode 100644
index 197f26255..000000000
--- a/tests/Unit/Http/Controllers/ControllerTestCase.php
+++ /dev/null
@@ -1,99 +0,0 @@
-buildRequestMock();
- }
-
- /**
- * Set an instance of the controller.
- *
- * @param \Pterodactyl\Http\Controllers\Controller|\Mockery\Mock $controller
- */
- public function setControllerInstance($controller)
- {
- $this->controller = $controller;
- }
-
- /**
- * Return an instance of the controller.
- *
- * @return \Mockery\Mock|\Pterodactyl\Http\Controllers\Controller
- */
- public function getControllerInstance()
- {
- return $this->controller;
- }
-
- /**
- * Helper function to mock injectJavascript requests.
- *
- * @param array|null $args
- * @param bool $subset
- */
- protected function mockInjectJavascript(array $args = null, bool $subset = false)
- {
- $controller = $this->getControllerInstance();
-
- $controller->shouldReceive('setRequest')->with($this->request)->once()->andReturnSelf();
- if (is_null($args)) {
- $controller->shouldReceive('injectJavascript')->withAnyArgs()->once()->andReturnNull();
- } else {
- $with = $subset ? m::subset($args) : $args;
-
- $controller->shouldReceive('injectJavascript')->with($with)->once()->andReturnNull();
- }
- }
-
- /**
- * Mocks a request input call.
- *
- * @param string $param
- * @param mixed $return
- */
- protected function mockRequestInput(string $param, $return = null)
- {
- $this->request->shouldReceive('input')->withArgs(function ($k) use ($param) {
- return $k === $param;
- })->andReturn($return);
- }
-
- /**
- * Build and return a mocked controller instance to use for testing.
- *
- * @param string $class
- * @param array $args
- * @return \Mockery\Mock|\Pterodactyl\Http\Controllers\Controller
- */
- protected function buildMockedController(string $class, array $args = [])
- {
- $controller = m::mock($class, $args)->makePartial();
-
- if (is_null($this->getControllerInstance())) {
- $this->setControllerInstance($controller);
- }
-
- return $this->getControllerInstance();
- }
-}
diff --git a/tests/Unit/Services/Allocations/AllocationDeletionServiceTest.php b/tests/Unit/Services/Allocations/AllocationDeletionServiceTest.php
deleted file mode 100644
index 055aedaa1..000000000
--- a/tests/Unit/Services/Allocations/AllocationDeletionServiceTest.php
+++ /dev/null
@@ -1,60 +0,0 @@
-repository = m::mock(AllocationRepositoryInterface::class);
- }
-
- /**
- * Test that an allocation is deleted.
- */
- public function testAllocationIsDeleted()
- {
- $model = factory(Allocation::class)->make(['id' => 123]);
-
- $this->repository->expects('delete')->with($model->id)->andReturns(1);
-
- $response = $this->getService()->handle($model);
- $this->assertEquals(1, $response);
- }
-
- /**
- * Test that an exception gets thrown if an allocation is currently assigned to a server.
- */
- public function testExceptionThrownIfAssignedToServer()
- {
- $this->expectException(ServerUsingAllocationException::class);
-
- $model = factory(Allocation::class)->make(['server_id' => 123]);
-
- $this->getService()->handle($model);
- }
-
- /**
- * Return an instance of the service with mocked injections.
- *
- * @return \Pterodactyl\Services\Allocations\AllocationDeletionService
- */
- private function getService(): AllocationDeletionService
- {
- return new AllocationDeletionService($this->repository);
- }
-}
diff --git a/tests/Unit/Services/Allocations/AssignmentServiceTest.php b/tests/Unit/Services/Allocations/AssignmentServiceTest.php
deleted file mode 100644
index 0e6da9035..000000000
--- a/tests/Unit/Services/Allocations/AssignmentServiceTest.php
+++ /dev/null
@@ -1,291 +0,0 @@
-node = factory(Node::class)->make();
- $this->connection = m::mock(ConnectionInterface::class);
- $this->repository = m::mock(AllocationRepositoryInterface::class);
- }
-
- /**
- * Test a non-CIDR notated IP address without a port range.
- */
- public function testIndividualIpAddressWithoutRange()
- {
- $data = [
- 'allocation_ip' => '192.168.1.1',
- 'allocation_ports' => ['2222'],
- ];
-
- $this->connection->shouldReceive('beginTransaction')->once()->withNoArgs()->andReturnNull();
- $this->repository->shouldReceive('insertIgnore')->with([
- [
- 'node_id' => $this->node->id,
- 'ip' => '192.168.1.1',
- 'port' => 2222,
- 'ip_alias' => null,
- 'server_id' => null,
- ],
- ])->once()->andReturn(true);
- $this->connection->shouldReceive('commit')->once()->withNoArgs()->andReturnNull();
-
- $this->getService()->handle($this->node, $data);
- }
-
- /**
- * Test a non-CIDR IP address with a port range provided.
- */
- public function testIndividualIpAddressWithRange()
- {
- $data = [
- 'allocation_ip' => '192.168.1.1',
- 'allocation_ports' => ['1025-1027'],
- ];
-
- $this->connection->shouldReceive('beginTransaction')->once()->withNoArgs()->andReturnNull();
- $this->repository->shouldReceive('insertIgnore')->once()->with([
- [
- 'node_id' => $this->node->id,
- 'ip' => '192.168.1.1',
- 'port' => 1025,
- 'ip_alias' => null,
- 'server_id' => null,
- ],
- [
- 'node_id' => $this->node->id,
- 'ip' => '192.168.1.1',
- 'port' => 1026,
- 'ip_alias' => null,
- 'server_id' => null,
- ],
- [
- 'node_id' => $this->node->id,
- 'ip' => '192.168.1.1',
- 'port' => 1027,
- 'ip_alias' => null,
- 'server_id' => null,
- ],
- ])->andReturn(true);
- $this->connection->shouldReceive('commit')->once()->withNoArgs()->andReturnNull();
-
- $this->getService()->handle($this->node, $data);
- }
-
- /**
- * Test a non-CIDR IP address with a single port and an alias.
- */
- public function testIndividualIPAddressWithAlias()
- {
- $data = [
- 'allocation_ip' => '192.168.1.1',
- 'allocation_ports' => ['2222'],
- 'allocation_alias' => 'my.alias.net',
- ];
-
- $this->connection->shouldReceive('beginTransaction')->once()->withNoArgs()->andReturnNull();
- $this->repository->shouldReceive('insertIgnore')->once()->with([
- [
- 'node_id' => $this->node->id,
- 'ip' => '192.168.1.1',
- 'port' => 2222,
- 'ip_alias' => 'my.alias.net',
- 'server_id' => null,
- ],
- ])->andReturn(true);
- $this->connection->shouldReceive('commit')->once()->withNoArgs()->andReturnNull();
-
- $this->getService()->handle($this->node, $data);
- }
-
- /**
- * Test that a domain name can be passed in place of an IP address.
- */
- public function testDomainNamePassedInPlaceOfIPAddress()
- {
- $data = [
- 'allocation_ip' => 'unit-test-static.pterodactyl.io',
- 'allocation_ports' => ['2222'],
- ];
-
- $this->connection->shouldReceive('beginTransaction')->once()->withNoArgs()->andReturnNull();
- $this->repository->shouldReceive('insertIgnore')->once()->with([
- [
- 'node_id' => $this->node->id,
- 'ip' => '127.0.0.1',
- 'port' => 2222,
- 'ip_alias' => null,
- 'server_id' => null,
- ],
- ])->andReturn(true);
- $this->connection->shouldReceive('commit')->once()->withNoArgs()->andReturnNull();
-
- $this->getService()->handle($this->node, $data);
- }
-
- /**
- * Test that a CIDR IP address without a range works properly.
- */
- public function testCIDRNotatedIPAddressWithoutRange()
- {
- $data = [
- 'allocation_ip' => '192.168.1.100/31',
- 'allocation_ports' => ['2222'],
- ];
-
- $this->connection->shouldReceive('beginTransaction')->once()->withNoArgs()->andReturnNull();
- $this->repository->shouldReceive('insertIgnore')->once()->with([
- [
- 'node_id' => $this->node->id,
- 'ip' => '192.168.1.100',
- 'port' => 2222,
- 'ip_alias' => null,
- 'server_id' => null,
- ],
- ])->andReturn(true);
-
- $this->repository->shouldReceive('insertIgnore')->once()->with([
- [
- 'node_id' => $this->node->id,
- 'ip' => '192.168.1.101',
- 'port' => 2222,
- 'ip_alias' => null,
- 'server_id' => null,
- ],
- ])->andReturn(true);
- $this->connection->shouldReceive('commit')->once()->withNoArgs()->andReturnNull();
-
- $this->getService()->handle($this->node, $data);
- }
-
- /**
- * Test that a CIDR IP address with a range works properly.
- */
- public function testCIDRNotatedIPAddressOutsideRangeLimit()
- {
- $this->expectException(CidrOutOfRangeException::class);
- $this->expectExceptionMessage('CIDR notation only allows masks between /25 and /32.');
-
- $data = [
- 'allocation_ip' => '192.168.1.100/20',
- 'allocation_ports' => ['2222'],
- ];
-
- $this->getService()->handle($this->node, $data);
- }
-
- /**
- * Test that an exception is thrown if there are too many ports.
- */
- public function testAllocationWithPortsExceedingLimit()
- {
- $this->expectException(TooManyPortsInRangeException::class);
- $this->expectExceptionMessage('Adding more than 1000 ports in a single range at once is not supported.');
-
- $data = [
- 'allocation_ip' => '192.168.1.1',
- 'allocation_ports' => ['5000-7000'],
- ];
-
- $this->connection->shouldReceive('beginTransaction')->once()->withNoArgs()->andReturnNull();
-
- $this->getService()->handle($this->node, $data);
- }
-
- /**
- * Test that an exception is thrown if an invalid port is provided.
- */
- public function testInvalidPortProvided()
- {
- $this->expectException(InvalidPortMappingException::class);
- $this->expectExceptionMessage('The mapping provided for test123 was invalid and could not be processed.');
-
- $data = [
- 'allocation_ip' => '192.168.1.1',
- 'allocation_ports' => ['test123'],
- ];
-
- $this->connection->shouldReceive('beginTransaction')->once()->withNoArgs()->andReturnNull();
- $this->getService()->handle($this->node, $data);
- }
-
- /**
- * Test that ports outside of defined limits throw an error.
- *
- * @param array $ports
- *
- * @dataProvider invalidPortsDataProvider
- */
- public function testPortRangeOutsideOfRangeLimits(array $ports)
- {
- $this->expectException(PortOutOfRangeException::class);
- $this->expectExceptionMessage('Ports in an allocation must be greater than 1024 and less than or equal to 65535.');
-
- $data = ['allocation_ip' => '192.168.1.1', 'allocation_ports' => $ports];
-
- $this->connection->shouldReceive('beginTransaction')->once()->withNoArgs()->andReturnNull();
- $this->getService()->handle($this->node, $data);
- }
-
- /**
- * Provide ports and ranges of ports that exceed the viable port limits for the software.
- *
- * @return array
- */
- public function invalidPortsDataProvider(): array
- {
- return [
- [['65536']],
- [['1024']],
- [['1000']],
- [['0']],
- [['65530-65540']],
- [['65540-65560']],
- [[PHP_INT_MAX]],
- ];
- }
-
- /**
- * Returns an instance of the service with mocked dependencies for testing.
- *
- * @return \Pterodactyl\Services\Allocations\AssignmentService
- */
- private function getService(): AssignmentService
- {
- return new AssignmentService($this->repository, $this->connection);
- }
-}
diff --git a/tests/Unit/Services/Databases/DatabasePasswordServiceTest.php b/tests/Unit/Services/Databases/DatabasePasswordServiceTest.php
deleted file mode 100644
index 226723e9d..000000000
--- a/tests/Unit/Services/Databases/DatabasePasswordServiceTest.php
+++ /dev/null
@@ -1,92 +0,0 @@
-connection = m::mock(ConnectionInterface::class);
- $this->dynamic = m::mock(DynamicDatabaseConnection::class);
- $this->encrypter = m::mock(Encrypter::class);
- $this->repository = m::mock(DatabaseRepositoryInterface::class);
- }
-
- /**
- * Test that a password can be updated.
- */
- public function testPasswordIsChanged()
- {
- /** @var \Pterodactyl\Models\Database $model */
- $model = factory(Database::class)->make(['max_connections' => 0]);
-
- $this->connection->expects('transaction')->with(m::on(function ($closure) {
- return is_null($closure());
- }));
-
- $this->dynamic->expects('set')->with('dynamic', $model->database_host_id)->andReturnNull();
-
- $this->encrypter->expects('encrypt')->with(m::on(function ($string) {
- preg_match_all('/[!@+=.^-]/', $string, $matches, PREG_SET_ORDER);
- $this->assertTrue(count($matches) >= 2 && count($matches) <= 6, "Failed asserting that [{$string}] contains 2 to 6 special characters.");
- $this->assertTrue(strlen($string) === 24, "Failed asserting that [{$string}] is 24 characters in length.");
-
- return true;
- }))->andReturn('enc123');
-
- $this->repository->expects('withoutFreshModel')->withNoArgs()->andReturnSelf();
- $this->repository->expects('update')->with($model->id, ['password' => 'enc123'])->andReturn(true);
-
- $this->repository->expects('dropUser')->with($model->username, $model->remote)->andReturn(true);
- $this->repository->expects('createUser')->with($model->username, $model->remote, m::any(), 0)->andReturn(true);
- $this->repository->expects('assignUserToDatabase')->with($model->database, $model->username, $model->remote)->andReturn(true);
- $this->repository->expects('flush')->withNoArgs()->andReturn(true);
-
- $response = $this->getService()->handle($model);
- $this->assertNotEmpty($response);
- }
-
- /**
- * Return an instance of the service with mocked dependencies.
- *
- * @return \Pterodactyl\Services\Databases\DatabasePasswordService
- */
- private function getService(): DatabasePasswordService
- {
- return new DatabasePasswordService($this->connection, $this->repository, $this->dynamic, $this->encrypter);
- }
-}
diff --git a/tests/Unit/Services/Databases/Hosts/HostCreationServiceTest.php b/tests/Unit/Services/Databases/Hosts/HostCreationServiceTest.php
deleted file mode 100644
index 41fbb5de2..000000000
--- a/tests/Unit/Services/Databases/Hosts/HostCreationServiceTest.php
+++ /dev/null
@@ -1,103 +0,0 @@
-connection = m::mock(ConnectionInterface::class);
- $this->databaseManager = m::mock(DatabaseManager::class);
- $this->dynamic = m::mock(DynamicDatabaseConnection::class);
- $this->encrypter = m::mock(Encrypter::class);
- $this->repository = m::mock(DatabaseHostRepositoryInterface::class);
- }
-
- /**
- * Test that a database host can be created.
- */
- public function testDatabaseHostIsCreated()
- {
- $model = factory(DatabaseHost::class)->make();
-
- $this->connection->expects('transaction')->with(m::on(function ($closure) {
- return ! is_null($closure());
- }))->andReturn($model);
-
- $this->encrypter->expects('encrypt')->with('test123')->andReturn('enc123');
- $this->repository->expects('create')->with(m::subset([
- 'password' => 'enc123',
- 'username' => $model->username,
- 'node_id' => $model->node_id,
- ]))->andReturn($model);
-
- $this->dynamic->expects('set')->with('dynamic', $model)->andReturnNull();
- $this->databaseManager->expects('connection')->with('dynamic')->andReturnSelf();
- $this->databaseManager->expects('select')->with('SELECT 1 FROM dual')->andReturnNull();
-
- $response = $this->getService()->handle([
- 'password' => 'test123',
- 'username' => $model->username,
- 'node_id' => $model->node_id,
- ]);
-
- $this->assertNotEmpty($response);
- $this->assertSame($model, $response);
- }
-
- /**
- * Return an instance of the service with mocked dependencies.
- *
- * @return \Pterodactyl\Services\Databases\Hosts\HostCreationService
- */
- private function getService(): HostCreationService
- {
- return new HostCreationService(
- $this->connection,
- $this->databaseManager,
- $this->repository,
- $this->dynamic,
- $this->encrypter
- );
- }
-}
diff --git a/tests/Unit/Services/Databases/Hosts/HostDeletionServiceTest.php b/tests/Unit/Services/Databases/Hosts/HostDeletionServiceTest.php
deleted file mode 100644
index 092ceb6f8..000000000
--- a/tests/Unit/Services/Databases/Hosts/HostDeletionServiceTest.php
+++ /dev/null
@@ -1,85 +0,0 @@
-databaseRepository = m::mock(DatabaseRepositoryInterface::class);
- $this->repository = m::mock(DatabaseHostRepositoryInterface::class);
- }
-
- /**
- * Test that a host can be deleted.
- */
- public function testHostIsDeleted()
- {
- $this->databaseRepository->shouldReceive('findCountWhere')->with([['database_host_id', '=', 1234]])->once()->andReturn(0);
- $this->repository->shouldReceive('delete')->with(1234)->once()->andReturn(1);
-
- $response = $this->getService()->handle(1234);
- $this->assertNotEmpty($response);
- $this->assertSame(1, $response);
- }
-
- /**
- * Test that an exception is thrown if a host with databases is deleted.
- *
- * @dataProvider databaseCountDataProvider
- */
- public function testExceptionIsThrownIfDeletingHostWithDatabases(int $count)
- {
- $this->databaseRepository->shouldReceive('findCountWhere')->with([['database_host_id', '=', 1234]])->once()->andReturn($count);
-
- try {
- $this->getService()->handle(1234);
- } catch (PterodactylException $exception) {
- $this->assertInstanceOf(HasActiveServersException::class, $exception);
- $this->assertEquals(trans('exceptions.databases.delete_has_databases'), $exception->getMessage());
- }
- }
-
- /**
- * Data provider to ensure exceptions are thrown for any value > 0.
- *
- * @return array
- */
- public function databaseCountDataProvider(): array
- {
- return [[1], [2], [10]];
- }
-
- /**
- * Return an instance of the service with mocked dependencies.
- *
- * @return \Pterodactyl\Services\Databases\Hosts\HostDeletionService
- */
- private function getService(): HostDeletionService
- {
- return new HostDeletionService($this->databaseRepository, $this->repository);
- }
-}
diff --git a/tests/Unit/Services/Databases/Hosts/HostUpdateServiceTest.php b/tests/Unit/Services/Databases/Hosts/HostUpdateServiceTest.php
deleted file mode 100644
index 18bf336ef..000000000
--- a/tests/Unit/Services/Databases/Hosts/HostUpdateServiceTest.php
+++ /dev/null
@@ -1,114 +0,0 @@
-connection = m::mock(ConnectionInterface::class);
- $this->databaseManager = m::mock(DatabaseManager::class);
- $this->dynamic = m::mock(DynamicDatabaseConnection::class);
- $this->encrypter = m::mock(Encrypter::class);
- $this->repository = m::mock(DatabaseHostRepositoryInterface::class);
- }
-
- /**
- * Test that a password is encrypted before storage if provided.
- */
- public function testPasswordIsEncryptedWhenProvided()
- {
- $model = factory(DatabaseHost::class)->make();
-
- $this->connection->expects('transaction')->with(m::on(function ($closure) {
- return ! is_null($closure());
- }))->andReturn($model);
-
- $this->encrypter->expects('encrypt')->with('test123')->andReturn('enc123');
- $this->repository->expects('update')->with(1234, ['password' => 'enc123'])->andReturn($model);
- $this->dynamic->expects('set')->with('dynamic', $model)->andReturnNull();
- $this->databaseManager->expects('connection')->with('dynamic')->andReturnSelf();
- $this->databaseManager->expects('select')->with('SELECT 1 FROM dual')->andReturnNull();
-
- $response = $this->getService()->handle(1234, ['password' => 'test123']);
- $this->assertNotEmpty($response);
- $this->assertSame($model, $response);
- }
-
- /**
- * Test that updates still occur when no password is provided.
- */
- public function testUpdateOccursWhenNoPasswordIsProvided()
- {
- $model = factory(DatabaseHost::class)->make();
-
- $this->connection->expects('transaction')->with(m::on(function ($closure) {
- return ! is_null($closure());
- }))->andReturn($model);
-
- $this->repository->expects('update')->with(1234, ['username' => 'test'])->andReturn($model);
- $this->dynamic->expects('set')->with('dynamic', $model)->andReturnNull();
- $this->databaseManager->expects('connection')->with('dynamic')->andReturnSelf();
- $this->databaseManager->expects('select')->with('SELECT 1 FROM dual')->andReturnNull();
-
- $response = $this->getService()->handle(1234, ['password' => '', 'username' => 'test']);
- $this->assertNotEmpty($response);
- $this->assertSame($model, $response);
- }
-
- /**
- * Return an instance of the service with mocked dependencies.
- *
- * @return \Pterodactyl\Services\Databases\Hosts\HostUpdateService
- */
- private function getService(): HostUpdateService
- {
- return new HostUpdateService(
- $this->connection,
- $this->databaseManager,
- $this->repository,
- $this->dynamic,
- $this->encrypter
- );
- }
-}
diff --git a/tests/Unit/Services/Eggs/EggCreationServiceTest.php b/tests/Unit/Services/Eggs/EggCreationServiceTest.php
deleted file mode 100644
index 2b042571f..000000000
--- a/tests/Unit/Services/Eggs/EggCreationServiceTest.php
+++ /dev/null
@@ -1,145 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Services\Services\Options;
-
-use Mockery as m;
-use Tests\TestCase;
-use Pterodactyl\Models\Egg;
-use Tests\Traits\MocksUuids;
-use Illuminate\Contracts\Config\Repository;
-use Pterodactyl\Exceptions\PterodactylException;
-use Pterodactyl\Services\Eggs\EggCreationService;
-use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
-use Pterodactyl\Exceptions\Service\Egg\NoParentConfigurationFoundException;
-
-class EggCreationServiceTest extends TestCase
-{
- use MocksUuids;
-
- /**
- * @var \Illuminate\Contracts\Config\Repository|\Mockery\Mock
- */
- protected $config;
-
- /**
- * @var \Pterodactyl\Contracts\Repository\EggRepositoryInterface|\Mockery\Mock
- */
- protected $repository;
-
- /**
- * @var \Pterodactyl\Services\Eggs\EggCreationService
- */
- protected $service;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->config = m::mock(Repository::class);
- $this->repository = m::mock(EggRepositoryInterface::class);
-
- $this->service = new EggCreationService($this->config, $this->repository);
- }
-
- /**
- * Test that a new model is created when not using the config from attribute.
- */
- public function testCreateNewModelWithoutUsingConfigFrom()
- {
- $model = factory(Egg::class)->make();
-
- $this->config->shouldReceive('get')->with('pterodactyl.service.author')->once()->andReturn('test@example.com');
- $this->repository->shouldReceive('create')->with([
- 'uuid' => $this->getKnownUuid(),
- 'author' => 'test@example.com',
- 'config_from' => null,
- 'name' => $model->name,
- ], true, true)->once()->andReturn($model);
-
- $response = $this->service->handle(['name' => $model->name]);
-
- $this->assertNotEmpty($response);
- $this->assertNull(object_get($response, 'config_from'));
- $this->assertEquals($model->name, $response->name);
- }
-
- /**
- * Test that a new model is created when using the config from attribute.
- */
- public function testCreateNewModelUsingConfigFrom()
- {
- $model = factory(Egg::class)->make();
-
- $this->repository->shouldReceive('findCountWhere')->with([
- ['nest_id', '=', $model->nest_id],
- ['id', '=', 12345],
- ])->once()->andReturn(1);
-
- $this->config->shouldReceive('get')->with('pterodactyl.service.author')->once()->andReturn('test@example.com');
- $this->repository->shouldReceive('create')->with([
- 'nest_id' => $model->nest_id,
- 'config_from' => 12345,
- 'uuid' => $this->getKnownUuid(),
- 'author' => 'test@example.com',
- ], true, true)->once()->andReturn($model);
-
- $response = $this->service->handle([
- 'nest_id' => $model->nest_id,
- 'config_from' => 12345,
- ]);
-
- $this->assertNotEmpty($response);
- $this->assertEquals($response, $model);
- }
-
- /**
- * Test that certain data, such as the UUID or author takes priority over data
- * that is passed into the function.
- */
- public function testDataProvidedByHandlerTakesPriorityOverPassedData()
- {
- $model = factory(Egg::class)->make();
-
- $this->config->shouldReceive('get')->with('pterodactyl.service.author')->once()->andReturn('test@example.com');
- $this->repository->shouldReceive('create')->with([
- 'uuid' => $this->getKnownUuid(),
- 'author' => 'test@example.com',
- 'config_from' => null,
- 'name' => $model->name,
- ], true, true)->once()->andReturn($model);
-
- $response = $this->service->handle(['name' => $model->name, 'uuid' => 'should-be-ignored', 'author' => 'should-be-ignored']);
-
- $this->assertNotEmpty($response);
- $this->assertNull(object_get($response, 'config_from'));
- $this->assertEquals($model->name, $response->name);
- }
-
- /**
- * Test that an exception is thrown if no parent configuration can be located.
- */
- public function testExceptionIsThrownIfNoParentConfigurationIsFound()
- {
- $this->repository->shouldReceive('findCountWhere')->with([
- ['nest_id', '=', null],
- ['id', '=', 1],
- ])->once()->andReturn(0);
-
- try {
- $this->service->handle(['config_from' => 1]);
- } catch (PterodactylException $exception) {
- $this->assertInstanceOf(NoParentConfigurationFoundException::class, $exception);
- $this->assertEquals(trans('exceptions.nest.egg.must_be_child'), $exception->getMessage());
- }
- }
-}
diff --git a/tests/Unit/Services/Eggs/EggDeletionServiceTest.php b/tests/Unit/Services/Eggs/EggDeletionServiceTest.php
deleted file mode 100644
index bfc93f4b7..000000000
--- a/tests/Unit/Services/Eggs/EggDeletionServiceTest.php
+++ /dev/null
@@ -1,93 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Services\Services\Options;
-
-use Mockery as m;
-use Tests\TestCase;
-use Pterodactyl\Exceptions\PterodactylException;
-use Pterodactyl\Services\Eggs\EggDeletionService;
-use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
-use Pterodactyl\Exceptions\Service\Egg\HasChildrenException;
-use Pterodactyl\Exceptions\Service\HasActiveServersException;
-use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
-
-class EggDeletionServiceTest extends TestCase
-{
- /**
- * @var \Pterodactyl\Contracts\Repository\EggRepositoryInterface|\Mockery\Mock
- */
- protected $repository;
-
- /**
- * @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface|\Mockery\Mock
- */
- protected $serverRepository;
-
- /**
- * @var \Pterodactyl\Services\Eggs\EggDeletionService
- */
- protected $service;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->repository = m::mock(EggRepositoryInterface::class);
- $this->serverRepository = m::mock(ServerRepositoryInterface::class);
-
- $this->service = new EggDeletionService($this->serverRepository, $this->repository);
- }
-
- /**
- * Test that Egg is deleted if no servers are found.
- */
- public function testEggIsDeletedIfNoServersAreFound()
- {
- $this->serverRepository->shouldReceive('findCountWhere')->with([['egg_id', '=', 1]])->once()->andReturn(0);
- $this->repository->shouldReceive('findCountWhere')->with([['config_from', '=', 1]])->once()->andReturn(0);
- $this->repository->shouldReceive('delete')->with(1)->once()->andReturn(1);
-
- $this->assertEquals(1, $this->service->handle(1));
- }
-
- /**
- * Test that Egg is not deleted if servers are found.
- */
- public function testExceptionIsThrownIfServersAreFound()
- {
- $this->serverRepository->shouldReceive('findCountWhere')->with([['egg_id', '=', 1]])->once()->andReturn(1);
-
- try {
- $this->service->handle(1);
- } catch (PterodactylException $exception) {
- $this->assertInstanceOf(HasActiveServersException::class, $exception);
- $this->assertEquals(trans('exceptions.nest.egg.delete_has_servers'), $exception->getMessage());
- }
- }
-
- /**
- * Test that an exception is thrown if children Eggs exist.
- */
- public function testExceptionIsThrownIfChildrenArePresent()
- {
- $this->serverRepository->shouldReceive('findCountWhere')->with([['egg_id', '=', 1]])->once()->andReturn(0);
- $this->repository->shouldReceive('findCountWhere')->with([['config_from', '=', 1]])->once()->andReturn(1);
-
- try {
- $this->service->handle(1);
- } catch (PterodactylException $exception) {
- $this->assertInstanceOf(HasChildrenException::class, $exception);
- $this->assertEquals(trans('exceptions.nest.egg.has_children'), $exception->getMessage());
- }
- }
-}
diff --git a/tests/Unit/Services/Eggs/EggUpdateServiceTest.php b/tests/Unit/Services/Eggs/EggUpdateServiceTest.php
deleted file mode 100644
index 22104995e..000000000
--- a/tests/Unit/Services/Eggs/EggUpdateServiceTest.php
+++ /dev/null
@@ -1,91 +0,0 @@
-model = factory(Egg::class)->make(['id' => 123]);
- $this->repository = m::mock(EggRepositoryInterface::class);
-
- $this->service = new EggUpdateService($this->repository);
- }
-
- /**
- * Test that an Egg is updated when no config_from attribute is passed.
- */
- public function testEggIsUpdatedWhenNoConfigFromIsProvided()
- {
- $this->repository->shouldReceive('withoutFreshModel->update')
- ->with($this->model->id, ['test_field' => 'field_value'])->once()->andReturnNull();
-
- $this->service->handle($this->model, ['test_field' => 'field_value']);
-
- $this->assertTrue(true);
- }
-
- /**
- * Test that Egg is updated when a valid config_from attribute is passed.
- */
- public function testOptionIsUpdatedWhenValidConfigFromIsPassed()
- {
- $this->repository->shouldReceive('findCountWhere')->with([
- ['nest_id', '=', $this->model->nest_id],
- ['id', '=', 1],
- ])->once()->andReturn(1);
-
- $this->repository->shouldReceive('withoutFreshModel->update')
- ->with($this->model->id, ['config_from' => 1])->once()->andReturnNull();
-
- $this->service->handle($this->model, ['config_from' => 1]);
-
- $this->assertTrue(true);
- }
-
- /**
- * Test that an exception is thrown if an invalid config_from attribute is passed.
- */
- public function testExceptionIsThrownIfInvalidParentConfigIsPassed()
- {
- $this->repository->shouldReceive('findCountWhere')->with([
- ['nest_id', '=', $this->model->nest_id],
- ['id', '=', 1],
- ])->once()->andReturn(0);
-
- try {
- $this->service->handle($this->model, ['config_from' => 1]);
- } catch (PterodactylException $exception) {
- $this->assertInstanceOf(NoParentConfigurationFoundException::class, $exception);
- $this->assertEquals(trans('exceptions.nest.egg.must_be_child'), $exception->getMessage());
- }
- }
-}
diff --git a/tests/Unit/Services/Eggs/Scripts/InstallScriptServiceTest.php b/tests/Unit/Services/Eggs/Scripts/InstallScriptServiceTest.php
deleted file mode 100644
index cf3987937..000000000
--- a/tests/Unit/Services/Eggs/Scripts/InstallScriptServiceTest.php
+++ /dev/null
@@ -1,87 +0,0 @@
- 'test-script',
- 'script_is_privileged' => true,
- 'script_entry' => '/bin/bash',
- 'script_container' => 'ubuntu',
- 'copy_script_from' => null,
- ];
-
- /**
- * @var \Pterodactyl\Contracts\Repository\EggRepositoryInterface|\Mockery\Mock
- */
- protected $repository;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->repository = m::mock(EggRepositoryInterface::class);
- }
-
- /**
- * Test that passing a new copy_script_from attribute works properly.
- */
- public function testUpdateWithValidCopyScriptFromAttribute()
- {
- $model = factory(Egg::class)->make(['id' => 123, 'nest_id' => 456]);
- $this->data['copy_script_from'] = 1;
-
- $this->repository->shouldReceive('isCopyableScript')->with(1, $model->nest_id)->once()->andReturn(true);
- $this->repository->expects('withoutFreshModel->update')->with($model->id, $this->data)->andReturnNull();
-
- $this->getService()->handle($model, $this->data);
- }
-
- /**
- * Test that an exception gets raised when the script is not copyable.
- */
- public function testUpdateWithInvalidCopyScriptFromAttribute()
- {
- $this->data['copy_script_from'] = 1;
-
- $this->expectException(InvalidCopyFromException::class);
- $this->expectExceptionMessage(trans('exceptions.nest.egg.invalid_copy_id'));
-
- $model = factory(Egg::class)->make(['id' => 123, 'nest_id' => 456]);
-
- $this->repository->expects('isCopyableScript')->with(1, $model->nest_id)->andReturn(false);
- $this->getService()->handle($model, $this->data);
- }
-
- /**
- * Test standard functionality.
- */
- public function testUpdateWithoutNewCopyScriptFromAttribute()
- {
- $model = factory(Egg::class)->make(['id' => 123, 'nest_id' => 456]);
-
- $this->repository->expects('withoutFreshModel->update')->with($model->id, $this->data)->andReturnNull();
-
- $this->getService()->handle($model, $this->data);
- }
-
- private function getService()
- {
- return new InstallScriptService($this->repository);
- }
-}
diff --git a/tests/Unit/Services/Eggs/Sharing/EggExporterServiceTest.php b/tests/Unit/Services/Eggs/Sharing/EggExporterServiceTest.php
deleted file mode 100644
index 630f7e106..000000000
--- a/tests/Unit/Services/Eggs/Sharing/EggExporterServiceTest.php
+++ /dev/null
@@ -1,69 +0,0 @@
-repository = m::mock(EggRepositoryInterface::class);
- }
-
- /**
- * Test that a JSON structure is returned.
- */
- public function testJsonStructureIsExported()
- {
- $egg = factory(Egg::class)->make([
- 'id' => 123,
- 'nest_id' => 456,
- ]);
- $egg->variables = collect([$variable = factory(EggVariable::class)->make()]);
-
- $this->repository->shouldReceive('getWithExportAttributes')->with($egg->id)->once()->andReturn($egg);
-
- $service = new EggExporterService($this->repository);
-
- $response = $service->handle($egg->id);
- $this->assertNotEmpty($response);
-
- $data = json_decode($response);
- $this->assertEquals(JSON_ERROR_NONE, json_last_error());
- $this->assertObjectHasNestedAttribute('meta.version', $data);
- $this->assertObjectNestedValueEquals('meta.version', 'PTDL_v1', $data);
- $this->assertObjectHasNestedAttribute('author', $data);
- $this->assertObjectNestedValueEquals('author', $egg->author, $data);
- $this->assertObjectHasNestedAttribute('exported_at', $data);
- $this->assertObjectNestedValueEquals('exported_at', Carbon::now()->toIso8601String(), $data);
- $this->assertObjectHasNestedAttribute('scripts.installation.script', $data);
- $this->assertObjectHasNestedAttribute('scripts.installation.container', $data);
- $this->assertObjectHasNestedAttribute('scripts.installation.entrypoint', $data);
- $this->assertObjectHasAttribute('variables', $data);
- $this->assertArrayHasKey('0', $data->variables);
- $this->assertObjectHasAttribute('name', $data->variables[0]);
- $this->assertObjectNestedValueEquals('name', $variable->name, $data->variables[0]);
- }
-}
diff --git a/tests/Unit/Services/Eggs/Sharing/EggImporterServiceTest.php b/tests/Unit/Services/Eggs/Sharing/EggImporterServiceTest.php
deleted file mode 100644
index 0d53d5a7e..000000000
--- a/tests/Unit/Services/Eggs/Sharing/EggImporterServiceTest.php
+++ /dev/null
@@ -1,187 +0,0 @@
-file = m::mock(UploadedFile::class);
- $this->connection = m::mock(ConnectionInterface::class);
- $this->eggVariableRepository = m::mock(EggVariableRepositoryInterface::class);
- $this->nestRepository = m::mock(NestRepositoryInterface::class);
- $this->repository = m::mock(EggRepositoryInterface::class);
-
- $this->service = new EggImporterService(
- $this->connection, $this->repository, $this->eggVariableRepository, $this->nestRepository
- );
- }
-
- /**
- * Test that a service option can be successfully imported.
- */
- public function testEggConfigurationIsImported()
- {
- $egg = factory(Egg::class)->make(['id' => 123]);
- $nest = factory(Nest::class)->make(['id' => 456]);
-
- $this->file->expects('getError')->andReturn(UPLOAD_ERR_OK);
- $this->file->expects('isFile')->andReturn(true);
- $this->file->expects('getSize')->andReturn(100);
-
- $this->file->expects('openFile->fread')->with(100)->once()->andReturn(json_encode([
- 'meta' => ['version' => 'PTDL_v1'],
- 'name' => $egg->name,
- 'author' => $egg->author,
- 'variables' => [
- $variable = factory(EggVariable::class)->make(),
- ],
- ]));
- $this->nestRepository->shouldReceive('getWithEggs')->with($nest->id)->once()->andReturn($nest);
-
- $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
- $this->repository->shouldReceive('create')->with(m::subset([
- 'uuid' => $this->getKnownUuid(),
- 'nest_id' => $nest->id,
- 'name' => $egg->name,
- ]), true, true)->once()->andReturn($egg);
-
- $this->eggVariableRepository->shouldReceive('create')->with(m::subset([
- 'egg_id' => $egg->id,
- 'env_variable' => $variable->env_variable,
- ]))->once()->andReturnNull();
- $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull();
-
- $response = $this->service->handle($this->file, $nest->id);
- $this->assertNotEmpty($response);
- $this->assertInstanceOf(Egg::class, $response);
- $this->assertSame($egg, $response);
- }
-
- /**
- * Test that an exception is thrown if the file is invalid.
- */
- public function testExceptionIsThrownIfFileIsInvalid()
- {
- $this->expectException(InvalidFileUploadException::class);
- $this->expectExceptionMessage(
- 'The selected file ["test.txt"] was not in a valid format to import. (is_file: true is_valid: true err_code: 4 err: UPLOAD_ERR_NO_FILE)'
- );
-
- $this->file->expects('getFilename')->andReturns('test.txt');
- $this->file->expects('isFile')->andReturns(true);
- $this->file->expects('isValid')->andReturns(true);
- $this->file->expects('getError')->twice()->andReturns(UPLOAD_ERR_NO_FILE);
- $this->file->expects('getErrorMessage')->andReturns('UPLOAD_ERR_NO_FILE');
-
- $this->service->handle($this->file, 1234);
- }
-
- /**
- * Test that an exception is thrown if the file is not a file.
- */
- public function testExceptionIsThrownIfFileIsNotAFile()
- {
- $this->expectException(InvalidFileUploadException::class);
- $this->expectExceptionMessage(
- 'The selected file ["test.txt"] was not in a valid format to import. (is_file: false is_valid: true err_code: 4 err: UPLOAD_ERR_NO_FILE)'
- );
-
- $this->file->expects('getFilename')->andReturns('test.txt');
- $this->file->expects('isFile')->andReturns(false);
- $this->file->expects('isValid')->andReturns(true);
- $this->file->expects('getError')->twice()->andReturns(UPLOAD_ERR_NO_FILE);
- $this->file->expects('getErrorMessage')->andReturns('UPLOAD_ERR_NO_FILE');
-
- $this->service->handle($this->file, 1234);
- }
-
- /**
- * Test that an exception is thrown if the JSON metadata is invalid.
- */
- public function testExceptionIsThrownIfJsonMetaDataIsInvalid()
- {
- $this->expectException(InvalidFileUploadException::class);
- $this->expectExceptionMessage(trans('exceptions.nest.importer.invalid_json_provided'));
-
- $this->file->expects('getError')->andReturn(UPLOAD_ERR_OK);
- $this->file->expects('isFile')->andReturn(true);
- $this->file->expects('getSize')->andReturn(100);
-
- $this->file->expects('openFile->fread')->with(100)->andReturn(json_encode([
- 'meta' => ['version' => 'hodor'],
- ]));
-
- $this->service->handle($this->file, 1234);
- }
-
- /**
- * Test that an exception is thrown if bad JSON is provided.
- */
- public function testExceptionIsThrownIfBadJsonIsProvided()
- {
- $this->expectException(BadJsonFormatException::class);
- $this->expectExceptionMessage(trans('exceptions.nest.importer.json_error', [
- 'error' => 'Syntax error',
- ]));
-
- $this->file->expects('getError')->andReturn(UPLOAD_ERR_OK);
- $this->file->expects('isFile')->andReturn(true);
- $this->file->expects('getSize')->andReturn(100);
- $this->file->expects('openFile->fread')->with(100)->andReturn('}');
-
- $this->service->handle($this->file, 1234);
- }
-}
diff --git a/tests/Unit/Services/Eggs/Sharing/EggUpdateImporterServiceTest.php b/tests/Unit/Services/Eggs/Sharing/EggUpdateImporterServiceTest.php
deleted file mode 100644
index a73fc1cda..000000000
--- a/tests/Unit/Services/Eggs/Sharing/EggUpdateImporterServiceTest.php
+++ /dev/null
@@ -1,219 +0,0 @@
-connection = m::mock(ConnectionInterface::class);
- $this->file = m::mock(UploadedFile::class);
- $this->repository = m::mock(EggRepositoryInterface::class);
- $this->variableRepository = m::mock(EggVariableRepositoryInterface::class);
-
- $this->service = new EggUpdateImporterService($this->connection, $this->repository, $this->variableRepository);
- }
-
- /**
- * Test that an egg update is handled correctly using an uploaded file.
- */
- public function testEggIsUpdated()
- {
- $egg = factory(Egg::class)->make(['id' => 123]);
- $variable = factory(EggVariable::class)->make();
-
- $this->file->shouldReceive('getError')->withNoArgs()->once()->andReturn(UPLOAD_ERR_OK);
- $this->file->shouldReceive('isFile')->withNoArgs()->once()->andReturn(true);
- $this->file->shouldReceive('getSize')->withNoArgs()->once()->andReturn(100);
- $this->file->shouldReceive('openFile->fread')->with(100)->once()->andReturn(json_encode([
- 'meta' => ['version' => 'PTDL_v1'],
- 'name' => $egg->name,
- 'author' => 'newauthor@example.com',
- 'variables' => [$variable->toArray()],
- ]));
-
- $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
- $this->repository->shouldReceive('update')->with($egg->id, m::subset([
- 'author' => 'newauthor@example.com',
- 'name' => $egg->name,
- ]), true, true)->once()->andReturn($egg);
-
- $this->variableRepository->shouldReceive('withoutFreshModel->updateOrCreate')->with([
- 'egg_id' => $egg->id,
- 'env_variable' => $variable->env_variable,
- ], collect($variable)->except(['egg_id', 'env_variable'])->toArray())->once()->andReturnNull();
-
- $this->variableRepository->shouldReceive('setColumns')->with(['id', 'env_variable'])->once()->andReturnSelf()
- ->shouldReceive('findWhere')->with([['egg_id', '=', $egg->id]])->once()->andReturn(collect([$variable]));
-
- $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull();
-
- $this->service->handle($egg, $this->file);
- $this->assertTrue(true);
- }
-
- /**
- * Test that an imported file with less variables than currently existing deletes
- * the un-needed variables from the database.
- */
- public function testVariablesMissingFromImportAreDeleted()
- {
- $egg = factory(Egg::class)->make(['id' => 123]);
- $variable1 = factory(EggVariable::class)->make();
- $variable2 = factory(EggVariable::class)->make();
-
- $this->file->shouldReceive('getError')->withNoArgs()->once()->andReturn(UPLOAD_ERR_OK);
- $this->file->shouldReceive('isFile')->withNoArgs()->once()->andReturn(true);
- $this->file->shouldReceive('getSize')->withNoArgs()->once()->andReturn(100);
- $this->file->shouldReceive('openFile->fread')->with(100)->once()->andReturn(json_encode([
- 'meta' => ['version' => 'PTDL_v1'],
- 'name' => $egg->name,
- 'author' => 'newauthor@example.com',
- 'variables' => [$variable1->toArray()],
- ]));
-
- $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
- $this->repository->shouldReceive('update')->with($egg->id, m::subset([
- 'author' => 'newauthor@example.com',
- 'name' => $egg->name,
- ]), true, true)->once()->andReturn($egg);
-
- $this->variableRepository->shouldReceive('withoutFreshModel->updateOrCreate')->with([
- 'egg_id' => $egg->id,
- 'env_variable' => $variable1->env_variable,
- ], collect($variable1)->except(['egg_id', 'env_variable'])->toArray())->once()->andReturnNull();
-
- $this->variableRepository->shouldReceive('setColumns')->with(['id', 'env_variable'])->once()->andReturnSelf()
- ->shouldReceive('findWhere')->with([['egg_id', '=', $egg->id]])->once()->andReturn(collect([$variable1, $variable2]));
-
- $this->variableRepository->shouldReceive('deleteWhere')->with([
- ['egg_id', '=', $egg->id],
- ['env_variable', '=', $variable2->env_variable],
- ])->once()->andReturn(1);
-
- $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull();
-
- $this->service->handle($egg, $this->file);
- $this->assertTrue(true);
- }
-
- /**
- * Test that an exception is thrown if the file is invalid.
- */
- public function testExceptionIsThrownIfFileIsInvalid()
- {
- $egg = factory(Egg::class)->make(['id' => 123]);
-
- $this->expectException(InvalidFileUploadException::class);
- $this->expectExceptionMessageMatches('/^The selected file \["test\.txt"\] was not in a valid format to import\./');
- $file = new UploadedFile('test.txt', 'original.txt', 'application/json', UPLOAD_ERR_NO_FILE, true);
-
- $this->service->handle($egg, $file);
- }
-
- /**
- * Test that an exception is thrown if the file is not a file.
- */
- public function testExceptionIsThrownIfFileIsNotAFile()
- {
- $egg = factory(Egg::class)->make(['id' => 123]);
-
- $this->expectException(InvalidFileUploadException::class);
- $this->expectExceptionMessageMatches('/^The selected file \["test\.txt"\] was not in a valid format to import\./');
-
- $file = m::mock(
- new UploadedFile('test.txt', 'original.txt', 'application/json', UPLOAD_ERR_INI_SIZE, true)
- )->makePartial();
-
- $file->expects('isFile')->andReturnFalse();
-
- $this->service->handle($egg, $file);
- }
-
- /**
- * Test that an exception is thrown if the JSON metadata is invalid.
- */
- public function testExceptionIsThrownIfJsonMetaDataIsInvalid()
- {
- $egg = factory(Egg::class)->make(['id' => 123]);
-
- $this->file->shouldReceive('getError')->withNoArgs()->once()->andReturn(UPLOAD_ERR_OK);
- $this->file->shouldReceive('isFile')->withNoArgs()->once()->andReturn(true);
- $this->file->shouldReceive('getSize')->withNoArgs()->once()->andReturn(100);
- $this->file->shouldReceive('openFile->fread')->with(100)->once()->andReturn(json_encode([
- 'meta' => ['version' => 'hodor'],
- ]));
-
- try {
- $this->service->handle($egg, $this->file);
- } catch (PterodactylException $exception) {
- $this->assertInstanceOf(InvalidFileUploadException::class, $exception);
- $this->assertEquals(trans('exceptions.nest.importer.invalid_json_provided'), $exception->getMessage());
- }
- }
-
- /**
- * Test that an exception is thrown if bad JSON is provided.
- */
- public function testExceptionIsThrownIfBadJsonIsProvided()
- {
- $egg = factory(Egg::class)->make(['id' => 123]);
-
- $this->file->shouldReceive('getError')->withNoArgs()->once()->andReturn(UPLOAD_ERR_OK);
- $this->file->shouldReceive('isFile')->withNoArgs()->once()->andReturn(true);
- $this->file->shouldReceive('getSize')->withNoArgs()->once()->andReturn(100);
- $this->file->shouldReceive('openFile->fread')->with(100)->once()->andReturn('}');
-
- try {
- $this->service->handle($egg, $this->file);
- } catch (PterodactylException $exception) {
- $this->assertInstanceOf(BadJsonFormatException::class, $exception);
- $this->assertEquals(trans('exceptions.nest.importer.json_error', [
- 'error' => json_last_error_msg(),
- ]), $exception->getMessage());
- }
- }
-}
diff --git a/tests/Unit/Services/Eggs/Variables/VariableCreationServiceTest.php b/tests/Unit/Services/Eggs/Variables/VariableCreationServiceTest.php
deleted file mode 100644
index bbac6009d..000000000
--- a/tests/Unit/Services/Eggs/Variables/VariableCreationServiceTest.php
+++ /dev/null
@@ -1,185 +0,0 @@
-repository = m::mock(EggVariableRepositoryInterface::class);
- $this->validator = m::mock(Factory::class);
- }
-
- /**
- * Test basic functionality, data should be stored in the database.
- */
- public function testVariableIsCreatedAndStored()
- {
- $data = ['env_variable' => 'TEST_VAR_123', 'default_value' => 'test'];
- $this->repository->shouldReceive('create')->with(m::subset([
- 'egg_id' => 1,
- 'default_value' => 'test',
- 'user_viewable' => false,
- 'user_editable' => false,
- 'env_variable' => 'TEST_VAR_123',
- ]))->once()->andReturn(new EggVariable);
-
- $this->assertInstanceOf(EggVariable::class, $this->getService()->handle(1, $data));
- }
-
- /**
- * Test that the option key in the data array is properly parsed.
- */
- public function testOptionsPassedInArrayKeyAreParsedProperly()
- {
- $data = ['env_variable' => 'TEST_VAR_123', 'options' => ['user_viewable', 'user_editable']];
- $this->repository->shouldReceive('create')->with(m::subset([
- 'default_value' => '',
- 'user_viewable' => true,
- 'user_editable' => true,
- 'env_variable' => 'TEST_VAR_123',
- ]))->once()->andReturn(new EggVariable);
-
- $this->assertInstanceOf(EggVariable::class, $this->getService()->handle(1, $data));
- }
-
- /**
- * Test that an empty (null) value passed in the option key is handled
- * properly as an array. Also tests the same case against the default_value.
- *
- * @see https://github.com/Pterodactyl/Panel/issues/841
- * @see https://github.com/Pterodactyl/Panel/issues/943
- */
- public function testNullOptionValueIsPassedAsArray()
- {
- $data = ['env_variable' => 'TEST_VAR_123', 'options' => null, 'default_value' => null];
- $this->repository->shouldReceive('create')->with(m::subset([
- 'default_value' => '',
- 'user_viewable' => false,
- 'user_editable' => false,
- ]))->once()->andReturn(new EggVariable);
-
- $this->assertInstanceOf(EggVariable::class, $this->getService()->handle(1, $data));
- }
-
- /**
- * Test that all of the reserved variables defined in the model trigger an exception.
- *
- * @param string $variable
- *
- * @dataProvider reservedNamesProvider
- */
- public function testExceptionIsThrownIfEnvironmentVariableIsInListOfReservedNames(string $variable)
- {
- $this->expectException(ReservedVariableNameException::class);
-
- $this->getService()->handle(1, ['env_variable' => $variable]);
- }
-
- /**
- * Test that the egg ID applied in the function takes higher priority than an
- * ID passed into the handler.
- */
- public function testEggIdPassedInDataIsNotApplied()
- {
- $data = ['egg_id' => 123456, 'env_variable' => 'TEST_VAR_123'];
- $this->repository->shouldReceive('create')->with(m::subset([
- 'egg_id' => 1,
- ]))->once()->andReturn(new EggVariable);
-
- $this->assertInstanceOf(EggVariable::class, $this->getService()->handle(1, $data));
- }
-
- /**
- * Test that validation errors due to invalid rules are caught and handled properly.
- */
- public function testInvalidValidationRulesResultInException()
- {
- $this->expectException(BadValidationRuleException::class);
- $this->expectExceptionMessage('The validation rule "hodor_door" is not a valid rule for this application.');
-
- $data = ['env_variable' => 'TEST_VAR_123', 'rules' => 'string|hodorDoor'];
-
- $this->validator->shouldReceive('make')->once()
- ->with(['__TEST' => 'test'], ['__TEST' => 'string|hodorDoor'])
- ->andReturnSelf();
-
- $this->validator->shouldReceive('fails')->once()
- ->withNoArgs()
- ->andThrow(new BadMethodCallException('Method [validateHodorDoor] does not exist.'));
-
- $this->getService()->handle(1, $data);
- }
-
- /**
- * Test that an exception not stemming from a bad rule is not caught.
- */
- public function testExceptionNotCausedByBadRuleIsNotCaught()
- {
- $this->expectException(BadMethodCallException::class);
- $this->expectExceptionMessage('Received something, but no expectations were specified.');
-
- $data = ['env_variable' => 'TEST_VAR_123', 'rules' => 'string'];
-
- $this->validator->shouldReceive('make')->once()
- ->with(['__TEST' => 'test'], ['__TEST' => 'string'])
- ->andReturnSelf();
-
- $this->validator->shouldReceive('fails')->once()
- ->withNoArgs()
- ->andThrow(new BadMethodCallException('Received something, but no expectations were specified.'));
-
- $this->getService()->handle(1, $data);
- }
-
- /**
- * Provides the data to be used in the tests.
- *
- * @return array
- */
- public function reservedNamesProvider()
- {
- $data = [];
- $exploded = explode(',', EggVariable::RESERVED_ENV_NAMES);
- foreach ($exploded as $e) {
- $data[] = [$e];
- }
-
- return $data;
- }
-
- /**
- * Return an instance of the service with mocked dependencies for testing.
- *
- * @return \Pterodactyl\Services\Eggs\Variables\VariableCreationService
- */
- private function getService(): VariableCreationService
- {
- return new VariableCreationService($this->repository, $this->validator);
- }
-}
diff --git a/tests/Unit/Services/Eggs/Variables/VariableUpdateServiceTest.php b/tests/Unit/Services/Eggs/Variables/VariableUpdateServiceTest.php
deleted file mode 100644
index a812da274..000000000
--- a/tests/Unit/Services/Eggs/Variables/VariableUpdateServiceTest.php
+++ /dev/null
@@ -1,241 +0,0 @@
-model = factory(EggVariable::class)->make();
- $this->repository = m::mock(EggVariableRepositoryInterface::class);
- $this->validator = m::mock(Factory::class);
- }
-
- /**
- * Test the function when no env_variable key is passed into the function.
- */
- public function testVariableIsUpdatedWhenNoEnvironmentVariableIsPassed()
- {
- $this->repository->shouldReceive('withoutFreshModel')->withNoArgs()->once()->andReturnSelf()
- ->shouldReceive('update')->with($this->model->id, m::subset([
- 'user_viewable' => false,
- 'user_editable' => false,
- ]))->once()->andReturn(true);
-
- $this->assertTrue($this->getService()->handle($this->model, []));
- }
-
- /**
- * Test that a null value passed in for the default is converted to a string.
- *
- * @see https://github.com/Pterodactyl/Panel/issues/934
- */
- public function testNullDefaultValue()
- {
- $this->repository->shouldReceive('withoutFreshModel->update')->with($this->model->id, m::subset([
- 'user_viewable' => false,
- 'user_editable' => false,
- 'default_value' => '',
- ]))->once()->andReturn(true);
-
- $this->assertTrue($this->getService()->handle($this->model, ['default_value' => null]));
- }
-
- /**
- * Test the function when a valid env_variable key is passed into the function.
- */
- public function testVariableIsUpdatedWhenValidEnvironmentVariableIsPassed()
- {
- $this->repository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf()
- ->shouldReceive('findCountWhere')->with([
- ['env_variable', '=', 'TEST_VAR_123'],
- ['egg_id', '=', $this->model->option_id],
- ['id', '!=', $this->model->id],
- ])->once()->andReturn(0);
-
- $this->repository->shouldReceive('withoutFreshModel')->withNoArgs()->once()->andReturnSelf()
- ->shouldReceive('update')->with($this->model->id, m::subset([
- 'user_viewable' => false,
- 'user_editable' => false,
- 'env_variable' => 'TEST_VAR_123',
- ]))->once()->andReturn(true);
-
- $this->assertTrue($this->getService()->handle($this->model, ['env_variable' => 'TEST_VAR_123']));
- }
-
- /**
- * Test that an empty (null) value passed in the option key is handled
- * properly as an array. Also tests that a null description is handled.
- *
- * @see https://github.com/Pterodactyl/Panel/issues/841
- */
- public function testNullOptionValueIsPassedAsArray()
- {
- $this->repository->shouldReceive('withoutFreshModel')->withNoArgs()->once()->andReturnSelf()
- ->shouldReceive('update')->with($this->model->id, m::subset([
- 'user_viewable' => false,
- 'user_editable' => false,
- 'description' => '',
- ]))->once()->andReturn(true);
-
- $this->assertTrue($this->getService()->handle($this->model, ['options' => null, 'description' => null]));
- }
-
- /**
- * Test that data passed into the handler is overwritten inside the handler.
- */
- public function testDataPassedIntoHandlerTakesLowerPriorityThanDataSet()
- {
- $this->repository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf()
- ->shouldReceive('findCountWhere')->with([
- ['env_variable', '=', 'TEST_VAR_123'],
- ['egg_id', '=', $this->model->option_id],
- ['id', '!=', $this->model->id],
- ])->once()->andReturn(0);
-
- $this->repository->shouldReceive('withoutFreshModel')->withNoArgs()->once()->andReturnSelf()
- ->shouldReceive('update')->with($this->model->id, m::subset([
- 'user_viewable' => false,
- 'user_editable' => false,
- 'env_variable' => 'TEST_VAR_123',
- ]))->once()->andReturn(true);
-
- $this->assertTrue($this->getService()->handle($this->model, ['user_viewable' => 123456, 'env_variable' => 'TEST_VAR_123']));
- }
-
- /**
- * Test that a non-unique environment variable triggers an exception.
- */
- public function testExceptionIsThrownIfEnvironmentVariableIsNotUnique()
- {
- $this->repository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf()
- ->shouldReceive('findCountWhere')->with([
- ['env_variable', '=', 'TEST_VAR_123'],
- ['egg_id', '=', $this->model->option_id],
- ['id', '!=', $this->model->id],
- ])->once()->andReturn(1);
-
- try {
- $this->getService()->handle($this->model, ['env_variable' => 'TEST_VAR_123']);
- } catch (Exception $exception) {
- $this->assertInstanceOf(DisplayException::class, $exception);
- $this->assertEquals(trans('exceptions.service.variables.env_not_unique', [
- 'name' => 'TEST_VAR_123',
- ]), $exception->getMessage());
- }
- }
-
- /**
- * Test that all of the reserved variables defined in the model trigger an exception.
- *
- * @dataProvider reservedNamesProvider
- */
- public function testExceptionIsThrownIfEnvironmentVariableIsInListOfReservedNames(string $variable)
- {
- $this->expectException(ReservedVariableNameException::class);
-
- $this->getService()->handle($this->model, ['env_variable' => $variable]);
- }
-
- /**
- * Test that validation errors due to invalid rules are caught and handled properly.
- */
- public function testInvalidValidationRulesResultInException()
- {
- $this->expectException(BadValidationRuleException::class);
- $this->expectExceptionMessage('The validation rule "hodor_door" is not a valid rule for this application.');
-
- $data = ['env_variable' => 'TEST_VAR_123', 'rules' => 'string|hodorDoor'];
-
- $this->repository->shouldReceive('setColumns->findCountWhere')->once()->andReturn(0);
-
- $this->validator->shouldReceive('make')->once()
- ->with(['__TEST' => 'test'], ['__TEST' => 'string|hodorDoor'])
- ->andReturnSelf();
-
- $this->validator->shouldReceive('fails')->once()
- ->withNoArgs()
- ->andThrow(new BadMethodCallException('Method [validateHodorDoor] does not exist.'));
-
- $this->getService()->handle($this->model, $data);
- }
-
- /**
- * Test that an exception not stemming from a bad rule is not caught.
- */
- public function testExceptionNotCausedByBadRuleIsNotCaught()
- {
- $this->expectException(BadMethodCallException::class);
- $this->expectExceptionMessage('Received something, but no expectations were specified.');
-
- $data = ['rules' => 'string'];
-
- $this->validator->shouldReceive('make')->once()
- ->with(['__TEST' => 'test'], ['__TEST' => 'string'])
- ->andReturnSelf();
-
- $this->validator->shouldReceive('fails')->once()
- ->withNoArgs()
- ->andThrow(new BadMethodCallException('Received something, but no expectations were specified.'));
-
- $this->getService()->handle($this->model, $data);
- }
-
- /**
- * Provides the data to be used in the tests.
- *
- * @return array
- */
- public function reservedNamesProvider()
- {
- $data = [];
- $exploded = explode(',', EggVariable::RESERVED_ENV_NAMES);
- foreach ($exploded as $e) {
- $data[] = [$e];
- }
-
- return $data;
- }
-
- /**
- * Return an instance of the service with mocked dependencies for testing.
- *
- * @return \Pterodactyl\Services\Eggs\Variables\VariableUpdateService
- */
- private function getService(): VariableUpdateService
- {
- return new VariableUpdateService($this->repository, $this->validator);
- }
-}
diff --git a/tests/Unit/Services/Locations/LocationCreationServiceTest.php b/tests/Unit/Services/Locations/LocationCreationServiceTest.php
deleted file mode 100644
index a7ea91506..000000000
--- a/tests/Unit/Services/Locations/LocationCreationServiceTest.php
+++ /dev/null
@@ -1,56 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Services\Locations;
-
-use Mockery as m;
-use Tests\TestCase;
-use Pterodactyl\Models\Location;
-use Pterodactyl\Services\Locations\LocationCreationService;
-use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
-
-class LocationCreationServiceTest extends TestCase
-{
- /**
- * @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
- */
- protected $repository;
-
- /**
- * @var \Pterodactyl\Services\Locations\LocationCreationService
- */
- protected $service;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->repository = m::mock(LocationRepositoryInterface::class);
-
- $this->service = new LocationCreationService($this->repository);
- }
-
- /**
- * Test that a location is created.
- */
- public function testLocationIsCreated()
- {
- $location = factory(Location::class)->make();
-
- $this->repository->shouldReceive('create')->with(['test_data' => 'test_value'])->once()->andReturn($location);
-
- $response = $this->service->handle(['test_data' => 'test_value']);
- $this->assertNotEmpty($response);
- $this->assertInstanceOf(Location::class, $response);
- $this->assertEquals($location, $response);
- }
-}
diff --git a/tests/Unit/Services/Locations/LocationDeletionServiceTest.php b/tests/Unit/Services/Locations/LocationDeletionServiceTest.php
deleted file mode 100644
index b92874c68..000000000
--- a/tests/Unit/Services/Locations/LocationDeletionServiceTest.php
+++ /dev/null
@@ -1,76 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Services\Locations;
-
-use Mockery as m;
-use Tests\TestCase;
-use Pterodactyl\Exceptions\DisplayException;
-use Pterodactyl\Services\Locations\LocationDeletionService;
-use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
-use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
-use Pterodactyl\Exceptions\Service\Location\HasActiveNodesException;
-
-class LocationDeletionServiceTest extends TestCase
-{
- /**
- * @var \Pterodactyl\Contracts\Repository\NodeRepositoryInterface
- */
- protected $nodeRepository;
-
- /**
- * @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
- */
- protected $repository;
-
- /**
- * @var \Pterodactyl\Services\Locations\LocationDeletionService
- */
- protected $service;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->nodeRepository = m::mock(NodeRepositoryInterface::class);
- $this->repository = m::mock(LocationRepositoryInterface::class);
-
- $this->service = new LocationDeletionService($this->repository, $this->nodeRepository);
- }
-
- /**
- * Test that a location is deleted.
- */
- public function testLocationIsDeleted()
- {
- $this->nodeRepository->shouldReceive('findCountWhere')->with([['location_id', '=', 123]])->once()->andReturn(0);
- $this->repository->shouldReceive('delete')->with(123)->once()->andReturn(1);
-
- $response = $this->service->handle(123);
- $this->assertEquals(1, $response);
- }
-
- /**
- * Test that an exception is thrown if nodes are attached to a location.
- */
- public function testExceptionIsThrownIfNodesAreAttached()
- {
- $this->nodeRepository->shouldReceive('findCountWhere')->with([['location_id', '=', 123]])->once()->andReturn(1);
-
- try {
- $this->service->handle(123);
- } catch (DisplayException $exception) {
- $this->assertInstanceOf(HasActiveNodesException::class, $exception);
- $this->assertEquals(trans('exceptions.locations.has_nodes'), $exception->getMessage());
- }
- }
-}
diff --git a/tests/Unit/Services/Locations/LocationUpdateServiceTest.php b/tests/Unit/Services/Locations/LocationUpdateServiceTest.php
deleted file mode 100644
index 14d4950a0..000000000
--- a/tests/Unit/Services/Locations/LocationUpdateServiceTest.php
+++ /dev/null
@@ -1,67 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Services\Locations;
-
-use Mockery as m;
-use Tests\TestCase;
-use Pterodactyl\Models\Location;
-use Pterodactyl\Services\Locations\LocationUpdateService;
-use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
-
-class LocationUpdateServiceTest extends TestCase
-{
- /**
- * @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
- */
- protected $repository;
-
- /**
- * @var \Pterodactyl\Services\Locations\LocationUpdateService
- */
- protected $service;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->repository = m::mock(LocationRepositoryInterface::class);
-
- $this->service = new LocationUpdateService($this->repository);
- }
-
- /**
- * Test location is updated.
- */
- public function testLocationIsUpdated()
- {
- $model = factory(Location::class)->make(['id' => 123]);
- $this->repository->shouldReceive('update')->with(123, ['test_data' => 'test_value'])->once()->andReturn($model);
-
- $response = $this->service->handle($model->id, ['test_data' => 'test_value']);
- $this->assertNotEmpty($response);
- $this->assertInstanceOf(Location::class, $response);
- }
-
- /**
- * Test that a model can be passed in place of an ID.
- */
- public function testModelCanBePassedToFunction()
- {
- $model = factory(Location::class)->make(['id' => 123]);
- $this->repository->shouldReceive('update')->with(123, ['test_data' => 'test_value'])->once()->andReturn($model);
-
- $response = $this->service->handle($model, ['test_data' => 'test_value']);
- $this->assertNotEmpty($response);
- $this->assertInstanceOf(Location::class, $response);
- }
-}
diff --git a/tests/Unit/Services/Nests/NestCreationServiceTest.php b/tests/Unit/Services/Nests/NestCreationServiceTest.php
deleted file mode 100644
index ea1068b21..000000000
--- a/tests/Unit/Services/Nests/NestCreationServiceTest.php
+++ /dev/null
@@ -1,95 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Services\Services;
-
-use Mockery as m;
-use Tests\TestCase;
-use Pterodactyl\Models\Nest;
-use Tests\Traits\MocksUuids;
-use Illuminate\Contracts\Config\Repository;
-use Pterodactyl\Services\Nests\NestCreationService;
-use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
-
-class NestCreationServiceTest extends TestCase
-{
- use MocksUuids;
-
- /**
- * @var \Illuminate\Contracts\Config\Repository|\Mockery\Mock
- */
- private $config;
-
- /**
- * @var \Pterodactyl\Contracts\Repository\NestRepositoryInterface|\Mockery\Mock
- */
- private $repository;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->config = m::mock(Repository::class);
- $this->repository = m::mock(NestRepositoryInterface::class);
- }
-
- /**
- * Test that a new service can be created using the correct data.
- */
- public function testCreateNewService()
- {
- $model = factory(Nest::class)->make();
-
- $this->config->shouldReceive('get')->with('pterodactyl.service.author')->once()->andReturn('testauthor@example.com');
- $this->repository->shouldReceive('create')->with([
- 'uuid' => $this->getKnownUuid(),
- 'author' => 'testauthor@example.com',
- 'name' => $model->name,
- 'description' => $model->description,
- ], true, true)->once()->andReturn($model);
-
- $response = $this->getService()->handle(['name' => $model->name, 'description' => $model->description]);
- $this->assertInstanceOf(Nest::class, $response);
- $this->assertEquals($model, $response);
- }
-
- /**
- * Test creation of a new nest with a defined author. This is used by seeder
- * scripts which need to set a specific author for nests in order for other
- * functionality to work correctly.
- */
- public function testCreateServiceWithDefinedAuthor()
- {
- $model = factory(Nest::class)->make();
-
- $this->repository->shouldReceive('create')->with([
- 'uuid' => $this->getKnownUuid(),
- 'author' => 'support@pterodactyl.io',
- 'name' => $model->name,
- 'description' => $model->description,
- ], true, true)->once()->andReturn($model);
-
- $response = $this->getService()->handle(['name' => $model->name, 'description' => $model->description], 'support@pterodactyl.io');
- $this->assertInstanceOf(Nest::class, $response);
- $this->assertEquals($model, $response);
- }
-
- /**
- * Return an instance of the service with mocked dependencies.
- *
- * @return \Pterodactyl\Services\Nests\NestCreationService
- */
- private function getService(): NestCreationService
- {
- return new NestCreationService($this->config, $this->repository);
- }
-}
diff --git a/tests/Unit/Services/Nests/NestDeletionServiceTest.php b/tests/Unit/Services/Nests/NestDeletionServiceTest.php
deleted file mode 100644
index 2fbb9f0c6..000000000
--- a/tests/Unit/Services/Nests/NestDeletionServiceTest.php
+++ /dev/null
@@ -1,91 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Services\Services;
-
-use Mockery as m;
-use Tests\TestCase;
-use Pterodactyl\Exceptions\PterodactylException;
-use Pterodactyl\Services\Nests\NestDeletionService;
-use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
-use Pterodactyl\Exceptions\Service\HasActiveServersException;
-use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
-
-class NestDeletionServiceTest extends TestCase
-{
- /**
- * @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface|\Mockery\Mock
- */
- protected $serverRepository;
-
- /**
- * @var \Pterodactyl\Contracts\Repository\NestRepositoryInterface|\Mockery\Mock
- */
- protected $repository;
-
- /**
- * @var \Pterodactyl\Services\Nests\NestDeletionService
- */
- protected $service;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->serverRepository = m::mock(ServerRepositoryInterface::class);
- $this->repository = m::mock(NestRepositoryInterface::class);
-
- $this->service = new NestDeletionService($this->serverRepository, $this->repository);
- }
-
- /**
- * Test that a service is deleted when there are no servers attached to a service.
- */
- public function testServiceIsDeleted()
- {
- $this->serverRepository->shouldReceive('findCountWhere')->with([['nest_id', '=', 1]])->once()->andReturn(0);
- $this->repository->shouldReceive('delete')->with(1)->once()->andReturn(1);
-
- $this->assertEquals(1, $this->service->handle(1));
- }
-
- /**
- * Test that an exception is thrown when there are servers attached to a service.
- *
- * @dataProvider serverCountProvider
- *
- * @param int $count
- */
- public function testExceptionIsThrownIfServersAreAttached(int $count)
- {
- $this->serverRepository->shouldReceive('findCountWhere')->with([['nest_id', '=', 1]])->once()->andReturn($count);
-
- try {
- $this->service->handle(1);
- } catch (PterodactylException $exception) {
- $this->assertInstanceOf(HasActiveServersException::class, $exception);
- $this->assertEquals(trans('exceptions.nest.delete_has_servers'), $exception->getMessage());
- }
- }
-
- /**
- * Provide assorted server counts to ensure that an exception is always thrown when more than 0 servers are found.
- *
- * @return array
- */
- public function serverCountProvider()
- {
- return [
- [1], [2], [5], [10],
- ];
- }
-}
diff --git a/tests/Unit/Services/Nests/NestUpdateServiceTest.php b/tests/Unit/Services/Nests/NestUpdateServiceTest.php
deleted file mode 100644
index 670fcec5f..000000000
--- a/tests/Unit/Services/Nests/NestUpdateServiceTest.php
+++ /dev/null
@@ -1,62 +0,0 @@
-.
- *
- * This software is licensed under the terms of the MIT license.
- * https://opensource.org/licenses/MIT
- */
-
-namespace Tests\Unit\Services\Services;
-
-use Mockery as m;
-use Tests\TestCase;
-use Pterodactyl\Services\Nests\NestUpdateService;
-use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
-
-class NestUpdateServiceTest extends TestCase
-{
- /**
- * @var \Pterodactyl\Contracts\Repository\NestRepositoryInterface|\Mockery\Mock
- */
- protected $repository;
-
- /**
- * @var \Pterodactyl\Services\Nests\NestUpdateService
- */
- protected $service;
-
- /**
- * Setup tests.
- */
- public function setUp(): void
- {
- parent::setUp();
-
- $this->repository = m::mock(NestRepositoryInterface::class);
-
- $this->service = new NestUpdateService($this->repository);
- }
-
- /**
- * Test that the author key is removed from the data array before updating the record.
- */
- public function testAuthorArrayKeyIsRemovedIfPassed()
- {
- $this->repository->shouldReceive('withoutFreshModel')->withNoArgs()->once()->andReturnSelf()
- ->shouldReceive('update')->with(1, ['otherfield' => 'value'])->once()->andReturnNull();
-
- $this->service->handle(1, ['author' => 'author1', 'otherfield' => 'value']);
- }
-
- /**
- * Test that the function continues to work when no author key is passed.
- */
- public function testServiceIsUpdatedWhenNoAuthorKeyIsPassed()
- {
- $this->repository->shouldReceive('withoutFreshModel')->withNoArgs()->once()->andReturnSelf()
- ->shouldReceive('update')->with(1, ['otherfield' => 'value'])->once()->andReturnNull();
-
- $this->service->handle(1, ['otherfield' => 'value']);
- }
-}
diff --git a/tests/Unit/Services/Nodes/NodeCreationServiceTest.php b/tests/Unit/Services/Nodes/NodeCreationServiceTest.php
deleted file mode 100644
index 561a14acc..000000000
--- a/tests/Unit/Services/Nodes/NodeCreationServiceTest.php
+++ /dev/null
@@ -1,79 +0,0 @@
- Uuid::fromString('00000000-0000-0000-0000-000000000000'),
- ])
- );
-
- $this->repository = m::mock(NodeRepositoryInterface::class);
- $this->encrypter = m::mock(Encrypter::class);
- }
-
- /**
- * Test that a node is created and a daemon secret token is created.
- */
- public function testNodeIsCreatedAndDaemonSecretIsGenerated()
- {
- /** @var \Pterodactyl\Models\Node $node */
- $node = factory(Node::class)->make();
-
- $this->encrypter->expects('encrypt')->with(m::on(function ($value) {
- return strlen($value) === Node::DAEMON_TOKEN_LENGTH;
- }))->andReturns('encrypted_value');
-
- $this->repository->expects('create')->with(m::on(function ($value) {
- $this->assertTrue(is_array($value));
- $this->assertSame('NodeName', $value['name']);
- $this->assertSame('00000000-0000-0000-0000-000000000000', $value['uuid']);
- $this->assertSame('encrypted_value', $value['daemon_token']);
- $this->assertTrue(strlen($value['daemon_token_id']) === Node::DAEMON_TOKEN_ID_LENGTH);
-
- return true;
- }), true, true)->andReturn($node);
-
- $this->assertSame($node, $this->getService()->handle(['name' => 'NodeName']));
- }
-
- /**
- * @return \Pterodactyl\Services\Nodes\NodeCreationService
- */
- private function getService()
- {
- return new NodeCreationService($this->encrypter, $this->repository);
- }
-}
diff --git a/tests/Unit/Services/Nodes/NodeDeletionServiceTest.php b/tests/Unit/Services/Nodes/NodeDeletionServiceTest.php
deleted file mode 100644
index dbab15495..000000000
--- a/tests/Unit/Services/Nodes/NodeDeletionServiceTest.php
+++ /dev/null
@@ -1,94 +0,0 @@
-repository = m::mock(NodeRepositoryInterface::class);
- $this->serverRepository = m::mock(ServerRepositoryInterface::class);
- $this->translator = m::mock(Translator::class);
-
- $this->service = new NodeDeletionService(
- $this->repository,
- $this->serverRepository,
- $this->translator
- );
- }
-
- /**
- * Test that a node is deleted if there are no servers attached to it.
- */
- public function testNodeIsDeletedIfNoServersAreAttached()
- {
- $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf()
- ->shouldReceive('findCountWhere')->with([['node_id', '=', 1]])->once()->andReturn(0);
- $this->repository->shouldReceive('delete')->with(1)->once()->andReturn(1);
-
- $this->assertEquals(1, $this->service->handle(1));
- }
-
- /**
- * Test that an exception is thrown if servers are attached to the node.
- */
- public function testExceptionIsThrownIfServersAreAttachedToNode()
- {
- $this->expectException(DisplayException::class);
-
- $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf()
- ->shouldReceive('findCountWhere')->with([['node_id', '=', 1]])->once()->andReturn(1);
- $this->translator->shouldReceive('trans')->with('exceptions.node.servers_attached')->once()->andReturnNull();
- $this->repository->shouldNotReceive('delete');
-
- $this->service->handle(1);
- }
-
- /**
- * Test that a model can be passed into the handle function rather than an ID.
- */
- public function testModelCanBePassedToFunctionInPlaceOfNodeId()
- {
- $node = factory(Node::class)->make(['id' => 123]);
-
- $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf()
- ->shouldReceive('findCountWhere')->with([['node_id', '=', $node->id]])->once()->andReturn(0);
- $this->repository->shouldReceive('delete')->with($node->id)->once()->andReturn(1);
-
- $this->assertEquals(1, $this->service->handle($node));
- }
-}
diff --git a/tests/Unit/Services/Nodes/NodeUpdateServiceTest.php b/tests/Unit/Services/Nodes/NodeUpdateServiceTest.php
deleted file mode 100644
index 1a836e446..000000000
--- a/tests/Unit/Services/Nodes/NodeUpdateServiceTest.php
+++ /dev/null
@@ -1,241 +0,0 @@
-connection = m::mock(ConnectionInterface::class);
- $this->encrypter = m::mock(Encrypter::class);
- $this->configurationRepository = m::mock(DaemonConfigurationRepository::class);
- $this->repository = m::mock(NodeRepository::class);
- }
-
- /**
- * Test that the daemon secret is reset when `reset_secret` is passed in the data.
- */
- public function testNodeIsUpdatedAndDaemonSecretIsReset()
- {
- /** @var \Pterodactyl\Models\Node $model */
- $model = factory(Node::class)->make([
- 'fqdn' => 'https://example.com',
- ]);
-
- /** @var \Pterodactyl\Models\Node $updatedModel */
- $updatedModel = factory(Node::class)->make([
- 'name' => 'New Name',
- 'fqdn' => 'https://example2.com',
- ]);
-
- $this->connection->expects('transaction')->with(m::on(function ($closure) use ($updatedModel) {
- $response = $closure();
-
- $this->assertIsArray($response);
- $this->assertTrue(count($response) === 2);
- $this->assertSame($updatedModel, $response[0]);
- $this->assertFalse($response[1]);
-
- return true;
- }))->andReturns([$updatedModel, false]);
-
- $this->encrypter->expects('encrypt')->with(m::on(function ($value) {
- return strlen($value) === Node::DAEMON_TOKEN_LENGTH;
- }))->andReturns('encrypted_value');
-
- $this->repository->expects('withFreshModel->update')->with($model->id, m::on(function ($value) {
- $this->assertTrue(is_array($value));
- $this->assertSame('New Name', $value['name']);
- $this->assertSame('encrypted_value', $value['daemon_token']);
- $this->assertTrue(strlen($value['daemon_token_id']) === Node::DAEMON_TOKEN_ID_LENGTH);
-
- return true;
- }), true, true)->andReturns($updatedModel);
-
- $this->configurationRepository->expects('setNode')->with(m::on(function ($value) use ($model, $updatedModel) {
- $this->assertInstanceOf(Node::class, $value);
- $this->assertSame($model->uuid, $value->uuid);
-
- // Yes, this is correct. Always use the updated model's FQDN when making requests to
- // the Daemon so that any changes to that are properly propagated down to the daemon.
- //
- // @see https://github.com/pterodactyl/panel/issues/1931
- $this->assertSame($updatedModel->fqdn, $value->fqdn);
-
- return true;
- }))->andReturnSelf();
-
- $this->configurationRepository->expects('update')->with($updatedModel);
-
- $this->getService()->handle($model, [
- 'name' => $updatedModel->name,
- ], true);
- }
-
- /**
- * Test that daemon secret is not modified when no variable is passed in data.
- */
- public function testNodeIsUpdatedAndDaemonSecretIsNotChanged()
- {
- /** @var \Pterodactyl\Models\Node $model */
- $model = factory(Node::class)->make(['fqdn' => 'https://example.com']);
-
- /** @var \Pterodactyl\Models\Node $updatedModel */
- $updatedModel = factory(Node::class)->make(['name' => 'New Name', 'fqdn' => $model->fqdn]);
-
- $this->connection->expects('transaction')->with(m::on(function ($closure) use ($updatedModel) {
- $response = $closure();
-
- $this->assertIsArray($response);
- $this->assertTrue(count($response) === 2);
- $this->assertSame($updatedModel, $response[0]);
- $this->assertFalse($response[1]);
-
- return true;
- }))->andReturns([$updatedModel, false]);
-
- $this->repository->expects('withFreshModel->update')->with($model->id, m::on(function ($value) {
- $this->assertTrue(is_array($value));
- $this->assertSame('New Name', $value['name']);
- $this->assertArrayNotHasKey('daemon_token', $value);
- $this->assertArrayNotHasKey('daemon_token_id', $value);
-
- return true;
- }), true, true)->andReturns($updatedModel);
-
- $this->configurationRepository->expects('setNode->update')->with($updatedModel);
-
- $this->getService()->handle($model, ['name' => $updatedModel->name]);
- }
-
- /**
- * Test that an exception caused by a connection error is handled.
- */
- public function testExceptionRelatedToConnection()
- {
- $this->configureExceptionMock(DaemonConnectionException::class);
- $this->expectException(ConfigurationNotPersistedException::class);
-
- /** @var \Pterodactyl\Models\Node $model */
- $model = factory(Node::class)->make(['fqdn' => 'https://example.com']);
-
- /** @var \Pterodactyl\Models\Node $updatedModel */
- $updatedModel = factory(Node::class)->make(['name' => 'New Name', 'fqdn' => $model->fqdn]);
-
- $this->connection->expects('transaction')->with(m::on(function ($closure) use ($updatedModel) {
- $response = $closure();
-
- $this->assertIsArray($response);
- $this->assertTrue(count($response) === 2);
- $this->assertSame($updatedModel, $response[0]);
- $this->assertTrue($response[1]);
-
- return true;
- }))->andReturn([$updatedModel, true]);
-
- $this->repository->expects('withFreshModel->update')->with($model->id, m::on(function ($value) {
- $this->assertTrue(is_array($value));
- $this->assertSame('New Name', $value['name']);
- $this->assertArrayNotHasKey('daemon_token', $value);
- $this->assertArrayNotHasKey('daemon_token_id', $value);
-
- return true;
- }), true, true)->andReturns($updatedModel);
-
- $this->configurationRepository->expects('setNode->update')->with($updatedModel)->andThrow(
- new DaemonConnectionException(
- new ConnectException('', new Request('GET', 'Test'), new Exception)
- )
- );
-
- $this->getService()->handle($model, ['name' => $updatedModel->name]);
- }
-
- /**
- * Test that an exception not caused by a daemon connection error is handled.
- */
- public function testExceptionNotRelatedToConnection()
- {
- /** @var \Pterodactyl\Models\Node $model */
- $model = factory(Node::class)->make(['fqdn' => 'https://example.com']);
-
- /** @var \Pterodactyl\Models\Node $updatedModel */
- $updatedModel = factory(Node::class)->make(['name' => 'New Name', 'fqdn' => $model->fqdn]);
-
- $this->connection->expects('transaction')->with(m::on(function ($closure) use ($updatedModel) {
- try {
- $closure();
- } catch (Exception $exception) {
- $this->assertInstanceOf(Exception::class, $exception);
- $this->assertSame('Foo', $exception->getMessage());
-
- return true;
- }
-
- return false;
- }));
-
- $this->repository->expects('withFreshModel->update')->andReturns($updatedModel);
- $this->configurationRepository->expects('setNode->update')->andThrow(
- new Exception('Foo')
- );
-
- $this->getService()->handle($model, ['name' => $updatedModel->name]);
- }
-
- /**
- * Return an instance of the service with mocked injections.
- *
- * @return \Pterodactyl\Services\Nodes\NodeUpdateService
- */
- private function getService(): NodeUpdateService
- {
- return new NodeUpdateService(
- $this->connection, $this->encrypter, $this->configurationRepository, $this->repository
- );
- }
-}
diff --git a/tests/Unit/Services/Servers/EnvironmentServiceTest.php b/tests/Unit/Services/Servers/EnvironmentServiceTest.php
deleted file mode 100644
index 73a41c346..000000000
--- a/tests/Unit/Services/Servers/EnvironmentServiceTest.php
+++ /dev/null
@@ -1,173 +0,0 @@
-set('pterodactyl.environment_variables', []);
- }
-
- /**
- * Test that set environment key stores the key into a retrievable array.
- */
- public function testSettingEnvironmentKeyPersistsItInArray()
- {
- $service = $this->getService();
-
- $service->setEnvironmentKey('TEST_KEY', function () {
- return true;
- });
-
- $this->assertNotEmpty($service->getEnvironmentKeys());
- $this->assertArrayHasKey('TEST_KEY', $service->getEnvironmentKeys());
- }
-
- /**
- * Test that environment defaults are returned by the process function.
- */
- public function testProcessShouldReturnDefaultEnvironmentVariablesForAServer()
- {
- $model = $this->getServerModel([
- 'TEST_VARIABLE' => factory(EggVariable::class)->make([
- 'id' => 987,
- 'env_variable' => 'TEST_VARIABLE',
- 'default_value' => 'Test Variable',
- ]),
- ]);
-
- $response = $this->getService()->handle($model);
- $this->assertNotEmpty($response);
- $this->assertCount(4, $response);
- $this->assertArrayHasKey('TEST_VARIABLE', $response);
- $this->assertSame('Test Variable', $response['TEST_VARIABLE']);
- }
-
- /**
- * Test that variables included at run-time are also included.
- */
- public function testProcessShouldReturnKeySetAtRuntime()
- {
- $model = $this->getServerModel([]);
- $service = $this->getService();
- $service->setEnvironmentKey('TEST_VARIABLE', function ($server) {
- return $server->uuidShort;
- });
-
- $response = $service->handle($model);
-
- $this->assertNotEmpty($response);
- $this->assertArrayHasKey('TEST_VARIABLE', $response);
- $this->assertSame($model->uuidShort, $response['TEST_VARIABLE']);
- }
-
- /**
- * Test that duplicate variables provided in config override the defaults.
- */
- public function testProcessShouldAllowOverwritingVariablesWithConfigurationFile()
- {
- config()->set('pterodactyl.environment_variables', [
- 'P_SERVER_UUID' => 'name',
- ]);
-
- $model = $this->getServerModel([]);
- $response = $this->getService()->handle($model);
-
- $this->assertNotEmpty($response);
- $this->assertSame(3, count($response));
- $this->assertArrayHasKey('P_SERVER_UUID', $response);
- $this->assertSame($model->name, $response['P_SERVER_UUID']);
- }
-
- /**
- * Test that config based environment variables can be done using closures.
- */
- public function testVariablesSetInConfigurationAllowForClosures()
- {
- config()->set('pterodactyl.environment_variables', [
- 'P_SERVER_UUID' => function ($server) {
- return $server->id * 2;
- },
- ]);
-
- $model = $this->getServerModel([]);
- $response = $this->getService()->handle($model);
-
- $this->assertNotEmpty($response);
- $this->assertSame(3, count($response));
- $this->assertArrayHasKey('P_SERVER_UUID', $response);
- $this->assertSame($model->id * 2, $response['P_SERVER_UUID']);
- }
-
- /**
- * Test that duplicate variables provided at run-time override the defaults and those
- * that are defined in the configuration file.
- */
- public function testProcessShouldAllowOverwritingDefaultVariablesWithRuntimeProvided()
- {
- config()->set('pterodactyl.environment_variables', [
- 'P_SERVER_UUID' => 'overwritten-config',
- ]);
-
- $model = $this->getServerModel([]);
- $service = $this->getService();
- $service->setEnvironmentKey('P_SERVER_UUID', function ($model) {
- return 'overwritten';
- });
-
- $response = $service->handle($model);
-
- $this->assertNotEmpty($response);
- $this->assertSame(3, count($response));
- $this->assertArrayHasKey('P_SERVER_UUID', $response);
- $this->assertSame('overwritten', $response['P_SERVER_UUID']);
- }
-
- /**
- * Return an instance of the service with mocked dependencies.
- *
- * @return \Pterodactyl\Services\Servers\EnvironmentService
- */
- private function getService(): EnvironmentService
- {
- return new EnvironmentService;
- }
-
- /**
- * Return a server model with a location relationship to be used in the tests.
- *
- * @param array $variables
- * @return \Pterodactyl\Models\Server
- */
- private function getServerModel(array $variables): Server
- {
- /** @var \Pterodactyl\Models\Server $server */
- $server = factory(Server::class)->make([
- 'id' => 123,
- 'location' => factory(Location::class)->make(),
- ]);
-
- $server->setRelation('variables', Collection::make($variables));
-
- return $server;
- }
-}
diff --git a/tests/Unit/Services/Servers/ServerConfigurationStructureServiceTest.php b/tests/Unit/Services/Servers/ServerConfigurationStructureServiceTest.php
deleted file mode 100644
index 9d32323dd..000000000
--- a/tests/Unit/Services/Servers/ServerConfigurationStructureServiceTest.php
+++ /dev/null
@@ -1,103 +0,0 @@
-environment = m::mock(EnvironmentService::class);
- $this->repository = m::mock(ServerRepositoryInterface::class);
- }
-
- /**
- * Test that a configuration is returned in the proper format when passed a
- * server model that is missing required relationships.
- */
- public function testCorrectStructureIsReturned()
- {
- /** @var \Pterodactyl\Models\Server $model */
- $model = factory(Server::class)->make();
- $model->setRelation('allocation', factory(Allocation::class)->make());
- $model->setRelation('allocations', collect(factory(Allocation::class)->times(2)->make()));
- $model->setRelation('egg', factory(Egg::class)->make());
-
- $this->environment->expects('handle')->with($model)->andReturn(['environment_array']);
-
- $response = $this->getService()->handle($model);
- $this->assertNotEmpty($response);
- $this->assertArrayNotHasKey('user', $response);
- $this->assertArrayNotHasKey('keys', $response);
-
- $this->assertArrayHasKey('uuid', $response);
- $this->assertArrayHasKey('suspended', $response);
- $this->assertArrayHasKey('environment', $response);
- $this->assertArrayHasKey('invocation', $response);
- $this->assertArrayHasKey('skip_egg_scripts', $response);
- $this->assertArrayHasKey('build', $response);
- $this->assertArrayHasKey('container', $response);
- $this->assertArrayHasKey('allocations', $response);
-
- $this->assertSame([
- 'default' => [
- 'ip' => $model->allocation->ip,
- 'port' => $model->allocation->port,
- ],
- 'mappings' => $model->getAllocationMappings(),
- ], $response['allocations']);
-
- $this->assertSame([
- 'memory_limit' => $model->memory,
- 'swap' => $model->swap,
- 'io_weight' => $model->io,
- 'cpu_limit' => $model->cpu,
- 'threads' => $model->threads,
- 'disk_space' => $model->disk,
- ], $response['build']);
-
- $this->assertSame([
- 'image' => $model->image,
- 'oom_disabled' => $model->oom_disabled,
- 'requires_rebuild' => false,
- ], $response['container']);
-
- $this->assertSame($model->uuid, $response['uuid']);
- $this->assertSame($model->suspended, $response['suspended']);
- $this->assertSame(['environment_array'], $response['environment']);
- $this->assertSame($model->startup, $response['invocation']);
- }
-
- /**
- * Return an instance of the service with mocked dependencies.
- *
- * @return \Pterodactyl\Services\Servers\ServerConfigurationStructureService
- */
- private function getService(): ServerConfigurationStructureService
- {
- return new ServerConfigurationStructureService($this->environment);
- }
-}
diff --git a/tests/Unit/Services/Servers/StartupCommandViewServiceTest.php b/tests/Unit/Services/Servers/StartupCommandViewServiceTest.php
deleted file mode 100644
index 6444b00dd..000000000
--- a/tests/Unit/Services/Servers/StartupCommandViewServiceTest.php
+++ /dev/null
@@ -1,73 +0,0 @@
-repository = m::mock(ServerRepositoryInterface::class);
- }
-
- /**
- * Test that the correct startup string is returned.
- */
- public function testServiceResponse()
- {
-
- $server = factory(Server::class)->make([
- 'id' => 123,
- 'startup' => 'example {{SERVER_MEMORY}} {{SERVER_IP}} {{SERVER_PORT}} {{TEST_VARIABLE}} {{TEST_VARIABLE_HIDDEN}} {{UNKNOWN}}',
- ]);
-
- $variables = collect([
- factory(EggVariable::class)->make([
- 'env_variable' => 'TEST_VARIABLE',
- 'server_value' => 'Test Value',
- 'user_viewable' => 1,
- ]),
- factory(EggVariable::class)->make([
- 'env_variable' => 'TEST_VARIABLE_HIDDEN',
- 'server_value' => 'Hidden Value',
- 'user_viewable' => 0,
- ]),
- ]);
-
- $server->setRelation('variables', $variables);
- $server->setRelation('allocation', $allocation = factory(Allocation::class)->make());
-
- $response = $this->getService()->handle($server);
- $this->assertSame(
- sprintf('example %s %s %s %s %s {{UNKNOWN}}', $server->memory, $allocation->ip, $allocation->port, 'Test Value', '[hidden]'),
- $response
- );
- }
-
- /**
- * Return an instance of the service with mocked dependencies.
- *
- * @return \Pterodactyl\Services\Servers\StartupCommandService
- */
- private function getService(): StartupCommandService
- {
- return new StartupCommandService;
- }
-}