CluPilotCloud/tests/Feature/Admin/DatacenterTest.php

169 lines
6.8 KiB
PHP

<?php
use App\Livewire\Admin\ConfirmDeleteDatacenter;
use App\Livewire\Admin\Datacenters;
use App\Livewire\Admin\HostCreate;
use App\Models\Datacenter;
use App\Models\Host;
use App\Models\User;
use Livewire\Livewire;
// admin() helper is defined in HostManagementTest (global Pest function).
it('gates the datacenters page', function () {
$this->get(route('admin.datacenters'))->assertRedirect(route('admin.login'));
$this->actingAs(User::factory()->create(['is_admin' => false]))->get(route('admin.datacenters'))->assertForbidden();
$this->actingAs(admin(), 'operator')->get(route('admin.datacenters'))->assertOk()->assertSee(__('datacenters.title'));
});
it('creates a datacenter', function () {
Livewire::actingAs(admin(), 'operator')
->test(Datacenters::class)
->set('code', 'NBG')
->set('name', 'Nürnberg')
->set('location', 'DE')
->call('save')
->assertHasNoErrors();
expect(Datacenter::query()->where('code', 'nbg')->where('name', 'Nürnberg')->exists())->toBeTrue();
});
it('rejects a duplicate datacenter code', function () {
Datacenter::query()->firstOrCreate(['code' => 'fsn'], ['name' => 'Falkenstein']);
Livewire::actingAs(admin(), 'operator')
->test(Datacenters::class)
->set('code', 'fsn')->set('name', 'Falkenstein')
->call('save')
->assertHasErrors(['code']);
});
it('edits a datacenter name and country via the modal', function () {
$dc = Datacenter::factory()->create(['code' => 'nbg', 'name' => 'Old', 'location' => 'AT']);
Livewire::actingAs(admin(), 'operator')
->test(\App\Livewire\Admin\EditDatacenter::class, ['uuid' => $dc->uuid])
->set('name', 'Nürnberg')
->set('location', 'DE')
->call('save')
->assertHasNoErrors();
$dc->refresh();
expect($dc->name)->toBe('Nürnberg')->and($dc->location)->toBe('DE')->and($dc->code)->toBe('nbg');
});
it('rejects an invalid country code on edit', function () {
$dc = Datacenter::factory()->create(['code' => 'nbg', 'location' => 'DE']);
Livewire::actingAs(admin(), 'operator')
->test(\App\Livewire\Admin\EditDatacenter::class, ['uuid' => $dc->uuid])
->set('location', 'ZZ')->call('save')->assertHasErrors(['location']);
});
it('deletes an unused datacenter', function () {
$dc = Datacenter::factory()->create(['code' => 'nbg']);
Livewire::actingAs(admin(), 'operator')->test(ConfirmDeleteDatacenter::class, ['uuid' => $dc->uuid])->call('delete');
expect(Datacenter::query()->where('uuid', $dc->uuid)->exists())->toBeFalse();
});
it('refuses to delete a datacenter that still has hosts', function () {
$dc = Datacenter::factory()->create(['code' => 'nbg']);
Host::factory()->create(['datacenter' => 'nbg']);
Livewire::actingAs(admin(), 'operator')->test(ConfirmDeleteDatacenter::class, ['uuid' => $dc->uuid])
->assertSet('hostCount', 1)
->call('delete');
expect(Datacenter::query()->where('uuid', $dc->uuid)->exists())->toBeTrue();
});
it('suspends and reactivates a customer', function () {
$customer = \App\Models\Customer::factory()->create(['status' => 'active']);
Livewire::actingAs(admin(), 'operator')->test(\App\Livewire\Admin\Customers::class)
->call('toggleSuspend', $customer->uuid);
expect($customer->fresh()->status)->toBe('suspended');
Livewire::actingAs(admin(), 'operator')->test(\App\Livewire\Admin\Customers::class)
->call('toggleSuspend', $customer->uuid);
expect($customer->fresh()->status)->toBe('active');
});
it('does not let the suspend toggle resurrect a closed customer', function () {
$customer = \App\Models\Customer::factory()->create(['status' => 'closed', 'closed_at' => now()]);
Livewire::actingAs(admin(), 'operator')->test(\App\Livewire\Admin\Customers::class)
->call('toggleSuspend', $customer->uuid);
$customer->refresh();
expect($customer->status)->toBe('closed')->and($customer->closed_at)->not->toBeNull();
});
it('toggles a datacenter active flag', function () {
$dc = Datacenter::factory()->create(['active' => true]);
Livewire::actingAs(admin(), 'operator')->test(Datacenters::class)->call('toggle', $dc->uuid);
expect($dc->fresh()->active)->toBeFalse();
});
it('offers only known datacenter codes when adding a host', function () {
Datacenter::query()->firstOrCreate(['code' => 'fsn'], ['name' => 'Falkenstein']);
// unknown code rejected
Livewire::actingAs(admin(), 'operator')
->test(HostCreate::class)
->set('name', 'pve-x')->set('datacenter', 'ghost')->set('public_ip', '203.0.113.5')->set('root_password', 'supersecret')
->call('save')
->assertHasErrors(['datacenter']);
// known code accepted (defaults to the first active datacenter on mount)
Livewire::actingAs(admin(), 'operator')
->test(HostCreate::class)
->assertSet('datacenter', 'fsn');
});
it('rejects creating a host in an inactive datacenter', function () {
Datacenter::query()->firstOrCreate(['code' => 'fsn'], ['name' => 'Falkenstein']);
Datacenter::factory()->create(['code' => 'old', 'active' => false]);
Livewire::actingAs(admin(), 'operator')
->test(HostCreate::class)
->set('name', 'pve-old')->set('datacenter', 'old')->set('public_ip', '203.0.113.6')->set('root_password', 'supersecret')
->call('save')
->assertHasErrors(['datacenter']);
});
it('can switch a location off, and does not evict what already runs there', function () {
// The column and the scope existed; the form did not offer them, so a
// datacenter could be created and never switched off again.
$dc = App\Models\Datacenter::factory()->create(['active' => true]);
App\Models\Host::factory()->create(['datacenter' => $dc->code]);
Livewire::actingAs(operator('Owner'), 'operator')
->test(App\Livewire\Admin\EditDatacenter::class, ['uuid' => $dc->uuid])
->assertSet('active', true)
->set('active', false)
->call('save')
->assertHasNoErrors();
expect($dc->refresh()->active)->toBeFalse()
// Switching off stops NEW placements; it does not evict what runs there.
->and(App\Models\Host::query()->where('datacenter', $dc->code)->exists())->toBeTrue();
});
it('warns about running hosts only when it actually switches a location off', function () {
// An already-inactive location announced that it had just been switched off
// every time its name was edited.
$dc = App\Models\Datacenter::factory()->create(['active' => false]);
App\Models\Host::factory()->create(['datacenter' => $dc->code]);
Livewire::actingAs(operator('Owner'), 'operator')
->test(App\Livewire\Admin\EditDatacenter::class, ['uuid' => $dc->uuid])
->set('name', 'Neuer Name')
->call('save')
->assertDispatched('notify', message: __('datacenters.updated'));
});