From 23eebbf2adc7e9e3503af2b9fb603ce5dbc1db21 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Sun, 1 Nov 2026 15:49:13 +0100 Subject: [PATCH] fix(servers): refresh provider status with server details action --- app/Livewire/Server/Show.php | 29 +++++++++++++- .../views/livewire/server/show.blade.php | 38 +++++-------------- tests/Feature/HostingerServerCreationTest.php | 16 ++++++-- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/app/Livewire/Server/Show.php b/app/Livewire/Server/Show.php index 45b617fab1..bf5d519018 100644 --- a/app/Livewire/Server/Show.php +++ b/app/Livewire/Server/Show.php @@ -850,8 +850,11 @@ class Show extends Component { try { $this->authorize('update', $this->server); + $providerRefreshed = $this->refreshProviderStatus(); if (! $this->server->isFunctional()) { - $this->dispatch('error', 'Validate the server connection before fetching details.'); + $providerRefreshed + ? $this->dispatch('info', 'Provider status refreshed. Validate the server connection to fetch server details.') + : $this->dispatch('error', 'Validate the server connection before fetching details.'); return; } @@ -868,6 +871,30 @@ class Show extends Component } } + /** + * Refresh the state of the linked cloud provider server, if there is one. + */ + private function refreshProviderStatus(): bool + { + if (! $this->server->cloudProviderToken || $this->server->isTransferredAway()) { + return false; + } + + $check = match (true) { + filled($this->server->hetzner_server_id) => $this->checkHetznerServerStatus(...), + filled($this->server->digitalocean_droplet_id) => $this->checkDigitalOceanDropletStatus(...), + filled($this->server->vultr_instance_id) => $this->checkVultrInstanceStatus(...), + filled($this->server->hostinger_virtual_machine_id) => $this->checkHostingerVirtualMachineStatus(...), + default => null, + }; + if (! $check) { + return false; + } + $check(); + + return true; + } + public function submit() { try { diff --git a/resources/views/livewire/server/show.blade.php b/resources/views/livewire/server/show.blade.php index bbd3c5935b..96387be41d 100644 --- a/resources/views/livewire/server/show.blade.php +++ b/resources/views/livewire/server/show.blade.php @@ -28,6 +28,7 @@ 'Hostinger' => $hostingerVirtualMachineStatus, default => null, }; + $canRefreshProvider = $provider && $server->cloudProviderToken && ! $server->isTransferredAway(); $providerStatusType = match (true) { in_array($providerStatus, ['running', 'active']) => 'success', in_array($providerStatus, ['starting', 'initializing', 'pending', 'new', 'initial', 'creating', 'unsuspending', 'recreating', 'restoring']) => 'warning', @@ -265,35 +266,14 @@ - - @if ($provider) + @if ($provider) + - @if ($provider === 'Hetzner') - - - - @elseif ($provider === 'DigitalOcean') - - - - @elseif ($provider === 'Vultr') - - - - @elseif ($provider === 'Hostinger') - - - - @endif + + @endif + + @if ($provider) @if ($server->cloudProviderToken && ! $server->isTransferredAway()) @if ($provider === 'Hetzner' && !$server->isFunctional() && $hetznerServerStatus === 'off') + :disabled="! $server->isFunctional() && ! $canRefreshProvider" + :tooltip="$server->isFunctional() || $canRefreshProvider ? null : 'Validate the connection first.'"> {{ $server->server_metadata ? 'Refresh details' : 'Fetch server details' }} diff --git a/tests/Feature/HostingerServerCreationTest.php b/tests/Feature/HostingerServerCreationTest.php index ac39d73271..378b03e8be 100644 --- a/tests/Feature/HostingerServerCreationTest.php +++ b/tests/Feature/HostingerServerCreationTest.php @@ -407,7 +407,7 @@ it('starts a stopped Hostinger VPS from the server page', function () { expect($server->fresh()->hostinger_virtual_machine_status)->toBe('starting'); }); -it('labels the Hostinger status refresh button on the server page', function () { +it('refreshes the Hostinger status from the server details action before the server is validated', function () { $server = Server::factory()->create([ 'team_id' => $this->team->id, 'private_key_id' => $this->privateKey->id, @@ -416,10 +416,20 @@ it('labels the Hostinger status refresh button on the server page', function () 'hostinger_virtual_machine_status' => 'running', ]); + Http::fake([ + 'https://developers.hostinger.com/api/vps/v1/virtual-machines/17923' => Http::response([ + 'id' => 17923, + 'state' => 'stopped', + 'ipv4' => [['address' => $server->ip]], + ]), + ]); + Livewire::test(Show::class, ['server_uuid' => $server->uuid]) ->assertSee('Hostinger · Running') - ->assertSee('Refresh provider status') - ->assertSeeHtml('wire:click.prevent="checkHostingerVirtualMachineStatus(true)"'); + ->call('refreshServerMetadata') + ->assertSet('hostingerVirtualMachineStatus', 'stopped') + ->assertDispatched('info', 'Provider status refreshed. Validate the server connection to fetch server details.') + ->assertSee('Hostinger · Stopped'); }); it('does not validate a stopped Hostinger VPS over SSH', function () {