mirror of
https://github.com/coollabsio/coolify.git
synced 2025-12-28 05:34:50 +00:00
Add detection system for PORT environment variable to help users configure applications correctly: - Add detectPortFromEnvironment() method to Application model to detect PORT env var - Add getDetectedPortInfoProperty() computed property in General Livewire component - Display contextual info banners in UI when PORT is detected: - Warning when PORT exists but ports_exposes is empty - Warning when PORT doesn't match ports_exposes configuration - Info message when PORT matches ports_exposes - Add deployment logging to warn about PORT/ports_exposes mismatches - Include comprehensive unit tests for port detection logic The ports_exposes field remains authoritative for proxy configuration, while PORT detection provides helpful suggestions to users.
157 lines
5.3 KiB
PHP
157 lines
5.3 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Unit tests for PORT environment variable detection feature.
|
|
*
|
|
* Tests verify that the Application model can correctly detect PORT environment
|
|
* variables and provide information to the UI about matches and mismatches with
|
|
* the configured ports_exposes field.
|
|
*/
|
|
|
|
use App\Models\Application;
|
|
use App\Models\EnvironmentVariable;
|
|
use Illuminate\Support\Collection;
|
|
use Mockery;
|
|
|
|
beforeEach(function () {
|
|
// Clean up Mockery after each test
|
|
Mockery::close();
|
|
});
|
|
|
|
it('detects PORT environment variable when present', function () {
|
|
// Create a mock Application instance
|
|
$application = Mockery::mock(Application::class)->makePartial();
|
|
|
|
// Mock environment variables collection with PORT set to 3000
|
|
$portEnvVar = Mockery::mock(EnvironmentVariable::class);
|
|
$portEnvVar->shouldReceive('getAttribute')->with('real_value')->andReturn('3000');
|
|
|
|
$envVars = new Collection([$portEnvVar]);
|
|
$application->shouldReceive('getAttribute')
|
|
->with('environment_variables')
|
|
->andReturn($envVars);
|
|
|
|
// Mock the firstWhere method to return our PORT env var
|
|
$envVars = Mockery::mock(Collection::class);
|
|
$envVars->shouldReceive('firstWhere')->with('key', 'PORT')->andReturn($portEnvVar);
|
|
$application->shouldReceive('getAttribute')
|
|
->with('environment_variables')
|
|
->andReturn($envVars);
|
|
|
|
// Call the method we're testing
|
|
$detectedPort = $application->detectPortFromEnvironment();
|
|
|
|
expect($detectedPort)->toBe(3000);
|
|
});
|
|
|
|
it('returns null when PORT environment variable is not set', function () {
|
|
$application = Mockery::mock(Application::class)->makePartial();
|
|
|
|
// Mock environment variables collection without PORT
|
|
$envVars = Mockery::mock(Collection::class);
|
|
$envVars->shouldReceive('firstWhere')->with('key', 'PORT')->andReturn(null);
|
|
$application->shouldReceive('getAttribute')
|
|
->with('environment_variables')
|
|
->andReturn($envVars);
|
|
|
|
$detectedPort = $application->detectPortFromEnvironment();
|
|
|
|
expect($detectedPort)->toBeNull();
|
|
});
|
|
|
|
it('returns null when PORT value is not numeric', function () {
|
|
$application = Mockery::mock(Application::class)->makePartial();
|
|
|
|
// Mock environment variables with non-numeric PORT value
|
|
$portEnvVar = Mockery::mock(EnvironmentVariable::class);
|
|
$portEnvVar->shouldReceive('getAttribute')->with('real_value')->andReturn('invalid-port');
|
|
|
|
$envVars = Mockery::mock(Collection::class);
|
|
$envVars->shouldReceive('firstWhere')->with('key', 'PORT')->andReturn($portEnvVar);
|
|
$application->shouldReceive('getAttribute')
|
|
->with('environment_variables')
|
|
->andReturn($envVars);
|
|
|
|
$detectedPort = $application->detectPortFromEnvironment();
|
|
|
|
expect($detectedPort)->toBeNull();
|
|
});
|
|
|
|
it('handles PORT value with whitespace', function () {
|
|
$application = Mockery::mock(Application::class)->makePartial();
|
|
|
|
// Mock environment variables with PORT value that has whitespace
|
|
$portEnvVar = Mockery::mock(EnvironmentVariable::class);
|
|
$portEnvVar->shouldReceive('getAttribute')->with('real_value')->andReturn(' 8080 ');
|
|
|
|
$envVars = Mockery::mock(Collection::class);
|
|
$envVars->shouldReceive('firstWhere')->with('key', 'PORT')->andReturn($portEnvVar);
|
|
$application->shouldReceive('getAttribute')
|
|
->with('environment_variables')
|
|
->andReturn($envVars);
|
|
|
|
$detectedPort = $application->detectPortFromEnvironment();
|
|
|
|
expect($detectedPort)->toBe(8080);
|
|
});
|
|
|
|
it('detects PORT from preview environment variables when isPreview is true', function () {
|
|
$application = Mockery::mock(Application::class)->makePartial();
|
|
|
|
// Mock preview environment variables with PORT
|
|
$portEnvVar = Mockery::mock(EnvironmentVariable::class);
|
|
$portEnvVar->shouldReceive('getAttribute')->with('real_value')->andReturn('4000');
|
|
|
|
$envVars = Mockery::mock(Collection::class);
|
|
$envVars->shouldReceive('firstWhere')->with('key', 'PORT')->andReturn($portEnvVar);
|
|
$application->shouldReceive('getAttribute')
|
|
->with('environment_variables_preview')
|
|
->andReturn($envVars);
|
|
|
|
$detectedPort = $application->detectPortFromEnvironment(true);
|
|
|
|
expect($detectedPort)->toBe(4000);
|
|
});
|
|
|
|
it('verifies ports_exposes array conversion logic', function () {
|
|
// Test the logic that converts comma-separated ports to array
|
|
$portsExposesString = '3000,3001,8080';
|
|
$expectedArray = [3000, 3001, 8080];
|
|
|
|
// This simulates what portsExposesArray accessor does
|
|
$result = is_null($portsExposesString)
|
|
? []
|
|
: explode(',', $portsExposesString);
|
|
|
|
// Convert to integers for comparison
|
|
$result = array_map('intval', $result);
|
|
|
|
expect($result)->toBe($expectedArray);
|
|
});
|
|
|
|
it('verifies PORT matches detection logic', function () {
|
|
$detectedPort = 3000;
|
|
$portsExposesArray = [3000, 3001];
|
|
|
|
$isMatch = in_array($detectedPort, $portsExposesArray);
|
|
|
|
expect($isMatch)->toBeTrue();
|
|
});
|
|
|
|
it('verifies PORT mismatch detection logic', function () {
|
|
$detectedPort = 8080;
|
|
$portsExposesArray = [3000, 3001];
|
|
|
|
$isMatch = in_array($detectedPort, $portsExposesArray);
|
|
|
|
expect($isMatch)->toBeFalse();
|
|
});
|
|
|
|
it('verifies empty ports_exposes detection logic', function () {
|
|
$portsExposesArray = [];
|
|
|
|
$isEmpty = empty($portsExposesArray);
|
|
|
|
expect($isEmpty)->toBeTrue();
|
|
});
|