mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-14 22:17:19 +00:00
feat(server): auto-resolve Sentinel URL and polish setup UI
Ensure a Sentinel endpoint from instance FQDN/IP when enabling, use process dialogs for validation with install state, and tidy server create, boarding, metrics empty state, and log timestamps.
This commit is contained in:
1 parent
a6f71909fd
commit
8f7eb2d790
22 files changed
+306
-97
No files matched your search
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
test('boarding utility actions are centered', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/boarding/index.blade.php'));
|
||||
|
||||
expect($view)->toContain('class="mx-auto mt-6 flex w-full max-w-3xl flex-col items-center gap-3"');
|
||||
});
|
||||
|
||||
test('server validation opens in the centered process dialog', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/boarding/index.blade.php'));
|
||||
|
||||
expect($view)
|
||||
->toContain('<x-process-dialog closeWithX size="xl">')
|
||||
->toContain('@click="processDialogOpen = true"')
|
||||
->not->toContain('<x-slide-over closeWithX fullScreen>');
|
||||
});
|
||||
@@ -19,3 +19,20 @@ it('dispatches a server navbar refresh after toggling sentinel', function () {
|
||||
expect($matches['body'] ?? '')
|
||||
->toContain("\$this->dispatch('refreshServerShow');");
|
||||
});
|
||||
|
||||
it('only marks sentinel enabled after startup succeeds', function () {
|
||||
$componentSource = file_get_contents(app_path('Livewire/Server/Sentinel.php'));
|
||||
|
||||
preg_match('/public function toggleSentinel\([^)]*\).*?\{(?<body>.*?)\n \}/s', $componentSource, $matches);
|
||||
$toggleBody = $matches['body'] ?? '';
|
||||
|
||||
expect(strpos($toggleBody, 'StartSentinel::run'))->toBeLessThan(
|
||||
strpos($toggleBody, '$this->isSentinelEnabled = true;')
|
||||
);
|
||||
});
|
||||
|
||||
it('does not repeat a disabled status badge in the sentinel empty state', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/sentinel.blade.php'));
|
||||
|
||||
expect($view)->not->toContain("? 'Disabled'");
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
test('server settings explain dedicated build server mode', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/show.blade.php'));
|
||||
|
||||
expect($view)
|
||||
->toContain('label="Use as a dedicated build server"')
|
||||
->toContain('helper="Build servers compile applications but do not host deployments. Enabling this makes the server build-only."');
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
test('server creation uses the standard page title without redundant navigation', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/create.blade.php'));
|
||||
|
||||
expect($view)
|
||||
->toContain('<h1 class="min-w-0 text-[24px]! leading-7! font-semibold! tracking-tight!">New server</h1>')
|
||||
->not->toContain('Back to servers')
|
||||
->not->toContain('title="Add a server"');
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
test('server creation keeps private key actions together and advanced options collapsed', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/new/by-ip.blade.php'));
|
||||
|
||||
expect($view)
|
||||
->toContain('class="flex items-end gap-3"')
|
||||
->toContain('x-data="{ advancedOpen: false }"')
|
||||
->toContain('x-show="advancedOpen" x-cloak')
|
||||
->toContain('Advanced settings')
|
||||
->toContain('label="Use as a dedicated build server"')
|
||||
->toContain('helper="Build servers compile applications but do not host deployments. Enabling this makes the server build-only."');
|
||||
});
|
||||
|
||||
test('server creation places the IP address and private key before optional details', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/new/by-ip.blade.php'));
|
||||
|
||||
expect($view)
|
||||
->toContain('class="mb-5"')
|
||||
->and(strpos($view, 'id="ip"'))->toBeLessThan(strpos($view, 'id="private_key_id"'))
|
||||
->and(strpos($view, 'id="private_key_id"'))->toBeLessThan(strpos($view, 'id="name"'));
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
test('sentinel-required metrics state does not repeat an unavailable badge', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/charts.blade.php'));
|
||||
$sentinelRequiredState = str($view)->after('@else')->before('@endif')->toString();
|
||||
|
||||
expect($sentinelRequiredState)
|
||||
->toContain('title="Sentinel is required"')
|
||||
->not->toContain('status="Unavailable"');
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
test('server revalidation opens in the centered process dialog', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/show.blade.php'));
|
||||
|
||||
expect($view)
|
||||
->toContain('<x-process-dialog closeWithX size="xl">')
|
||||
->toContain(':isHighlighted="! $server->isFunctional()"')
|
||||
->toContain('@click="processDialogOpen = true" wire:click.prevent="validateServer"');
|
||||
});
|
||||
|
||||
test('completed server validation shows a close action instead of empty logs', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/validate-and-install.blade.php'));
|
||||
|
||||
expect($view)
|
||||
->toContain('$validationComplete')
|
||||
->toContain('mt-auto')
|
||||
->toContain('<x-forms.button type="button" @click="processDialogOpen = false">')
|
||||
->toContain('@click="processDialogOpen = false"')
|
||||
->toContain('Validation complete')
|
||||
->toContain('Close');
|
||||
});
|
||||
|
||||
test('installation logs are only shown after an installation starts', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/validate-and-install.blade.php'));
|
||||
$component = file_get_contents(app_path('Livewire/Server/ValidateAndInstall.php'));
|
||||
|
||||
expect($view)->toContain('@elseif ($isInstalling)')
|
||||
->and($component)
|
||||
->toContain('public bool $isInstalling = false;')
|
||||
->toContain('$this->isInstalling = true;');
|
||||
});
|
||||
|
||||
test('server validation content scrolls within the dialog', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/validate-and-install.blade.php'));
|
||||
$activityMonitor = file_get_contents(resource_path('views/livewire/activity-monitor.blade.php'));
|
||||
|
||||
expect($view)->toContain('class="flex h-full min-h-0 flex-col gap-4 overflow-y-auto scrollbar"')
|
||||
->and($activityMonitor)->toContain("'overflow-hidden' => !\$fullHeight")
|
||||
->and($activityMonitor)->not->toContain("'h-full overflow-hidden' => !\$fullHeight");
|
||||
});
|
||||
|
||||
test('validation checkpoints use the standard bordered list treatment', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/validate-and-install.blade.php'));
|
||||
|
||||
expect($view)
|
||||
->toContain('data-validation-checkpoints')
|
||||
->toContain('overflow-hidden rounded-[10px] border border-neutral-200 dark:border-white/[0.08]');
|
||||
});
|
||||
|
||||
test('all validation checkpoints remain visible while only the current phase runs', function () {
|
||||
$view = file_get_contents(resource_path('views/livewire/server/validate-and-install.blade.php'));
|
||||
|
||||
expect($view)->not->toContain("@continue(! \$checkpoint['visible'])");
|
||||
});
|
||||
Reference in new issue
Block a user