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')); });