Move env var default values to EnvVars enum

This commit is contained in:
Alejandro Celaya 2024-10-13 12:24:59 +02:00
parent be822646e4
commit 83e8801827
20 changed files with 147 additions and 78 deletions

View file

@ -45,7 +45,7 @@
"ramsey/uuid": "^4.7",
"shlinkio/doctrine-specification": "^2.1.1",
"shlinkio/shlink-common": "^6.3",
"shlinkio/shlink-config": "dev-main#76a96ee as 3.1",
"shlinkio/shlink-config": "dev-main#5e43e96 as 3.1",
"shlinkio/shlink-event-dispatcher": "^4.1",
"shlinkio/shlink-importer": "^5.3.2",
"shlinkio/shlink-installer": "^9.2",

View file

@ -6,7 +6,7 @@ use Shlinkio\Shlink\Core\Config\EnvVars;
return (static function (): array {
$redisServers = EnvVars::REDIS_SERVERS->loadFromEnv();
$redis = ['pub_sub_enabled' => $redisServers !== null && EnvVars::REDIS_PUB_SUB_ENABLED->loadFromEnv(false)];
$redis = ['pub_sub_enabled' => $redisServers !== null && EnvVars::REDIS_PUB_SUB_ENABLED->loadFromEnv()];
$cacheRedisBlock = $redisServers === null ? [] : [
'redis' => [
'servers' => $redisServers,
@ -16,7 +16,7 @@ return (static function (): array {
return [
'cache' => [
'namespace' => EnvVars::CACHE_NAMESPACE->loadFromEnv('Shlink'),
'namespace' => EnvVars::CACHE_NAMESPACE->loadFromEnv(),
...$cacheRedisBlock,
],
'redis' => $redis,

View file

@ -23,11 +23,6 @@ return (static function (): array {
$value = $envVar->loadFromEnv();
return $value === null ? null : (string) $value;
};
$resolveDefaultPort = static fn () => match ($driver) {
'postgres' => '5432',
'mssql' => '1433',
default => '3306',
};
$resolveCharset = static fn () => match ($driver) {
// This does not determine charsets or collations in tables or columns, but the charset used in the data
// flowing in the connection, so it has to match what has been set in the database.
@ -43,11 +38,11 @@ return (static function (): array {
],
default => [
'driver' => $resolveDriver(),
'dbname' => EnvVars::DB_NAME->loadFromEnv('shlink'),
'dbname' => EnvVars::DB_NAME->loadFromEnv(),
'user' => $readCredentialAsString(EnvVars::DB_USER),
'password' => $readCredentialAsString(EnvVars::DB_PASSWORD),
'host' => EnvVars::DB_HOST->loadFromEnv(EnvVars::DB_UNIX_SOCKET->loadFromEnv()),
'port' => EnvVars::DB_PORT->loadFromEnv($resolveDefaultPort()),
'host' => EnvVars::DB_HOST->loadFromEnv(),
'port' => EnvVars::DB_PORT->loadFromEnv(),
'unix_socket' => $isMysqlCompatible ? EnvVars::DB_UNIX_SOCKET->loadFromEnv() : null,
'charset' => $resolveCharset(),
'driverOptions' => $driver !== 'mssql' ? [] : [

View file

@ -7,7 +7,7 @@ use Shlinkio\Shlink\Core\Config\EnvVars;
return [
'matomo' => [
'enabled' => (bool) EnvVars::MATOMO_ENABLED->loadFromEnv(false),
'enabled' => (bool) EnvVars::MATOMO_ENABLED->loadFromEnv(),
'base_url' => EnvVars::MATOMO_BASE_URL->loadFromEnv(),
'site_id' => EnvVars::MATOMO_SITE_ID->loadFromEnv(),
'api_token' => EnvVars::MATOMO_API_TOKEN->loadFromEnv(),

View file

@ -15,7 +15,7 @@ return (static function (): array {
'mercure' => [
'public_hub_url' => $publicUrl,
'internal_hub_url' => EnvVars::MERCURE_INTERNAL_HUB_URL->loadFromEnv($publicUrl),
'internal_hub_url' => EnvVars::MERCURE_INTERNAL_HUB_URL->loadFromEnv(),
'jwt_secret' => EnvVars::MERCURE_JWT_SECRET->loadFromEnv(),
'jwt_issuer' => 'Shlink',
],

View file

@ -4,32 +4,17 @@ declare(strict_types=1);
use Shlinkio\Shlink\Core\Config\EnvVars;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_BG_COLOR;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_COLOR;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_ENABLED_FOR_DISABLED_SHORT_URLS;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_ERROR_CORRECTION;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_FORMAT;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_MARGIN;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_ROUND_BLOCK_SIZE;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_SIZE;
return [
'qr_codes' => [
'size' => (int) EnvVars::DEFAULT_QR_CODE_SIZE->loadFromEnv(DEFAULT_QR_CODE_SIZE),
'margin' => (int) EnvVars::DEFAULT_QR_CODE_MARGIN->loadFromEnv(DEFAULT_QR_CODE_MARGIN),
'format' => EnvVars::DEFAULT_QR_CODE_FORMAT->loadFromEnv(DEFAULT_QR_CODE_FORMAT),
'error_correction' => EnvVars::DEFAULT_QR_CODE_ERROR_CORRECTION->loadFromEnv(
DEFAULT_QR_CODE_ERROR_CORRECTION,
),
'round_block_size' => (bool) EnvVars::DEFAULT_QR_CODE_ROUND_BLOCK_SIZE->loadFromEnv(
DEFAULT_QR_CODE_ROUND_BLOCK_SIZE,
),
'enabled_for_disabled_short_urls' => (bool) EnvVars::QR_CODE_FOR_DISABLED_SHORT_URLS->loadFromEnv(
DEFAULT_QR_CODE_ENABLED_FOR_DISABLED_SHORT_URLS,
),
'color' => EnvVars::DEFAULT_QR_CODE_COLOR->loadFromEnv(DEFAULT_QR_CODE_COLOR),
'bg_color' => EnvVars::DEFAULT_QR_CODE_BG_COLOR->loadFromEnv(DEFAULT_QR_CODE_BG_COLOR),
'size' => (int) EnvVars::DEFAULT_QR_CODE_SIZE->loadFromEnv(),
'margin' => (int) EnvVars::DEFAULT_QR_CODE_MARGIN->loadFromEnv(),
'format' => EnvVars::DEFAULT_QR_CODE_FORMAT->loadFromEnv(),
'error_correction' => EnvVars::DEFAULT_QR_CODE_ERROR_CORRECTION->loadFromEnv(),
'round_block_size' => (bool) EnvVars::DEFAULT_QR_CODE_ROUND_BLOCK_SIZE->loadFromEnv(),
'enabled_for_disabled_short_urls' => (bool) EnvVars::QR_CODE_FOR_DISABLED_SHORT_URLS->loadFromEnv(),
'color' => EnvVars::DEFAULT_QR_CODE_COLOR->loadFromEnv(),
'bg_color' => EnvVars::DEFAULT_QR_CODE_BG_COLOR->loadFromEnv(),
'logo_url' => EnvVars::DEFAULT_QR_CODE_LOGO_URL->loadFromEnv(),
],

View file

@ -7,13 +7,13 @@ use Shlinkio\Shlink\Core\Config\EnvVars;
return [
'rabbitmq' => [
'enabled' => (bool) EnvVars::RABBITMQ_ENABLED->loadFromEnv(false),
'enabled' => (bool) EnvVars::RABBITMQ_ENABLED->loadFromEnv(),
'host' => EnvVars::RABBITMQ_HOST->loadFromEnv(),
'use_ssl' => (bool) EnvVars::RABBITMQ_USE_SSL->loadFromEnv(false),
'port' => (int) EnvVars::RABBITMQ_PORT->loadFromEnv('5672'),
'use_ssl' => (bool) EnvVars::RABBITMQ_USE_SSL->loadFromEnv(),
'port' => (int) EnvVars::RABBITMQ_PORT->loadFromEnv(),
'user' => EnvVars::RABBITMQ_USER->loadFromEnv(),
'password' => EnvVars::RABBITMQ_PASSWORD->loadFromEnv(),
'vhost' => EnvVars::RABBITMQ_VHOST->loadFromEnv('/'),
'vhost' => EnvVars::RABBITMQ_VHOST->loadFromEnv(),
],
];

View file

@ -4,9 +4,6 @@ declare(strict_types=1);
use Shlinkio\Shlink\Core\Config\EnvVars;
use const Shlinkio\Shlink\DEFAULT_REDIRECT_CACHE_LIFETIME;
use const Shlinkio\Shlink\DEFAULT_REDIRECT_STATUS_CODE;
return [
'not_found_redirects' => [
@ -16,10 +13,8 @@ return [
],
'redirects' => [
'redirect_status_code' => (int) EnvVars::REDIRECT_STATUS_CODE->loadFromEnv(DEFAULT_REDIRECT_STATUS_CODE->value),
'redirect_cache_lifetime' => (int) EnvVars::REDIRECT_CACHE_LIFETIME->loadFromEnv(
DEFAULT_REDIRECT_CACHE_LIFETIME,
),
'redirect_status_code' => (int) EnvVars::REDIRECT_STATUS_CODE->loadFromEnv(),
'redirect_cache_lifetime' => (int) EnvVars::REDIRECT_CACHE_LIFETIME->loadFromEnv(),
],
];

View file

@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Core;
return [
'robots' => [
'allow-all-short-urls' => (bool) Config\EnvVars::ROBOTS_ALLOW_ALL_SHORT_URLS->loadFromEnv(false),
'allow-all-short-urls' => (bool) Config\EnvVars::ROBOTS_ALLOW_ALL_SHORT_URLS->loadFromEnv(),
'user-agents' => splitByComma(Config\EnvVars::ROBOTS_USER_AGENTS->loadFromEnv()),
],

View file

@ -8,7 +8,7 @@ use Shlinkio\Shlink\Core\Config\EnvVars;
return [
'router' => [
'base_path' => EnvVars::BASE_PATH->loadFromEnv(''),
'base_path' => EnvVars::BASE_PATH->loadFromEnv(),
'fastroute' => [
// Disabling config cache for cli, ensures it's never used for RoadRunner, and also that console

View file

@ -21,7 +21,7 @@ return (static function (): array {
$overrideDomainMiddleware = Middleware\ShortUrl\OverrideDomainMiddleware::class;
// TODO This should be based on config, not the env var
$shortUrlRouteSuffix = EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv(false) ? '[/]' : '';
$shortUrlRouteSuffix = EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv() ? '[/]' : '';
return [

View file

@ -11,25 +11,25 @@ return [
'tracking' => [
// Tells if IP addresses should be anonymized before persisting, to fulfil data protection regulations
// This applies only if IP address tracking is enabled
'anonymize_remote_addr' => (bool) EnvVars::ANONYMIZE_REMOTE_ADDR->loadFromEnv(true),
'anonymize_remote_addr' => (bool) EnvVars::ANONYMIZE_REMOTE_ADDR->loadFromEnv(),
// Tells if visits to not-found URLs should be tracked. The disable_tracking option takes precedence
'track_orphan_visits' => (bool) EnvVars::TRACK_ORPHAN_VISITS->loadFromEnv(true),
'track_orphan_visits' => (bool) EnvVars::TRACK_ORPHAN_VISITS->loadFromEnv(),
// A query param that, if provided, will disable tracking of one particular visit. Always takes precedence
'disable_track_param' => EnvVars::DISABLE_TRACK_PARAM->loadFromEnv(),
// If true, visits will not be tracked at all
'disable_tracking' => (bool) EnvVars::DISABLE_TRACKING->loadFromEnv(false),
'disable_tracking' => (bool) EnvVars::DISABLE_TRACKING->loadFromEnv(),
// If true, visits will be tracked, but neither the IP address, nor the location will be resolved
'disable_ip_tracking' => (bool) EnvVars::DISABLE_IP_TRACKING->loadFromEnv(false),
'disable_ip_tracking' => (bool) EnvVars::DISABLE_IP_TRACKING->loadFromEnv(),
// If true, the referrer will not be tracked
'disable_referrer_tracking' => (bool) EnvVars::DISABLE_REFERRER_TRACKING->loadFromEnv(false),
'disable_referrer_tracking' => (bool) EnvVars::DISABLE_REFERRER_TRACKING->loadFromEnv(),
// If true, the user agent will not be tracked
'disable_ua_tracking' => (bool) EnvVars::DISABLE_UA_TRACKING->loadFromEnv(false),
'disable_ua_tracking' => (bool) EnvVars::DISABLE_UA_TRACKING->loadFromEnv(),
// A list of IP addresses, patterns or CIDR blocks from which tracking is disabled by default
'disable_tracking_from' => splitByComma(EnvVars::DISABLE_TRACKING_FROM->loadFromEnv()),

View file

@ -5,29 +5,28 @@ declare(strict_types=1);
use Shlinkio\Shlink\Core\Config\EnvVars;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlMode;
use const Shlinkio\Shlink\DEFAULT_SHORT_CODES_LENGTH;
use const Shlinkio\Shlink\MIN_SHORT_CODES_LENGTH;
return (static function (): array {
$shortCodesLength = max(
(int) EnvVars::DEFAULT_SHORT_CODES_LENGTH->loadFromEnv(DEFAULT_SHORT_CODES_LENGTH),
(int) EnvVars::DEFAULT_SHORT_CODES_LENGTH->loadFromEnv(),
MIN_SHORT_CODES_LENGTH,
);
$modeFromEnv = EnvVars::SHORT_URL_MODE->loadFromEnv(ShortUrlMode::STRICT->value);
$modeFromEnv = EnvVars::SHORT_URL_MODE->loadFromEnv();
$mode = ShortUrlMode::tryFrom($modeFromEnv) ?? ShortUrlMode::STRICT;
return [
'url_shortener' => [
'domain' => [ // TODO Refactor this structure to url_shortener.schema and url_shortener.default_domain
'schema' => ((bool) EnvVars::IS_HTTPS_ENABLED->loadFromEnv(true)) ? 'https' : 'http',
'hostname' => EnvVars::DEFAULT_DOMAIN->loadFromEnv(''),
'schema' => ((bool) EnvVars::IS_HTTPS_ENABLED->loadFromEnv()) ? 'https' : 'http',
'hostname' => EnvVars::DEFAULT_DOMAIN->loadFromEnv(),
],
'default_short_codes_length' => $shortCodesLength,
'auto_resolve_titles' => (bool) EnvVars::AUTO_RESOLVE_TITLES->loadFromEnv(true),
'append_extra_path' => (bool) EnvVars::REDIRECT_APPEND_EXTRA_PATH->loadFromEnv(false),
'multi_segment_slugs_enabled' => (bool) EnvVars::MULTI_SEGMENT_SLUGS_ENABLED->loadFromEnv(false),
'trailing_slash_enabled' => (bool) EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv(false),
'auto_resolve_titles' => (bool) EnvVars::AUTO_RESOLVE_TITLES->loadFromEnv(),
'append_extra_path' => (bool) EnvVars::REDIRECT_APPEND_EXTRA_PATH->loadFromEnv(),
'multi_segment_slugs_enabled' => (bool) EnvVars::MULTI_SEGMENT_SLUGS_ENABLED->loadFromEnv(),
'trailing_slash_enabled' => (bool) EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv(),
'mode' => $mode,
],

View file

@ -19,8 +19,8 @@ require 'vendor/autoload.php';
loadEnvVarsFromConfig('config/params/generated_config.php', enumValues(EnvVars::class));
// This is one of the first files loaded. Configure the timezone and memory limit here
ini_set('memory_limit', EnvVars::MEMORY_LIMIT->loadFromEnv('512M'));
date_default_timezone_set(EnvVars::TIMEZONE->loadFromEnv(date_default_timezone_get()));
ini_set('memory_limit', EnvVars::MEMORY_LIMIT->loadFromEnv());
date_default_timezone_set(EnvVars::TIMEZONE->loadFromEnv());
// This class alias tricks the ConfigAbstractFactory to return Lock\Factory instances even with a different service name
// It needs to be placed here as individual config files will not be loaded once config is cached

View file

@ -8,6 +8,11 @@ mkdir -p data/cache data/locks data/log data/proxies
flags="--no-interaction --clear-db-cache"
# Read env vars through Shlink command, so that it applies the `_FILE` env var fallback logic
GEOLITE_LICENSE_KEY=$(bin/cli env-var:read GEOLITE_LICENSE_KEY)
SKIP_INITIAL_GEOLITE_DOWNLOAD=$(bin/cli env-var:read SKIP_INITIAL_GEOLITE_DOWNLOAD)
INITIAL_API_KEY=$(bin/cli env-var:read INITIAL_API_KEY)
# Skip downloading GeoLite2 db file if the license key env var was not defined or skipping was explicitly set
if [ -z "${GEOLITE_LICENSE_KEY}" ] || [ "${SKIP_INITIAL_GEOLITE_DOWNLOAD}" = "true" ]; then
flags="${flags} --skip-download-geolite"

View file

@ -45,6 +45,8 @@ return [
Command\RedirectRule\ManageRedirectRulesCommand::class,
Command\Integration\MatomoSendVisitsCommand::NAME => Command\Integration\MatomoSendVisitsCommand::class,
Command\Config\ReadEnvVarCommand::NAME => Command\Config\ReadEnvVarCommand::class,
],
],

View file

@ -75,6 +75,8 @@ return [
Command\RedirectRule\ManageRedirectRulesCommand::class => ConfigAbstractFactory::class,
Command\Integration\MatomoSendVisitsCommand::class => ConfigAbstractFactory::class,
Command\Config\ReadEnvVarCommand::class => InvokableFactory::class,
],
],

View file

@ -17,7 +17,7 @@ abstract class AbstractDatabaseCommand extends AbstractLockedCommand
public function __construct(
LockFactory $locker,
private ProcessRunnerInterface $processRunner,
private readonly ProcessRunnerInterface $processRunner,
PhpExecutableFinder $phpFinder,
) {
parent::__construct($locker);

View file

@ -4,12 +4,27 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Config;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlMode;
use function date_default_timezone_get;
use function file_get_contents;
use function getenv;
use function is_file;
use function Shlinkio\Shlink\Config\env;
use function Shlinkio\Shlink\Config\parseEnvVar;
use function sprintf;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_COLOR;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_ENABLED_FOR_DISABLED_SHORT_URLS;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_ERROR_CORRECTION;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_FORMAT;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_MARGIN;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_ROUND_BLOCK_SIZE;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_SIZE;
use const Shlinkio\Shlink\DEFAULT_REDIRECT_CACHE_LIFETIME;
use const Shlinkio\Shlink\DEFAULT_REDIRECT_STATUS_CODE;
use const Shlinkio\Shlink\DEFAULT_SHORT_CODES_LENGTH;
enum EnvVars: string
{
case DELETE_SHORT_URL_THRESHOLD = 'DELETE_SHORT_URL_THRESHOLD';
@ -74,10 +89,67 @@ enum EnvVars: string
case ROBOTS_USER_AGENTS = 'ROBOTS_USER_AGENTS';
case TIMEZONE = 'TIMEZONE';
case MEMORY_LIMIT = 'MEMORY_LIMIT';
case INITIAL_API_KEY = 'INITIAL_API_KEY';
case SKIP_INITIAL_GEOLITE_DOWNLOAD = 'SKIP_INITIAL_GEOLITE_DOWNLOAD';
public function loadFromEnv(mixed $default = null): mixed
public function loadFromEnv(): mixed
{
return env($this->value) ?? $this->loadFromFileEnv() ?? $default;
return env($this->value) ?? $this->loadFromFileEnv() ?? $this->defaultValue();
}
private function defaultValue(): string|int|bool|null
{
return match ($this) {
self::MEMORY_LIMIT => '512M',
self::TIMEZONE => date_default_timezone_get(),
self::DEFAULT_SHORT_CODES_LENGTH => DEFAULT_SHORT_CODES_LENGTH,
self::SHORT_URL_MODE => ShortUrlMode::STRICT->value,
self::IS_HTTPS_ENABLED, self::AUTO_RESOLVE_TITLES => true,
self::REDIRECT_APPEND_EXTRA_PATH,
self::MULTI_SEGMENT_SLUGS_ENABLED,
self::SHORT_URL_TRAILING_SLASH => false,
self::DEFAULT_DOMAIN, self::BASE_PATH => '',
self::CACHE_NAMESPACE => 'Shlink',
self::REDIS_PUB_SUB_ENABLED,
self::MATOMO_ENABLED,
self::ROBOTS_ALLOW_ALL_SHORT_URLS => false,
self::DB_NAME => 'shlink',
self::DB_HOST => self::DB_UNIX_SOCKET->loadFromEnv(),
self::DB_DRIVER => 'sqlite',
self::DB_PORT => match (self::DB_DRIVER->loadFromEnv()) {
'postgres' => '5432',
'mssql' => '1433',
default => '3306',
},
self::MERCURE_INTERNAL_HUB_URL => self::MERCURE_PUBLIC_HUB_URL->loadFromEnv(),
self::DEFAULT_QR_CODE_SIZE, => DEFAULT_QR_CODE_SIZE,
self::DEFAULT_QR_CODE_MARGIN, => DEFAULT_QR_CODE_MARGIN,
self::DEFAULT_QR_CODE_FORMAT, => DEFAULT_QR_CODE_FORMAT,
self::DEFAULT_QR_CODE_ERROR_CORRECTION, => DEFAULT_QR_CODE_ERROR_CORRECTION,
self::DEFAULT_QR_CODE_ROUND_BLOCK_SIZE, => DEFAULT_QR_CODE_ROUND_BLOCK_SIZE,
self::QR_CODE_FOR_DISABLED_SHORT_URLS, => DEFAULT_QR_CODE_ENABLED_FOR_DISABLED_SHORT_URLS,
self::DEFAULT_QR_CODE_COLOR, => DEFAULT_QR_CODE_COLOR,
self::RABBITMQ_ENABLED, self::RABBITMQ_USE_SSL => false,
self::RABBITMQ_PORT => 5672,
self::RABBITMQ_VHOST => '/',
self::REDIRECT_STATUS_CODE => DEFAULT_REDIRECT_STATUS_CODE->value,
self::REDIRECT_CACHE_LIFETIME => DEFAULT_REDIRECT_CACHE_LIFETIME,
self::ANONYMIZE_REMOTE_ADDR, self::TRACK_ORPHAN_VISITS => true,
self::DISABLE_TRACKING,
self::DISABLE_IP_TRACKING,
self::DISABLE_REFERRER_TRACKING,
self::DISABLE_UA_TRACKING => false,
default => null,
};
}
/**

View file

@ -6,6 +6,7 @@ namespace ShlinkioTest\Shlink\Core\Config;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
use Shlinkio\Shlink\Core\Config\EnvVars;
@ -44,19 +45,16 @@ class EnvVarsTest extends TestCase
}
#[Test, DataProvider('provideEnvVarsValues')]
public function expectedValueIsLoadedFromEnv(EnvVars $envVar, mixed $expected, mixed $default): void
public function expectedValueIsLoadedFromEnv(EnvVars $envVar, mixed $expected): void
{
self::assertEquals($expected, $envVar->loadFromEnv($default));
self::assertEquals($expected, $envVar->loadFromEnv());
}
public static function provideEnvVarsValues(): iterable
{
yield 'DB_NAME without default' => [EnvVars::DB_NAME, 'shlink', null];
yield 'DB_NAME with default' => [EnvVars::DB_NAME, 'shlink', 'foobar'];
yield 'BASE_PATH without default' => [EnvVars::BASE_PATH, 'the_base_path', null];
yield 'BASE_PATH with default' => [EnvVars::BASE_PATH, 'the_base_path', 'foobar'];
yield 'DB_DRIVER without default' => [EnvVars::DB_DRIVER, null, null];
yield 'DB_DRIVER with default' => [EnvVars::DB_DRIVER, 'foobar', 'foobar'];
yield 'DB_NAME (is set)' => [EnvVars::DB_NAME, 'shlink'];
yield 'BASE_PATH (is set)' => [EnvVars::BASE_PATH, 'the_base_path'];
yield 'DB_DRIVER (has default)' => [EnvVars::DB_DRIVER, 'sqlite'];
}
#[Test]
@ -64,4 +62,20 @@ class EnvVarsTest extends TestCase
{
self::assertEquals('this_is_the_password', EnvVars::DB_PASSWORD->loadFromEnv());
}
#[Test]
#[TestWith(['mysql', '3306'])]
#[TestWith(['maria', '3306'])]
#[TestWith(['postgres', '5432'])]
#[TestWith(['mssql', '1433'])]
public function defaultPortIsResolvedBasedOnDbDriver(string $dbDriver, string $expectedPort): void
{
putenv(EnvVars::DB_DRIVER->value . '=' . $dbDriver);
try {
self::assertEquals($expectedPort, EnvVars::DB_PORT->loadFromEnv());
} finally {
putenv(EnvVars::DB_DRIVER->value . '=');
}
}
}