fix(domains): close edit modal after save and drop Lima seeds

Dispatch edit-domain-saved so Alpine closes the domain edit modal,
wire Save to updateDomain, and force white active log toolbar text in
dark mode. Seed railpack examples on the local Docker destination only
and remove Lima servers, environments, and V5DevLimaSeeder.
This commit is contained in:
Andras Bacsai
2026-08-06 13:45:19 +02:00
parent bb83c1e3be
commit 9fd2a21f24
17 changed files with 116 additions and 402 deletions
@@ -1039,6 +1039,7 @@ class Domains extends Component
$this->forceSaveDomains = false;
$this->pendingAction = null;
$this->cancelEdit();
$this->dispatch('edit-domain-saved');
$this->dispatch('success', 'Domain updated.');
$this->refreshDomains();
$this->checkUrlsDns([$newUrl], $service);
+1
View File
@@ -964,6 +964,7 @@ class Domains extends Component
}
$this->cancelEdit();
$this->dispatch('edit-domain-saved');
$this->forceSaveDomains = false;
$this->forceRemovePort = false;
$this->pendingAction = null;
-1
View File
@@ -35,7 +35,6 @@ class DatabaseSeeder extends Seeder
if (in_array(config('app.env'), ['local', 'development', 'dev'], true)) {
$this->call([
DevelopmentRailpackExamplesSeeder::class,
V5DevLimaSeeder::class,
]);
}
}
@@ -26,27 +26,6 @@ class DevelopmentRailpackExamplesSeeder extends Seeder
public const REPOSITORY_PROJECT_ID = 603035348;
public const LIMA_SERVERS = [
[
'server_uuid' => 'lima-ubuntu-2404',
'server_name' => 'lima-ubuntu-2404',
'port' => 2222,
'environment_name' => 'ubuntu24',
'environment_uuid' => 'railpack-examples-ubuntu24',
'uuid_prefix' => 'ubuntu24-',
],
[
'server_uuid' => 'lima-ubuntu-2604',
'server_name' => 'lima-ubuntu-2604',
'port' => 2223,
'environment_name' => 'ubuntu26',
'environment_uuid' => 'railpack-examples-ubuntu26',
'uuid_prefix' => 'ubuntu26-',
],
];
private const LIMA_SENTINEL_URL = 'http://host.lima.internal:8000';
public function run(): void
{
if (! $this->isDevelopmentEnvironment()) {
@@ -64,15 +43,7 @@ class DevelopmentRailpackExamplesSeeder extends Seeder
$this->cleanupLegacyLimaProjects();
$this->cleanupLegacyProductionExamples();
foreach (self::LIMA_SERVERS as $limaServer) {
$this->seedEnvironment(
environmentUuid: $limaServer['environment_uuid'],
environmentName: $limaServer['environment_name'],
destination: $this->limaDestination($limaServer['server_uuid']),
uuidPrefix: $limaServer['uuid_prefix'],
nameSuffix: " ({$limaServer['environment_name']})",
);
}
$this->seedEnvironment(StandaloneDocker::query()->findOrFail(0));
}
/**
@@ -465,37 +436,6 @@ KEY,
],
);
foreach (self::LIMA_SERVERS as $limaServer) {
$server = Server::query()->firstOrCreate(
['uuid' => $limaServer['server_uuid']],
[
'name' => $limaServer['server_name'],
'description' => 'This is a Lima VM for local development testing',
'ip' => 'host.docker.internal',
'port' => $limaServer['port'],
'team_id' => 0,
'private_key_id' => 1,
'proxy' => [
'type' => ProxyTypes::TRAEFIK->value,
'status' => ProxyStatus::EXITED->value,
],
],
);
$server->settings->forceFill([
'sentinel_custom_url' => self::LIMA_SENTINEL_URL,
])->saveQuietly();
StandaloneDocker::query()->firstOrCreate(
['server_id' => $server->id],
[
'uuid' => "{$limaServer['server_uuid']}-docker",
'name' => "{$limaServer['server_name']} Docker",
'network' => 'coolify',
],
);
}
StandaloneDocker::query()->firstOrCreate(
['id' => 0],
[
@@ -545,21 +485,6 @@ KEY,
return in_array(config('app.env'), ['local', 'development', 'dev'], true);
}
private function limaDestination(string $serverUuid): StandaloneDocker
{
$limaDestination = Server::query()
->where('uuid', $serverUuid)
->first()
?->standaloneDockers()
->first();
if (! $limaDestination) {
throw new RuntimeException("Lima StandaloneDocker destination is required for {$serverUuid} before running DevelopmentRailpackExamplesSeeder.");
}
return $limaDestination;
}
private function cleanupLegacyLimaProjects(): void
{
Project::query()
@@ -595,21 +520,16 @@ KEY,
->forceDelete();
}
private function seedEnvironment(
string $environmentUuid,
string $environmentName,
StandaloneDocker $destination,
string $uuidPrefix = '',
string $nameSuffix = '',
): void {
$environment = $this->prepareEnvironment($environmentUuid, $environmentName);
private function seedEnvironment(StandaloneDocker $destination): void
{
$environment = $this->prepareEnvironment();
foreach (self::examples() as $example) {
$this->upsertApplication($environment, $destination, $example, $uuidPrefix, $nameSuffix);
$this->upsertApplication($environment, $destination, $example);
}
}
private function prepareEnvironment(string $environmentUuid, string $environmentName): Environment
private function prepareEnvironment(): Environment
{
$project = Project::query()->firstOrNew(['uuid' => self::PROJECT_UUID]);
$project->fill([
@@ -619,31 +539,20 @@ KEY,
]);
$project->save();
$environment = $project->environments()
->where(function ($query) use ($environmentName, $environmentUuid): void {
$query
->where('name', $environmentName)
->orWhere('uuid', $environmentUuid);
})
->first();
$environment = $project->environments()->firstOrCreate(['name' => 'production']);
$existingEnvironment = $project->environments()->first();
$project->environments()
->whereKeyNot($environment->id)
->get()
->each(function (Environment $obsoleteEnvironment): void {
Application::withTrashed()
->where('environment_id', $obsoleteEnvironment->id)
->get()
->each
->forceDelete();
if (! $environment && $project->environments()->count() === 1 && $existingEnvironment?->name === 'production') {
$environment = $existingEnvironment;
}
if (! $environment) {
$environment = $project->environments()->create([
'name' => $environmentName,
'uuid' => $environmentUuid,
]);
} else {
$environment->update([
'name' => $environmentName,
'uuid' => $environmentUuid,
]);
}
$obsoleteEnvironment->delete();
});
return $environment;
}
@@ -651,10 +560,10 @@ KEY,
/**
* @param array<string, mixed> $example
*/
private function upsertApplication(Environment $environment, StandaloneDocker $destination, array $example, string $uuidPrefix = '', string $nameSuffix = ''): void
private function upsertApplication(Environment $environment, StandaloneDocker $destination, array $example): void
{
$uuid = $uuidPrefix.$example['uuid'];
$name = $example['name'].$nameSuffix;
$uuid = $example['uuid'];
$name = $example['name'];
$application = Application::withTrashed()->firstOrNew(['uuid' => $uuid]);
$application->fill([
'name' => $name,
+1 -16
View File
@@ -7,28 +7,13 @@ use Illuminate\Database\Seeder;
class ProjectSeeder extends Seeder
{
private const LIMA_ENVIRONMENTS = [
['name' => 'ubuntu24', 'uuid' => 'ubuntu24'],
['name' => 'ubuntu26', 'uuid' => 'ubuntu26'],
];
public function run(): void
{
$project = Project::create([
Project::create([
'uuid' => 'project',
'name' => 'My first project',
'description' => 'This is a test project in development',
'team_id' => 0,
]);
foreach (self::LIMA_ENVIRONMENTS as $index => $environment) {
if ($index === 0) {
$project->environments()->first()->update($environment);
continue;
}
$project->environments()->create($environment);
}
}
}
-27
View File
@@ -9,13 +9,6 @@ use Illuminate\Database\Seeder;
class ServerSeeder extends Seeder
{
private const LIMA_SENTINEL_URL = 'http://host.lima.internal:8000';
private const LIMA_SERVERS = [
['uuid' => 'lima-ubuntu-2404', 'name' => 'lima-ubuntu-2404', 'port' => 2222],
['uuid' => 'lima-ubuntu-2604', 'name' => 'lima-ubuntu-2604', 'port' => 2223],
];
public function run(): void
{
Server::create([
@@ -31,25 +24,5 @@ class ServerSeeder extends Seeder
'status' => ProxyStatus::EXITED->value,
],
]);
foreach (self::LIMA_SERVERS as $limaServer) {
$server = Server::create([
'uuid' => $limaServer['uuid'],
'name' => $limaServer['name'],
'description' => 'This is a Lima VM for local development testing',
'ip' => 'host.docker.internal',
'port' => $limaServer['port'],
'team_id' => 0,
'private_key_id' => 1,
'proxy' => [
'type' => ProxyTypes::TRAEFIK->value,
'status' => ProxyStatus::EXITED->value,
],
]);
$server->settings->forceFill([
'sentinel_custom_url' => self::LIMA_SENTINEL_URL,
])->saveQuietly();
}
}
}
+4
View File
@@ -2692,6 +2692,10 @@ input[type="search"]::-webkit-search-results-decoration {
color: #fff;
}
.dark .logs-viewer-btn-active {
color: #fff;
}
.logs-viewer-viewport {
min-width: 0;
padding: 0.5rem 0.75rem;
@@ -38,7 +38,8 @@
$wire.showEditDomainModal = true;
},
}"
@open-edit-domain.window="openEditDomain($event.detail.index, $event.detail.url, $event.detail.service)">
@open-edit-domain.window="openEditDomain($event.detail.index, $event.detail.url, $event.detail.service)"
@edit-domain-saved.window="closeEditDomain()">
<x-application.settings-section id="domains-section" title="Domains" :helper="$helperText">
@can('update', $application)
<x-slot:actions>
@@ -368,16 +369,13 @@
@endif
<div class="flex flex-wrap items-center justify-end gap-2 pt-2">
<x-forms.button type="button" @click="closeEditDomain()">
Cancel
</x-forms.button>
@if ($editDomainDnsFailed)
<x-forms.button type="button" isError
@click="prepareEditSubmit(); $wire.forceSaveEditDns = true; $wire.confirmUpdateDomainDespiteDns()">
Continue
</x-forms.button>
@else
<x-forms.button type="submit" isHighlighted>
<x-forms.button type="submit" wire:target="updateDomain" isHighlighted>
Save
</x-forms.button>
@endif
@@ -37,7 +37,8 @@
$wire.showEditDomainModal = true;
},
}"
@open-edit-domain.window="openEditDomain($event.detail.index, $event.detail.url, $event.detail.serviceApplicationId, $event.detail.serviceLabel)">
@open-edit-domain.window="openEditDomain($event.detail.index, $event.detail.url, $event.detail.serviceApplicationId, $event.detail.serviceLabel)"
@edit-domain-saved.window="closeEditDomain()">
<x-application.settings-section id="service-domains-section" title="Domains">
@can('update', $service)
<x-slot:actions>
@@ -273,16 +274,13 @@
@endif
<div class="flex flex-wrap items-center justify-end gap-2 pt-2">
<x-forms.button type="button" @click="closeEditDomain()">
Cancel
</x-forms.button>
@if ($editDomainDnsFailed)
<x-forms.button type="button" isError
@click="prepareEditSubmit(); $wire.forceSaveEditDns = true; $wire.confirmUpdateDomainDespiteDns()">
Continue
</x-forms.button>
@else
<x-forms.button type="submit" isHighlighted>
<x-forms.button type="submit" wire:target="updateDomain" isHighlighted>
Save
</x-forms.button>
@endif
+1
View File
@@ -275,6 +275,7 @@ it('updates a domain in place via modal', function () {
->call('updateDomain')
->assertHasNoErrors()
->assertSet('showEditDomainModal', false)
->assertDispatched('edit-domain-saved')
->assertDispatched('success');
$this->application->refresh();
@@ -5,6 +5,7 @@ test('active deployment log controls use a coollabs background and white icon',
expect($styles)
->toMatch('/\.logs-viewer-btn-active\s*\{[^}]*background:\s*var\(--color-coollabs\);[^}]*color:\s*#fff;/s')
->toMatch('/\.dark \.logs-viewer-btn-active\s*\{[^}]*color:\s*#fff;/s')
->not->toMatch('/\.logs-viewer-btn-active\s*\{[^}]*var\(--color-warning\)/s');
});
+1 -1
View File
@@ -32,7 +32,7 @@ it('runs the v5 dev Lima seeder with the normal development database seeder', fu
$developmentSeederBlock = str($databaseSeeder)->after("if (in_array(config('app.env'), ['local', 'development', 'dev'], true)) {")->before(' }')->toString();
expect($developmentSeederBlock)->toContain('DevelopmentRailpackExamplesSeeder::class')
->and($developmentSeederBlock)->toContain('V5DevLimaSeeder::class');
->and($developmentSeederBlock)->not->toContain('V5DevLimaSeeder::class');
});
it('disables Flux host binding by default in the Docker development environment', function () {
@@ -17,7 +17,6 @@ use Database\Seeders\StandaloneDockerSeeder;
use Database\Seeders\TeamSeeder;
use Database\Seeders\UserSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Collection;
uses(RefreshDatabase::class);
@@ -34,189 +33,79 @@ function seedRailpackExamplePrerequisites(): void
]);
}
function limaServers(): Collection
{
return collect(DevelopmentRailpackExamplesSeeder::LIMA_SERVERS);
}
it('can seed the railpack examples directly on a clean development database', function () {
config()->set('app.env', 'local');
$this->seed(DevelopmentRailpackExamplesSeeder::class);
expect(Team::query()->find(0))->not->toBeNull();
expect(PrivateKey::query()->find(1))->not->toBeNull();
expect(Server::query()->find(0))->not->toBeNull();
expect(StandaloneDocker::query()->find(0))->not->toBeNull();
expect(GithubApp::query()->find(0))->not->toBeNull();
expect(GitlabApp::query()->find(1))->not->toBeNull();
expect(Application::query()->count())->toBe(count(DevelopmentRailpackExamplesSeeder::examples()) * limaServers()->count());
expect(Team::query()->find(0))->not->toBeNull()
->and(PrivateKey::query()->find(1))->not->toBeNull()
->and(Server::query()->count())->toBe(1)
->and(Server::query()->find(0)?->uuid)->toBe('localhost')
->and(StandaloneDocker::query()->find(0))->not->toBeNull()
->and(GithubApp::query()->find(0))->not->toBeNull()
->and(GitlabApp::query()->find(1))->not->toBeNull()
->and(Application::query()->count())->toBe(count(DevelopmentRailpackExamplesSeeder::examples()));
$project = Project::query()
->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)
->first();
$project = Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->firstOrFail();
expect($project)
->not->toBeNull()
->and($project->environments)->toHaveCount(limaServers()->count());
foreach (limaServers() as $limaServer) {
$server = Server::query()->where('uuid', $limaServer['server_uuid'])->first();
expect($server)->not->toBeNull();
expect($server->settings->sentinel_custom_url)->toBe('http://host.lima.internal:8000');
expect(StandaloneDocker::query()->whereRelation('server', 'uuid', $limaServer['server_uuid'])->exists())->toBeTrue();
expect($project->environments()->where('uuid', $limaServer['environment_uuid'])->exists())->toBeTrue();
}
expect($project->environments)->toHaveCount(1)
->and($project->environments->first()->name)->toBe('production')
->and($project->applications()->whereRelation('destination.server', 'uuid', 'localhost')->count())
->toBe(count(DevelopmentRailpackExamplesSeeder::examples()));
});
it('seeds the railpack examples in development mode', function () {
it('seeds every railpack example in the production environment on testing-host', function () {
config()->set('app.env', 'local');
seedRailpackExamplePrerequisites();
$legacyProject = Project::query()->create([
'uuid' => 'railpack-examples-lima-ubuntu-2404',
'name' => 'Railpack Examples - lima-ubuntu-2404',
'description' => 'Legacy generated Railpack examples project',
$this->seed(DevelopmentRailpackExamplesSeeder::class);
$project = Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->firstOrFail();
$environment = $project->environments()->sole();
$applications = $environment->applications()->with('settings', 'destination.server')->orderBy('uuid')->get();
expect($environment->name)->toBe('production')
->and($applications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()))
->and($applications->every(fn (Application $application) => $application->build_pack === 'railpack'))->toBeTrue()
->and($applications->every(fn (Application $application) => $application->destination->server->uuid === 'localhost'))->toBeTrue()
->and($applications->pluck('uuid')->sort()->values()->all())
->toBe(collect(DevelopmentRailpackExamplesSeeder::examples())->pluck('uuid')->sort()->values()->all());
$nestjs = $applications->firstWhere('uuid', 'railpack-nestjs');
$angularStatic = $applications->firstWhere('uuid', 'railpack-angular-static');
$githubDeployKey = $applications->firstWhere('uuid', 'railpack-github-deploy-key');
$gitlabDeployKey = $applications->firstWhere('uuid', 'railpack-gitlab-deploy-key');
expect($nestjs->base_directory)->toBe('/node/nestjs')
->and($nestjs->build_command)->toBe('npm run build')
->and($nestjs->start_command)->toBe('npm run start:prod')
->and($angularStatic->publish_directory)->toBe('/dist/static/browser')
->and($angularStatic->settings->is_static)->toBeTrue()
->and($githubDeployKey->private_key_id)->toBe(1)
->and($githubDeployKey->source_type)->toBe(GithubApp::class)
->and($gitlabDeployKey->source_type)->toBe(GitlabApp::class);
});
it('consolidates legacy railpack environments into production', function () {
config()->set('app.env', 'local');
seedRailpackExamplePrerequisites();
$project = Project::query()->create([
'uuid' => DevelopmentRailpackExamplesSeeder::PROJECT_UUID,
'name' => 'Railpack Examples',
'team_id' => 0,
]);
Application::query()->create([
'uuid' => 'lima-ubuntu-2404-railpack-nextjs-ssr',
'name' => 'Legacy Railpack Next.js SSR Example',
'repository_project_id' => DevelopmentRailpackExamplesSeeder::REPOSITORY_PROJECT_ID,
'git_repository' => DevelopmentRailpackExamplesSeeder::GIT_REPOSITORY,
'git_branch' => DevelopmentRailpackExamplesSeeder::GIT_BRANCH,
'build_pack' => 'railpack',
'ports_exposes' => '3000',
'environment_id' => $legacyProject->environments()->first()->id,
'destination_id' => 0,
'destination_type' => StandaloneDocker::class,
'source_id' => 0,
'source_type' => GithubApp::class,
]);
$project->environments()->first()->update(['name' => 'ubuntu24', 'uuid' => 'railpack-examples-ubuntu24']);
$project->environments()->create(['name' => 'ubuntu26', 'uuid' => 'railpack-examples-ubuntu26']);
$this->seed(DevelopmentRailpackExamplesSeeder::class);
$project = Project::query()
->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)
->first();
$project->refresh();
expect($project)
->not->toBeNull()
->and($project->name)->toBe('Railpack Examples')
->and($project->environments)->toHaveCount(limaServers()->count());
expect(Project::query()->pluck('uuid')->sort()->values()->all())->toBe([
'project',
DevelopmentRailpackExamplesSeeder::PROJECT_UUID,
]);
expect(Application::query()->where('uuid', 'lima-ubuntu-2404-railpack-nextjs-ssr')->exists())->toBeFalse();
$applications = $project->applications()->with('settings')->orderBy('uuid')->get();
expect($applications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()) * limaServers()->count());
expect($applications->every(fn (Application $application) => $application->build_pack === 'railpack'))->toBeTrue();
$examples = collect(DevelopmentRailpackExamplesSeeder::examples())->keyBy('uuid');
expect($applications->every(
fn (Application $application) => $application->git_repository === ($examples->get(str($application->uuid)->after('-')->value())['git_repository'] ?? DevelopmentRailpackExamplesSeeder::GIT_REPOSITORY)
))->toBeTrue();
expect($applications->every(
fn (Application $application) => $application->git_branch === ($examples->get(str($application->uuid)->after('-')->value())['git_branch'] ?? DevelopmentRailpackExamplesSeeder::GIT_BRANCH)
))->toBeTrue();
foreach (limaServers() as $limaServer) {
$limaEnvironment = $project->environments()
->where('uuid', $limaServer['environment_uuid'])
->first();
expect($limaEnvironment)
->not->toBeNull()
->and($limaEnvironment->name)->toBe($limaServer['environment_name']);
$limaApplications = $limaEnvironment->applications()->with('settings', 'destination.server')->orderBy('uuid')->get();
expect($limaApplications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()));
expect($limaApplications->every(fn (Application $application) => $application->build_pack === 'railpack'))->toBeTrue();
expect($limaApplications->every(fn (Application $application) => str($application->uuid)->startsWith($limaServer['uuid_prefix'])))->toBeTrue();
expect($limaApplications->every(fn (Application $application) => $application->destination->server->uuid === $limaServer['server_uuid']))->toBeTrue();
expect($limaApplications->every(
fn (Application $application) => $application->git_repository === ($examples->get(str($application->uuid)->after($limaServer['uuid_prefix'])->value())['git_repository'] ?? DevelopmentRailpackExamplesSeeder::GIT_REPOSITORY)
))->toBeTrue();
expect($limaApplications->every(
fn (Application $application) => $application->git_branch === ($examples->get(str($application->uuid)->after($limaServer['uuid_prefix'])->value())['git_branch'] ?? DevelopmentRailpackExamplesSeeder::GIT_BRANCH)
))->toBeTrue();
}
$nestjs = $applications->firstWhere('uuid', 'ubuntu24-railpack-nestjs');
$angularStatic = $applications->firstWhere('uuid', 'ubuntu24-railpack-angular-static');
$eleventyStatic = $applications->firstWhere('uuid', 'ubuntu24-railpack-eleventy-static');
$pythonFlask = $applications->firstWhere('uuid', 'ubuntu24-railpack-python-flask');
$goGin = $applications->firstWhere('uuid', 'ubuntu24-railpack-go-gin');
$rust = $applications->firstWhere('uuid', 'ubuntu24-railpack-rust');
$githubDeployKey = $applications->firstWhere('uuid', 'ubuntu24-railpack-github-deploy-key');
$gitlabDeployKey = $applications->firstWhere('uuid', 'ubuntu24-railpack-gitlab-deploy-key');
$gitlabPublic = $applications->firstWhere('uuid', 'ubuntu24-railpack-gitlab-public-example');
expect($nestjs)
->not->toBeNull()
->and($nestjs->base_directory)->toBe('/node/nestjs')
->and($nestjs->ports_exposes)->toBe('3000')
->and($nestjs->build_command)->toBe('npm run build')
->and($nestjs->start_command)->toBe('npm run start:prod')
->and($nestjs->settings->is_static)->toBeFalse();
expect($angularStatic)
->not->toBeNull()
->and($angularStatic->publish_directory)->toBe('/dist/static/browser')
->and($angularStatic->ports_exposes)->toBe('80')
->and($angularStatic->settings->is_static)->toBeTrue()
->and($angularStatic->settings->is_spa)->toBeTrue();
expect($eleventyStatic)
->not->toBeNull()
->and($eleventyStatic->publish_directory)->toBe('/_site')
->and($eleventyStatic->settings->is_static)->toBeTrue()
->and($eleventyStatic->settings->is_spa)->toBeFalse();
expect($pythonFlask)
->not->toBeNull()
->and($pythonFlask->ports_exposes)->toBe('5000')
->and($pythonFlask->start_command)->toBe('flask run --host=0.0.0.0 --port=5000');
expect($goGin)
->not->toBeNull()
->and($goGin->ports_exposes)->toBe('3000');
expect($rust)
->not->toBeNull()
->and($rust->ports_exposes)->toBe('8000');
expect($githubDeployKey)
->not->toBeNull()
->and($githubDeployKey->git_repository)->toBe('git@github.com:coollabsio/coolify-examples-deploy-key.git')
->and($githubDeployKey->git_branch)->toBe('main')
->and($githubDeployKey->build_pack)->toBe('railpack')
->and($githubDeployKey->private_key_id)->toBe(1)
->and($githubDeployKey->source_type)->toBe(GithubApp::class)
->and($githubDeployKey->source_id)->toBe(0);
expect($gitlabDeployKey)
->not->toBeNull()
->and($gitlabDeployKey->git_repository)->toBe('git@gitlab.com:coollabsio/php-example.git')
->and($gitlabDeployKey->git_branch)->toBe('main')
->and($gitlabDeployKey->build_pack)->toBe('railpack')
->and($gitlabDeployKey->private_key_id)->toBe(1)
->and($gitlabDeployKey->source_type)->toBe(GitlabApp::class)
->and($gitlabDeployKey->source_id)->toBe(1);
expect($gitlabPublic)
->not->toBeNull()
->and($gitlabPublic->git_repository)->toBe('https://gitlab.com/andrasbacsai/coolify-examples.git')
->and($gitlabPublic->base_directory)->toBe('/astro/static')
->and($gitlabPublic->publish_directory)->toBe('/dist')
->and($gitlabPublic->build_pack)->toBe('railpack')
->and($gitlabPublic->source_type)->toBe(GitlabApp::class)
->and($gitlabPublic->settings->is_static)->toBeTrue();
expect($project->environments)->toHaveCount(1)
->and($project->environments->first()->name)->toBe('production')
->and($project->applications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()));
});
it('skips the railpack examples outside development mode', function () {
@@ -226,13 +115,6 @@ it('skips the railpack examples outside development mode', function () {
$this->seed(DevelopmentRailpackExamplesSeeder::class);
expect(Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->exists())->toBeFalse();
expect(Application::query()->where('uuid', 'railpack-nextjs-ssr')->exists())->toBeFalse();
foreach (limaServers() as $limaServer) {
expect(Project::query()->where('uuid', 'railpack-examples-lima-ubuntu-2404')->exists())->toBeFalse();
expect(Project::query()->where('uuid', 'railpack-examples-lima-ubuntu-2604')->exists())->toBeFalse();
expect(Application::query()->where('uuid', $limaServer['uuid_prefix'].'railpack-nextjs-ssr')->exists())->toBeFalse();
}
});
it('is idempotent when run multiple times', function () {
@@ -242,19 +124,8 @@ it('is idempotent when run multiple times', function () {
$this->seed(DevelopmentRailpackExamplesSeeder::class);
$this->seed(DevelopmentRailpackExamplesSeeder::class);
$project = Project::query()
->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)
->first();
$project = Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->firstOrFail();
expect($project)->not->toBeNull();
expect($project->applications()->count())->toBe(count(DevelopmentRailpackExamplesSeeder::examples()) * limaServers()->count());
foreach (limaServers() as $limaServer) {
$limaEnvironment = $project->environments()
->where('uuid', $limaServer['environment_uuid'])
->first();
expect($limaEnvironment)->not->toBeNull();
expect($limaEnvironment->applications()->count())->toBe(count(DevelopmentRailpackExamplesSeeder::examples()));
}
expect($project->environments)->toHaveCount(1)
->and($project->applications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()));
});
@@ -1,5 +1,19 @@
<?php
test('edit domain dialogs close after saving and omit redundant cancel actions', function () {
foreach ([
resource_path('views/livewire/project/application/domains.blade.php'),
resource_path('views/livewire/project/service/domains.blade.php'),
] as $viewPath) {
$view = file_get_contents($viewPath);
expect($view)
->toContain('@edit-domain-saved.window="closeEditDomain()"')
->toContain('<x-forms.button type="submit" wire:target="updateDomain" isHighlighted>')
->not->toContain("@click=\"closeEditDomain()\">\n Cancel");
}
});
it('provides a reusable domain chips form component', function () {
$component = file_get_contents(resource_path('views/components/forms/domain-chips.blade.php'));
+3 -5
View File
@@ -9,7 +9,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
it('seeds the first project with lima environments', function () {
it('seeds the first project with only a production environment', function () {
$this->seed([
UserSeeder::class,
TeamSeeder::class,
@@ -24,8 +24,6 @@ it('seeds the first project with lima environments', function () {
expect($project)
->not->toBeNull()
->and($project->name)->toBe('My first project')
->and($project->environments()->pluck('uuid', 'name')->all())->toBe([
'ubuntu24' => 'ubuntu24',
'ubuntu26' => 'ubuntu26',
]);
->and($project->environments)->toHaveCount(1)
->and($project->environments->first()->name)->toBe('production');
});
+3 -43
View File
@@ -6,19 +6,10 @@ use Database\Seeders\ServerSeeder;
use Database\Seeders\TeamSeeder;
use Database\Seeders\UserSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Symfony\Component\Yaml\Yaml;
uses(RefreshDatabase::class);
function limaServerDefinitions(): array
{
return [
['uuid' => 'lima-ubuntu-2404', 'port' => 2222, 'template' => 'ubuntu-2404.yaml', 'memory' => '2GiB', 'disk' => '20GiB'],
['uuid' => 'lima-ubuntu-2604', 'port' => 2223, 'template' => 'ubuntu-2604.yaml', 'memory' => '2GiB', 'disk' => '20GiB'],
];
}
it('seeds the development testing host and lima servers', function () {
it('seeds only the development testing host', function () {
$this->seed([
UserSeeder::class,
TeamSeeder::class,
@@ -30,37 +21,6 @@ it('seeds the development testing host and lima servers', function () {
expect($testingHost)
->not->toBeNull()
->and($testingHost->ip)->toBe('coolify-testing-host');
foreach (limaServerDefinitions() as $definition) {
$limaServer = Server::query()->where('uuid', $definition['uuid'])->first();
expect($limaServer)
->not->toBeNull()
->and($limaServer->name)->toBe($definition['uuid'])
->and($limaServer->ip)->toBe('host.docker.internal')
->and($limaServer->port)->toBe($definition['port'])
->and($limaServer->user)->toBe('root')
->and($limaServer->team_id)->toBe(0)
->and($limaServer->private_key_id)->toBe(1)
->and($limaServer->settings)->not->toBeNull()
->and($limaServer->settings->sentinel_custom_url)->toBe('http://host.lima.internal:8000')
->and($limaServer->destinations())->toHaveCount(1);
}
});
it('keeps the lima templates aligned with the seeded servers', function () {
foreach (limaServerDefinitions() as $definition) {
$template = Yaml::parseFile(base_path("docker/lima/{$definition['template']}"));
$script = data_get($template, 'provision.0.script');
expect(data_get($template, 'ssh.localPort'))
->toBe($definition['port'])
->and(data_get($template, 'memory'))->toBe($definition['memory'])
->and(data_get($template, 'disk'))->toBe($definition['disk'])
->and(data_get($template, 'containerd.system'))->toBeFalse()
->and(data_get($template, 'containerd.user'))->toBeFalse()
->and(data_get($template, 'networks'))->toBeNull()
->and($script)->toContain('ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFuGmoeGq/pojrsyP1pszcNVuZx9iFkCELtxrh31QJ68');
}
->and($testingHost->ip)->toBe('coolify-testing-host')
->and(Server::query()->count())->toBe(1);
});
+1
View File
@@ -332,6 +332,7 @@ it('prunes the previous dns status when a service domain is renamed', function (
->set('editingDomain', 'https://renamed.example.com')
->call('updateDomain')
->assertHasNoErrors()
->assertDispatched('edit-domain-saved')
->assertDispatched('success');
$this->apiApp->refresh();