Fix tests
This commit is contained in:
parent
d50ea18598
commit
532025a348
10 changed files with 463 additions and 573 deletions
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Services\Databases;
|
namespace Pterodactyl\Services\Databases;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Database;
|
||||||
use Illuminate\Database\DatabaseManager;
|
use Illuminate\Database\DatabaseManager;
|
||||||
use Illuminate\Contracts\Encryption\Encrypter;
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
||||||
|
@ -95,7 +96,7 @@ class DatabaseManagementService
|
||||||
$this->database->commit();
|
$this->database->commit();
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
try {
|
try {
|
||||||
if (isset($database)) {
|
if (isset($database) && $database instanceof Database) {
|
||||||
$this->repository->dropDatabase($database->database);
|
$this->repository->dropDatabase($database->database);
|
||||||
$this->repository->dropUser($database->username, $database->remote);
|
$this->repository->dropUser($database->username, $database->remote);
|
||||||
$this->repository->flush();
|
$this->repository->flush();
|
||||||
|
|
|
@ -39,6 +39,8 @@ $factory->define(Pterodactyl\Models\Server::class, function (Faker\Generator $fa
|
||||||
});
|
});
|
||||||
|
|
||||||
$factory->define(Pterodactyl\Models\User::class, function (Faker\Generator $faker) {
|
$factory->define(Pterodactyl\Models\User::class, function (Faker\Generator $faker) {
|
||||||
|
static $password;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $faker->unique()->randomNumber(),
|
'id' => $faker->unique()->randomNumber(),
|
||||||
'external_id' => null,
|
'external_id' => null,
|
||||||
|
@ -47,7 +49,7 @@ $factory->define(Pterodactyl\Models\User::class, function (Faker\Generator $fake
|
||||||
'email' => $faker->safeEmail,
|
'email' => $faker->safeEmail,
|
||||||
'name_first' => $faker->firstName,
|
'name_first' => $faker->firstName,
|
||||||
'name_last' => $faker->lastName,
|
'name_last' => $faker->lastName,
|
||||||
'password' => bcrypt('password'),
|
'password' => $password ?: $password = bcrypt('password'),
|
||||||
'language' => 'en',
|
'language' => 'en',
|
||||||
'root_admin' => false,
|
'root_admin' => false,
|
||||||
'use_totp' => false,
|
'use_totp' => false,
|
||||||
|
@ -173,6 +175,21 @@ $factory->define(Pterodactyl\Models\DatabaseHost::class, function (Faker\Generat
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$factory->define(Pterodactyl\Models\Database::class, function (Faker\Generator $faker) {
|
||||||
|
static $password;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $faker->unique()->randomNumber(),
|
||||||
|
'server_id' => $faker->randomNumber(),
|
||||||
|
'database_host_id' => $faker->randomNumber(),
|
||||||
|
'database' => str_random(10),
|
||||||
|
'username' => str_random(10),
|
||||||
|
'password' => $password ?: bcrypt('test123'),
|
||||||
|
'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
|
||||||
|
'updated_at' => \Carbon\Carbon::now()->toDateTimeString(),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
$factory->define(Pterodactyl\Models\Schedule::class, function (Faker\Generator $faker) {
|
$factory->define(Pterodactyl\Models\Schedule::class, function (Faker\Generator $faker) {
|
||||||
return [
|
return [
|
||||||
'id' => $faker->unique()->randomNumber(),
|
'id' => $faker->unique()->randomNumber(),
|
||||||
|
|
|
@ -14,6 +14,9 @@ use Tests\TestCase;
|
||||||
use Prologue\Alerts\AlertsMessageBag;
|
use Prologue\Alerts\AlertsMessageBag;
|
||||||
use Tests\Assertions\ControllerAssertionsTrait;
|
use Tests\Assertions\ControllerAssertionsTrait;
|
||||||
use Pterodactyl\Http\Controllers\Admin\DatabaseController;
|
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\LocationRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
||||||
|
|
||||||
|
@ -22,29 +25,34 @@ class DatabaseControllerTest extends TestCase
|
||||||
use ControllerAssertionsTrait;
|
use ControllerAssertionsTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Prologue\Alerts\AlertsMessageBag
|
* @var \Prologue\Alerts\AlertsMessageBag|\Mockery\Mock
|
||||||
*/
|
*/
|
||||||
protected $alert;
|
private $alert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Http\Controllers\Admin\DatabaseController
|
* @var \Pterodactyl\Services\Databases\Hosts\HostCreationService|\Mockery\Mock
|
||||||
*/
|
*/
|
||||||
protected $controller;
|
private $creationService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
|
* @var \Pterodactyl\Services\Databases\Hosts\HostDeletionService|\Mockery\Mock
|
||||||
*/
|
*/
|
||||||
protected $locationRepository;
|
private $deletionService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface
|
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface|\Mockery\Mock
|
||||||
*/
|
*/
|
||||||
protected $repository;
|
private $locationRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Services\Databases\HostsUpdateService
|
* @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface|\Mockery\Mock
|
||||||
*/
|
*/
|
||||||
protected $service;
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Databases\Hosts\HostUpdateService|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $updateService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup tests.
|
* Setup tests.
|
||||||
|
@ -54,16 +62,11 @@ class DatabaseControllerTest extends TestCase
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->alert = m::mock(AlertsMessageBag::class);
|
$this->alert = m::mock(AlertsMessageBag::class);
|
||||||
|
$this->creationService = m::mock(HostCreationService::class);
|
||||||
|
$this->deletionService = m::mock(HostDeletionService::class);
|
||||||
$this->locationRepository = m::mock(LocationRepositoryInterface::class);
|
$this->locationRepository = m::mock(LocationRepositoryInterface::class);
|
||||||
$this->repository = m::mock(DatabaseHostRepositoryInterface::class);
|
$this->repository = m::mock(DatabaseHostRepositoryInterface::class);
|
||||||
$this->service = m::mock(HostUpdateService::class);
|
$this->updateService = m::mock(HostUpdateService::class);
|
||||||
|
|
||||||
$this->controller = new DatabaseController(
|
|
||||||
$this->alert,
|
|
||||||
$this->repository,
|
|
||||||
$this->service,
|
|
||||||
$this->locationRepository
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +77,7 @@ class DatabaseControllerTest extends TestCase
|
||||||
$this->locationRepository->shouldReceive('getAllWithNodes')->withNoArgs()->once()->andReturn('getAllWithNodes');
|
$this->locationRepository->shouldReceive('getAllWithNodes')->withNoArgs()->once()->andReturn('getAllWithNodes');
|
||||||
$this->repository->shouldReceive('getWithViewDetails')->withNoArgs()->once()->andReturn('getWithViewDetails');
|
$this->repository->shouldReceive('getWithViewDetails')->withNoArgs()->once()->andReturn('getWithViewDetails');
|
||||||
|
|
||||||
$response = $this->controller->index();
|
$response = $this->getController()->index();
|
||||||
|
|
||||||
$this->assertIsViewResponse($response);
|
$this->assertIsViewResponse($response);
|
||||||
$this->assertViewNameEquals('admin.databases.index', $response);
|
$this->assertViewNameEquals('admin.databases.index', $response);
|
||||||
|
@ -92,7 +95,7 @@ class DatabaseControllerTest extends TestCase
|
||||||
$this->locationRepository->shouldReceive('getAllWithNodes')->withNoArgs()->once()->andReturn('getAllWithNodes');
|
$this->locationRepository->shouldReceive('getAllWithNodes')->withNoArgs()->once()->andReturn('getAllWithNodes');
|
||||||
$this->repository->shouldReceive('getWithServers')->with(1)->once()->andReturn('getWithServers');
|
$this->repository->shouldReceive('getWithServers')->with(1)->once()->andReturn('getWithServers');
|
||||||
|
|
||||||
$response = $this->controller->view(1);
|
$response = $this->getController()->view(1);
|
||||||
|
|
||||||
$this->assertIsViewResponse($response);
|
$this->assertIsViewResponse($response);
|
||||||
$this->assertViewNameEquals('admin.databases.view', $response);
|
$this->assertViewNameEquals('admin.databases.view', $response);
|
||||||
|
@ -101,4 +104,21 @@ class DatabaseControllerTest extends TestCase
|
||||||
$this->assertViewKeyEquals('locations', 'getAllWithNodes', $response);
|
$this->assertViewKeyEquals('locations', 'getAllWithNodes', $response);
|
||||||
$this->assertViewKeyEquals('host', 'getWithServers', $response);
|
$this->assertViewKeyEquals('host', 'getWithServers', $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->creationService,
|
||||||
|
$this->deletionService,
|
||||||
|
$this->updateService,
|
||||||
|
$this->locationRepository
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ class DatabaseRepositoryTest extends TestCase
|
||||||
public function testCreateDatabaseStatement()
|
public function testCreateDatabaseStatement()
|
||||||
{
|
{
|
||||||
$query = sprintf('CREATE DATABASE IF NOT EXISTS `%s`', 'test_database');
|
$query = sprintf('CREATE DATABASE IF NOT EXISTS `%s`', 'test_database');
|
||||||
$this->repository->shouldReceive('runStatement')->with($query, 'test')->once()->andReturn(true);
|
$this->repository->shouldReceive('runStatement')->with($query)->once()->andReturn(true);
|
||||||
|
|
||||||
$this->assertTrue($this->repository->createDatabase('test_database', 'test'));
|
$this->assertTrue($this->repository->createDatabase('test_database', 'test'));
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ class DatabaseRepositoryTest extends TestCase
|
||||||
public function testCreateUserStatement()
|
public function testCreateUserStatement()
|
||||||
{
|
{
|
||||||
$query = sprintf('CREATE USER `%s`@`%s` IDENTIFIED BY \'%s\'', 'test', '%', 'password');
|
$query = sprintf('CREATE USER `%s`@`%s` IDENTIFIED BY \'%s\'', 'test', '%', 'password');
|
||||||
$this->repository->shouldReceive('runStatement')->with($query, 'test')->once()->andReturn(true);
|
$this->repository->shouldReceive('runStatement')->with($query)->once()->andReturn(true);
|
||||||
|
|
||||||
$this->assertTrue($this->repository->createUser('test', '%', 'password', 'test'));
|
$this->assertTrue($this->repository->createUser('test', '%', 'password', 'test'));
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ class DatabaseRepositoryTest extends TestCase
|
||||||
public function testUserAssignmentToDatabaseStatement()
|
public function testUserAssignmentToDatabaseStatement()
|
||||||
{
|
{
|
||||||
$query = sprintf('GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, EXECUTE ON `%s`.* TO `%s`@`%s`', 'test_database', 'test', '%');
|
$query = sprintf('GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, EXECUTE ON `%s`.* TO `%s`@`%s`', 'test_database', 'test', '%');
|
||||||
$this->repository->shouldReceive('runStatement')->with($query, 'test')->once()->andReturn(true);
|
$this->repository->shouldReceive('runStatement')->with($query)->once()->andReturn(true);
|
||||||
|
|
||||||
$this->assertTrue($this->repository->assignUserToDatabase('test_database', 'test', '%', 'test'));
|
$this->assertTrue($this->repository->assignUserToDatabase('test_database', 'test', '%', 'test'));
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ class DatabaseRepositoryTest extends TestCase
|
||||||
*/
|
*/
|
||||||
public function testFlushStatement()
|
public function testFlushStatement()
|
||||||
{
|
{
|
||||||
$this->repository->shouldReceive('runStatement')->with('FLUSH PRIVILEGES', 'test')->once()->andReturn(true);
|
$this->repository->shouldReceive('runStatement')->with('FLUSH PRIVILEGES')->once()->andReturn(true);
|
||||||
|
|
||||||
$this->assertTrue($this->repository->flush('test'));
|
$this->assertTrue($this->repository->flush('test'));
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ class DatabaseRepositoryTest extends TestCase
|
||||||
public function testDropDatabaseStatement()
|
public function testDropDatabaseStatement()
|
||||||
{
|
{
|
||||||
$query = sprintf('DROP DATABASE IF EXISTS `%s`', 'test_database');
|
$query = sprintf('DROP DATABASE IF EXISTS `%s`', 'test_database');
|
||||||
$this->repository->shouldReceive('runStatement')->with($query, 'test')->once()->andReturn(true);
|
$this->repository->shouldReceive('runStatement')->with($query)->once()->andReturn(true);
|
||||||
|
|
||||||
$this->assertTrue($this->repository->dropDatabase('test_database', 'test'));
|
$this->assertTrue($this->repository->dropDatabase('test_database', 'test'));
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ class DatabaseRepositoryTest extends TestCase
|
||||||
public function testDropUserStatement()
|
public function testDropUserStatement()
|
||||||
{
|
{
|
||||||
$query = sprintf('DROP USER IF EXISTS `%s`@`%s`', 'test', '%');
|
$query = sprintf('DROP USER IF EXISTS `%s`@`%s`', 'test', '%');
|
||||||
$this->repository->shouldReceive('runStatement')->with($query, 'test')->once()->andReturn(true);
|
$this->repository->shouldReceive('runStatement')->with($query)->once()->andReturn(true);
|
||||||
|
|
||||||
$this->assertTrue($this->repository->dropUser('test', '%', 'test'));
|
$this->assertTrue($this->repository->dropUser('test', '%', 'test'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,201 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Pterodactyl - Panel
|
|
||||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
|
||||||
*
|
|
||||||
* This software is licensed under the terms of the MIT license.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Tests\Unit\Services\Administrative;
|
|
||||||
|
|
||||||
use Mockery as m;
|
|
||||||
use Tests\TestCase;
|
|
||||||
use Illuminate\Database\DatabaseManager;
|
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
|
||||||
use Illuminate\Contracts\Encryption\Encrypter;
|
|
||||||
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
|
||||||
|
|
||||||
class DatabaseHostServiceTest extends TestCase
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Database\DatabaseManager
|
|
||||||
*/
|
|
||||||
protected $database;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface
|
|
||||||
*/
|
|
||||||
protected $databaseRepository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Extensions\DynamicDatabaseConnection
|
|
||||||
*/
|
|
||||||
protected $dynamic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Contracts\Encryption\Encrypter
|
|
||||||
*/
|
|
||||||
protected $encrypter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface
|
|
||||||
*/
|
|
||||||
protected $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Databases\HostsUpdateService
|
|
||||||
*/
|
|
||||||
protected $service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup tests.
|
|
||||||
*/
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
|
|
||||||
$this->database = m::mock(DatabaseManager::class);
|
|
||||||
$this->databaseRepository = m::mock(DatabaseRepositoryInterface::class);
|
|
||||||
$this->dynamic = m::mock(DynamicDatabaseConnection::class);
|
|
||||||
$this->encrypter = m::mock(Encrypter::class);
|
|
||||||
$this->repository = m::mock(DatabaseHostRepositoryInterface::class);
|
|
||||||
|
|
||||||
$this->service = new HostUpdateService(
|
|
||||||
$this->database,
|
|
||||||
$this->databaseRepository,
|
|
||||||
$this->repository,
|
|
||||||
$this->dynamic,
|
|
||||||
$this->encrypter
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that creating a host returns the correct data.
|
|
||||||
*/
|
|
||||||
public function testHostIsCreated()
|
|
||||||
{
|
|
||||||
$data = [
|
|
||||||
'password' => 'raw-password',
|
|
||||||
'name' => 'HostName',
|
|
||||||
'host' => '127.0.0.1',
|
|
||||||
'port' => 3306,
|
|
||||||
'username' => 'someusername',
|
|
||||||
'node_id' => null,
|
|
||||||
];
|
|
||||||
|
|
||||||
$finalData = (object) array_replace($data, ['password' => 'enc-password']);
|
|
||||||
|
|
||||||
$this->database->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
|
||||||
$this->encrypter->shouldReceive('encrypt')->with('raw-password')->once()->andReturn('enc-password');
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('create')->with([
|
|
||||||
'password' => 'enc-password',
|
|
||||||
'name' => 'HostName',
|
|
||||||
'host' => '127.0.0.1',
|
|
||||||
'port' => 3306,
|
|
||||||
'username' => 'someusername',
|
|
||||||
'max_databases' => null,
|
|
||||||
'node_id' => null,
|
|
||||||
])->once()->andReturn($finalData);
|
|
||||||
|
|
||||||
$this->dynamic->shouldReceive('set')->with('dynamic', $finalData)->once()->andReturnNull();
|
|
||||||
$this->database->shouldReceive('connection')->with('dynamic')->once()->andReturnSelf()
|
|
||||||
->shouldReceive('select')->with('SELECT 1 FROM dual')->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->database->shouldReceive('commit')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
$response = $this->service->create($data);
|
|
||||||
|
|
||||||
$this->assertNotNull($response);
|
|
||||||
$this->assertTrue(is_object($response), 'Assert that response is an object.');
|
|
||||||
|
|
||||||
$this->assertEquals('enc-password', $response->password);
|
|
||||||
$this->assertEquals('HostName', $response->name);
|
|
||||||
$this->assertEquals('127.0.0.1', $response->host);
|
|
||||||
$this->assertEquals(3306, $response->port);
|
|
||||||
$this->assertEquals('someusername', $response->username);
|
|
||||||
$this->assertNull($response->node_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that passing a password will store an encrypted version in the DB.
|
|
||||||
*/
|
|
||||||
public function testHostIsUpdatedWithPasswordProvided()
|
|
||||||
{
|
|
||||||
$finalData = (object) ['password' => 'enc-pass', 'host' => '123.456.78.9'];
|
|
||||||
|
|
||||||
$this->database->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
|
||||||
$this->encrypter->shouldReceive('encrypt')->with('raw-pass')->once()->andReturn('enc-pass');
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('update')->with(1, [
|
|
||||||
'password' => 'enc-pass',
|
|
||||||
'host' => '123.456.78.9',
|
|
||||||
])->once()->andReturn($finalData);
|
|
||||||
|
|
||||||
$this->dynamic->shouldReceive('set')->with('dynamic', $finalData)->once()->andReturnNull();
|
|
||||||
$this->database->shouldReceive('connection')->with('dynamic')->once()->andReturnSelf()
|
|
||||||
->shouldReceive('select')->with('SELECT 1 FROM dual')->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->database->shouldReceive('commit')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
$response = $this->service->update(1, ['password' => 'raw-pass', 'host' => '123.456.78.9']);
|
|
||||||
|
|
||||||
$this->assertNotNull($response);
|
|
||||||
$this->assertEquals('enc-pass', $response->password);
|
|
||||||
$this->assertEquals('123.456.78.9', $response->host);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that passing no or empty password will skip storing it.
|
|
||||||
*/
|
|
||||||
public function testHostIsUpdatedWithoutPassword()
|
|
||||||
{
|
|
||||||
$finalData = (object) ['host' => '123.456.78.9'];
|
|
||||||
|
|
||||||
$this->database->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
|
||||||
$this->encrypter->shouldNotReceive('encrypt');
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('update')->with(1, ['host' => '123.456.78.9'])->once()->andReturn($finalData);
|
|
||||||
|
|
||||||
$this->dynamic->shouldReceive('set')->with('dynamic', $finalData)->once()->andReturnNull();
|
|
||||||
$this->database->shouldReceive('connection')->with('dynamic')->once()->andReturnSelf()
|
|
||||||
->shouldReceive('select')->with('SELECT 1 FROM dual')->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->database->shouldReceive('commit')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
$response = $this->service->update(1, ['password' => '', 'host' => '123.456.78.9']);
|
|
||||||
|
|
||||||
$this->assertNotNull($response);
|
|
||||||
$this->assertEquals('123.456.78.9', $response->host);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that a database host can be deleted.
|
|
||||||
*/
|
|
||||||
public function testHostIsDeleted()
|
|
||||||
{
|
|
||||||
$this->databaseRepository->shouldReceive('findCountWhere')->with([['database_host_id', '=', 1]])->once()->andReturn(0);
|
|
||||||
$this->repository->shouldReceive('delete')->with(1)->once()->andReturn(true);
|
|
||||||
|
|
||||||
$response = $this->service->delete(1);
|
|
||||||
|
|
||||||
$this->assertTrue($response, 'Assert that response is true.');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test exception is thrown when there are databases attached to a host.
|
|
||||||
*/
|
|
||||||
public function testExceptionIsThrownIfHostHasDatabases()
|
|
||||||
{
|
|
||||||
$this->databaseRepository->shouldReceive('findCountWhere')->with([['database_host_id', '=', 1]])->once()->andReturn(2);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->service->delete(1);
|
|
||||||
} catch (DisplayException $exception) {
|
|
||||||
$this->assertEquals(trans('exceptions.databases.delete_has_databases'), $exception->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,344 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Pterodactyl - Panel
|
|
||||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
|
||||||
*
|
|
||||||
* This software is licensed under the terms of the MIT license.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Tests\Unit\Services\Database;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Mockery as m;
|
|
||||||
use Tests\TestCase;
|
|
||||||
use phpmock\phpunit\PHPMock;
|
|
||||||
use Illuminate\Database\DatabaseManager;
|
|
||||||
use Illuminate\Contracts\Encryption\Encrypter;
|
|
||||||
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
|
||||||
use Pterodactyl\Services\Databases\DatabaseManagementService;
|
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
|
||||||
|
|
||||||
class DatabaseManagementServiceTest extends TestCase
|
|
||||||
{
|
|
||||||
use PHPMock;
|
|
||||||
|
|
||||||
const TEST_DATA = [
|
|
||||||
'server_id' => 1,
|
|
||||||
'database' => 'd1_dbname',
|
|
||||||
'remote' => '%',
|
|
||||||
'username' => 'u1_str_random',
|
|
||||||
'password' => 'enc_password',
|
|
||||||
'database_host_id' => 3,
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Database\DatabaseManager
|
|
||||||
*/
|
|
||||||
protected $database;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Extensions\DynamicDatabaseConnection
|
|
||||||
*/
|
|
||||||
protected $dynamic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Contracts\Encryption\Encrypter
|
|
||||||
*/
|
|
||||||
protected $encrypter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface
|
|
||||||
*/
|
|
||||||
protected $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Databases\DatabaseManagementService
|
|
||||||
*/
|
|
||||||
protected $service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup tests.
|
|
||||||
*/
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
|
|
||||||
$this->database = m::mock(DatabaseManager::class);
|
|
||||||
$this->dynamic = m::mock(DynamicDatabaseConnection::class);
|
|
||||||
$this->encrypter = m::mock(Encrypter::class);
|
|
||||||
$this->repository = m::mock(DatabaseRepositoryInterface::class);
|
|
||||||
|
|
||||||
$this->getFunctionMock('\\Pterodactyl\\Services\\Database', 'str_random')
|
|
||||||
->expects($this->any())->willReturn('str_random');
|
|
||||||
|
|
||||||
$this->service = new DatabaseManagementService(
|
|
||||||
$this->database,
|
|
||||||
$this->dynamic,
|
|
||||||
$this->repository,
|
|
||||||
$this->encrypter
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that a new database can be created that is linked to a specific host.
|
|
||||||
*/
|
|
||||||
public function testCreateANewDatabaseThatIsLinkedToAHost()
|
|
||||||
{
|
|
||||||
$this->encrypter->shouldReceive('encrypt')->with('str_random')->once()->andReturn('enc_password');
|
|
||||||
$this->database->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('createIfNotExists')
|
|
||||||
->with(self::TEST_DATA)
|
|
||||||
->once()
|
|
||||||
->andReturn((object) self::TEST_DATA);
|
|
||||||
$this->dynamic->shouldReceive('set')
|
|
||||||
->with('dynamic', self::TEST_DATA['database_host_id'])
|
|
||||||
->once()
|
|
||||||
->andReturnNull();
|
|
||||||
$this->repository->shouldReceive('createDatabase')->with(
|
|
||||||
self::TEST_DATA['database'],
|
|
||||||
'dynamic'
|
|
||||||
)->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->encrypter->shouldReceive('decrypt')->with('enc_password')->once()->andReturn('str_random');
|
|
||||||
$this->repository->shouldReceive('createUser')->with(
|
|
||||||
self::TEST_DATA['username'],
|
|
||||||
self::TEST_DATA['remote'],
|
|
||||||
'str_random',
|
|
||||||
'dynamic'
|
|
||||||
)->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('assignUserToDatabase')->with(
|
|
||||||
self::TEST_DATA['database'],
|
|
||||||
self::TEST_DATA['username'],
|
|
||||||
self::TEST_DATA['remote'],
|
|
||||||
'dynamic'
|
|
||||||
)->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('flush')->with('dynamic')->once()->andReturnNull();
|
|
||||||
$this->database->shouldReceive('commit')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
$response = $this->service->create(1, [
|
|
||||||
'database' => 'dbname',
|
|
||||||
'remote' => '%',
|
|
||||||
'database_host_id' => 3,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->assertNotEmpty($response);
|
|
||||||
$this->assertTrue(is_object($response), 'Assert that response is an object.');
|
|
||||||
|
|
||||||
$this->assertEquals(self::TEST_DATA['database'], $response->database);
|
|
||||||
$this->assertEquals(self::TEST_DATA['remote'], $response->remote);
|
|
||||||
$this->assertEquals(self::TEST_DATA['username'], $response->username);
|
|
||||||
$this->assertEquals(self::TEST_DATA['password'], $response->password);
|
|
||||||
$this->assertEquals(self::TEST_DATA['database_host_id'], $response->database_host_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that an exception before the database is created and returned does not attempt any actions.
|
|
||||||
*
|
|
||||||
* @expectedException \Exception
|
|
||||||
*/
|
|
||||||
public function testExceptionBeforeDatabaseIsCreatedShouldNotAttemptAnyRollBackOperations()
|
|
||||||
{
|
|
||||||
$this->encrypter->shouldReceive('encrypt')->with('str_random')->once()->andReturn('enc_password');
|
|
||||||
$this->database->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
|
||||||
$this->repository->shouldReceive('createIfNotExists')
|
|
||||||
->with(self::TEST_DATA)
|
|
||||||
->once()
|
|
||||||
->andThrow(new Exception('Test Message'));
|
|
||||||
$this->repository->shouldNotReceive('dropDatabase');
|
|
||||||
$this->database->shouldReceive('rollBack')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->service->create(1, [
|
|
||||||
'database' => 'dbname',
|
|
||||||
'remote' => '%',
|
|
||||||
'database_host_id' => 3,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that an exception after database creation attempts to clean up previous operations.
|
|
||||||
*
|
|
||||||
* @expectedException \Exception
|
|
||||||
*/
|
|
||||||
public function testExceptionAfterDatabaseCreationShouldAttemptRollBackOperations()
|
|
||||||
{
|
|
||||||
$this->encrypter->shouldReceive('encrypt')->with('str_random')->once()->andReturn('enc_password');
|
|
||||||
$this->database->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
|
||||||
$this->repository->shouldReceive('createIfNotExists')
|
|
||||||
->with(self::TEST_DATA)
|
|
||||||
->once()
|
|
||||||
->andReturn((object) self::TEST_DATA);
|
|
||||||
$this->dynamic->shouldReceive('set')
|
|
||||||
->with('dynamic', self::TEST_DATA['database_host_id'])
|
|
||||||
->once()
|
|
||||||
->andReturnNull();
|
|
||||||
$this->repository->shouldReceive('createDatabase')->with(
|
|
||||||
self::TEST_DATA['database'],
|
|
||||||
'dynamic'
|
|
||||||
)->once()->andThrow(new Exception('Test Message'));
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('dropDatabase')
|
|
||||||
->with(self::TEST_DATA['database'], 'dynamic')
|
|
||||||
->once()
|
|
||||||
->andReturnNull();
|
|
||||||
$this->repository->shouldReceive('dropUser')->with(
|
|
||||||
self::TEST_DATA['username'],
|
|
||||||
self::TEST_DATA['remote'],
|
|
||||||
'dynamic'
|
|
||||||
)->once()->andReturnNull();
|
|
||||||
$this->repository->shouldReceive('flush')->with('dynamic')->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->database->shouldReceive('rollBack')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->service->create(1, [
|
|
||||||
'database' => 'dbname',
|
|
||||||
'remote' => '%',
|
|
||||||
'database_host_id' => 3,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that an exception thrown during a rollback operation is silently handled and not returned.
|
|
||||||
*/
|
|
||||||
public function testExceptionThrownDuringRollBackProcessShouldNotBeThrownToCallingFunction()
|
|
||||||
{
|
|
||||||
$this->encrypter->shouldReceive('encrypt')->with('str_random')->once()->andReturn('enc_password');
|
|
||||||
$this->database->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
|
||||||
$this->repository->shouldReceive('createIfNotExists')
|
|
||||||
->with(self::TEST_DATA)
|
|
||||||
->once()
|
|
||||||
->andReturn((object) self::TEST_DATA);
|
|
||||||
$this->dynamic->shouldReceive('set')
|
|
||||||
->with('dynamic', self::TEST_DATA['database_host_id'])
|
|
||||||
->once()
|
|
||||||
->andReturnNull();
|
|
||||||
$this->repository->shouldReceive('createDatabase')->with(
|
|
||||||
self::TEST_DATA['database'],
|
|
||||||
'dynamic'
|
|
||||||
)->once()->andThrow(new Exception('Test One'));
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('dropDatabase')->with(self::TEST_DATA['database'], 'dynamic')
|
|
||||||
->once()->andThrow(new Exception('Test Two'));
|
|
||||||
|
|
||||||
$this->database->shouldReceive('rollBack')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->service->create(1, [
|
|
||||||
'database' => 'dbname',
|
|
||||||
'remote' => '%',
|
|
||||||
'database_host_id' => 3,
|
|
||||||
]);
|
|
||||||
} catch (Exception $ex) {
|
|
||||||
$this->assertInstanceOf(Exception::class, $ex);
|
|
||||||
$this->assertEquals('Test One', $ex->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that a password can be changed for a given database.
|
|
||||||
*/
|
|
||||||
public function testDatabasePasswordShouldBeChanged()
|
|
||||||
{
|
|
||||||
$this->repository->shouldReceive('find')->with(1)->once()->andReturn((object) self::TEST_DATA);
|
|
||||||
$this->dynamic->shouldReceive('set')
|
|
||||||
->with('dynamic', self::TEST_DATA['database_host_id'])
|
|
||||||
->once()
|
|
||||||
->andReturnNull();
|
|
||||||
$this->database->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->encrypter->shouldReceive('encrypt')->with('new_password')->once()->andReturn('new_enc_password');
|
|
||||||
$this->repository->shouldReceive('withoutFresh')->withNoArgs()->once()->andReturnSelf()
|
|
||||||
->shouldReceive('update')->with(1, [
|
|
||||||
'password' => 'new_enc_password',
|
|
||||||
])->andReturn(true);
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('dropUser')->with(
|
|
||||||
self::TEST_DATA['username'],
|
|
||||||
self::TEST_DATA['remote'],
|
|
||||||
'dynamic'
|
|
||||||
)->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('createUser')->with(
|
|
||||||
self::TEST_DATA['username'],
|
|
||||||
self::TEST_DATA['remote'],
|
|
||||||
'new_password',
|
|
||||||
'dynamic'
|
|
||||||
)->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('assignUserToDatabase')->with(
|
|
||||||
self::TEST_DATA['database'],
|
|
||||||
self::TEST_DATA['username'],
|
|
||||||
self::TEST_DATA['remote'],
|
|
||||||
'dynamic'
|
|
||||||
)->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('flush')->with('dynamic')->once()->andReturnNull();
|
|
||||||
$this->database->shouldReceive('commit')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
$response = $this->service->changePassword(1, 'new_password');
|
|
||||||
|
|
||||||
$this->assertTrue($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that an exception thrown while changing a password will attempt a rollback.
|
|
||||||
*
|
|
||||||
* @expectedException \Exception
|
|
||||||
*/
|
|
||||||
public function testExceptionThrownWhileChangingDatabasePasswordShouldRollBack()
|
|
||||||
{
|
|
||||||
$this->repository->shouldReceive('find')->with(1)->once()->andReturn((object) self::TEST_DATA);
|
|
||||||
$this->dynamic->shouldReceive('set')
|
|
||||||
->with('dynamic', self::TEST_DATA['database_host_id'])
|
|
||||||
->once()
|
|
||||||
->andReturnNull();
|
|
||||||
$this->database->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->encrypter->shouldReceive('encrypt')->with('new_password')->once()->andReturn('new_enc_password');
|
|
||||||
$this->repository->shouldReceive('withoutFresh')->withNoArgs()->once()->andReturnSelf()
|
|
||||||
->shouldReceive('update')->with(1, [
|
|
||||||
'password' => 'new_enc_password',
|
|
||||||
])->andReturn(true);
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('dropUser')->with(
|
|
||||||
self::TEST_DATA['username'],
|
|
||||||
self::TEST_DATA['remote'],
|
|
||||||
'dynamic'
|
|
||||||
)->once()->andThrow(new Exception());
|
|
||||||
|
|
||||||
$this->database->shouldReceive('rollBack')->withNoArgs()->once()->andReturnNull();
|
|
||||||
|
|
||||||
$this->service->changePassword(1, 'new_password');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that a database can be deleted.
|
|
||||||
*/
|
|
||||||
public function testDatabaseShouldBeDeleted()
|
|
||||||
{
|
|
||||||
$this->repository->shouldReceive('find')->with(1)->once()->andReturn((object) self::TEST_DATA);
|
|
||||||
$this->dynamic->shouldReceive('set')
|
|
||||||
->with('dynamic', self::TEST_DATA['database_host_id'])
|
|
||||||
->once()
|
|
||||||
->andReturnNull();
|
|
||||||
|
|
||||||
$this->repository->shouldReceive('dropDatabase')
|
|
||||||
->with(self::TEST_DATA['database'], 'dynamic')
|
|
||||||
->once()
|
|
||||||
->andReturnNull();
|
|
||||||
$this->repository->shouldReceive('dropUser')->with(
|
|
||||||
self::TEST_DATA['username'],
|
|
||||||
self::TEST_DATA['remote'],
|
|
||||||
'dynamic'
|
|
||||||
)->once()->andReturnNull();
|
|
||||||
$this->repository->shouldReceive('flush')->with('dynamic')->once()->andReturnNull();
|
|
||||||
$this->repository->shouldReceive('delete')->with(1)->once()->andReturn(1);
|
|
||||||
|
|
||||||
$response = $this->service->delete(1);
|
|
||||||
|
|
||||||
$this->assertEquals(1, $response);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Unit\Services\Databases;
|
||||||
|
|
||||||
|
use Mockery as m;
|
||||||
|
use Tests\TestCase;
|
||||||
|
use Pterodactyl\Models\Database;
|
||||||
|
use Illuminate\Database\ConnectionInterface;
|
||||||
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
|
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
||||||
|
use Pterodactyl\Services\Databases\DatabasePasswordService;
|
||||||
|
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
||||||
|
|
||||||
|
class DatabasePasswordServiceTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Database\ConnectionInterface|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Extensions\DynamicDatabaseConnection|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $dynamic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Encryption\Encrypter|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $encrypter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup tests.
|
||||||
|
*/
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->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.
|
||||||
|
*
|
||||||
|
* @dataProvider useModelDataProvider
|
||||||
|
*/
|
||||||
|
public function testPasswordIsChanged($useModel)
|
||||||
|
{
|
||||||
|
$model = factory(Database::class)->make();
|
||||||
|
|
||||||
|
if (! $useModel) {
|
||||||
|
$this->repository->shouldReceive('find')->with(1234)->once()->andReturn($model);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dynamic->shouldReceive('set')->with('dynamic', $model->database_host_id)->once()->andReturnNull();
|
||||||
|
$this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
||||||
|
$this->encrypter->shouldReceive('encrypt')->with('test123')->once()->andReturn('enc123');
|
||||||
|
|
||||||
|
$this->repository->shouldReceive('withoutFresh')->withNoArgs()->once()->andReturnSelf();
|
||||||
|
$this->repository->shouldReceive('update')->with($model->id, ['password' => 'enc123'])->once()->andReturn(true);
|
||||||
|
|
||||||
|
$this->repository->shouldReceive('dropUser')->with($model->username, $model->remote)->once()->andReturnNull();
|
||||||
|
$this->repository->shouldReceive('createUser')->with($model->username, $model->remote, 'test123')->once()->andReturnNull();
|
||||||
|
$this->repository->shouldReceive('assignUserToDatabase')->with($model->database, $model->username, $model->remote)->once()->andReturnNull();
|
||||||
|
$this->repository->shouldReceive('flush')->withNoArgs()->once()->andReturnNull();
|
||||||
|
$this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull();
|
||||||
|
|
||||||
|
$response = $this->getService()->handle($useModel ? $model : 1234, 'test123');
|
||||||
|
$this->assertNotEmpty($response);
|
||||||
|
$this->assertTrue($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider to determine if a model should be passed or an int.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function useModelDataProvider(): array
|
||||||
|
{
|
||||||
|
return [[false], [true]];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
101
tests/Unit/Services/Databases/Hosts/HostCreationServiceTest.php
Normal file
101
tests/Unit/Services/Databases/Hosts/HostCreationServiceTest.php
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Unit\Services\Databases\Hosts;
|
||||||
|
|
||||||
|
use Mockery as m;
|
||||||
|
use Tests\TestCase;
|
||||||
|
use Pterodactyl\Models\DatabaseHost;
|
||||||
|
use Illuminate\Database\DatabaseManager;
|
||||||
|
use Illuminate\Database\ConnectionInterface;
|
||||||
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
|
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
||||||
|
use Pterodactyl\Services\Databases\Hosts\HostCreationService;
|
||||||
|
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
||||||
|
|
||||||
|
class HostCreationServiceTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Database\ConnectionInterface|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Database\DatabaseManager|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $databaseManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Extensions\DynamicDatabaseConnection|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $dynamic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Encryption\Encrypter|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $encrypter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup tests.
|
||||||
|
*/
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->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->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
||||||
|
$this->encrypter->shouldReceive('encrypt')->with('test123')->once()->andReturn('enc123');
|
||||||
|
$this->repository->shouldReceive('create')->with(m::subset([
|
||||||
|
'password' => 'enc123',
|
||||||
|
'username' => $model->username,
|
||||||
|
'node_id' => $model->node_id,
|
||||||
|
]))->once()->andReturn($model);
|
||||||
|
|
||||||
|
$this->dynamic->shouldReceive('set')->with('dynamic', $model)->once()->andReturnNull();
|
||||||
|
$this->databaseManager->shouldReceive('connection')->with('dynamic')->once()->andReturnSelf();
|
||||||
|
$this->databaseManager->shouldReceive('select')->with('SELECT 1 FROM dual')->once()->andReturnNull();
|
||||||
|
$this->connection->shouldReceive('commit')->withNoArgs()->once()->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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Unit\Services\Databases\Hosts;
|
||||||
|
|
||||||
|
use Mockery as m;
|
||||||
|
use Tests\TestCase;
|
||||||
|
use Pterodactyl\Exceptions\PterodactylException;
|
||||||
|
use Pterodactyl\Exceptions\Service\HasActiveServersException;
|
||||||
|
use Pterodactyl\Services\Databases\Hosts\HostDeletionService;
|
||||||
|
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
||||||
|
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
||||||
|
|
||||||
|
class HostDeletionServiceTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $databaseRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup tests.
|
||||||
|
*/
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->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($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);
|
||||||
|
}
|
||||||
|
}
|
112
tests/Unit/Services/Databases/Hosts/HostUpdateServiceTest.php
Normal file
112
tests/Unit/Services/Databases/Hosts/HostUpdateServiceTest.php
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Unit\Services\Databases\Hosts;
|
||||||
|
|
||||||
|
use Mockery as m;
|
||||||
|
use Tests\TestCase;
|
||||||
|
use Pterodactyl\Models\DatabaseHost;
|
||||||
|
use Illuminate\Database\DatabaseManager;
|
||||||
|
use Illuminate\Database\ConnectionInterface;
|
||||||
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
|
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
||||||
|
use Pterodactyl\Services\Databases\Hosts\HostUpdateService;
|
||||||
|
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
||||||
|
|
||||||
|
class HostUpdateServiceTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Database\ConnectionInterface|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Database\DatabaseManager|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $databaseManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Extensions\DynamicDatabaseConnection|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $dynamic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Encryption\Encrypter|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $encrypter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface|\Mockery\Mock
|
||||||
|
*/
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup tests.
|
||||||
|
*/
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->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->encrypter->shouldReceive('encrypt')->with('test123')->once()->andReturn('enc123');
|
||||||
|
$this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
||||||
|
$this->repository->shouldReceive('update')->with(1234, ['password' => 'enc123'])->once()->andReturn($model);
|
||||||
|
|
||||||
|
$this->dynamic->shouldReceive('set')->with('dynamic', $model)->once()->andReturnNull();
|
||||||
|
$this->databaseManager->shouldReceive('connection')->with('dynamic')->once()->andReturnSelf();
|
||||||
|
$this->databaseManager->shouldReceive('select')->with('SELECT 1 FROM dual')->once()->andReturnNull();
|
||||||
|
$this->connection->shouldReceive('commit')->withNoArgs()->once()->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->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
|
||||||
|
$this->repository->shouldReceive('update')->with(1234, ['username' => 'test'])->once()->andReturn($model);
|
||||||
|
|
||||||
|
$this->dynamic->shouldReceive('set')->with('dynamic', $model)->once()->andReturnNull();
|
||||||
|
$this->databaseManager->shouldReceive('connection')->with('dynamic')->once()->andReturnSelf();
|
||||||
|
$this->databaseManager->shouldReceive('select')->with('SELECT 1 FROM dual')->once()->andReturnNull();
|
||||||
|
$this->connection->shouldReceive('commit')->withNoArgs()->once()->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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue