diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index eb3c02685f..6a587c6574 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -4047,95 +4047,28 @@ class ApplicationsController extends Controller ], 422); } $is_preview = $request->is_preview ?? false; - $is_literal = $request->is_literal ?? false; $key = str($request->key)->trim()->replace(' ', '_')->value; - if ($is_preview) { - $env = $application->environment_variables_preview->where('key', $key)->first(); - if ($env) { - $env->value = $request->value; - if ($env->is_literal != $is_literal) { - $env->is_literal = $is_literal; - } - if ($env->is_preview != $is_preview) { - $env->is_preview = $is_preview; - } - if ($env->is_multiline != $request->is_multiline) { - $env->is_multiline = $request->is_multiline; - } - if ($env->is_shown_once != $request->is_shown_once) { - $env->is_shown_once = $request->is_shown_once; - } - if ($request->has('is_runtime') && $env->is_runtime != $request->is_runtime) { - $env->is_runtime = $request->is_runtime; - } - if ($request->has('is_buildtime') && $env->is_buildtime != $request->is_buildtime) { - $env->is_buildtime = $request->is_buildtime; - } - if ($request->has('comment') && $env->comment != $request->comment) { - $env->comment = $request->comment; - } - $env->save(); - - auditLog('api.application.env_updated', [ - 'team_id' => $teamId, - 'application_uuid' => $application->uuid, - 'env_uuid' => $env->uuid, - 'env_key' => $env->key, - 'is_preview' => (bool) $is_preview, - ]); - - return response()->json($this->removeSensitiveData($env))->setStatusCode(201); - } else { - return response()->json([ - 'message' => 'Environment variable not found.', - ], 404); - } - } else { - $env = $application->environment_variables->where('key', $key)->first(); - if ($env) { - $env->value = $request->value; - if ($env->is_literal != $is_literal) { - $env->is_literal = $is_literal; - } - if ($env->is_preview != $is_preview) { - $env->is_preview = $is_preview; - } - if ($env->is_multiline != $request->is_multiline) { - $env->is_multiline = $request->is_multiline; - } - if ($env->is_shown_once != $request->is_shown_once) { - $env->is_shown_once = $request->is_shown_once; - } - if ($request->has('is_runtime') && $env->is_runtime != $request->is_runtime) { - $env->is_runtime = $request->is_runtime; - } - if ($request->has('is_buildtime') && $env->is_buildtime != $request->is_buildtime) { - $env->is_buildtime = $request->is_buildtime; - } - if ($request->has('comment') && $env->comment != $request->comment) { - $env->comment = $request->comment; - } - $env->save(); - - auditLog('api.application.env_updated', [ - 'team_id' => $teamId, - 'application_uuid' => $application->uuid, - 'env_uuid' => $env->uuid, - 'env_key' => $env->key, - 'is_preview' => (bool) $is_preview, - ]); - - return response()->json($this->removeSensitiveData($env))->setStatusCode(201); - } else { - return response()->json([ - 'message' => 'Environment variable not found.', - ], 404); - } + $environmentVariables = $is_preview ? $application->environment_variables_preview : $application->environment_variables; + $env = $environmentVariables->where('key', $key)->first(); + if (! $env) { + return response()->json([ + 'message' => 'Environment variable not found.', + ], 404); } - return response()->json([ - 'message' => 'Something is not okay. Are you okay?', - ], 500); + $env->value = $request->value; + $env->fill($request->only(['is_literal', 'is_multiline', 'is_shown_once', 'is_runtime', 'is_buildtime', 'comment'])); + $env->save(); + + auditLog('api.application.env_updated', [ + 'team_id' => $teamId, + 'application_uuid' => $application->uuid, + 'env_uuid' => $env->uuid, + 'env_key' => $env->key, + 'is_preview' => (bool) $is_preview, + ]); + + return response()->json($this->removeSensitiveData($env))->setStatusCode(201); } #[OA\Patch( @@ -4280,25 +4213,7 @@ class ApplicationsController extends Controller $env = $application->environment_variables_preview()->where('key', $key)->first(); if ($env) { $env->value = $item->get('value'); - - if ($env->is_literal != $is_literal) { - $env->is_literal = $is_literal; - } - if ($env->is_multiline != $item->get('is_multiline')) { - $env->is_multiline = $item->get('is_multiline'); - } - if ($env->is_shown_once != $item->get('is_shown_once')) { - $env->is_shown_once = $item->get('is_shown_once'); - } - if ($item->has('is_runtime') && $env->is_runtime != $item->get('is_runtime')) { - $env->is_runtime = $item->get('is_runtime'); - } - if ($item->has('is_buildtime') && $env->is_buildtime != $item->get('is_buildtime')) { - $env->is_buildtime = $item->get('is_buildtime'); - } - if ($item->has('comment') && $env->comment != $item->get('comment')) { - $env->comment = $item->get('comment'); - } + $env->fill($item->only(['is_literal', 'is_multiline', 'is_shown_once', 'is_runtime', 'is_buildtime', 'comment'])->all()); $env->save(); } else { $env = $application->environment_variables()->create([ @@ -4319,24 +4234,7 @@ class ApplicationsController extends Controller $env = $application->environment_variables()->where('key', $key)->first(); if ($env) { $env->value = $item->get('value'); - if ($env->is_literal != $is_literal) { - $env->is_literal = $is_literal; - } - if ($env->is_multiline != $item->get('is_multiline')) { - $env->is_multiline = $item->get('is_multiline'); - } - if ($env->is_shown_once != $item->get('is_shown_once')) { - $env->is_shown_once = $item->get('is_shown_once'); - } - if ($item->has('is_runtime') && $env->is_runtime != $item->get('is_runtime')) { - $env->is_runtime = $item->get('is_runtime'); - } - if ($item->has('is_buildtime') && $env->is_buildtime != $item->get('is_buildtime')) { - $env->is_buildtime = $item->get('is_buildtime'); - } - if ($item->has('comment') && $env->comment != $item->get('comment')) { - $env->comment = $item->get('comment'); - } + $env->fill($item->only(['is_literal', 'is_multiline', 'is_shown_once', 'is_runtime', 'is_buildtime', 'comment'])->all()); $env->save(); } else { $env = $application->environment_variables()->create([ diff --git a/tests/Feature/Api/EnvironmentVariableUpdateApiTest.php b/tests/Feature/Api/EnvironmentVariableUpdateApiTest.php index 14821756e5..6bb5b79efb 100644 --- a/tests/Feature/Api/EnvironmentVariableUpdateApiTest.php +++ b/tests/Feature/Api/EnvironmentVariableUpdateApiTest.php @@ -253,6 +253,78 @@ describe('PATCH /api/v1/applications/{uuid}/envs', function () { }); }); +describe('application env PATCH keeps omitted flags', function () { + beforeEach(function () { + $this->application = Application::factory()->create([ + 'environment_id' => $this->environment->id, + 'destination_id' => $this->destination->id, + 'destination_type' => $this->destination->getMorphClass(), + ]); + + $this->env = EnvironmentVariable::create([ + 'key' => 'FLAGGED_KEY', + 'value' => 'old-value', + 'resourceable_type' => Application::class, + 'resourceable_id' => $this->application->id, + 'is_preview' => false, + 'is_literal' => true, + 'is_multiline' => true, + 'is_shown_once' => true, + ]); + + $this->headers = [ + 'Authorization' => 'Bearer '.$this->bearerToken, + 'Content-Type' => 'application/json', + ]; + }); + + test('single update with only key and value keeps flags', function () { + $this->withHeaders($this->headers) + ->patchJson("/api/v1/applications/{$this->application->uuid}/envs", [ + 'key' => 'FLAGGED_KEY', + 'value' => 'new-value', + ]) + ->assertStatus(201); + + $env = $this->env->fresh(); + expect($env->value)->toBe('new-value') + ->and((bool) $env->is_literal)->toBeTrue() + ->and($env->is_multiline)->toBeTrue() + ->and((bool) $env->is_shown_once)->toBeTrue(); + }); + + test('bulk update with only key and value keeps flags', function () { + $this->withHeaders($this->headers) + ->patchJson("/api/v1/applications/{$this->application->uuid}/envs/bulk", [ + 'data' => [['key' => 'FLAGGED_KEY', 'value' => 'new-value']], + ]) + ->assertStatus(201); + + $env = $this->env->fresh(); + expect($env->value)->toBe('new-value') + ->and((bool) $env->is_literal)->toBeTrue() + ->and($env->is_multiline)->toBeTrue() + ->and((bool) $env->is_shown_once)->toBeTrue(); + }); + + test('explicit flags are still applied', function () { + $this->withHeaders($this->headers) + ->patchJson("/api/v1/applications/{$this->application->uuid}/envs", [ + 'key' => 'FLAGGED_KEY', + 'value' => 'new-value', + 'is_literal' => false, + 'is_multiline' => false, + 'is_shown_once' => false, + ]) + ->assertStatus(201); + + $env = $this->env->fresh(); + expect((bool) $env->is_literal)->toBeFalse() + ->and($env->is_multiline)->toBeFalse() + ->and((bool) $env->is_shown_once)->toBeFalse(); + }); +}); + describe('environment variable key validation for app and service APIs', function () { test('rejects invalid service environment variable keys on create update and bulk', function () { $service = Service::factory()->create([