Decouple GeolocationMiddleware from GeoLite2

This commit is contained in:
Alejandro Celaya committed 2026-11-03 23:16:11 +01:00
1 parent 34f04a56e0
commit 6fda91cac7
4 files changed
+1 -34

No files matched your search

+1 -1
View File
@@ -47,7 +47,7 @@
"shlinkio/shlink-event-dispatcher": "^4.4.0",
"shlinkio/shlink-importer": "^5.8",
"shlinkio/shlink-installer": "dev-develop#27854d6 as 10.2.0",
"shlinkio/shlink-ip-geolocation": "dev-main#dae4b32 as 6.0.0",
"shlinkio/shlink-ip-geolocation": "dev-main#789cbbe as 6.0.0",
"shlinkio/shlink-json": "^1.3",
"spiral/roadrunner": "^2025.1",
"spiral/roadrunner-cli": "^2.7",
@@ -253,7 +253,6 @@ return [
],
Geolocation\Middleware\GeolocationMiddleware::class => [
LocationResolverInterface::class,
DbUpdater::class,
'Logger_Shlink',
Config\Options\TrackingOptions::class,
],
@@ -11,7 +11,6 @@ use Psr\Http\Server\RequestHandlerInterface;
use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Core\Config\Options\TrackingOptions;
use Shlinkio\Shlink\Geolocation\Exception\LocationResolutionException;
use Shlinkio\Shlink\Geolocation\GeoLite2\DbUpdaterInterface;
use Shlinkio\Shlink\Geolocation\Model\Location;
use Shlinkio\Shlink\Geolocation\Resolver\LocationResolverInterface;
use Throwable;
@@ -20,7 +19,6 @@ readonly class GeolocationMiddleware implements MiddlewareInterface
{
public function __construct(
private LocationResolverInterface $ipLocationResolver,
private DbUpdaterInterface $dbUpdater,
private LoggerInterface $logger,
private TrackingOptions $trackingOptions,
) {}
@@ -31,11 +29,6 @@ readonly class GeolocationMiddleware implements MiddlewareInterface
return $handler->handle($request);
}
if (!$this->dbUpdater->databaseFileExists()) {
$this->logger->warning('Tried to geolocate IP address, but a GeoLite2 db was not found.');
return $handler->handle($request);
}
$location = $this->geolocateIpAddress($request);
return $handler->handle($request->withAttribute(Location::class, $location));
}
@@ -17,7 +17,6 @@ use RuntimeException;
use Shlinkio\Shlink\Core\Config\Options\TrackingOptions;
use Shlinkio\Shlink\Core\Geolocation\Middleware\GeolocationMiddleware;
use Shlinkio\Shlink\Geolocation\Exception\LocationResolutionException;
use Shlinkio\Shlink\Geolocation\GeoLite2\DbUpdaterInterface;
use Shlinkio\Shlink\Geolocation\Model\Location;
use Shlinkio\Shlink\Geolocation\Resolver\LocationResolverInterface;
use Throwable;
@@ -27,14 +26,12 @@ use const Shlinkio\Shlink\Geolocation\IP_ADDRESS_REQUEST_ATTRIBUTE;
class GeolocationMiddlewareTest extends TestCase
{
private MockObject&LocationResolverInterface $ipLocationResolver;
private MockObject&DbUpdaterInterface $dbUpdater;
private MockObject&LoggerInterface $logger;
private MockObject&RequestHandlerInterface $handler;
protected function setUp(): void
{
$this->ipLocationResolver = $this->createMock(LocationResolverInterface::class);
$this->dbUpdater = $this->createMock(DbUpdaterInterface::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->handler = $this->createMock(RequestHandlerInterface::class);
}
@@ -42,7 +39,6 @@ class GeolocationMiddlewareTest extends TestCase
#[Test]
public function geolocationIsSkippedIfTrackingIsDisabled(): void
{
$this->dbUpdater->expects($this->never())->method('databaseFileExists');
$this->ipLocationResolver->expects($this->never())->method('resolveRequestLocation');
$this->logger->expects($this->never())->method('warning');
@@ -52,30 +48,11 @@ class GeolocationMiddlewareTest extends TestCase
$this->middleware(disableTracking: true)->process($request, $this->handler);
}
#[Test]
public function warningIsLoggedIfGeoLiteDbDoesNotExist(): void
{
$this->ipLocationResolver->expects($this->never())->method('resolveRequestLocation');
$this->dbUpdater->expects($this->once())->method('databaseFileExists')->willReturn(false);
$this->logger
->expects($this->once())
->method('warning')
->with(
'Tried to geolocate IP address, but a GeoLite2 db was not found.',
);
$request = ServerRequestFactory::fromGlobals();
$this->handler->expects($this->once())->method('handle')->with($request);
$this->middleware()->process($request, $this->handler);
}
#[Test]
public function locationIsResolvedFromIpAddress(): void
{
$request = ServerRequestFactory::fromGlobals()->withAttribute(IP_ADDRESS_REQUEST_ATTRIBUTE, '1.2.3.4');
$this->dbUpdater->expects($this->once())->method('databaseFileExists')->willReturn(true);
$this->ipLocationResolver
->expects($this->once())
->method('resolveRequestLocation')
@@ -122,7 +99,6 @@ class GeolocationMiddlewareTest extends TestCase
): void {
$request = ServerRequestFactory::fromGlobals()->withAttribute(IP_ADDRESS_REQUEST_ATTRIBUTE, '1.2.3.4');
$this->dbUpdater->expects($this->once())->method('databaseFileExists')->willReturn(true);
$this->ipLocationResolver
->expects($this->once())
->method('resolveRequestLocation')
@@ -152,7 +128,6 @@ class GeolocationMiddlewareTest extends TestCase
{
return new GeolocationMiddleware(
$this->ipLocationResolver,
$this->dbUpdater,
$this->logger,
new TrackingOptions(disableTracking: $disableTracking),
);