Skip to content

Commit 6d1b994

Browse files
committed
More tests
1 parent fd24729 commit 6d1b994

File tree

11 files changed

+625
-63
lines changed

11 files changed

+625
-63
lines changed

app/Http/Controllers/Admin/VariableController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public function view($option)
116116
*
117117
* @throws \Pterodactyl\Exceptions\DisplayException
118118
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
119+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
119120
* @throws \Pterodactyl\Exceptions\Services\ServiceVariable\ReservedVariableNameException
120121
*/
121122
public function update(OptionVariableFormRequest $request, ServiceOption $option, ServiceVariable $variable)

app/Services/Servers/CreationService.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ public function create(array $data)
196196
} catch (RequestException $exception) {
197197
$response = $exception->getResponse();
198198
$this->writer->warning($exception);
199+
$this->database->rollBack();
199200

200201
throw new DisplayException(trans('admin/server.exceptions.daemon_exception', [
201202
'code' => is_null($response) ? 'E_CONN_REFUSED' : $response->getStatusCode(),

app/Services/Servers/DeletionService.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
class DeletionService
3838
{
3939
/**
40-
* @var \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface
40+
* @var \Illuminate\Database\ConnectionInterface
4141
*/
42-
protected $daemonServerRepository;
42+
protected $connection;
4343

4444
/**
45-
* @var \Illuminate\Database\ConnectionInterface
45+
* @var \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface
4646
*/
47-
protected $database;
47+
protected $daemonServerRepository;
4848

4949
/**
5050
* @var \Pterodactyl\Services\Database\DatabaseManagementService
@@ -74,23 +74,23 @@ class DeletionService
7474
/**
7575
* DeletionService constructor.
7676
*
77-
* @param \Illuminate\Database\ConnectionInterface $database
77+
* @param \Illuminate\Database\ConnectionInterface $connection
7878
* @param \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface $daemonServerRepository
7979
* @param \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface $databaseRepository
8080
* @param \Pterodactyl\Services\Database\DatabaseManagementService $databaseManagementService
8181
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
8282
* @param \Illuminate\Log\Writer $writer
8383
*/
8484
public function __construct(
85-
ConnectionInterface $database,
85+
ConnectionInterface $connection,
8686
DaemonServerRepositoryInterface $daemonServerRepository,
8787
DatabaseRepositoryInterface $databaseRepository,
8888
DatabaseManagementService $databaseManagementService,
8989
ServerRepositoryInterface $repository,
9090
Writer $writer
9191
) {
9292
$this->daemonServerRepository = $daemonServerRepository;
93-
$this->database = $database;
93+
$this->connection = $connection;
9494
$this->databaseManagementService = $databaseManagementService;
9595
$this->databaseRepository = $databaseRepository;
9696
$this->repository = $repository;
@@ -114,7 +114,9 @@ public function withForce($bool = true)
114114
* Delete a server from the panel and remove any associated databases from hosts.
115115
*
116116
* @param int|\Pterodactyl\Models\Server $server
117+
*
117118
* @throws \Pterodactyl\Exceptions\DisplayException
119+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
118120
*/
119121
public function handle($server)
120122
{
@@ -140,12 +142,12 @@ public function handle($server)
140142
}
141143
}
142144

143-
$this->database->beginTransaction();
145+
$this->connection->beginTransaction();
144146
$this->databaseRepository->withColumns('id')->findWhere([['server_id', '=', $server->id]])->each(function ($item) {
145147
$this->databaseManagementService->delete($item->id);
146148
});
147149

148150
$this->repository->delete($server->id);
149-
$this->database->commit();
151+
$this->connection->commit();
150152
}
151153
}

app/Services/Servers/StartupModificationService.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ public function isAdmin($bool = true)
125125
*
126126
* @throws \Pterodactyl\Exceptions\DisplayException
127127
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
128+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
128129
*/
129130
public function handle($server, array $data)
130131
{

app/Services/Services/Variables/VariableCreationService.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ public function __construct(
5353
/**
5454
* Create a new variable for a given service option.
5555
*
56-
* @param int $option
57-
* @param array $data
56+
* @param int|\Pterodactyl\Models\ServiceOption $option
57+
* @param array $data
5858
* @return \Pterodactyl\Models\ServiceVariable
5959
*
6060
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
@@ -67,7 +67,9 @@ public function handle($option, array $data)
6767
}
6868

6969
if (in_array(strtoupper(array_get($data, 'env_variable')), explode(',', ServiceVariable::RESERVED_ENV_NAMES))) {
70-
throw new ReservedVariableNameException(sprintf('Cannot use the protected name %s for this environment variable.'));
70+
throw new ReservedVariableNameException(sprintf(
71+
'Cannot use the protected name %s for this environment variable.', array_get($data, 'env_variable')
72+
));
7173
}
7274

7375
$options = array_get($data, 'options', []);

app/Services/Services/Variables/VariableUpdateService.php

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,34 @@ class VariableUpdateService
3434
/**
3535
* @var \Pterodactyl\Contracts\Repository\ServiceVariableRepositoryInterface
3636
*/
37-
protected $serviceVariableRepository;
37+
protected $repository;
3838

39-
public function __construct(ServiceVariableRepositoryInterface $serviceVariableRepository)
39+
/**
40+
* VariableUpdateService constructor.
41+
*
42+
* @param \Pterodactyl\Contracts\Repository\ServiceVariableRepositoryInterface $repository
43+
*/
44+
public function __construct(ServiceVariableRepositoryInterface $repository)
4045
{
41-
$this->serviceVariableRepository = $serviceVariableRepository;
46+
$this->repository = $repository;
4247
}
4348

4449
/**
4550
* Update a specific service variable.
4651
*
4752
* @param int|\Pterodactyl\Models\ServiceVariable $variable
4853
* @param array $data
49-
* @return \Pterodactyl\Models\ServiceVariable
54+
* @return mixed
5055
*
5156
* @throws \Pterodactyl\Exceptions\DisplayException
5257
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
58+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
5359
* @throws \Pterodactyl\Exceptions\Services\ServiceVariable\ReservedVariableNameException
5460
*/
5561
public function handle($variable, array $data)
5662
{
5763
if (! $variable instanceof ServiceVariable) {
58-
$variable = $this->serviceVariableRepository->find($variable);
64+
$variable = $this->repository->find($variable);
5965
}
6066

6167
if (! is_null(array_get($data, 'env_variable'))) {
@@ -65,7 +71,7 @@ public function handle($variable, array $data)
6571
]));
6672
}
6773

68-
$search = $this->serviceVariableRepository->withColumns('id')->findCountWhere([
74+
$search = $this->repository->withColumns('id')->findCountWhere([
6975
['env_variable', '=', array_get($data, 'env_variable')],
7076
['option_id', '=', $variable->option_id],
7177
['id', '!=', $variable->id],
@@ -80,9 +86,9 @@ public function handle($variable, array $data)
8086

8187
$options = array_get($data, 'options', []);
8288

83-
return $this->serviceVariableRepository->update($variable->id, array_merge([
84-
'user_viewable' => in_array('user_viewable', $options, $variable->user_viewable),
85-
'user_editable' => in_array('user_editable', $options, $variable->user_editable),
89+
return $this->repository->withoutFresh()->update($variable->id, array_merge([
90+
'user_viewable' => in_array('user_viewable', $options),
91+
'user_editable' => in_array('user_editable', $options),
8692
], $data));
8793
}
8894
}

database/factories/ModelFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
'id' => $faker->unique()->randomNumber(),
9494
'service_id' => $faker->unique()->randomNumber(),
9595
'name' => $faker->name,
96-
'description' => $faker->sentences(3),
96+
'description' => implode(' ', $faker->sentences(3)),
9797
'tag' => $faker->unique()->randomNumber(5),
9898
];
9999
});

tests/Unit/Services/Servers/CreationServiceTest.php

Lines changed: 83 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424

2525
namespace Tests\Unit\Services\Servers;
2626

27+
use Exception;
28+
use GuzzleHttp\Exception\RequestException;
2729
use Mockery as m;
30+
use Pterodactyl\Exceptions\DisplayException;
2831
use Tests\TestCase;
29-
use Ramsey\Uuid\Uuid;
3032
use Illuminate\Log\Writer;
3133
use phpmock\phpunit\PHPMock;
3234
use Illuminate\Database\DatabaseManager;
@@ -54,11 +56,40 @@ class CreationServiceTest extends TestCase
5456
*/
5557
protected $daemonServerRepository;
5658

59+
/**
60+
* @var array
61+
*/
62+
protected $data = [
63+
'node_id' => 1,
64+
'name' => 'SomeName',
65+
'description' => null,
66+
'owner_id' => 1,
67+
'memory' => 128,
68+
'disk' => 128,
69+
'swap' => 0,
70+
'io' => 500,
71+
'cpu' => 0,
72+
'allocation_id' => 1,
73+
'allocation_additional' => [2, 3],
74+
'environment' => [
75+
'TEST_VAR_1' => 'var1-value',
76+
],
77+
'service_id' => 1,
78+
'option_id' => 1,
79+
'startup' => 'startup-param',
80+
'docker_image' => 'some/image',
81+
];
82+
5783
/**
5884
* @var \Illuminate\Database\DatabaseManager
5985
*/
6086
protected $database;
6187

88+
/**
89+
* @var \GuzzleHttp\Exception\RequestException
90+
*/
91+
protected $exception;
92+
6293
/**
6394
* @var \Pterodactyl\Contracts\Repository\NodeRepositoryInterface
6495
*/
@@ -114,6 +145,7 @@ public function setUp()
114145
$this->allocationRepository = m::mock(AllocationRepositoryInterface::class);
115146
$this->daemonServerRepository = m::mock(DaemonServerRepositoryInterface::class);
116147
$this->database = m::mock(DatabaseManager::class);
148+
$this->exception = m::mock(RequestException::class);
117149
$this->nodeRepository = m::mock(NodeRepositoryInterface::class);
118150
$this->repository = m::mock(ServerRepositoryInterface::class);
119151
$this->serverVariableRepository = m::mock(ServerVariableRepositoryInterface::class);
@@ -148,67 +180,46 @@ public function setUp()
148180
*/
149181
public function testCreateShouldHitAllOfTheNecessaryServicesAndStoreTheServer()
150182
{
151-
$data = [
152-
'node_id' => 1,
153-
'name' => 'SomeName',
154-
'description' => null,
155-
'owner_id' => 1,
156-
'memory' => 128,
157-
'disk' => 128,
158-
'swap' => 0,
159-
'io' => 500,
160-
'cpu' => 0,
161-
'allocation_id' => 1,
162-
'allocation_additional' => [2, 3],
163-
'environment' => [
164-
'TEST_VAR_1' => 'var1-value',
165-
],
166-
'service_id' => 1,
167-
'option_id' => 1,
168-
'startup' => 'startup-param',
169-
'docker_image' => 'some/image',
170-
];
171-
172183
$this->validatorService->shouldReceive('isAdmin')->withNoArgs()->once()->andReturnSelf()
173-
->shouldReceive('setFields')->with($data['environment'])->once()->andReturnSelf()
174-
->shouldReceive('validate')->with($data['option_id'])->once()->andReturnSelf();
184+
->shouldReceive('setFields')->with($this->data['environment'])->once()->andReturnSelf()
185+
->shouldReceive('validate')->with($this->data['option_id'])->once()->andReturnSelf();
175186

176187
$this->database->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
177188
$this->uuid->shouldReceive('uuid4')->withNoArgs()->once()->andReturnSelf()
178189
->shouldReceive('toString')->withNoArgs()->once()->andReturn('uuid-0000');
179-
$this->usernameService->shouldReceive('generate')->with($data['name'], 'randomstring')
190+
$this->usernameService->shouldReceive('generate')->with($this->data['name'], 'randomstring')
180191
->once()->andReturn('user_name');
181192

182193
$this->repository->shouldReceive('create')->with([
183194
'uuid' => 'uuid-0000',
184195
'uuidShort' => 'randomstring',
185-
'node_id' => $data['node_id'],
186-
'name' => $data['name'],
187-
'description' => $data['description'],
196+
'node_id' => $this->data['node_id'],
197+
'name' => $this->data['name'],
198+
'description' => $this->data['description'],
188199
'skip_scripts' => false,
189200
'suspended' => false,
190-
'owner_id' => $data['owner_id'],
191-
'memory' => $data['memory'],
192-
'swap' => $data['swap'],
193-
'disk' => $data['disk'],
194-
'io' => $data['io'],
195-
'cpu' => $data['cpu'],
201+
'owner_id' => $this->data['owner_id'],
202+
'memory' => $this->data['memory'],
203+
'swap' => $this->data['swap'],
204+
'disk' => $this->data['disk'],
205+
'io' => $this->data['io'],
206+
'cpu' => $this->data['cpu'],
196207
'oom_disabled' => false,
197-
'allocation_id' => $data['allocation_id'],
198-
'service_id' => $data['service_id'],
199-
'option_id' => $data['option_id'],
208+
'allocation_id' => $this->data['allocation_id'],
209+
'service_id' => $this->data['service_id'],
210+
'option_id' => $this->data['option_id'],
200211
'pack_id' => null,
201-
'startup' => $data['startup'],
212+
'startup' => $this->data['startup'],
202213
'daemonSecret' => 'randomstring',
203-
'image' => $data['docker_image'],
214+
'image' => $this->data['docker_image'],
204215
'username' => 'user_name',
205216
'sftp_password' => null,
206217
])->once()->andReturn((object) [
207218
'node_id' => 1,
208219
'id' => 1,
209220
]);
210221

211-
$this->allocationRepository->shouldReceive('assignAllocationsToServer')->with(1, [1, 2, 3]);
222+
$this->allocationRepository->shouldReceive('assignAllocationsToServer')->with(1, [1, 2, 3])->once()->andReturnNull();
212223
$this->validatorService->shouldReceive('getResults')->withNoArgs()->once()->andReturn([[
213224
'id' => 1,
214225
'key' => 'TEST_VAR_1',
@@ -224,9 +235,40 @@ public function testCreateShouldHitAllOfTheNecessaryServicesAndStoreTheServer()
224235
->shouldReceive('create')->with(1)->once()->andReturnNull();
225236
$this->database->shouldReceive('commit')->withNoArgs()->once()->andReturnNull();
226237

227-
$response = $this->service->create($data);
238+
$response = $this->service->create($this->data);
228239

229240
$this->assertEquals(1, $response->id);
230241
$this->assertEquals(1, $response->node_id);
231242
}
243+
244+
/**
245+
* Test handling of node timeout or other daemon error.
246+
*/
247+
public function testExceptionShouldBeThrownIfTheRequestFails()
248+
{
249+
$this->validatorService->shouldReceive('isAdmin->setFields->validate->getResults')->once()->andReturn([]);
250+
$this->database->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
251+
$this->uuid->shouldReceive('uuid4->toString')->once()->andReturn('uuid-0000');
252+
$this->usernameService->shouldReceive('generate')->once()->andReturn('user_name');
253+
$this->repository->shouldReceive('create')->once()->andReturn((object) [
254+
'node_id' => 1,
255+
'id' => 1,
256+
]);
257+
258+
$this->allocationRepository->shouldReceive('assignAllocationsToServer')->once()->andReturnNull();
259+
$this->serverVariableRepository->shouldReceive('insert')->with([])->once()->andReturnNull();
260+
$this->daemonServerRepository->shouldReceive('setNode->create')->once()->andThrow($this->exception);
261+
$this->exception->shouldReceive('getResponse')->withNoArgs()->once()->andReturnNull();
262+
$this->writer->shouldReceive('warning')->with($this->exception)->once()->andReturnNull();
263+
$this->database->shouldReceive('rollBack')->withNoArgs()->once()->andReturnNull();
264+
265+
try {
266+
$this->service->create($this->data);
267+
} catch (Exception $exception) {
268+
$this->assertInstanceOf(DisplayException::class, $exception);
269+
$this->assertEquals(trans('admin/server.exceptions.daemon_exception', [
270+
'code' => 'E_CONN_REFUSED',
271+
]), $exception->getMessage());
272+
}
273+
}
232274
}

0 commit comments

Comments
 (0)