148 lines
5.7 KiB
PHP
148 lines
5.7 KiB
PHP
<?php
|
|
|
|
use App\Livewire\Admin\ConfirmReleaseReservation;
|
|
use App\Livewire\Admin\HostDetail;
|
|
use App\Models\Customer;
|
|
use App\Models\Host;
|
|
use App\Services\Provisioning\HostCapacity;
|
|
use Livewire\Livewire;
|
|
|
|
/**
|
|
* Ein Host, der jemandem gehört.
|
|
*
|
|
* Enterprise verkauft eine eigene Maschine. Ohne Markierung landet der nächste
|
|
* Startkunde darauf, und die Kapazitätszahlen versprechen den Platz obendrein
|
|
* ein zweites Mal.
|
|
*/
|
|
it('platziert keinen fremden Kunden auf einem reservierten Host', function () {
|
|
$mieter = Customer::factory()->create();
|
|
$fremder = Customer::factory()->create();
|
|
|
|
Host::factory()->active()->create([
|
|
'datacenter' => 'fsn', 'total_gb' => 4000,
|
|
'reserved_for_customer_id' => $mieter->id,
|
|
]);
|
|
|
|
expect(Host::placeableIn('fsn', 100, $fremder->id))->toBeNull()
|
|
->and(Host::placeableIn('fsn', 100, $mieter->id))->not->toBeNull();
|
|
});
|
|
|
|
it('zählt einen reservierten Host nicht zum allgemeinen Bestand', function () {
|
|
$mieter = Customer::factory()->create();
|
|
|
|
Host::factory()->active()->create([
|
|
'datacenter' => 'fsn', 'total_gb' => 4000,
|
|
'reserved_for_customer_id' => $mieter->id,
|
|
]);
|
|
|
|
expect(app(HostCapacity::class)->largestPlaceableGb('fsn'))->toBe(0)
|
|
->and(app(HostCapacity::class)->canPlace('fsn', 40))->toBeFalse();
|
|
});
|
|
|
|
it('lässt einen freien Host frei', function () {
|
|
Host::factory()->active()->create(['datacenter' => 'fsn', 'total_gb' => 500]);
|
|
|
|
expect(app(HostCapacity::class)->canPlace('fsn', 40))->toBeTrue();
|
|
});
|
|
|
|
/**
|
|
* Die Konsole: setzen und lösen.
|
|
*
|
|
* Setzen braucht keine Bestätigung — ein Host, der noch niemandem gehört,
|
|
* bekommt einen Besitzer, nichts geht verloren. Lösen schon (R23): danach
|
|
* ist die Maschine wieder allgemeiner Bestand, und der nächste Startkunde
|
|
* kann darauf landen.
|
|
*/
|
|
it('reserviert einen Host für einen Kunden von der Konsole aus', function () {
|
|
$host = Host::factory()->active()->create();
|
|
$customer = Customer::factory()->create();
|
|
|
|
Livewire::actingAs(admin(), 'operator')
|
|
->test(HostDetail::class, ['host' => $host])
|
|
->call('reserveFor', $customer->uuid)
|
|
->assertDispatched('notify');
|
|
|
|
expect($host->fresh()->reserved_for_customer_id)->toBe($customer->id);
|
|
});
|
|
|
|
it('verweigert das Reservieren ohne hosts.manage', function () {
|
|
$host = Host::factory()->active()->create();
|
|
$customer = Customer::factory()->create();
|
|
|
|
Livewire::actingAs(operator('Read-only'), 'operator')
|
|
->test(HostDetail::class, ['host' => $host])
|
|
->call('reserveFor', $customer->uuid)
|
|
->assertForbidden();
|
|
|
|
expect($host->fresh()->reserved_for_customer_id)->toBeNull();
|
|
});
|
|
|
|
it('bestätigt das Lösen im eigenen Modal, ohne dabei selbst etwas zu ändern', function () {
|
|
$mieter = Customer::factory()->create(['name' => 'Acme GmbH']);
|
|
$host = Host::factory()->active()->create(['reserved_for_customer_id' => $mieter->id]);
|
|
|
|
Livewire::actingAs(admin(), 'operator')
|
|
->test(ConfirmReleaseReservation::class, ['uuid' => $host->uuid])
|
|
->assertSee('Acme GmbH')
|
|
->call('confirmRelease')
|
|
->assertDispatched('host-reservation-release-confirmed');
|
|
|
|
// Das Modal selbst rührt nichts an — die Reservierung steht noch.
|
|
expect($host->fresh()->reserved_for_customer_id)->toBe($mieter->id);
|
|
});
|
|
|
|
it('löst die Reservierung, sobald die Seite das bestätigte Ereignis empfängt', function () {
|
|
$mieter = Customer::factory()->create();
|
|
$host = Host::factory()->active()->create(['reserved_for_customer_id' => $mieter->id]);
|
|
|
|
Livewire::actingAs(admin(), 'operator')
|
|
->test(HostDetail::class, ['host' => $host])
|
|
->call('onReleaseConfirmed')
|
|
->assertDispatched('notify');
|
|
|
|
expect($host->fresh()->reserved_for_customer_id)->toBeNull();
|
|
});
|
|
|
|
/**
|
|
* Erklärt statt versteckt (Aufgabenauflösung #4): eine reservierte Maschine
|
|
* verschwindet nirgends kommentarlos aus dem Bestand — Host-Detailseite,
|
|
* Host-Liste und Kapazitätsseite weisen sie jeweils als solche aus.
|
|
*/
|
|
it('zeigt die Reservierung auf der Host-Detailseite', function () {
|
|
$mieter = Customer::factory()->create(['name' => 'Contoso KG']);
|
|
$host = Host::factory()->active()->create(['reserved_for_customer_id' => $mieter->id]);
|
|
|
|
$this->actingAs(admin(), 'operator')->get(route('admin.hosts.show', $host))
|
|
->assertOk()
|
|
->assertSee(__('hosts.detail.reserved_for', ['name' => 'Contoso KG']));
|
|
});
|
|
|
|
it('bietet auf der Host-Detailseite eine Kundenauswahl, solange nichts reserviert ist', function () {
|
|
$host = Host::factory()->active()->create();
|
|
$customer = Customer::factory()->create(['name' => 'Globex AG']);
|
|
|
|
$this->actingAs(admin(), 'operator')->get(route('admin.hosts.show', $host))
|
|
->assertOk()
|
|
->assertSee(__('hosts.detail.reserved_general'))
|
|
->assertSee('Globex AG');
|
|
});
|
|
|
|
it('weist die Reservierung auf der Host-Liste aus', function () {
|
|
$mieter = Customer::factory()->create(['name' => 'Umbrella Corp']);
|
|
Host::factory()->active()->create(['name' => 'pve-reserved-1', 'reserved_for_customer_id' => $mieter->id]);
|
|
|
|
$this->actingAs(admin(), 'operator')->get(route('admin.hosts'))
|
|
->assertOk()
|
|
->assertSee(__('hosts.reserved_badge', ['name' => 'Umbrella Corp']));
|
|
});
|
|
|
|
it('weist die Reservierung auf der Kapazitätsseite aus', function () {
|
|
App\Models\Datacenter::factory()->create(['code' => 'fsn2']);
|
|
$mieter = Customer::factory()->create(['name' => 'Initech Ltd']);
|
|
Host::factory()->active()->create(['datacenter' => 'fsn2', 'reserved_for_customer_id' => $mieter->id]);
|
|
|
|
$this->actingAs(admin(), 'operator')->get(route('admin.capacity'))
|
|
->assertOk()
|
|
->assertSee(__('hosts.reserved_badge', ['name' => 'Initech Ltd']));
|
|
});
|