141 lines
5.2 KiB
PHP
141 lines
5.2 KiB
PHP
<?php
|
|
|
|
use App\Enums\RolePermissionModels;
|
|
use App\Filament\Admin\Resources\Servers\Pages\CreateServer;
|
|
use App\Filament\Admin\Resources\Servers\Pages\EditServer;
|
|
use App\Filament\Admin\Resources\Servers\RelationManagers\AllocationsRelationManager;
|
|
use App\Models\Allocation;
|
|
use App\Models\Egg;
|
|
use App\Models\Node;
|
|
use App\Models\Role;
|
|
use App\Models\Server;
|
|
use App\Repositories\Daemon\DaemonServerRepository;
|
|
use Filament\Actions\Testing\TestAction;
|
|
use Filament\Facades\Filament;
|
|
use Spatie\Permission\Models\Permission;
|
|
|
|
use function Pest\Livewire\livewire;
|
|
|
|
beforeEach(function () {
|
|
Filament::setCurrentPanel(Filament::getPanel('admin'));
|
|
|
|
[$this->admin] = generateTestAccount();
|
|
$this->admin->syncRoles(Role::getRootAdmin());
|
|
$this->actingAs($this->admin);
|
|
});
|
|
afterEach(fn () => Filament::setCurrentPanel(null));
|
|
|
|
it('can create a server', function () {
|
|
$daemon = Mockery::mock(DaemonServerRepository::class);
|
|
$daemon->expects('setServer')->andReturnSelf();
|
|
$daemon->expects('create')->andReturnUndefined();
|
|
$this->swap(DaemonServerRepository::class, $daemon);
|
|
|
|
$node = Node::factory()->create();
|
|
$allocation = Allocation::factory()->create(['node_id' => $node->id, 'server_id' => null]);
|
|
// A factory egg has no variables, so no required environment values get in the way.
|
|
$egg = Egg::factory()->create();
|
|
|
|
livewire(CreateServer::class)
|
|
->fillForm([
|
|
'name' => 'test-server',
|
|
'node_id' => $node->id,
|
|
'owner_id' => $this->admin->id,
|
|
'allocation_id' => $allocation->id,
|
|
'egg_id' => $egg->id,
|
|
'startup' => 'java -jar test.jar',
|
|
'image' => 'ghcr.io/pelican-eggs/yolks:java_21',
|
|
])
|
|
->call('create')
|
|
->assertHasNoFormErrors();
|
|
|
|
$this->assertDatabaseHas('servers', [
|
|
'name' => 'test-server',
|
|
'node_id' => $node->id,
|
|
'owner_id' => $this->admin->id,
|
|
'egg_id' => $egg->id,
|
|
]);
|
|
});
|
|
|
|
it('can edit a server', function () {
|
|
$server = Server::factory()->withNode()->create();
|
|
|
|
// Renaming is excluded from the daemon sync diff, so no daemon call happens.
|
|
livewire(EditServer::class, ['record' => $server->getKey()])
|
|
->fillForm([
|
|
'name' => 'renamed-server',
|
|
'allocation_limit' => 0,
|
|
'database_limit' => 0,
|
|
])
|
|
->call('save')
|
|
->assertHasNoFormErrors();
|
|
|
|
$this->assertDatabaseHas('servers', ['id' => $server->id, 'name' => 'renamed-server']);
|
|
});
|
|
|
|
it('can delete a server', function () {
|
|
$daemon = Mockery::mock(DaemonServerRepository::class);
|
|
$daemon->shouldReceive('setServer')->andReturnSelf();
|
|
// Rendering the edit page polls the server's container status.
|
|
$daemon->shouldReceive('getDetails')->andReturn(['state' => 'offline']);
|
|
$daemon->shouldReceive('delete');
|
|
$this->swap(DaemonServerRepository::class, $daemon);
|
|
|
|
$server = Server::factory()->withNode()->create();
|
|
|
|
livewire(EditServer::class, ['record' => $server->getKey()])
|
|
->callAction(TestAction::make('Delete'));
|
|
|
|
$this->assertDatabaseMissing('servers', ['id' => $server->id]);
|
|
});
|
|
|
|
it('moves the primary allocation when it is removed from a server', function () {
|
|
$server = createServerModel();
|
|
$primary = $server->allocation;
|
|
$other = Allocation::factory()->forServer($server)->create();
|
|
|
|
livewire(AllocationsRelationManager::class, ['ownerRecord' => $server, 'pageClass' => EditServer::class])
|
|
->callAction(TestAction::make('dissociate')->table($primary));
|
|
|
|
expect($primary->refresh()->server_id)->toBeNull()
|
|
->and($server->refresh()->allocation_id)->toBe($other->id);
|
|
});
|
|
|
|
it('clears the primary allocation when the last allocation is removed from a server', function () {
|
|
$server = createServerModel();
|
|
$primary = $server->allocation;
|
|
|
|
livewire(AllocationsRelationManager::class, ['ownerRecord' => $server, 'pageClass' => EditServer::class])
|
|
->callAction(TestAction::make('dissociate')->table($primary));
|
|
|
|
$server->refresh();
|
|
|
|
expect($server->allocation_id)->toBeNull()
|
|
->and(json_encode($server->getAllocationMappings()))->toBe('{"":[]}');
|
|
});
|
|
|
|
it('moves the primary allocation when it is removed from a server in bulk', function () {
|
|
$server = createServerModel();
|
|
$primary = $server->allocation;
|
|
[$removed, $kept] = Allocation::factory()->count(2)->forServer($server)->create();
|
|
|
|
livewire(AllocationsRelationManager::class, ['ownerRecord' => $server, 'pageClass' => EditServer::class])
|
|
->selectTableRecords([$primary->id, $removed->id])
|
|
->callAction(TestAction::make('dissociate')->table()->bulk());
|
|
|
|
expect($primary->refresh()->server_id)->toBeNull()
|
|
->and($removed->refresh()->server_id)->toBeNull()
|
|
->and($server->refresh()->allocation_id)->toBe($kept->id);
|
|
});
|
|
|
|
it('non root admin without permission cannot create servers', function () {
|
|
$role = Role::factory()->create(['name' => 'Egg Viewer', 'guard_name' => 'web']);
|
|
// Egg permission is on purpose, we check the wrong permissions.
|
|
$role->givePermissionTo(Permission::findOrCreate(RolePermissionModels::Egg->viewAny(), 'web'));
|
|
[$user] = generateTestAccount();
|
|
$user->syncRoles($role);
|
|
|
|
$this->actingAs($user);
|
|
livewire(CreateServer::class)->assertForbidden();
|
|
});
|