coolify/tests/Feature/ApplicationPreviewSettingsTest.php
Andras Bacsai d75881fa96 feat(domains): keep domain drafts and move preview settings
Preserve in-progress domain edits and redirects across Livewire
refreshes, copy www port overrides for service redirect pairs, and
relocate preview deployment toggles from Advanced to Previews.
Unsaved bars can stay dirty via Alpine while a modal is closed, and
service domain tables stack at narrow widths.
2026-09-07 18:29:58 +02:00

139 lines
5.2 KiB
PHP

<?php
use App\Livewire\Project\Application\Previews;
use App\Models\Application;
use App\Models\Environment;
use App\Models\InstanceSettings;
use App\Models\PrivateKey;
use App\Models\Project;
use App\Models\Server;
use App\Models\StandaloneDocker;
use App\Models\Team;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Str;
use Livewire\Livewire;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->withoutVite();
config(['app.maintenance.driver' => 'file']);
InstanceSettings::unguarded(fn () => InstanceSettings::updateOrCreate(
['id' => 0],
[
'id' => 0,
'is_dns_validation_enabled' => false,
]
));
$this->team = Team::factory()->create();
$this->user = User::factory()->create();
$this->team->members()->attach($this->user->id, ['role' => 'owner']);
$this->actingAs($this->user);
session(['currentTeam' => $this->team]);
$key = PrivateKey::withoutEvents(fn () => PrivateKey::forceCreate([
'uuid' => (string) Str::uuid(),
'name' => 'Test Key',
'private_key' => 'test-key',
'team_id' => $this->team->id,
'created_at' => now(),
'updated_at' => now(),
]));
$this->server = Server::factory()->create([
'team_id' => $this->team->id,
'private_key_id' => $key->id,
'ip' => '203.0.113.10',
]);
$this->server->settings()->update([
'is_reachable' => true,
'is_usable' => true,
]);
StandaloneDocker::withoutEvents(function () {
$this->destination = StandaloneDocker::firstOrCreate(
['server_id' => $this->server->id, 'network' => 'coolify'],
['uuid' => (string) Str::uuid(), 'name' => 'test-docker']
);
});
$this->project = Project::factory()->create(['team_id' => $this->team->id]);
$this->environment = Environment::factory()->create(['project_id' => $this->project->id]);
$this->application = Application::factory()->create([
'uuid' => (string) Str::uuid(),
'name' => 'Preview App',
'preview_url_template' => '{{pr_id}}.{{domain}}',
'environment_id' => $this->environment->id,
'destination_id' => $this->destination->id,
'destination_type' => $this->destination->getMorphClass(),
'fqdn' => null,
'redirect' => 'both',
'build_pack' => 'nixpacks',
]);
$this->application->settings()->update([
'is_container_label_readonly_enabled' => true,
]);
});
it('shows preview settings and persists changes independently of preview inputs', function () {
Livewire::test(Previews::class, ['application' => $this->application])
->assertSee('PR deployment access')
->assertSet('isPreviewDeploymentsEnabled', false)
->set('manualPullRequestId', -1)
->set('isPreviewDeploymentsEnabled', true)
->set('isPrDeploymentsPublicEnabled', true)
->call('savePreviewSettings')
->assertHasNoErrors()
->assertDispatched('success');
expect($this->application->fresh()->settings)
->is_preview_deployments_enabled->toBeTrue()
->is_pr_deployments_public_enabled->toBeTrue();
Livewire::test(Previews::class, ['application' => $this->application->fresh()])
->assertSet('isPreviewDeploymentsEnabled', true)
->assertSet('isPrDeploymentsPublicEnabled', true)
->set('isPreviewDeploymentsEnabled', false)
->call('savePreviewSettings');
expect($this->application->fresh()->settings->is_preview_deployments_enabled)->toBeFalse();
});
it('does not show git preview settings for non-git applications', function (string $buildPack, ?string $dockerfile) {
$this->application->update(['build_pack' => $buildPack, 'dockerfile' => $dockerfile]);
Livewire::test(Previews::class, ['application' => $this->application->fresh()])
->assertDontSee('PR deployment access');
})->with([['dockerimage', null], ['dockerfile', 'FROM nginx']]);
it('denies preview setting changes without application update permission', function (string $role, bool $otherTeam) {
$user = User::factory()->create();
$team = $otherTeam ? Team::factory()->create() : $this->team;
$team->members()->attach($user->id, ['role' => $role]);
$this->actingAs($user);
session(['currentTeam' => $team]);
Livewire::test(Previews::class, ['application' => $this->application])
->set('isPreviewDeploymentsEnabled', true)
->set('isPrDeploymentsPublicEnabled', true)
->call('savePreviewSettings')
->assertForbidden();
expect($this->application->fresh()->settings)
->is_preview_deployments_enabled->toBeFalse()
->is_pr_deployments_public_enabled->toBeFalse();
})->with([['member', false], ['owner', true]]);
it('removes preview settings from Advanced including its persistence path', function () {
expect(file_get_contents(resource_path('views/livewire/project/application/advanced.blade.php')))
->not->toContain('isPreviewDeploymentsEnabled', 'isPrDeploymentsPublicEnabled');
expect(file_get_contents(app_path('Livewire/Project/Application/Advanced.php')))
->not->toContain('is_preview_deployments_enabled', 'is_pr_deployments_public_enabled');
});