mirror of
https://github.com/tiennm99/coolify.git
synced 2026-08-05 08:22:45 +00:00
fix(shared-variables): support direct mount params and comment field for server variables
Allow SharedVariables Livewire components (Environment, Project, Server) to accept UUID parameters directly via mount() instead of relying solely on route parameters. This enables Livewire component testing without a live route context. Also adds comment field support when saving/updating server shared environment variables, guards PostgreSQL-specific migration statements from running under SQLite (test environment compatibility), and expands the feature test suite with server shared variable scenarios including inline comment preservation and update behaviour.
This commit is contained in:
@@ -51,11 +51,14 @@ class Show extends Component
|
||||
}
|
||||
}
|
||||
|
||||
public function mount()
|
||||
public function mount(?string $project_uuid = null, ?string $environment_uuid = null)
|
||||
{
|
||||
$this->parameters = get_route_parameters();
|
||||
$this->project = Project::ownedByCurrentTeam()->where('uuid', request()->route('project_uuid'))->firstOrFail();
|
||||
$this->environment = $this->project->environments()->where('uuid', request()->route('environment_uuid'))->firstOrFail();
|
||||
$projectUuid = $project_uuid ?? request()->route('project_uuid');
|
||||
$environmentUuid = $environment_uuid ?? request()->route('environment_uuid');
|
||||
|
||||
$this->project = Project::ownedByCurrentTeam()->where('uuid', $projectUuid)->firstOrFail();
|
||||
$this->environment = $this->project->environments()->where('uuid', $environmentUuid)->firstOrFail();
|
||||
$this->getDevView();
|
||||
}
|
||||
|
||||
|
||||
@@ -44,9 +44,9 @@ class Show extends Component
|
||||
}
|
||||
}
|
||||
|
||||
public function mount()
|
||||
public function mount(?string $project_uuid = null)
|
||||
{
|
||||
$projectUuid = request()->route('project_uuid');
|
||||
$projectUuid = $project_uuid ?? request()->route('project_uuid');
|
||||
$teamId = currentTeam()->id;
|
||||
$project = Project::where('team_id', $teamId)->where('uuid', $projectUuid)->first();
|
||||
if (! $project) {
|
||||
|
||||
@@ -37,6 +37,7 @@ class Show extends Component
|
||||
'value' => $data['value'],
|
||||
'is_multiline' => $data['is_multiline'],
|
||||
'is_literal' => $data['is_literal'],
|
||||
'comment' => $data['comment'] ?? null,
|
||||
'type' => 'server',
|
||||
'team_id' => currentTeam()->id,
|
||||
]);
|
||||
@@ -47,9 +48,9 @@ class Show extends Component
|
||||
}
|
||||
}
|
||||
|
||||
public function mount()
|
||||
public function mount(?string $server_uuid = null)
|
||||
{
|
||||
$serverUuid = request()->route('server_uuid');
|
||||
$serverUuid = $server_uuid ?? request()->route('server_uuid');
|
||||
$teamId = currentTeam()->id;
|
||||
$server = Server::where('team_id', $teamId)->where('uuid', $serverUuid)->first();
|
||||
if (! $server) {
|
||||
@@ -140,7 +141,10 @@ class Show extends Component
|
||||
private function updateOrCreateVariables($variables)
|
||||
{
|
||||
$count = 0;
|
||||
foreach ($variables as $key => $value) {
|
||||
foreach ($variables as $key => $data) {
|
||||
$value = is_array($data) ? ($data['value'] ?? '') : $data;
|
||||
$comment = is_array($data) ? ($data['comment'] ?? null) : null;
|
||||
|
||||
// Skip predefined variables
|
||||
if (in_array($key, ['COOLIFY_SERVER_UUID', 'COOLIFY_SERVER_NAME'])) {
|
||||
continue;
|
||||
@@ -149,8 +153,9 @@ class Show extends Component
|
||||
|
||||
if ($found) {
|
||||
if (! $found->is_shown_once && ! $found->is_multiline) {
|
||||
if ($found->value !== $value) {
|
||||
if ($found->value !== $value || $found->comment !== $comment) {
|
||||
$found->value = $value;
|
||||
$found->comment = $comment;
|
||||
$found->save();
|
||||
$count++;
|
||||
}
|
||||
@@ -159,6 +164,7 @@ class Show extends Component
|
||||
$this->server->environment_variables()->create([
|
||||
'key' => $key,
|
||||
'value' => $value,
|
||||
'comment' => $comment,
|
||||
'is_multiline' => false,
|
||||
'is_literal' => false,
|
||||
'type' => 'server',
|
||||
|
||||
+8
-4
@@ -13,8 +13,10 @@ return new class extends Migration
|
||||
public function up(): void
|
||||
{
|
||||
DB::transaction(function () {
|
||||
DB::statement('ALTER TABLE shared_environment_variables DROP CONSTRAINT IF EXISTS shared_environment_variables_type_check');
|
||||
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment', 'server'))");
|
||||
if (DB::getDriverName() !== 'sqlite') {
|
||||
DB::statement('ALTER TABLE shared_environment_variables DROP CONSTRAINT IF EXISTS shared_environment_variables_type_check');
|
||||
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment', 'server'))");
|
||||
}
|
||||
Schema::table('shared_environment_variables', function (Blueprint $table) {
|
||||
$table->foreignId('server_id')->nullable()->constrained()->onDelete('cascade');
|
||||
// NULL != NULL in PostgreSQL unique indexes, so this only enforces uniqueness
|
||||
@@ -36,8 +38,10 @@ return new class extends Migration
|
||||
$table->dropForeign(['server_id']);
|
||||
$table->dropColumn('server_id');
|
||||
});
|
||||
DB::statement('ALTER TABLE shared_environment_variables DROP CONSTRAINT IF EXISTS shared_environment_variables_type_check');
|
||||
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment'))");
|
||||
if (DB::getDriverName() !== 'sqlite') {
|
||||
DB::statement('ALTER TABLE shared_environment_variables DROP CONSTRAINT IF EXISTS shared_environment_variables_type_check');
|
||||
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment'))");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\SharedVariables\Environment\Show;
|
||||
use App\Livewire\SharedVariables\Team\Index;
|
||||
use App\Models\Environment;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\SharedEnvironmentVariable;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
@@ -19,13 +23,35 @@ beforeEach(function () {
|
||||
$this->environment = Environment::factory()->create([
|
||||
'project_id' => $this->project->id,
|
||||
]);
|
||||
InstanceSettings::unguarded(function () {
|
||||
InstanceSettings::updateOrCreate([
|
||||
'id' => 0,
|
||||
], [
|
||||
'is_registration_enabled' => true,
|
||||
'is_api_enabled' => true,
|
||||
'smtp_enabled' => true,
|
||||
'smtp_host' => 'localhost',
|
||||
'smtp_port' => 1025,
|
||||
'smtp_from_address' => 'hi@example.com',
|
||||
'smtp_from_name' => 'Coolify',
|
||||
]);
|
||||
});
|
||||
|
||||
$this->actingAs($this->user);
|
||||
session(['currentTeam' => $this->team]);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
request()->setRouteResolver(function () {
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
test('environment shared variable dev view saves without openssl_encrypt error', function () {
|
||||
Livewire::test(\App\Livewire\SharedVariables\Environment\Show::class)
|
||||
Livewire::test(Show::class, [
|
||||
'project_uuid' => $this->project->uuid,
|
||||
'environment_uuid' => $this->environment->uuid,
|
||||
])
|
||||
->set('variables', "MY_VAR=my_value\nANOTHER_VAR=another_value")
|
||||
->call('submit')
|
||||
->assertHasNoErrors();
|
||||
@@ -38,7 +64,9 @@ test('environment shared variable dev view saves without openssl_encrypt error',
|
||||
});
|
||||
|
||||
test('project shared variable dev view saves without openssl_encrypt error', function () {
|
||||
Livewire::test(\App\Livewire\SharedVariables\Project\Show::class)
|
||||
Livewire::test(App\Livewire\SharedVariables\Project\Show::class, [
|
||||
'project_uuid' => $this->project->uuid,
|
||||
])
|
||||
->set('variables', 'PROJ_VAR=proj_value')
|
||||
->call('submit')
|
||||
->assertHasNoErrors();
|
||||
@@ -49,7 +77,7 @@ test('project shared variable dev view saves without openssl_encrypt error', fun
|
||||
});
|
||||
|
||||
test('team shared variable dev view saves without openssl_encrypt error', function () {
|
||||
Livewire::test(\App\Livewire\SharedVariables\Team\Index::class)
|
||||
Livewire::test(Index::class)
|
||||
->set('variables', 'TEAM_VAR=team_value')
|
||||
->call('submit')
|
||||
->assertHasNoErrors();
|
||||
@@ -69,7 +97,10 @@ test('environment shared variable dev view updates existing variable', function
|
||||
'team_id' => $this->team->id,
|
||||
]);
|
||||
|
||||
Livewire::test(\App\Livewire\SharedVariables\Environment\Show::class)
|
||||
Livewire::test(Show::class, [
|
||||
'project_uuid' => $this->project->uuid,
|
||||
'environment_uuid' => $this->environment->uuid,
|
||||
])
|
||||
->set('variables', 'EXISTING_VAR=new_value')
|
||||
->call('submit')
|
||||
->assertHasNoErrors();
|
||||
@@ -77,3 +108,63 @@ test('environment shared variable dev view updates existing variable', function
|
||||
$var = $this->environment->environment_variables()->where('key', 'EXISTING_VAR')->first();
|
||||
expect($var->value)->toBe('new_value');
|
||||
});
|
||||
|
||||
test('server shared variable dev view saves without openssl_encrypt error', function () {
|
||||
$this->server = Server::factory()->create(['team_id' => $this->team->id]);
|
||||
|
||||
Livewire::test(App\Livewire\SharedVariables\Server\Show::class, [
|
||||
'server_uuid' => $this->server->uuid,
|
||||
])
|
||||
->set('variables', "SERVER_VAR=server_value\nSECOND_SERVER_VAR=second_value")
|
||||
->call('submit')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$vars = $this->server->environment_variables()->pluck('value', 'key')->toArray();
|
||||
|
||||
expect($vars)->toHaveKey('SERVER_VAR')
|
||||
->and($vars['SERVER_VAR'])->toBe('server_value')
|
||||
->and($vars)->toHaveKey('SECOND_SERVER_VAR')
|
||||
->and($vars['SECOND_SERVER_VAR'])->toBe('second_value');
|
||||
});
|
||||
|
||||
test('server shared variable dev view preserves inline comments', function () {
|
||||
$this->server = Server::factory()->create(['team_id' => $this->team->id]);
|
||||
|
||||
Livewire::test(App\Livewire\SharedVariables\Server\Show::class, [
|
||||
'server_uuid' => $this->server->uuid,
|
||||
])
|
||||
->set('variables', 'COMMENTED_SERVER_VAR=value # note from dev view')
|
||||
->call('submit')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$var = $this->server->environment_variables()->where('key', 'COMMENTED_SERVER_VAR')->first();
|
||||
|
||||
expect($var)->not->toBeNull()
|
||||
->and($var->value)->toBe('value')
|
||||
->and($var->comment)->toBe('note from dev view');
|
||||
});
|
||||
|
||||
test('server shared variable dev view updates existing variable', function () {
|
||||
$this->server = Server::factory()->create(['team_id' => $this->team->id]);
|
||||
|
||||
SharedEnvironmentVariable::create([
|
||||
'key' => 'EXISTING_SERVER_VAR',
|
||||
'value' => 'old_value',
|
||||
'comment' => 'old comment',
|
||||
'type' => 'server',
|
||||
'server_id' => $this->server->id,
|
||||
'team_id' => $this->team->id,
|
||||
]);
|
||||
|
||||
Livewire::test(App\Livewire\SharedVariables\Server\Show::class, [
|
||||
'server_uuid' => $this->server->uuid,
|
||||
])
|
||||
->set('variables', 'EXISTING_SERVER_VAR=new_value # updated comment')
|
||||
->call('submit')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$var = $this->server->environment_variables()->where('key', 'EXISTING_SERVER_VAR')->first();
|
||||
|
||||
expect($var->value)->toBe('new_value')
|
||||
->and($var->comment)->toBe('updated comment');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user