diff --git a/CHANGELOG.md b/CHANGELOG.md index ac74a67b..383f89a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this ### Added * [#2438](https://github.com/shlinkio/shlink/issues/2438) Add `MERCURE_ENABLED` env var and corresponding config option, to more easily allow the mercure integration to be toggled. - For BC, if this env vars is not present, we'll still consider the integration enabled if the `MERCURE_PUBLIC_HUB_URL` env var has a value. This is considered deprecated though, and next major version will rely only on `MERCURE_ENABLED`, so if you are using Mercure, make sure to set `MERCURE_ENABLED=true` to be ready. + For BC, if this env var is not present, we'll still consider the integration enabled if the `MERCURE_PUBLIC_HUB_URL` env var has a value. This is considered deprecated though, and next major version will rely only on `MERCURE_ENABLED`, so if you are using Mercure, make sure to set `MERCURE_ENABLED=true` to be ready. * [#2387](https://github.com/shlinkio/shlink/issues/2387) Add `REAL_TIME_UPDATES_TOPICS` env var and corresponding config option, to granularly decide which real-time updates topics should be enabled. * [#2418](https://github.com/shlinkio/shlink/issues/2418) Add more granular control over how Shlink handles CORS. It is now possible to customize the `Access-Control-Allow-Origin`, `Access-Control-Max-Age` and `Access-Control-Allow-Credentials` headers via env vars or config options. diff --git a/module/Core/test/RedirectRule/Entity/RedirectConditionTest.php b/module/Core/test/RedirectRule/Entity/RedirectConditionTest.php index bec6d263..28e3f6b1 100644 --- a/module/Core/test/RedirectRule/Entity/RedirectConditionTest.php +++ b/module/Core/test/RedirectRule/Entity/RedirectConditionTest.php @@ -32,6 +32,33 @@ class RedirectConditionTest extends TestCase self::assertEquals($expectedResult, $result); } + #[Test] + #[TestWith(['nop', '', false])] // param not present + #[TestWith(['foo', '', true])] + #[TestWith(['foo', 'something', true])] + #[TestWith(['foo', 'something else', true])] + public function matchesAnyValueQueryParams(string $param, string $value, bool $expectedResult): void + { + $request = ServerRequestFactory::fromGlobals()->withQueryParams(['foo' => $value]); + $result = RedirectCondition::forAnyValueQueryParam($param)->matchesRequest($request); + + self::assertEquals($expectedResult, $result); + } + + #[Test] + #[TestWith(['nop', '', false])] // param not present + #[TestWith(['foo', '', true])] + #[TestWith(['foo', null, true])] + #[TestWith(['foo', 'something', false])] + #[TestWith(['foo', 'something else', false])] + public function matchesValuelessQueryParams(string $param, string|null $value, bool $expectedResult): void + { + $request = ServerRequestFactory::fromGlobals()->withQueryParams(['foo' => $value]); + $result = RedirectCondition::forValuelessQueryParam($param)->matchesRequest($request); + + self::assertEquals($expectedResult, $result); + } + #[Test] #[TestWith([null, '', false], 'no accept language')] #[TestWith(['', '', false], 'empty accept language')] @@ -141,6 +168,8 @@ class RedirectConditionTest extends TestCase #[TestWith([RedirectConditionType::DEVICE->value, RedirectConditionType::DEVICE])] #[TestWith([RedirectConditionType::LANGUAGE->value, RedirectConditionType::LANGUAGE])] #[TestWith([RedirectConditionType::QUERY_PARAM->value, RedirectConditionType::QUERY_PARAM])] + #[TestWith([RedirectConditionType::ANY_VALUE_QUERY_PARAM->value, RedirectConditionType::ANY_VALUE_QUERY_PARAM])] + #[TestWith([RedirectConditionType::VALUELESS_QUERY_PARAM->value, RedirectConditionType::VALUELESS_QUERY_PARAM])] #[TestWith([RedirectConditionType::IP_ADDRESS->value, RedirectConditionType::IP_ADDRESS])] #[TestWith( [RedirectConditionType::GEOLOCATION_COUNTRY_CODE->value, RedirectConditionType::GEOLOCATION_COUNTRY_CODE],