Add more strict parameter for GeolocationDbUpdater

This commit is contained in:
Alejandro Celaya
2024-12-11 08:27:50 +01:00
parent 06c0a94b31
commit b8ac9f3673
6 changed files with 111 additions and 64 deletions

View File

@@ -7,6 +7,7 @@ namespace Shlinkio\Shlink\CLI\Command\Visit;
use Shlinkio\Shlink\CLI\Util\ExitCode;
use Shlinkio\Shlink\Core\Exception\GeolocationDbUpdateFailedException;
use Shlinkio\Shlink\Core\Geolocation\GeolocationDbUpdaterInterface;
use Shlinkio\Shlink\Core\Geolocation\GeolocationDownloadProgressHandlerInterface;
use Shlinkio\Shlink\Core\Geolocation\GeolocationResult;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar;
@@ -16,13 +17,14 @@ use Symfony\Component\Console\Style\SymfonyStyle;
use function sprintf;
class DownloadGeoLiteDbCommand extends Command
class DownloadGeoLiteDbCommand extends Command implements GeolocationDownloadProgressHandlerInterface
{
public const string NAME = 'visit:download-db';
private ProgressBar|null $progressBar = null;
private SymfonyStyle $io;
public function __construct(private GeolocationDbUpdaterInterface $dbUpdater)
public function __construct(private readonly GeolocationDbUpdaterInterface $dbUpdater)
{
parent::__construct();
}
@@ -39,32 +41,26 @@ class DownloadGeoLiteDbCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$this->io = new SymfonyStyle($input, $output);
try {
$result = $this->dbUpdater->checkDbUpdate(function (bool $olderDbExists) use ($io): void {
$io->text(sprintf('<fg=blue>%s GeoLite2 db file...</>', $olderDbExists ? 'Updating' : 'Downloading'));
$this->progressBar = new ProgressBar($io);
}, function (int $total, int $downloaded): void {
$this->progressBar?->setMaxSteps($total);
$this->progressBar?->setProgress($downloaded);
});
$result = $this->dbUpdater->checkDbUpdate($this);
if ($result === GeolocationResult::LICENSE_MISSING) {
$io->warning('It was not possible to download GeoLite2 db, because a license was not provided.');
$this->io->warning('It was not possible to download GeoLite2 db, because a license was not provided.');
return ExitCode::EXIT_WARNING;
}
if ($this->progressBar === null) {
$io->info('GeoLite2 db file is up to date.');
$this->io->info('GeoLite2 db file is up to date.');
} else {
$this->progressBar->finish();
$io->success('GeoLite2 db file properly downloaded.');
$this->io->success('GeoLite2 db file properly downloaded.');
}
return ExitCode::EXIT_SUCCESS;
} catch (GeolocationDbUpdateFailedException $e) {
return $this->processGeoLiteUpdateError($e, $io);
return $this->processGeoLiteUpdateError($e, $this->io);
}
}
@@ -86,4 +82,16 @@ class DownloadGeoLiteDbCommand extends Command
return $olderDbExists ? ExitCode::EXIT_WARNING : ExitCode::EXIT_FAILURE;
}
public function beforeDownload(bool $olderDbExists): void
{
$this->io->text(sprintf('<fg=blue>%s GeoLite2 db file...</>', $olderDbExists ? 'Updating' : 'Downloading'));
$this->progressBar = new ProgressBar($this->io);
}
public function handleProgress(int $total, int $downloaded, bool $olderDbExists): void
{
$this->progressBar?->setMaxSteps($total);
$this->progressBar?->setProgress($downloaded);
}
}

View File

@@ -14,6 +14,7 @@ use PHPUnit\Framework\TestCase;
use Shlinkio\Shlink\Core\Config\Options\TrackingOptions;
use Shlinkio\Shlink\Core\Exception\GeolocationDbUpdateFailedException;
use Shlinkio\Shlink\Core\Geolocation\GeolocationDbUpdater;
use Shlinkio\Shlink\Core\Geolocation\GeolocationDownloadProgressHandlerInterface;
use Shlinkio\Shlink\Core\Geolocation\GeolocationResult;
use Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException;
use Shlinkio\Shlink\IpGeolocation\Exception\MissingLicenseException;
@@ -29,6 +30,8 @@ class GeolocationDbUpdaterTest extends TestCase
private MockObject & DbUpdaterInterface $dbUpdater;
private MockObject & Reader $geoLiteDbReader;
private MockObject & Lock\LockInterface $lock;
/** @var GeolocationDownloadProgressHandlerInterface&object{beforeDownloadCalled: bool, handleProgressCalled: bool} */
private GeolocationDownloadProgressHandlerInterface $progressHandler;
protected function setUp(): void
{
@@ -36,6 +39,23 @@ class GeolocationDbUpdaterTest extends TestCase
$this->geoLiteDbReader = $this->createMock(Reader::class);
$this->lock = $this->createMock(Lock\SharedLockInterface::class);
$this->lock->method('acquire')->with($this->isTrue())->willReturn(true);
$this->progressHandler = new class implements GeolocationDownloadProgressHandlerInterface {
public function __construct(
public bool $beforeDownloadCalled = false,
public bool $handleProgressCalled = false,
) {
}
public function beforeDownload(bool $olderDbExists): void
{
$this->beforeDownloadCalled = true;
}
public function handleProgress(int $total, int $downloaded, bool $olderDbExists): void
{
$this->handleProgressCalled = true;
}
};
}
#[Test]
@@ -47,12 +67,9 @@ class GeolocationDbUpdaterTest extends TestCase
);
$this->geoLiteDbReader->expects($this->never())->method('metadata');
$isCalled = false;
$result = $this->geolocationDbUpdater()->checkDbUpdate(function () use (&$isCalled): void {
$isCalled = true;
});
$result = $this->geolocationDbUpdater()->checkDbUpdate($this->progressHandler);
self::assertTrue($isCalled);
self::assertTrue($this->progressHandler->beforeDownloadCalled);
self::assertEquals(GeolocationResult::LICENSE_MISSING, $result);
}
@@ -67,17 +84,14 @@ class GeolocationDbUpdaterTest extends TestCase
)->willThrowException($prev);
$this->geoLiteDbReader->expects($this->never())->method('metadata');
$isCalled = false;
try {
$this->geolocationDbUpdater()->checkDbUpdate(function () use (&$isCalled): void {
$isCalled = true;
});
$this->geolocationDbUpdater()->checkDbUpdate($this->progressHandler);
self::fail();
} catch (Throwable $e) {
self::assertInstanceOf(GeolocationDbUpdateFailedException::class, $e);
self::assertSame($prev, $e->getPrevious());
self::assertFalse($e->olderDbExists());
self::assertTrue($isCalled);
self::assertTrue($this->progressHandler->beforeDownloadCalled);
}
}