Skip to content

Commit acb716c

Browse files
committed
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.
2 parents 466eb85 + f01953d commit acb716c

File tree

5 files changed

+121
-17
lines changed

5 files changed

+121
-17
lines changed

app/Livewire/SharedVariables/Environment/Show.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,14 @@ public function saveKey($data)
5151
}
5252
}
5353

54-
public function mount()
54+
public function mount(?string $project_uuid = null, ?string $environment_uuid = null)
5555
{
5656
$this->parameters = get_route_parameters();
57-
$this->project = Project::ownedByCurrentTeam()->where('uuid', request()->route('project_uuid'))->firstOrFail();
58-
$this->environment = $this->project->environments()->where('uuid', request()->route('environment_uuid'))->firstOrFail();
57+
$projectUuid = $project_uuid ?? request()->route('project_uuid');
58+
$environmentUuid = $environment_uuid ?? request()->route('environment_uuid');
59+
60+
$this->project = Project::ownedByCurrentTeam()->where('uuid', $projectUuid)->firstOrFail();
61+
$this->environment = $this->project->environments()->where('uuid', $environmentUuid)->firstOrFail();
5962
$this->getDevView();
6063
}
6164

app/Livewire/SharedVariables/Project/Show.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ public function saveKey($data)
4444
}
4545
}
4646

47-
public function mount()
47+
public function mount(?string $project_uuid = null)
4848
{
49-
$projectUuid = request()->route('project_uuid');
49+
$projectUuid = $project_uuid ?? request()->route('project_uuid');
5050
$teamId = currentTeam()->id;
5151
$project = Project::where('team_id', $teamId)->where('uuid', $projectUuid)->first();
5252
if (! $project) {

app/Livewire/SharedVariables/Server/Show.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public function saveKey($data)
3737
'value' => $data['value'],
3838
'is_multiline' => $data['is_multiline'],
3939
'is_literal' => $data['is_literal'],
40+
'comment' => $data['comment'] ?? null,
4041
'type' => 'server',
4142
'team_id' => currentTeam()->id,
4243
]);
@@ -47,9 +48,9 @@ public function saveKey($data)
4748
}
4849
}
4950

