From b5666da342b6bd5dbf52932cd0db49e535843d02 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 27 Nov 2025 10:45:39 +0100 Subject: [PATCH] test: add tests for shared environment variable spacing and resolution --- app/Models/EnvironmentVariable.php | 6 +- .../EnvironmentVariableSharedSpacingTest.php | 194 ++++++++++++++++++ 2 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 tests/Feature/EnvironmentVariableSharedSpacingTest.php diff --git a/app/Models/EnvironmentVariable.php b/app/Models/EnvironmentVariable.php index 80399a16b..843f01e59 100644 --- a/app/Models/EnvironmentVariable.php +++ b/app/Models/EnvironmentVariable.php @@ -190,11 +190,11 @@ private function get_real_environment_variables(?string $environment_variable = return $environment_variable; } foreach ($sharedEnvsFound as $sharedEnv) { - $type = str($sharedEnv)->match('/(.*?)\./'); + $type = str($sharedEnv)->trim()->match('/(.*?)\./'); if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) { continue; } - $variable = str($sharedEnv)->match('/\.(.*)/'); + $variable = str($sharedEnv)->trim()->match('/\.(.*)/'); if ($type->value() === 'environment') { $id = $resource->environment->id; } elseif ($type->value() === 'project') { @@ -231,7 +231,7 @@ private function set_environment_variables(?string $environment_variable = null) $environment_variable = trim($environment_variable); $type = str($environment_variable)->after('{{')->before('.')->value; if (str($environment_variable)->startsWith('{{'.$type) && str($environment_variable)->endsWith('}}')) { - return encrypt((string) str($environment_variable)->replace(' ', '')); + return encrypt($environment_variable); } return encrypt($environment_variable); diff --git a/tests/Feature/EnvironmentVariableSharedSpacingTest.php b/tests/Feature/EnvironmentVariableSharedSpacingTest.php new file mode 100644 index 000000000..2514ae94a --- /dev/null +++ b/tests/Feature/EnvironmentVariableSharedSpacingTest.php @@ -0,0 +1,194 @@ +user = User::factory()->create(); + $this->team = Team::factory()->create(); + $this->user->teams()->attach($this->team); + + // Create project and environment + $this->project = Project::factory()->create(['team_id' => $this->team->id]); + $this->environment = Environment::factory()->create([ + 'project_id' => $this->project->id, + ]); + + // Create application for testing + $this->application = Application::factory()->create([ + 'environment_id' => $this->environment->id, + ]); +}); + +test('shared variable preserves spacing in reference', function () { + $env = EnvironmentVariable::create([ + 'key' => 'TEST_VAR', + 'value' => '{{ project.aaa }}', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + $env->refresh(); + expect($env->value)->toBe('{{ project.aaa }}'); +}); + +test('shared variable preserves no-space format', function () { + $env = EnvironmentVariable::create([ + 'key' => 'TEST_VAR', + 'value' => '{{project.aaa}}', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + $env->refresh(); + expect($env->value)->toBe('{{project.aaa}}'); +}); + +test('shared variable with spaces resolves correctly', function () { + // Create shared variable + $shared = SharedEnvironmentVariable::create([ + 'key' => 'TEST_KEY', + 'value' => 'test-value-123', + 'type' => 'project', + 'project_id' => $this->project->id, + 'team_id' => $this->team->id, + ]); + + // Create env var with spaces + $env = EnvironmentVariable::create([ + 'key' => 'MY_VAR', + 'value' => '{{ project.TEST_KEY }}', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + // Verify it resolves correctly + $realValue = $env->real_value; + expect($realValue)->toBe('test-value-123'); +}); + +test('shared variable without spaces resolves correctly', function () { + // Create shared variable + $shared = SharedEnvironmentVariable::create([ + 'key' => 'TEST_KEY', + 'value' => 'test-value-456', + 'type' => 'project', + 'project_id' => $this->project->id, + 'team_id' => $this->team->id, + ]); + + // Create env var without spaces + $env = EnvironmentVariable::create([ + 'key' => 'MY_VAR', + 'value' => '{{project.TEST_KEY}}', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + // Verify it resolves correctly + $realValue = $env->real_value; + expect($realValue)->toBe('test-value-456'); +}); + +test('shared variable with extra internal spaces resolves correctly', function () { + // Create shared variable + $shared = SharedEnvironmentVariable::create([ + 'key' => 'TEST_KEY', + 'value' => 'test-value-789', + 'type' => 'project', + 'project_id' => $this->project->id, + 'team_id' => $this->team->id, + ]); + + // Create env var with multiple spaces + $env = EnvironmentVariable::create([ + 'key' => 'MY_VAR', + 'value' => '{{ project.TEST_KEY }}', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + // Verify it resolves correctly (parser trims when extracting) + $realValue = $env->real_value; + expect($realValue)->toBe('test-value-789'); +}); + +test('is_shared attribute detects variable with spaces', function () { + $env = EnvironmentVariable::create([ + 'key' => 'TEST', + 'value' => '{{ project.aaa }}', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + expect($env->is_shared)->toBeTrue(); +}); + +test('is_shared attribute detects variable without spaces', function () { + $env = EnvironmentVariable::create([ + 'key' => 'TEST', + 'value' => '{{project.aaa}}', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + expect($env->is_shared)->toBeTrue(); +}); + +test('non-shared variable preserves spaces', function () { + $env = EnvironmentVariable::create([ + 'key' => 'REGULAR', + 'value' => 'regular value with spaces', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + $env->refresh(); + expect($env->value)->toBe('regular value with spaces'); +}); + +test('mixed content with shared variable preserves all spacing', function () { + $env = EnvironmentVariable::create([ + 'key' => 'MIXED', + 'value' => 'prefix {{ project.aaa }} suffix', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + $env->refresh(); + expect($env->value)->toBe('prefix {{ project.aaa }} suffix'); +}); + +test('multiple shared variables preserve individual spacing', function () { + $env = EnvironmentVariable::create([ + 'key' => 'MULTI', + 'value' => '{{ project.a }} and {{team.b}}', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + $env->refresh(); + expect($env->value)->toBe('{{ project.a }} and {{team.b}}'); +}); + +test('leading and trailing spaces are trimmed', function () { + $env = EnvironmentVariable::create([ + 'key' => 'TRIMMED', + 'value' => ' {{ project.aaa }} ', + 'resource_id' => $this->application->id, + 'resource_type' => $this->application->getMorphClass(), + ]); + + $env->refresh(); + // External spaces trimmed, internal preserved + expect($env->value)->toBe('{{ project.aaa }}'); +});