Created new command containing the logic to download the GeoLite2 db file

This commit is contained in:
Alejandro Celaya
2021-04-08 13:12:37 +02:00
parent 74ea5969be
commit f7b6f4ba19
7 changed files with 182 additions and 96 deletions

View File

@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace ShlinkioTest\Shlink\CLI;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
trait CliTestUtilsTrait
{
use ProphecyTrait;
/**
* @return ObjectProphecy|Command
*/
private function createCommandMock(string $name): ObjectProphecy
{
$command = $this->prophesize(Command::class);
$command->getName()->willReturn($name);
$command->getDefinition()->willReturn($name);
$command->isEnabled()->willReturn(true);
$command->getAliases()->willReturn([]);
$command->setApplication(Argument::type(Application::class))->willReturn(function (): void {
});
return $command;
}
}

View File

@@ -6,11 +6,10 @@ namespace ShlinkioTest\Shlink\CLI\Command\Visit;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\Visit\DownloadGeoLiteDbCommand;
use Shlinkio\Shlink\CLI\Command\Visit\LocateVisitsCommand;
use Shlinkio\Shlink\CLI\Exception\GeolocationDbUpdateFailedException;
use Shlinkio\Shlink\CLI\Util\GeolocationDbUpdaterInterface;
use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\Common\Util\IpAddress;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit;
@@ -21,6 +20,7 @@ use Shlinkio\Shlink\Core\Visit\VisitLocator;
use Shlinkio\Shlink\IpGeolocation\Exception\WrongIpException;
use Shlinkio\Shlink\IpGeolocation\Model\Location;
use Shlinkio\Shlink\IpGeolocation\Resolver\IpLocationResolverInterface;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Output\OutputInterface;
@@ -33,19 +33,18 @@ use const PHP_EOL;
class LocateVisitsCommandTest extends TestCase
{
use ProphecyTrait;
use CliTestUtilsTrait;
private CommandTester $commandTester;
private ObjectProphecy $visitService;
private ObjectProphecy $ipResolver;
private ObjectProphecy $lock;
private ObjectProphecy $dbUpdater;
private ObjectProphecy $downloadDbCommand;
public function setUp(): void
{
$this->visitService = $this->prophesize(VisitLocator::class);
$this->ipResolver = $this->prophesize(IpLocationResolverInterface::class);
$this->dbUpdater = $this->prophesize(GeolocationDbUpdaterInterface::class);
$locker = $this->prophesize(Lock\LockFactory::class);
$this->lock = $this->prophesize(Lock\LockInterface::class);
@@ -58,11 +57,14 @@ class LocateVisitsCommandTest extends TestCase
$this->visitService->reveal(),
$this->ipResolver->reveal(),
$locker->reveal(),
$this->dbUpdater->reveal(),
);
$app = new Application();
$app->add($command);
$this->downloadDbCommand = $this->createCommandMock(DownloadGeoLiteDbCommand::NAME);
$this->downloadDbCommand->run(Argument::cetera())->willReturn(ExitCodes::EXIT_SUCCESS);
$app->add($this->downloadDbCommand->reveal());
$this->commandTester = new CommandTester($command);
}
@@ -202,44 +204,56 @@ class LocateVisitsCommandTest extends TestCase
$resolveIpLocation->shouldNotHaveBeenCalled();
}
/**
* @test
* @dataProvider provideParams
*/
public function showsProperMessageWhenGeoLiteUpdateFails(bool $olderDbExists, string $expectedMessage): void
/** @test */
public function showsProperMessageWhenGeoLiteUpdateFails(): void
{
$locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will(function (): void {
});
$checkDbUpdate = $this->dbUpdater->checkDbUpdate(Argument::cetera())->will(
function (array $args) use ($olderDbExists): void {
[$mustBeUpdated, $handleProgress] = $args;
$mustBeUpdated($olderDbExists);
$handleProgress(100, 50);
throw $olderDbExists
? GeolocationDbUpdateFailedException::withOlderDb()
: GeolocationDbUpdateFailedException::withoutOlderDb();
},
);
$this->downloadDbCommand->run(Argument::cetera())->willReturn(ExitCodes::EXIT_FAILURE);
$this->commandTester->execute([]);
$output = $this->commandTester->getDisplay();
self::assertStringContainsString(
sprintf('%s GeoLite2 db file...', $olderDbExists ? 'Updating' : 'Downloading'),
$output,
);
self::assertStringContainsString($expectedMessage, $output);
$locateVisits->shouldHaveBeenCalledTimes((int) $olderDbExists);
$checkDbUpdate->shouldHaveBeenCalledOnce();
self::assertStringContainsString('It is not possible to locate visits without a GeoLite2 db file.', $output);
$this->visitService->locateUnlocatedVisits(Argument::cetera())->shouldNotHaveBeenCalled();
}
public function provideParams(): iterable
{
yield [true, '[Warning] GeoLite2 database update failed. Proceeding with old version.'];
yield [false, 'GeoLite2 database download failed. It is not possible to locate visits.'];
}
// /**
// * @test
// * @dataProvider provideParams
// */
// public function showsProperMessageWhenGeoLiteUpdateFails(bool $olderDbExists, string $expectedMessage): void
// {
// $locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will(function (): void {
// });
// $checkDbUpdate = $this->dbUpdater->checkDbUpdate(Argument::cetera())->will(
// function (array $args) use ($olderDbExists): void {
// [$mustBeUpdated, $handleProgress] = $args;
//
// $mustBeUpdated($olderDbExists);
// $handleProgress(100, 50);
//
// throw $olderDbExists
// ? GeolocationDbUpdateFailedException::withOlderDb()
// : GeolocationDbUpdateFailedException::withoutOlderDb();
// },
// );
//
// $this->commandTester->execute([]);
// $output = $this->commandTester->getDisplay();
//
// self::assertStringContainsString(
// sprintf('%s GeoLite2 db file...', $olderDbExists ? 'Updating' : 'Downloading'),
// $output,
// );
// self::assertStringContainsString($expectedMessage, $output);
// $locateVisits->shouldHaveBeenCalledTimes((int) $olderDbExists);
// $checkDbUpdate->shouldHaveBeenCalledOnce();
// }
//
// public function provideParams(): iterable
// {
// yield [true, '[Warning] GeoLite2 database update failed. Proceeding with old version.'];
// yield [false, 'GeoLite2 database download failed. It is not possible to locate visits.'];
// }
/** @test */
public function providingAllFlagOnItsOwnDisplaysNotice(): void

View File

@@ -6,17 +6,13 @@ namespace ShlinkioTest\Shlink\CLI\Factory;
use Laminas\ServiceManager\ServiceManager;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Factory\ApplicationFactory;
use Shlinkio\Shlink\Core\Options\AppOptions;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;
class ApplicationFactoryTest extends TestCase
{
use ProphecyTrait;
use CliTestUtilsTrait;
private ApplicationFactory $factory;
@@ -54,17 +50,4 @@ class ApplicationFactoryTest extends TestCase
AppOptions::class => new AppOptions(),
]]);
}
private function createCommandMock(string $name): ObjectProphecy
{
$command = $this->prophesize(Command::class);
$command->getName()->willReturn($name);
$command->getDefinition()->willReturn($name);
$command->isEnabled()->willReturn(true);
$command->getAliases()->willReturn([]);
$command->setApplication(Argument::type(Application::class))->willReturn(function (): void {
});
return $command;
}
}