50-
public function mount()
51+
public function mount(?string $server_uuid = null)
5152
{
52-
$serverUuid = request()->route('server_uuid');
53+
$serverUuid = $server_uuid ?? request()->route('server_uuid');
5354
$teamId = currentTeam()->id;
5455
$server = Server::where('team_id', $teamId)->where('uuid', $serverUuid)->first();
5556
if (! $server) {
@@ -140,7 +141,10 @@ private function deleteRemovedVariables($variables)
140141
private function updateOrCreateVariables($variables)
141142
{
142143
$count = 0;
143-
foreach ($variables as $key => $value) {
144+
foreach ($variables as $key => $data) {
145+
$value = is_array($data) ? ($data['value'] ?? '') : $data;
146+
$comment = is_array($data) ? ($data['comment'] ?? null) : null;
147+
144148
// Skip predefined variables
145149
if (in_array($key, ['COOLIFY_SERVER_UUID', 'COOLIFY_SERVER_NAME'])) {
146150
continue;
@@ -149,8 +153,9 @@ private function updateOrCreateVariables($variables)
149153

150154
if ($found) {
151155
if (! $found->is_shown_once && ! $found->is_multiline) {
152-
if ($found->value !== $value) {
156+
if ($found->value !== $value || $found->comment !== $comment) {
153157
$found->value = $value;
158+
$found->comment = $comment;
154159
$found->save();
155160
$count++;
156161
}
@@ -159,6 +164,7 @@ private function updateOrCreateVariables($variables)
159164
$this->server->environment_variables()->create([
160165
'key' => $key,
161166
'value' => $value,
167+
'comment' => $comment,
162168
'is_multiline' => false,
163169
'is_literal' => false,
164170
'type' => 'server',

database/migrations/2025_12_24_095507_add_server_to_shared_environment_variables_table.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
public function up(): void
1414
{
1515
DB::transaction(function () {
16-
DB::statement('ALTER TABLE shared_environment_variables DROP CONSTRAINT IF EXISTS shared_environment_variables_type_check');
17-
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment', 'server'))");
16+
if (DB::getDriverName() !== 'sqlite') {
17+
DB::statement('ALTER TABLE shared_environment_variables DROP CONSTRAINT IF EXISTS shared_environment_variables_type_check');
18+
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment', 'server'))");
19+
}
1820
Schema::table('shared_environment_variables', function (Blueprint $table) {
1921
$table->foreignId('server_id')->nullable()->constrained()->onDelete('cascade');
2022
// NULL != NULL in PostgreSQL unique indexes, so this only enforces uniqueness
@@ -36,8 +38,10 @@ public function down(): void
3638
$table->dropForeign(['server_id']);
3739
$table->dropColumn('server_id');
3840
});
39-
DB::statement('ALTER TABLE shared_environment_variables DROP CONSTRAINT IF EXISTS shared_environment_variables_type_check');
40-
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment'))");
41+
if (DB::getDriverName() !== 'sqlite') {
42+
DB::statement('ALTER TABLE shared_environment_variables DROP CONSTRAINT IF EXISTS shared_environment_variables_type_check');
43+
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment'))");
44+
}
4145
});
4246
}
4347
};

tests/Feature/SharedVariableDevViewTest.php

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
<?php
22

3+
use App\Livewire\SharedVariables\Environment\Show;
4+
use App\Livewire\SharedVariables\Team\Index;
35
use App\Models\Environment;
6+
use App\Models\InstanceSettings;
47
use App\Models\Project;
8+
use App\Models\Server;
59
use App\Models\SharedEnvironmentVariable;
610
use App\Models\Team;
711
use App\Models\User;
@@ -19,13 +23,35 @@
1923
$this->environment = Environment::factory()->create([
2024
'project_id' => $this->project->id,
2125
]);
26+
InstanceSettings::unguarded(function () {
27+
InstanceSettings::updateOrCreate([
28+
'id' => 0,
29+
], [
30+
'is_registration_enabled' => true,
31+
'is_api_enabled' => true,
32+
'smtp_enabled' => true,
33+
'smtp_host' => 'localhost',
34+
'smtp_port' => 1025,
35+
'smtp_from_address' => 'hi@example.com',
36+
'smtp_from_name' => 'Coolify',
37+
]);
38+
});
2239

2340
$this->actingAs($this->user);
2441
session(['currentTeam' => $this->team]);
2542
});
2643

44+
afterEach(function () {
45+
request()->setRouteResolver(function () {
46+
return null;
47+
});
48+
});
49+
2750
test('environment shared variable dev view saves without openssl_encrypt error', function () {
28-
Livewire::test(\App\Livewire\SharedVariables\Environment\Show::class)
51+
Livewire::test(Show::class, [
52+
'project_uuid' => $this->project->uuid,
53+
'environment_uuid' => $this->environment->uuid,
54+
])
2955
->set('variables', "MY_VAR=my_value\nANOTHER_VAR=another_value")
3056
->call('submit')
3157
->assertHasNoErrors();
@@ -38,7 +64,9 @@
3864
});
3965

4066
test('project shared variable dev view saves without openssl_encrypt error', function () {
41-
Livewire::test(\App\Livewire\SharedVariables\Project\Show::class)
67+
Livewire::test(App\Livewire\SharedVariables\Project\Show::class, [
68+
'project_uuid' => $this->project->uuid,
69+
])
4270
->set('variables', 'PROJ_VAR=proj_value')
4371
->call('submit')
4472
->assertHasNoErrors();
@@ -49,7 +77,7 @@
4977
});
5078

5179
test('team shared variable dev view saves without openssl_encrypt error', function () {
52-
Livewire::test(\App\Livewire\SharedVariables\Team\Index::class)
80+
Livewire::test(Index::class)
5381
->set('variables', 'TEAM_VAR=team_value')
5482
->call('submit')
5583
->assertHasNoErrors();
@@ -69,11 +97,74 @@
6997
'team_id' => $this->team->id,
7098
]);
7199

72-
Livewire::test(\App\Livewire\SharedVariables\Environment\Show::class)
100+
Livewire::test(Show::class, [
101+
'project_uuid' => $this->project->uuid,
102+
'environment_uuid' => $this->environment->uuid,
103+
])
73104
->set('variables', 'EXISTING_VAR=new_value')
74105
->call('submit')
75106
->assertHasNoErrors();
76107

77108
$var = $this->environment->environment_variables()->where('key', 'EXISTING_VAR')->first();
78109
expect($var->value)->toBe('new_value');
79110
});
111+
112+
test('server shared variable dev view saves without openssl_encrypt error', function () {
113+
$this->server = Server::factory()->create(['team_id' => $this->team->id]);
114+
115+
Livewire::test(App\Livewire\SharedVariables\Server\Show::class, [
116+
'server_uuid' => $this->server->uuid,
117+
])
118+
->set('variables', "SERVER_VAR=server_value\nSECOND_SERVER_VAR=second_value")
119+
->call('submit')
120+
->assertHasNoErrors();
121+
122+
$vars = $this->server->environment_variables()->pluck('value', 'key')->toArray();
123+
124+
expect($vars)->toHaveKey('SERVER_VAR')
125+
->and($vars['SERVER_VAR'])->toBe('server_value')
126+
->and($vars)->toHaveKey('SECOND_SERVER_VAR')
127+
->and($vars['SECOND_SERVER_VAR'])->toBe('second_value');
128+
});
129+
130+
test('server shared variable dev view preserves inline comments', function () {
131+
$this->server = Server::factory()->create(['team_id' => $this->team->id]);
132+
133+
Livewire::test(App\Livewire\SharedVariables\Server\Show::class, [
134+
'server_uuid' => $this->server->uuid,
135+
])
136+
->set('variables', 'COMMENTED_SERVER_VAR=value # note from dev view')
137+
->call('submit')
138+
->assertHasNoErrors();
139+
140+
$var = $this->server->environment_variables()->where('key', 'COMMENTED_SERVER_VAR')->first();
141+
142+
expect($var)->not->toBeNull()
143+
->and($var->value)->toBe('value')
144+
->and($var->comment)->toBe('note from dev view');
145+
});
146+
147+
test('server shared variable dev view updates existing variable', function () {
148+
$this->server = Server::factory()->create(['team_id' => $this->team->id]);
149+
150+
SharedEnvironmentVariable::create([
151+
'key' => 'EXISTING_SERVER_VAR',
152+
'value' => 'old_value',
153+
'comment' => 'old comment',
154+
'type' => 'server',
155+
'server_id' => $this->server->id,
156+
'team_id' => $this->team->id,
157+
]);
158+
159+
Livewire::test(App\Livewire\SharedVariables\Server\Show::class, [
160+
'server_uuid' => $this->server->uuid,
161+
])
162+
->set('variables', 'EXISTING_SERVER_VAR=new_value # updated comment')
163+
->call('submit')
164+
->assertHasNoErrors();
165+
166+
$var = $this->server->environment_variables()->where('key', 'EXISTING_SERVER_VAR')->first();
167+
168+
expect($var->value)->toBe('new_value')
169+
->and($var->comment)->toBe('updated comment');
170+
});

0 commit comments

Comments
 (0)