Merge pull request #593 from acelaya-forks/feature/coding-standard-2.1

Feature/coding standard 2.1
This commit is contained in:
Alejandro Celaya 2020-01-01 20:56:47 +01:00 committed by GitHub
commit 18312b0624
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
113 changed files with 254 additions and 301 deletions

View file

@ -13,7 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
#### Changed #### Changed
* *Nothing* * [#592](https://github.com/shlinkio/shlink/issues/592) Updated coding styles to use [shlinkio/php-coding-standard](https://github.com/shlinkio/php-coding-standard) v2.1.0.
#### Deprecated #### Deprecated

View file

@ -63,7 +63,7 @@
"phpstan/phpstan": "^0.12.3", "phpstan/phpstan": "^0.12.3",
"phpunit/phpunit": "^8.3", "phpunit/phpunit": "^8.3",
"roave/security-advisories": "dev-master", "roave/security-advisories": "dev-master",
"shlinkio/php-coding-standard": "~2.0.0", "shlinkio/php-coding-standard": "~2.1.0",
"shlinkio/shlink-test-utils": "^1.2", "shlinkio/shlink-test-utils": "^1.2",
"symfony/var-dumper": "^5.0" "symfony/var-dumper": "^5.0"
}, },

View file

@ -17,7 +17,6 @@ final class Version20180801183328 extends AbstractMigration
private const OLD_SIZE = 10; private const OLD_SIZE = 10;
/** /**
* @param Schema $schema
* @throws SchemaException * @throws SchemaException
*/ */
public function up(Schema $schema): void public function up(Schema $schema): void
@ -26,7 +25,6 @@ final class Version20180801183328 extends AbstractMigration
} }
/** /**
* @param Schema $schema
* @throws SchemaException * @throws SchemaException
*/ */
public function down(Schema $schema): void public function down(Schema $schema): void
@ -35,8 +33,6 @@ final class Version20180801183328 extends AbstractMigration
} }
/** /**
* @param Schema $schema
* @param int $size
* @throws SchemaException * @throws SchemaException
*/ */
private function setSize(Schema $schema, int $size): void private function setSize(Schema $schema, int $size): void

View file

@ -17,7 +17,6 @@ use Shlinkio\Shlink\Common\Util\IpAddress;
final class Version20180913205455 extends AbstractMigration final class Version20180913205455 extends AbstractMigration
{ {
/** /**
* @param Schema $schema
*/ */
public function up(Schema $schema): void public function up(Schema $schema): void
{ {
@ -25,7 +24,6 @@ final class Version20180913205455 extends AbstractMigration
} }
/** /**
* @param Schema $schema
* @throws DBALException * @throws DBALException
*/ */
public function postUp(Schema $schema): void public function postUp(Schema $schema): void
@ -67,7 +65,6 @@ final class Version20180913205455 extends AbstractMigration
} }
/** /**
* @param Schema $schema
*/ */
public function down(Schema $schema): void public function down(Schema $schema): void
{ {

View file

@ -19,7 +19,6 @@ final class Version20180915110857 extends AbstractMigration
]; ];
/** /**
* @param Schema $schema
* @throws SchemaException * @throws SchemaException
*/ */
public function up(Schema $schema): void public function up(Schema $schema): void
@ -39,7 +38,7 @@ final class Version20180915110857 extends AbstractMigration
[ [
'onDelete' => self::ON_DELETE_MAP[$foreignTable], 'onDelete' => self::ON_DELETE_MAP[$foreignTable],
'onUpdate' => 'RESTRICT', 'onUpdate' => 'RESTRICT',
] ],
); );
} }
} }

View file

@ -24,7 +24,6 @@ final class Version20181020060559 extends AbstractMigration
]; ];
/** /**
* @param Schema $schema
* @throws SchemaException * @throws SchemaException
*/ */
public function up(Schema $schema): void public function up(Schema $schema): void

View file

@ -36,7 +36,7 @@ class GenerateKeyCommand extends Command
'expirationDate', 'expirationDate',
'e', 'e',
InputOption::VALUE_REQUIRED, InputOption::VALUE_REQUIRED,
'The date in which the API key should expire. Use any valid PHP format.' 'The date in which the API key should expire. Use any valid PHP format.',
); );
} }

View file

@ -42,7 +42,7 @@ class ListKeysCommand extends Command
'enabledOnly', 'enabledOnly',
'e', 'e',
InputOption::VALUE_NONE, InputOption::VALUE_NONE,
'Tells if only enabled API keys should be returned.' 'Tells if only enabled API keys should be returned.',
); );
} }
@ -81,8 +81,6 @@ class ListKeysCommand extends Command
} }
/** /**
* @param ApiKey $apiKey
* @return string
*/ */
private function getEnabledSymbol(ApiKey $apiKey): string private function getEnabledSymbol(ApiKey $apiKey): string
{ {

View file

@ -41,7 +41,7 @@ class CreateDatabaseCommand extends AbstractDatabaseCommand
$this $this
->setName(self::NAME) ->setName(self::NAME)
->setDescription( ->setDescription(
'Creates the database needed for shlink to work. It will do nothing if the database already exists' 'Creates the database needed for shlink to work. It will do nothing if the database already exists',
); );
} }

View file

@ -39,7 +39,7 @@ class DeleteShortUrlCommand extends Command
'i', 'i',
InputOption::VALUE_NONE, InputOption::VALUE_NONE,
'Ignores the safety visits threshold check, which could make short URLs with many visits to be ' 'Ignores the safety visits threshold check, which could make short URLs with many visits to be '
. 'accidentally deleted' . 'accidentally deleted',
); );
} }

View file

@ -47,45 +47,45 @@ class GenerateShortUrlCommand extends Command
'tags', 'tags',
't', 't',
InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED,
'Tags to apply to the new short URL' 'Tags to apply to the new short URL',
) )
->addOption( ->addOption(
'validSince', 'validSince',
's', 's',
InputOption::VALUE_REQUIRED, InputOption::VALUE_REQUIRED,
'The date from which this short URL will be valid. ' 'The date from which this short URL will be valid. '
. 'If someone tries to access it before this date, it will not be found.' . 'If someone tries to access it before this date, it will not be found.',
) )
->addOption( ->addOption(
'validUntil', 'validUntil',
'u', 'u',
InputOption::VALUE_REQUIRED, InputOption::VALUE_REQUIRED,
'The date until which this short URL will be valid. ' 'The date until which this short URL will be valid. '
. 'If someone tries to access it after this date, it will not be found.' . 'If someone tries to access it after this date, it will not be found.',
) )
->addOption( ->addOption(
'customSlug', 'customSlug',
'c', 'c',
InputOption::VALUE_REQUIRED, InputOption::VALUE_REQUIRED,
'If provided, this slug will be used instead of generating a short code' 'If provided, this slug will be used instead of generating a short code',
) )
->addOption( ->addOption(
'maxVisits', 'maxVisits',
'm', 'm',
InputOption::VALUE_REQUIRED, InputOption::VALUE_REQUIRED,
'This will limit the number of visits for this short URL.' 'This will limit the number of visits for this short URL.',
) )
->addOption( ->addOption(
'findIfExists', 'findIfExists',
'f', 'f',
InputOption::VALUE_NONE, InputOption::VALUE_NONE,
'This will force existing matching URL to be returned if found, instead of creating a new one.' 'This will force existing matching URL to be returned if found, instead of creating a new one.',
) )
->addOption( ->addOption(
'domain', 'domain',
'd', 'd',
InputOption::VALUE_REQUIRED, InputOption::VALUE_REQUIRED,
'The domain to which this short URL will be attached.' 'The domain to which this short URL will be attached.',
); );
} }
@ -127,8 +127,8 @@ class GenerateShortUrlCommand extends Command
$customSlug, $customSlug,
$maxVisits !== null ? (int) $maxVisits : null, $maxVisits !== null ? (int) $maxVisits : null,
$input->getOption('findIfExists'), $input->getOption('findIfExists'),
$input->getOption('domain') $input->getOption('domain'),
) ),
); );
$io->writeln([ $io->writeln([

View file

@ -61,25 +61,25 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
'p', 'p',
InputOption::VALUE_REQUIRED, InputOption::VALUE_REQUIRED,
sprintf('The first page to list (%s items per page)', ShortUrlRepositoryAdapter::ITEMS_PER_PAGE), sprintf('The first page to list (%s items per page)', ShortUrlRepositoryAdapter::ITEMS_PER_PAGE),
'1' '1',
) )
->addOption( ->addOption(
'searchTerm', 'searchTerm',
'st', 'st',
InputOption::VALUE_REQUIRED, InputOption::VALUE_REQUIRED,
'A query used to filter results by searching for it on the longUrl and shortCode fields' 'A query used to filter results by searching for it on the longUrl and shortCode fields',
) )
->addOption( ->addOption(
'tags', 'tags',
't', 't',
InputOption::VALUE_REQUIRED, InputOption::VALUE_REQUIRED,
'A comma-separated list of tags to filter results' 'A comma-separated list of tags to filter results',
) )
->addOption( ->addOption(
'orderBy', 'orderBy',
'o', 'o',
InputOption::VALUE_REQUIRED, InputOption::VALUE_REQUIRED,
'The field from which we want to order by. Pass ASC or DESC separated by a comma' 'The field from which we want to order by. Pass ASC or DESC separated by a comma',
) )
->addOption('showTags', null, InputOption::VALUE_NONE, 'Whether to display the tags or not'); ->addOption('showTags', null, InputOption::VALUE_NONE, 'Whether to display the tags or not');
} }
@ -122,6 +122,9 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
return ExitCodes::EXIT_SUCCESS; return ExitCodes::EXIT_SUCCESS;
} }
/**
* @param string|array|null $orderBy
*/
private function renderPage( private function renderPage(
OutputInterface $output, OutputInterface $output,
int $page, int $page,
@ -137,7 +140,7 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
$searchTerm, $searchTerm,
$tags, $tags,
$orderBy, $orderBy,
new DateRange($startDate, $endDate) new DateRange($startDate, $endDate),
); );
$headers = ['Short code', 'Short URL', 'Long URL', 'Date created', 'Visits count']; $headers = ['Short code', 'Short URL', 'Long URL', 'Date created', 'Visits count'];
@ -159,7 +162,7 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
ShlinkTable::fromOutput($output)->render($headers, $rows, $this->formatCurrentPageMessage( ShlinkTable::fromOutput($output)->render($headers, $rows, $this->formatCurrentPageMessage(
$result, $result,
'Page %s of %s' 'Page %s of %s',
)); ));
return $result; return $result;

View file

@ -33,7 +33,7 @@ class CreateTagCommand extends Command
'name', 'name',
't', 't',
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'The name of the tags to create' 'The name of the tags to create',
); );
} }

View file

@ -33,7 +33,7 @@ class DeleteTagsCommand extends Command
'name', 'name',
't', 't',
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'The name of the tags to delete' 'The name of the tags to delete',
); );
} }

View file

@ -29,7 +29,7 @@ abstract class AbstractLockedCommand extends Command
if (! $lock->acquire($lockConfig->isBlocking())) { if (! $lock->acquire($lockConfig->isBlocking())) {
$output->writeln( $output->writeln(
sprintf('<comment>Command "%s" is already in progress. Skipping.</comment>', $lockConfig->lockName()) sprintf('<comment>Command "%s" is already in progress. Skipping.</comment>', $lockConfig->lockName()),
); );
return ExitCodes::EXIT_WARNING; return ExitCodes::EXIT_WARNING;
} }

View file

@ -36,7 +36,7 @@ abstract class AbstractWithDateRangeCommand extends Command
$output->writeln(sprintf( $output->writeln(sprintf(
'<comment>> Ignored provided "%s" since its value "%s" is not a valid date. <</comment>', '<comment>> Ignored provided "%s" since its value "%s" is not a valid date. <</comment>',
$key, $key,
$value $value,
)); ));
if ($output->isVeryVerbose()) { if ($output->isVeryVerbose()) {

View file

@ -66,13 +66,13 @@ class LocateVisitsCommand extends AbstractLockedCommand
$this->visitService->locateUnlocatedVisits( $this->visitService->locateUnlocatedVisits(
[$this, 'getGeolocationDataForVisit'], [$this, 'getGeolocationDataForVisit'],
static function (VisitLocation $location) use ($output) { static function (VisitLocation $location) use ($output): void {
if (!$location->isEmpty()) { if (!$location->isEmpty()) {
$output->writeln( $output->writeln(
sprintf(' [<info>Address located at "%s"</info>]', $location->getCountryName()) sprintf(' [<info>Address located at "%s"</info>]', $location->getCountryName()),
); );
} }
} },
); );
$this->io->success('Finished processing all IPs'); $this->io->success('Finished processing all IPs');
@ -92,7 +92,7 @@ class LocateVisitsCommand extends AbstractLockedCommand
if (! $visit->hasRemoteAddr()) { if (! $visit->hasRemoteAddr()) {
$this->io->writeln( $this->io->writeln(
'<comment>Ignored visit with no IP address</comment>', '<comment>Ignored visit with no IP address</comment>',
OutputInterface::VERBOSITY_VERBOSE OutputInterface::VERBOSITY_VERBOSE,
); );
throw IpCannotBeLocatedException::forEmptyAddress(); throw IpCannotBeLocatedException::forEmptyAddress();
} }
@ -119,12 +119,12 @@ class LocateVisitsCommand extends AbstractLockedCommand
private function checkDbUpdate(): void private function checkDbUpdate(): void
{ {
try { try {
$this->dbUpdater->checkDbUpdate(function (bool $olderDbExists) { $this->dbUpdater->checkDbUpdate(function (bool $olderDbExists): void {
$this->io->writeln( $this->io->writeln(
sprintf('<fg=blue>%s GeoLite2 database...</>', $olderDbExists ? 'Updating' : 'Downloading') sprintf('<fg=blue>%s GeoLite2 database...</>', $olderDbExists ? 'Updating' : 'Downloading'),
); );
$this->progressBar = new ProgressBar($this->io); $this->progressBar = new ProgressBar($this->io);
}, function (int $total, int $downloaded) { }, function (int $total, int $downloaded): void {
$this->progressBar->setMaxSteps($total); $this->progressBar->setMaxSteps($total);
$this->progressBar->setProgress($downloaded); $this->progressBar->setProgress($downloaded);
}); });
@ -141,7 +141,7 @@ class LocateVisitsCommand extends AbstractLockedCommand
$this->io->newLine(); $this->io->newLine();
$this->io->writeln( $this->io->writeln(
'<fg=yellow;options=bold>[Warning] GeoLite2 database update failed. Proceeding with old version.</>' '<fg=yellow;options=bold>[Warning] GeoLite2 database update failed. Proceeding with old version.</>',
); );
} }
} }

View file

@ -8,7 +8,7 @@ use function Shlinkio\Shlink\Common\loadConfigFromGlob;
class ConfigProvider class ConfigProvider
{ {
public function __invoke() public function __invoke(): array
{ {
return loadConfigFromGlob(__DIR__ . '/../config/{,*.}config.php'); return loadConfigFromGlob(__DIR__ . '/../config/{,*.}config.php');
} }

View file

@ -16,7 +16,7 @@ class GeolocationDbUpdateFailedException extends RuntimeException implements Exc
$e = new self( $e = new self(
'An error occurred while updating geolocation database, and an older version could not be found', 'An error occurred while updating geolocation database, and an older version could not be found',
0, 0,
$prev $prev,
); );
$e->olderDbExists = $olderDbExists; $e->olderDbExists = $olderDbExists;

View file

@ -29,7 +29,7 @@ class GenerateKeyCommandTest extends TestCase
} }
/** @test */ /** @test */
public function noExpirationDateIsDefinedIfNotProvided() public function noExpirationDateIsDefinedIfNotProvided(): void
{ {
$create = $this->apiKeyService->create(null)->willReturn(new ApiKey()); $create = $this->apiKeyService->create(null)->willReturn(new ApiKey());
@ -41,7 +41,7 @@ class GenerateKeyCommandTest extends TestCase
} }
/** @test */ /** @test */
public function expirationDateIsDefinedIfProvided() public function expirationDateIsDefinedIfProvided(): void
{ {
$this->apiKeyService->create(Argument::type(Chronos::class))->shouldBeCalledOnce() $this->apiKeyService->create(Argument::type(Chronos::class))->shouldBeCalledOnce()
->willReturn(new ApiKey()); ->willReturn(new ApiKey());

View file

@ -33,7 +33,7 @@ class CreateDatabaseCommandTest extends TestCase
$locker = $this->prophesize(LockFactory::class); $locker = $this->prophesize(LockFactory::class);
$lock = $this->prophesize(LockInterface::class); $lock = $this->prophesize(LockInterface::class);
$lock->acquire(Argument::any())->willReturn(true); $lock->acquire(Argument::any())->willReturn(true);
$lock->release()->will(function () { $lock->release()->will(function (): void {
}); });
$locker->createLock(Argument::cetera())->willReturn($lock->reveal()); $locker->createLock(Argument::cetera())->willReturn($lock->reveal());
@ -55,7 +55,7 @@ class CreateDatabaseCommandTest extends TestCase
$this->processHelper->reveal(), $this->processHelper->reveal(),
$phpExecutableFinder->reveal(), $phpExecutableFinder->reveal(),
$this->regularConn->reveal(), $this->regularConn->reveal(),
$this->noDbNameConn->reveal() $this->noDbNameConn->reveal(),
); );
$app = new Application(); $app = new Application();
$app->add($command); $app->add($command);
@ -69,7 +69,7 @@ class CreateDatabaseCommandTest extends TestCase
$shlinkDatabase = 'shlink_database'; $shlinkDatabase = 'shlink_database';
$getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase); $getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase);
$listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', $shlinkDatabase, 'bar']); $listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', $shlinkDatabase, 'bar']);
$createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function () { $createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function (): void {
}); });
$listTables = $this->schemaManager->listTableNames()->willReturn(['foo_table', 'bar_table']); $listTables = $this->schemaManager->listTableNames()->willReturn(['foo_table', 'bar_table']);
@ -89,7 +89,7 @@ class CreateDatabaseCommandTest extends TestCase
$shlinkDatabase = 'shlink_database'; $shlinkDatabase = 'shlink_database';
$getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase); $getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase);
$listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', 'bar']); $listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', 'bar']);
$createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function () { $createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function (): void {
}); });
$listTables = $this->schemaManager->listTableNames()->willReturn(['foo_table', 'bar_table']); $listTables = $this->schemaManager->listTableNames()->willReturn(['foo_table', 'bar_table']);
@ -107,7 +107,7 @@ class CreateDatabaseCommandTest extends TestCase
$shlinkDatabase = 'shlink_database'; $shlinkDatabase = 'shlink_database';
$getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase); $getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase);
$listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', $shlinkDatabase, 'bar']); $listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', $shlinkDatabase, 'bar']);
$createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function () { $createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function (): void {
}); });
$listTables = $this->schemaManager->listTableNames()->willReturn([]); $listTables = $this->schemaManager->listTableNames()->willReturn([]);
$runCommand = $this->processHelper->mustRun(Argument::type(OutputInterface::class), [ $runCommand = $this->processHelper->mustRun(Argument::type(OutputInterface::class), [
@ -136,7 +136,7 @@ class CreateDatabaseCommandTest extends TestCase
$shlinkDatabase = 'shlink_database'; $shlinkDatabase = 'shlink_database';
$getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase); $getDatabase = $this->regularConn->getDatabase()->willReturn($shlinkDatabase);
$listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', 'bar']); $listDatabases = $this->schemaManager->listDatabases()->willReturn(['foo', 'bar']);
$createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function () { $createDatabase = $this->schemaManager->createDatabase($shlinkDatabase)->will(function (): void {
}); });
$listTables = $this->schemaManager->listTableNames()->willReturn(['foo_table', 'bar_table']); $listTables = $this->schemaManager->listTableNames()->willReturn(['foo_table', 'bar_table']);

View file

@ -26,7 +26,7 @@ class MigrateDatabaseCommandTest extends TestCase
$locker = $this->prophesize(LockFactory::class); $locker = $this->prophesize(LockFactory::class);
$lock = $this->prophesize(LockInterface::class); $lock = $this->prophesize(LockInterface::class);
$lock->acquire(Argument::any())->willReturn(true); $lock->acquire(Argument::any())->willReturn(true);
$lock->release()->will(function () { $lock->release()->will(function (): void {
}); });
$locker->createLock(Argument::cetera())->willReturn($lock->reveal()); $locker->createLock(Argument::cetera())->willReturn($lock->reveal());
@ -38,7 +38,7 @@ class MigrateDatabaseCommandTest extends TestCase
$command = new MigrateDatabaseCommand( $command = new MigrateDatabaseCommand(
$locker->reveal(), $locker->reveal(),
$this->processHelper->reveal(), $this->processHelper->reveal(),
$phpExecutableFinder->reveal() $phpExecutableFinder->reveal(),
); );
$app = new Application(); $app = new Application();
$app->add($command); $app->add($command);

View file

@ -38,7 +38,7 @@ class DeleteShortUrlCommandTest extends TestCase
public function successMessageIsPrintedIfUrlIsProperlyDeleted(): void public function successMessageIsPrintedIfUrlIsProperlyDeleted(): void
{ {
$shortCode = 'abc123'; $shortCode = 'abc123';
$deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->will(function () { $deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->will(function (): void {
}); });
$this->commandTester->execute(['shortCode' => $shortCode]); $this->commandTester->execute(['shortCode' => $shortCode]);
@ -46,7 +46,7 @@ class DeleteShortUrlCommandTest extends TestCase
$this->assertStringContainsString( $this->assertStringContainsString(
sprintf('Short URL with short code "%s" successfully deleted.', $shortCode), sprintf('Short URL with short code "%s" successfully deleted.', $shortCode),
$output $output,
); );
$deleteByShortCode->shouldHaveBeenCalledOnce(); $deleteByShortCode->shouldHaveBeenCalledOnce();
} }
@ -56,7 +56,7 @@ class DeleteShortUrlCommandTest extends TestCase
{ {
$shortCode = 'abc123'; $shortCode = 'abc123';
$deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->willThrow( $deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->willThrow(
Exception\ShortUrlNotFoundException::fromNotFoundShortCode($shortCode) Exception\ShortUrlNotFoundException::fromNotFoundShortCode($shortCode),
); );
$this->commandTester->execute(['shortCode' => $shortCode]); $this->commandTester->execute(['shortCode' => $shortCode]);
@ -77,13 +77,13 @@ class DeleteShortUrlCommandTest extends TestCase
): void { ): void {
$shortCode = 'abc123'; $shortCode = 'abc123';
$deleteByShortCode = $this->service->deleteByShortCode($shortCode, Argument::type('bool'))->will( $deleteByShortCode = $this->service->deleteByShortCode($shortCode, Argument::type('bool'))->will(
function (array $args) use ($shortCode) { function (array $args) use ($shortCode): void {
$ignoreThreshold = array_pop($args); $ignoreThreshold = array_pop($args);
if (!$ignoreThreshold) { if (!$ignoreThreshold) {
throw Exception\DeleteShortUrlException::fromVisitsThreshold(10, $shortCode); throw Exception\DeleteShortUrlException::fromVisitsThreshold(10, $shortCode);
} }
} },
); );
$this->commandTester->setInputs($retryAnswer); $this->commandTester->setInputs($retryAnswer);
@ -92,7 +92,7 @@ class DeleteShortUrlCommandTest extends TestCase
$this->assertStringContainsString(sprintf( $this->assertStringContainsString(sprintf(
'Impossible to delete short URL with short code "%s" since it has more than "10" visits.', 'Impossible to delete short URL with short code "%s" since it has more than "10" visits.',
$shortCode $shortCode,
), $output); ), $output);
$this->assertStringContainsString($expectedMessage, $output); $this->assertStringContainsString($expectedMessage, $output);
$deleteByShortCode->shouldHaveBeenCalledTimes($expectedDeleteCalls); $deleteByShortCode->shouldHaveBeenCalledTimes($expectedDeleteCalls);
@ -110,7 +110,7 @@ class DeleteShortUrlCommandTest extends TestCase
{ {
$shortCode = 'abc123'; $shortCode = 'abc123';
$deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->willThrow( $deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->willThrow(
Exception\DeleteShortUrlException::fromVisitsThreshold(10, $shortCode) Exception\DeleteShortUrlException::fromVisitsThreshold(10, $shortCode),
); );
$this->commandTester->setInputs(['no']); $this->commandTester->setInputs(['no']);
@ -119,7 +119,7 @@ class DeleteShortUrlCommandTest extends TestCase
$this->assertStringContainsString(sprintf( $this->assertStringContainsString(sprintf(
'Impossible to delete short URL with short code "%s" since it has more than "10" visits.', 'Impossible to delete short URL with short code "%s" since it has more than "10" visits.',
$shortCode $shortCode,
), $output); ), $output);
$this->assertStringContainsString('Short URL was not deleted.', $output); $this->assertStringContainsString('Short URL was not deleted.', $output);
$deleteByShortCode->shouldHaveBeenCalledOnce(); $deleteByShortCode->shouldHaveBeenCalledOnce();

View file

@ -72,7 +72,7 @@ class GenerateShortUrlCommandTest extends TestCase
public function providingNonUniqueSlugOutputsError(): void public function providingNonUniqueSlugOutputsError(): void
{ {
$urlToShortCode = $this->urlShortener->urlToShortCode(Argument::cetera())->willThrow( $urlToShortCode = $this->urlShortener->urlToShortCode(Argument::cetera())->willThrow(
NonUniqueSlugException::fromSlug('my-slug') NonUniqueSlugException::fromSlug('my-slug'),
); );
$this->commandTester->execute(['longUrl' => 'http://domain.com/invalid', '--customSlug' => 'my-slug']); $this->commandTester->execute(['longUrl' => 'http://domain.com/invalid', '--customSlug' => 'my-slug']);
@ -93,7 +93,7 @@ class GenerateShortUrlCommandTest extends TestCase
Assert::assertEquals(['foo', 'bar', 'baz', 'boo', 'zar'], $tags); Assert::assertEquals(['foo', 'bar', 'baz', 'boo', 'zar'], $tags);
return $tags; return $tags;
}), }),
Argument::cetera() Argument::cetera(),
)->willReturn($shortUrl); )->willReturn($shortUrl);
$this->commandTester->execute([ $this->commandTester->execute([

View file

@ -43,7 +43,7 @@ class GetVisitsCommandTest extends TestCase
{ {
$shortCode = 'abc123'; $shortCode = 'abc123';
$this->visitsTracker->info($shortCode, new VisitsParams(new DateRange(null, null)))->willReturn( $this->visitsTracker->info($shortCode, new VisitsParams(new DateRange(null, null)))->willReturn(
new Paginator(new ArrayAdapter([])) new Paginator(new ArrayAdapter([])),
)->shouldBeCalledOnce(); )->shouldBeCalledOnce();
$this->commandTester->execute(['shortCode' => $shortCode]); $this->commandTester->execute(['shortCode' => $shortCode]);
@ -57,7 +57,7 @@ class GetVisitsCommandTest extends TestCase
$endDate = '2016-02-01'; $endDate = '2016-02-01';
$this->visitsTracker->info( $this->visitsTracker->info(
$shortCode, $shortCode,
new VisitsParams(new DateRange(Chronos::parse($startDate), Chronos::parse($endDate))) new VisitsParams(new DateRange(Chronos::parse($startDate), Chronos::parse($endDate))),
) )
->willReturn(new Paginator(new ArrayAdapter([]))) ->willReturn(new Paginator(new ArrayAdapter([])))
->shouldBeCalledOnce(); ->shouldBeCalledOnce();
@ -86,7 +86,7 @@ class GetVisitsCommandTest extends TestCase
$info->shouldHaveBeenCalledOnce(); $info->shouldHaveBeenCalledOnce();
$this->assertStringContainsString( $this->assertStringContainsString(
sprintf('Ignored provided "startDate" since its value "%s" is not a valid date', $startDate), sprintf('Ignored provided "startDate" since its value "%s" is not a valid date', $startDate),
$output $output,
); );
} }
@ -97,9 +97,9 @@ class GetVisitsCommandTest extends TestCase
$this->visitsTracker->info($shortCode, Argument::any())->willReturn( $this->visitsTracker->info($shortCode, Argument::any())->willReturn(
new Paginator(new ArrayAdapter([ new Paginator(new ArrayAdapter([
(new Visit(new ShortUrl(''), new Visitor('bar', 'foo', '')))->locate( (new Visit(new ShortUrl(''), new Visitor('bar', 'foo', '')))->locate(
new VisitLocation(new Location('', 'Spain', '', '', 0, 0, '')) new VisitLocation(new Location('', 'Spain', '', '', 0, 0, '')),
), ),
])) ])),
)->shouldBeCalledOnce(); )->shouldBeCalledOnce();
$this->commandTester->execute(['shortCode' => $shortCode]); $this->commandTester->execute(['shortCode' => $shortCode]);

View file

@ -162,6 +162,7 @@ class ListShortUrlsCommandTest extends TestCase
} }
/** /**
* @param string|array|null $expectedOrderBy
* @test * @test
* @dataProvider provideOrderBy * @dataProvider provideOrderBy
*/ */

View file

@ -40,7 +40,7 @@ class DeleteTagsCommandTest extends TestCase
public function serviceIsInvokedOnSuccess(): void public function serviceIsInvokedOnSuccess(): void
{ {
$tagNames = ['foo', 'bar']; $tagNames = ['foo', 'bar'];
$deleteTags = $this->tagService->deleteTags($tagNames)->will(function () { $deleteTags = $this->tagService->deleteTags($tagNames)->will(function (): void {
}); });
$this->commandTester->execute([ $this->commandTester->execute([

View file

@ -45,7 +45,7 @@ class LocateVisitsCommandTest extends TestCase
$this->locker = $this->prophesize(Lock\LockFactory::class); $this->locker = $this->prophesize(Lock\LockFactory::class);
$this->lock = $this->prophesize(Lock\LockInterface::class); $this->lock = $this->prophesize(Lock\LockInterface::class);
$this->lock->acquire(false)->willReturn(true); $this->lock->acquire(false)->willReturn(true);
$this->lock->release()->will(function () { $this->lock->release()->will(function (): void {
}); });
$this->locker->createLock(Argument::type('string'), 90.0, false)->willReturn($this->lock->reveal()); $this->locker->createLock(Argument::type('string'), 90.0, false)->willReturn($this->lock->reveal());
@ -53,7 +53,7 @@ class LocateVisitsCommandTest extends TestCase
$this->visitService->reveal(), $this->visitService->reveal(),
$this->ipResolver->reveal(), $this->ipResolver->reveal(),
$this->locker->reveal(), $this->locker->reveal(),
$this->dbUpdater->reveal() $this->dbUpdater->reveal(),
); );
$app = new Application(); $app = new Application();
$app->add($command); $app->add($command);
@ -68,16 +68,16 @@ class LocateVisitsCommandTest extends TestCase
$location = new VisitLocation(Location::emptyInstance()); $location = new VisitLocation(Location::emptyInstance());
$locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will( $locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will(
function (array $args) use ($visit, $location) { function (array $args) use ($visit, $location): void {
$firstCallback = array_shift($args); $firstCallback = array_shift($args);
$firstCallback($visit); $firstCallback($visit);
$secondCallback = array_shift($args); $secondCallback = array_shift($args);
$secondCallback($location, $visit); $secondCallback($location, $visit);
} },
); );
$resolveIpLocation = $this->ipResolver->resolveIpLocation(Argument::any())->willReturn( $resolveIpLocation = $this->ipResolver->resolveIpLocation(Argument::any())->willReturn(
Location::emptyInstance() Location::emptyInstance(),
); );
$this->commandTester->execute([]); $this->commandTester->execute([]);
@ -98,16 +98,16 @@ class LocateVisitsCommandTest extends TestCase
$location = new VisitLocation(Location::emptyInstance()); $location = new VisitLocation(Location::emptyInstance());
$locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will( $locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will(
function (array $args) use ($visit, $location) { function (array $args) use ($visit, $location): void {
$firstCallback = array_shift($args); $firstCallback = array_shift($args);
$firstCallback($visit); $firstCallback($visit);
$secondCallback = array_shift($args); $secondCallback = array_shift($args);
$secondCallback($location, $visit); $secondCallback($location, $visit);
} },
); );
$resolveIpLocation = $this->ipResolver->resolveIpLocation(Argument::any())->willReturn( $resolveIpLocation = $this->ipResolver->resolveIpLocation(Argument::any())->willReturn(
Location::emptyInstance() Location::emptyInstance(),
); );
$this->commandTester->execute([], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE]); $this->commandTester->execute([], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE]);
@ -137,13 +137,13 @@ class LocateVisitsCommandTest extends TestCase
$location = new VisitLocation(Location::emptyInstance()); $location = new VisitLocation(Location::emptyInstance());
$locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will( $locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will(
function (array $args) use ($visit, $location) { function (array $args) use ($visit, $location): void {
$firstCallback = array_shift($args); $firstCallback = array_shift($args);
$firstCallback($visit); $firstCallback($visit);
$secondCallback = array_shift($args); $secondCallback = array_shift($args);
$secondCallback($location, $visit); $secondCallback($location, $visit);
} },
); );
$resolveIpLocation = $this->ipResolver->resolveIpLocation(Argument::any())->willThrow(WrongIpException::class); $resolveIpLocation = $this->ipResolver->resolveIpLocation(Argument::any())->willThrow(WrongIpException::class);
@ -161,7 +161,7 @@ class LocateVisitsCommandTest extends TestCase
{ {
$this->lock->acquire(false)->willReturn(false); $this->lock->acquire(false)->willReturn(false);
$locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will(function () { $locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will(function (): void {
}); });
$resolveIpLocation = $this->ipResolver->resolveIpLocation(Argument::any())->willReturn([]); $resolveIpLocation = $this->ipResolver->resolveIpLocation(Argument::any())->willReturn([]);
@ -170,7 +170,7 @@ class LocateVisitsCommandTest extends TestCase
$this->assertStringContainsString( $this->assertStringContainsString(
sprintf('Command "%s" is already in progress. Skipping.', LocateVisitsCommand::NAME), sprintf('Command "%s" is already in progress. Skipping.', LocateVisitsCommand::NAME),
$output $output,
); );
$locateVisits->shouldNotHaveBeenCalled(); $locateVisits->shouldNotHaveBeenCalled();
$resolveIpLocation->shouldNotHaveBeenCalled(); $resolveIpLocation->shouldNotHaveBeenCalled();
@ -182,17 +182,17 @@ class LocateVisitsCommandTest extends TestCase
*/ */
public function showsProperMessageWhenGeoLiteUpdateFails(bool $olderDbExists, string $expectedMessage): void public function showsProperMessageWhenGeoLiteUpdateFails(bool $olderDbExists, string $expectedMessage): void
{ {
$locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will(function () { $locateVisits = $this->visitService->locateUnlocatedVisits(Argument::cetera())->will(function (): void {
}); });
$checkDbUpdate = $this->dbUpdater->checkDbUpdate(Argument::cetera())->will( $checkDbUpdate = $this->dbUpdater->checkDbUpdate(Argument::cetera())->will(
function (array $args) use ($olderDbExists) { function (array $args) use ($olderDbExists): void {
[$mustBeUpdated, $handleProgress] = $args; [$mustBeUpdated, $handleProgress] = $args;
$mustBeUpdated($olderDbExists); $mustBeUpdated($olderDbExists);
$handleProgress(100, 50); $handleProgress(100, 50);
throw GeolocationDbUpdateFailedException::create($olderDbExists); throw GeolocationDbUpdateFailedException::create($olderDbExists);
} },
); );
$this->commandTester->execute([]); $this->commandTester->execute([]);
@ -200,7 +200,7 @@ class LocateVisitsCommandTest extends TestCase
$this->assertStringContainsString( $this->assertStringContainsString(
sprintf('%s GeoLite2 database...', $olderDbExists ? 'Updating' : 'Downloading'), sprintf('%s GeoLite2 database...', $olderDbExists ? 'Updating' : 'Downloading'),
$output $output,
); );
$this->assertStringContainsString($expectedMessage, $output); $this->assertStringContainsString($expectedMessage, $output);
$locateVisits->shouldHaveBeenCalledTimes((int) $olderDbExists); $locateVisits->shouldHaveBeenCalledTimes((int) $olderDbExists);

View file

@ -17,7 +17,7 @@ class ConfigProviderTest extends TestCase
} }
/** @test */ /** @test */
public function confiIsProperlyReturned() public function confiIsProperlyReturned(): void
{ {
$config = ($this->configProvider)(); $config = ($this->configProvider)();

View file

@ -23,7 +23,7 @@ class GeolocationDbUpdateFailedExceptionTest extends TestCase
$this->assertEquals($olderDbExists, $e->olderDbExists()); $this->assertEquals($olderDbExists, $e->olderDbExists());
$this->assertEquals( $this->assertEquals(
'An error occurred while updating geolocation database, and an older version could not be found', 'An error occurred while updating geolocation database, and an older version could not be found',
$e->getMessage() $e->getMessage(),
); );
$this->assertEquals(0, $e->getCode()); $this->assertEquals(0, $e->getCode());
$this->assertEquals($prev, $e->getPrevious()); $this->assertEquals($prev, $e->getPrevious());

View file

@ -59,7 +59,7 @@ class ApplicationFactoryTest extends TestCase
$command->getDefinition()->willReturn($name); $command->getDefinition()->willReturn($name);
$command->isEnabled()->willReturn(true); $command->isEnabled()->willReturn(true);
$command->getAliases()->willReturn([]); $command->getAliases()->willReturn([]);
$command->setApplication(Argument::type(Application::class))->willReturn(function () { $command->setApplication(Argument::type(Application::class))->willReturn(function (): void {
}); });
return $command; return $command;

View file

@ -36,14 +36,14 @@ class GeolocationDbUpdaterTest extends TestCase
$this->locker = $this->prophesize(Lock\LockFactory::class); $this->locker = $this->prophesize(Lock\LockFactory::class);
$this->lock = $this->prophesize(Lock\LockInterface::class); $this->lock = $this->prophesize(Lock\LockInterface::class);
$this->lock->acquire(true)->willReturn(true); $this->lock->acquire(true)->willReturn(true);
$this->lock->release()->will(function () { $this->lock->release()->will(function (): void {
}); });
$this->locker->createLock(Argument::type('string'))->willReturn($this->lock->reveal()); $this->locker->createLock(Argument::type('string'))->willReturn($this->lock->reveal());
$this->geolocationDbUpdater = new GeolocationDbUpdater( $this->geolocationDbUpdater = new GeolocationDbUpdater(
$this->dbUpdater->reveal(), $this->dbUpdater->reveal(),
$this->geoLiteDbReader->reveal(), $this->geoLiteDbReader->reveal(),
$this->locker->reveal() $this->locker->reveal(),
); );
} }
@ -134,7 +134,7 @@ class GeolocationDbUpdaterTest extends TestCase
'node_count' => 1, 'node_count' => 1,
'record_size' => 4, 'record_size' => 4,
])); ]));
$download = $this->dbUpdater->downloadFreshCopy(null)->will(function () { $download = $this->dbUpdater->downloadFreshCopy(null)->will(function (): void {
}); });
$this->geolocationDbUpdater->checkDbUpdate(); $this->geolocationDbUpdater->checkDbUpdate();

View file

@ -33,7 +33,7 @@ class ShlinkTableTest extends TestCase
$footerTitle = 'Footer'; $footerTitle = 'Footer';
$setStyle = $this->baseTable->setStyle(Argument::type(TableStyle::class))->willReturn( $setStyle = $this->baseTable->setStyle(Argument::type(TableStyle::class))->willReturn(
$this->baseTable->reveal() $this->baseTable->reveal(),
); );
$setHeaders = $this->baseTable->setHeaders($headers)->willReturn($this->baseTable->reveal()); $setHeaders = $this->baseTable->setHeaders($headers)->willReturn($this->baseTable->reveal());
$setRows = $this->baseTable->setRows($rows)->willReturn($this->baseTable->reveal()); $setRows = $this->baseTable->setRows($rows)->willReturn($this->baseTable->reveal());

View file

@ -46,10 +46,7 @@ abstract class AbstractTrackingAction implements MiddlewareInterface
* Process an incoming server request and return a response, optionally delegating * Process an incoming server request and return a response, optionally delegating
* to the next middleware component to create the response. * to the next middleware component to create the response.
* *
* @param ServerRequestInterface $request
* @param RequestHandlerInterface $handler
* *
* @return ResponseInterface
*/ */
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{ {

View file

@ -41,10 +41,7 @@ class QrCodeAction implements MiddlewareInterface
* Process an incoming server request and return a response, optionally delegating * Process an incoming server request and return a response, optionally delegating
* to the next middleware component to create the response. * to the next middleware component to create the response.
* *
* @param Request $request
* @param RequestHandlerInterface $handler
* *
* @return Response
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws RuntimeException * @throws RuntimeException
*/ */
@ -71,8 +68,6 @@ class QrCodeAction implements MiddlewareInterface
} }
/** /**
* @param Request $request
* @return int
*/ */
private function getSizeParam(Request $request): int private function getSizeParam(Request $request): int
{ {

View file

@ -76,7 +76,7 @@ class SimplifiedConfigParser
$simplifiedConfigOrder = array_flip(array_keys(self::SIMPLIFIED_CONFIG_MAPPING)); $simplifiedConfigOrder = array_flip(array_keys(self::SIMPLIFIED_CONFIG_MAPPING));
uksort( uksort(
$configForExistingKeys, $configForExistingKeys,
fn (string $a, string $b): int => $simplifiedConfigOrder[$a] - $simplifiedConfigOrder[$b] fn (string $a, string $b): int => $simplifiedConfigOrder[$a] - $simplifiedConfigOrder[$b],
); );
return $configForExistingKeys; return $configForExistingKeys;

View file

@ -8,7 +8,7 @@ use function Shlinkio\Shlink\Common\loadConfigFromGlob;
class ConfigProvider class ConfigProvider
{ {
public function __invoke() public function __invoke(): array
{ {
return loadConfigFromGlob(__DIR__ . '/../config/{,*.}config.php'); return loadConfigFromGlob(__DIR__ . '/../config/{,*.}config.php');
} }

View file

@ -189,7 +189,7 @@ class ShortUrl extends AbstractEntity
$hasAllTags = count($shortUrlTags) === count($tags) && array_reduce( $hasAllTags = count($shortUrlTags) === count($tags) && array_reduce(
$tags, $tags,
fn (bool $hasAllTags, string $tag) => $hasAllTags && contains($shortUrlTags, $tag), fn (bool $hasAllTags, string $tag) => $hasAllTags && contains($shortUrlTags, $tag),
true true,
); );
return $hasAllTags; return $hasAllTags;

View file

@ -28,9 +28,7 @@ class NotFoundTemplateHandler implements RequestHandlerInterface
/** /**
* Dispatch the next available middleware and return the response. * Dispatch the next available middleware and return the response.
* *
* @param ServerRequestInterface $request
* *
* @return ResponseInterface
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
public function handle(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface

View file

@ -62,14 +62,14 @@ class LocateShortUrlVisit
private function downloadOrUpdateGeoLiteDb(string $visitId): bool private function downloadOrUpdateGeoLiteDb(string $visitId): bool
{ {
try { try {
$this->dbUpdater->checkDbUpdate(function (bool $olderDbExists) { $this->dbUpdater->checkDbUpdate(function (bool $olderDbExists): void {
$this->logger->notice(sprintf('%s GeoLite2 database...', $olderDbExists ? 'Updating' : 'Downloading')); $this->logger->notice(sprintf('%s GeoLite2 database...', $olderDbExists ? 'Updating' : 'Downloading'));
}); });
} catch (GeolocationDbUpdateFailedException $e) { } catch (GeolocationDbUpdateFailedException $e) {
if (! $e->olderDbExists()) { if (! $e->olderDbExists()) {
$this->logger->error( $this->logger->error(
'GeoLite2 database download failed. It is not possible to locate visit with id {visitId}. {e}', 'GeoLite2 database download failed. It is not possible to locate visit with id {visitId}. {e}',
['e' => $e, 'visitId' => $visitId] ['e' => $e, 'visitId' => $visitId],
); );
return false; return false;
} }
@ -92,7 +92,7 @@ class LocateShortUrlVisit
} catch (WrongIpException $e) { } catch (WrongIpException $e) {
$this->logger->warning( $this->logger->warning(
'Tried to locate visit with id "{visitId}", but its address seems to be wrong. {e}', 'Tried to locate visit with id "{visitId}", but its address seems to be wrong. {e}',
['e' => $e, 'visitId' => $visitId] ['e' => $e, 'visitId' => $visitId],
); );
} }
} }

View file

@ -92,7 +92,7 @@ class NotifyVisitToWebHooks
return map($this->webhooks, function (string $webhook) use ($requestOptions, $visitId) { return map($this->webhooks, function (string $webhook) use ($requestOptions, $visitId) {
$promise = $this->httpClient->requestAsync(RequestMethodInterface::METHOD_POST, $webhook, $requestOptions); $promise = $this->httpClient->requestAsync(RequestMethodInterface::METHOD_POST, $webhook, $requestOptions);
return $promise->otherwise( return $promise->otherwise(
partial_left(Closure::fromCallable([$this, 'logWebhookFailure']), $webhook, $visitId) partial_left(Closure::fromCallable([$this, 'logWebhookFailure']), $webhook, $visitId),
); );
}); });
} }

View file

@ -22,7 +22,7 @@ class DeleteShortUrlException extends DomainException implements ProblemDetailsE
$e = new self(sprintf( $e = new self(sprintf(
'Impossible to delete short URL with short code "%s" since it has more than "%s" visits.', 'Impossible to delete short URL with short code "%s" since it has more than "%s" visits.',
$shortCode, $shortCode,
$threshold $threshold,
)); ));
$e->detail = $e->getMessage(); $e->detail = $e->getMessage();

View file

@ -63,7 +63,7 @@ class ValidationException extends InvalidArgumentException implements ProblemDet
$this->invalidElementsToString(), $this->invalidElementsToString(),
PHP_EOL, PHP_EOL,
PHP_EOL, PHP_EOL,
$this->getTraceAsString() $this->getTraceAsString(),
); );
} }
@ -72,7 +72,7 @@ class ValidationException extends InvalidArgumentException implements ProblemDet
return reduce_left($this->getInvalidElements(), fn ($messages, string $name, $_, string $acc) => $acc . sprintf( return reduce_left($this->getInvalidElements(), fn ($messages, string $name, $_, string $acc) => $acc . sprintf(
"\n '%s' => %s", "\n '%s' => %s",
$name, $name,
is_array($messages) ? print_r($messages, true) : $messages is_array($messages) ? print_r($messages, true) : $messages,
), ''); ), '');
} }
} }

View file

@ -24,10 +24,7 @@ class QrCodeCacheMiddleware implements MiddlewareInterface
* Process an incoming server request and return a response, optionally delegating * Process an incoming server request and return a response, optionally delegating
* to the next middleware component to create the response. * to the next middleware component to create the response.
* *
* @param Request $request
* @param RequestHandlerInterface $handler
* *
* @return Response
*/ */
public function process(Request $request, RequestHandlerInterface $handler): Response public function process(Request $request, RequestHandlerInterface $handler): Response
{ {

View file

@ -23,7 +23,6 @@ final class CreateShortUrlData
} }
/** /**
* @return UriInterface
*/ */
public function getLongUrl(): UriInterface public function getLongUrl(): UriInterface
{ {
@ -39,7 +38,6 @@ final class CreateShortUrlData
} }
/** /**
* @return ShortUrlMeta
*/ */
public function getMeta(): ShortUrlMeta public function getMeta(): ShortUrlMeta
{ {

View file

@ -48,7 +48,7 @@ final class ShortUrlMeta
* @param string|null $domain * @param string|null $domain
* @throws ValidationException * @throws ValidationException
*/ */
public static function createFromParams( public static function createFromParams( // phpcs:ignore
$validSince = null, $validSince = null,
$validUntil = null, $validUntil = null,
$customSlug = null, $customSlug = null,

View file

@ -36,7 +36,7 @@ final class Visitor
return new self( return new self(
$request->getHeaderLine('User-Agent'), $request->getHeaderLine('User-Agent'),
$request->getHeaderLine('Referer'), $request->getHeaderLine('Referer'),
$request->getAttribute(IpAddressMiddlewareFactory::REQUEST_ATTR) $request->getAttribute(IpAddressMiddlewareFactory::REQUEST_ATTR),
); );
} }

View file

@ -40,7 +40,7 @@ final class VisitsParams
return new self( return new self(
new DateRange($startDate, $endDate), new DateRange($startDate, $endDate),
(int) ($query['page'] ?? 1), (int) ($query['page'] ?? 1),
isset($query['itemsPerPage']) ? (int) $query['itemsPerPage'] : null isset($query['itemsPerPage']) ? (int) $query['itemsPerPage'] : null,
); );
} }

View file

@ -40,7 +40,6 @@ class AppOptions extends AbstractOptions
} }
/** /**
* @return string|null
*/ */
public function getDisableTrackParam(): ?string public function getDisableTrackParam(): ?string
{ {

View file

@ -8,8 +8,8 @@ use Zend\Stdlib\AbstractOptions;
class DeleteShortUrlsOptions extends AbstractOptions class DeleteShortUrlsOptions extends AbstractOptions
{ {
private $visitsThreshold = 15; private int $visitsThreshold = 15;
private $checkVisitsThreshold = true; private bool $checkVisitsThreshold = true;
public function getVisitsThreshold(): int public function getVisitsThreshold(): int
{ {

View file

@ -8,20 +8,18 @@ use Zend\Stdlib\AbstractOptions;
class UrlShortenerOptions extends AbstractOptions class UrlShortenerOptions extends AbstractOptions
{ {
// phpcs:disable protected $__strictMode__ = false; // phpcs:ignore
protected $__strictMode__ = false;
// phpcs:enable
private $validateUrl = true; private bool $validateUrl = true;
public function isUrlValidationEnabled(): bool public function isUrlValidationEnabled(): bool
{ {
return $this->validateUrl; return $this->validateUrl;
} }
protected function setValidateUrl($validateUrl): self protected function setValidateUrl(bool $validateUrl): self
{ {
$this->validateUrl = (bool) $validateUrl; $this->validateUrl = $validateUrl;
return $this; return $this;
} }
} }

View file

@ -22,9 +22,12 @@ class ShortUrlRepositoryAdapter implements AdapterInterface
private array $tags; private array $tags;
private ?DateRange $dateRange; private ?DateRange $dateRange;
/**
* @param string|array|null $orderBy
*/
public function __construct( public function __construct(
ShortUrlRepositoryInterface $repository, ShortUrlRepositoryInterface $repository,
$searchTerm = null, ?string $searchTerm = null,
array $tags = [], array $tags = [],
$orderBy = null, $orderBy = null,
?DateRange $dateRange = null ?DateRange $dateRange = null
@ -41,9 +44,8 @@ class ShortUrlRepositoryAdapter implements AdapterInterface
* *
* @param int $offset Page offset * @param int $offset Page offset
* @param int $itemCountPerPage Number of items per page * @param int $itemCountPerPage Number of items per page
* @return array
*/ */
public function getItems($offset, $itemCountPerPage): array public function getItems($offset, $itemCountPerPage): array // phpcs:ignore
{ {
return $this->repository->findList( return $this->repository->findList(
$itemCountPerPage, $itemCountPerPage,
@ -51,7 +53,7 @@ class ShortUrlRepositoryAdapter implements AdapterInterface
$this->searchTerm, $this->searchTerm,
$this->tags, $this->tags,
$this->orderBy, $this->orderBy,
$this->dateRange $this->dateRange,
); );
} }

View file

@ -21,13 +21,13 @@ class VisitsPaginatorAdapter implements AdapterInterface
$this->params = $params; $this->params = $params;
} }
public function getItems($offset, $itemCountPerPage): array public function getItems($offset, $itemCountPerPage): array // phpcs:ignore
{ {
return $this->visitRepository->findVisitsByShortCode( return $this->visitRepository->findVisitsByShortCode(
$this->shortCode, $this->shortCode,
$this->params->getDateRange(), $this->params->getDateRange(),
$itemCountPerPage, $itemCountPerPage,
$offset $offset,
); );
} }

View file

@ -52,6 +52,9 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
return $qb->getQuery()->getResult(); return $qb->getQuery()->getResult();
} }
/**
* @param string|array|null $orderBy
*/
private function processOrderByForList(QueryBuilder $qb, $orderBy): array private function processOrderByForList(QueryBuilder $qb, $orderBy): array
{ {
$isArray = is_array($orderBy); $isArray = is_array($orderBy);
@ -117,7 +120,7 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
$qb->andWhere($qb->expr()->orX( $qb->andWhere($qb->expr()->orX(
$qb->expr()->like('s.longUrl', ':searchPattern'), $qb->expr()->like('s.longUrl', ':searchPattern'),
$qb->expr()->like('s.shortCode', ':searchPattern'), $qb->expr()->like('s.shortCode', ':searchPattern'),
$qb->expr()->like('t.name', ':searchPattern') $qb->expr()->like('t.name', ':searchPattern'),
)); ));
$qb->setParameter('searchPattern', '%' . $searchTerm . '%'); $qb->setParameter('searchPattern', '%' . $searchTerm . '%');
} }

View file

@ -32,7 +32,7 @@ class DeleteShortUrlService implements DeleteShortUrlServiceInterface
if (! $ignoreThreshold && $this->isThresholdReached($shortUrl)) { if (! $ignoreThreshold && $this->isThresholdReached($shortUrl)) {
throw Exception\DeleteShortUrlException::fromVisitsThreshold( throw Exception\DeleteShortUrlException::fromVisitsThreshold(
$this->deleteShortUrlsOptions->getVisitsThreshold(), $this->deleteShortUrlsOptions->getVisitsThreshold(),
$shortUrl->getShortCode() $shortUrl->getShortCode(),
); );
} }

View file

@ -11,8 +11,6 @@ use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
trait FindShortCodeTrait trait FindShortCodeTrait
{ {
/** /**
* @param string $shortCode
* @return ShortUrl
* @throws ShortUrlNotFoundException * @throws ShortUrlNotFoundException
*/ */
private function findByShortCode(EntityManagerInterface $em, string $shortCode): ShortUrl private function findByShortCode(EntityManagerInterface $em, string $shortCode): ShortUrl

View file

@ -22,7 +22,7 @@ class ShortUrlDataTransformer implements DataTransformerInterface
/** /**
* @param ShortUrl $shortUrl * @param ShortUrl $shortUrl
*/ */
public function transform($shortUrl): array public function transform($shortUrl): array // phpcs:ignore
{ {
$longUrl = $shortUrl->getLongUrl(); $longUrl = $shortUrl->getLongUrl();

View file

@ -16,7 +16,6 @@ use function trim;
trait TagManagerTrait trait TagManagerTrait
{ {
/** /**
* @param EntityManagerInterface $em
* @param string[] $tags * @param string[] $tags
* @return Collections\Collection|Tag[] * @return Collections\Collection|Tag[]
*/ */

View file

@ -43,7 +43,7 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
$notYetValid = new ShortUrl( $notYetValid = new ShortUrl(
'bar', 'bar',
ShortUrlMeta::createFromParams(Chronos::now()->addMonth(), null, 'bar_very_long_text') ShortUrlMeta::createFromParams(Chronos::now()->addMonth(), null, 'bar_very_long_text'),
); );
$this->getEntityManager()->persist($notYetValid); $this->getEntityManager()->persist($notYetValid);
@ -82,11 +82,11 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
$this->assertSame($withDomain, $this->repo->findOneByShortCode($withDomain->getShortCode(), 'example.com')); $this->assertSame($withDomain, $this->repo->findOneByShortCode($withDomain->getShortCode(), 'example.com'));
$this->assertSame( $this->assertSame(
$withDomainDuplicatingRegular, $withDomainDuplicatingRegular,
$this->repo->findOneByShortCode($withDomainDuplicatingRegular->getShortCode(), 'doma.in') $this->repo->findOneByShortCode($withDomainDuplicatingRegular->getShortCode(), 'doma.in'),
); );
$this->assertSame( $this->assertSame(
$regularOne, $regularOne,
$this->repo->findOneByShortCode($withDomainDuplicatingRegular->getShortCode(), 'other-domain.com') $this->repo->findOneByShortCode($withDomainDuplicatingRegular->getShortCode(), 'other-domain.com'),
); );
$this->assertNull($this->repo->findOneByShortCode('invalid')); $this->assertNull($this->repo->findOneByShortCode('invalid'));
$this->assertNull($this->repo->findOneByShortCode($withDomain->getShortCode())); $this->assertNull($this->repo->findOneByShortCode($withDomain->getShortCode()));
@ -160,7 +160,7 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
$this->assertCount( $this->assertCount(
2, 2,
$this->repo->findList(null, null, null, [], null, new DateRange(Chronos::now()->subDays(2))) $this->repo->findList(null, null, null, [], null, new DateRange(Chronos::now()->subDays(2))),
); );
$this->assertEquals(2, $this->repo->countList(null, [], new DateRange(Chronos::now()->subDays(2)))); $this->assertEquals(2, $this->repo->countList(null, [], new DateRange(Chronos::now()->subDays(2))));
} }
@ -192,7 +192,7 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
$shortUrlWithDomain = new ShortUrl( $shortUrlWithDomain = new ShortUrl(
'foo', 'foo',
ShortUrlMeta::createFromRawData(['domain' => 'doma.in', 'customSlug' => 'another-slug']) ShortUrlMeta::createFromRawData(['domain' => 'doma.in', 'customSlug' => 'another-slug']),
); );
$this->getEntityManager()->persist($shortUrlWithDomain); $this->getEntityManager()->persist($shortUrlWithDomain);

View file

@ -22,13 +22,13 @@ class TagRepositoryTest extends DatabaseTestCase
} }
/** @test */ /** @test */
public function deleteByNameDoesNothingWhenEmptyListIsProvided() public function deleteByNameDoesNothingWhenEmptyListIsProvided(): void
{ {
$this->assertEquals(0, $this->repo->deleteByName([])); $this->assertEquals(0, $this->repo->deleteByName([]));
} }
/** @test */ /** @test */
public function allTagsWhichMatchNameAreDeleted() public function allTagsWhichMatchNameAreDeleted(): void
{ {
$names = ['foo', 'bar', 'baz']; $names = ['foo', 'bar', 'baz'];
$toDelete = ['foo', 'baz']; $toDelete = ['foo', 'baz'];

View file

@ -85,10 +85,10 @@ class VisitRepositoryTest extends DatabaseTestCase
$this->assertCount(6, $this->repo->findVisitsByShortCode($shortUrl->getShortCode())); $this->assertCount(6, $this->repo->findVisitsByShortCode($shortUrl->getShortCode()));
$this->assertCount(2, $this->repo->findVisitsByShortCode($shortUrl->getShortCode(), new DateRange( $this->assertCount(2, $this->repo->findVisitsByShortCode($shortUrl->getShortCode(), new DateRange(
Chronos::parse('2016-01-02'), Chronos::parse('2016-01-02'),
Chronos::parse('2016-01-03') Chronos::parse('2016-01-03'),
))); )));
$this->assertCount(4, $this->repo->findVisitsByShortCode($shortUrl->getShortCode(), new DateRange( $this->assertCount(4, $this->repo->findVisitsByShortCode($shortUrl->getShortCode(), new DateRange(
Chronos::parse('2016-01-03') Chronos::parse('2016-01-03'),
))); )));
$this->assertCount(3, $this->repo->findVisitsByShortCode($shortUrl->getShortCode(), null, 3, 2)); $this->assertCount(3, $this->repo->findVisitsByShortCode($shortUrl->getShortCode(), null, 3, 2));
$this->assertCount(2, $this->repo->findVisitsByShortCode($shortUrl->getShortCode(), null, 5, 4)); $this->assertCount(2, $this->repo->findVisitsByShortCode($shortUrl->getShortCode(), null, 5, 4));
@ -110,10 +110,10 @@ class VisitRepositoryTest extends DatabaseTestCase
$this->assertEquals(6, $this->repo->countVisitsByShortCode($shortUrl->getShortCode())); $this->assertEquals(6, $this->repo->countVisitsByShortCode($shortUrl->getShortCode()));
$this->assertEquals(2, $this->repo->countVisitsByShortCode($shortUrl->getShortCode(), new DateRange( $this->assertEquals(2, $this->repo->countVisitsByShortCode($shortUrl->getShortCode(), new DateRange(
Chronos::parse('2016-01-02'), Chronos::parse('2016-01-02'),
Chronos::parse('2016-01-03') Chronos::parse('2016-01-03'),
))); )));
$this->assertEquals(4, $this->repo->countVisitsByShortCode($shortUrl->getShortCode(), new DateRange( $this->assertEquals(4, $this->repo->countVisitsByShortCode($shortUrl->getShortCode(), new DateRange(
Chronos::parse('2016-01-03') Chronos::parse('2016-01-03'),
))); )));
} }
} }

View file

@ -30,7 +30,7 @@ class PixelActionTest extends TestCase
$this->action = new PixelAction( $this->action = new PixelAction(
$this->urlShortener->reveal(), $this->urlShortener->reveal(),
$this->visitTracker->reveal(), $this->visitTracker->reveal(),
new AppOptions() new AppOptions(),
); );
} }
@ -39,7 +39,7 @@ class PixelActionTest extends TestCase
{ {
$shortCode = 'abc123'; $shortCode = 'abc123';
$this->urlShortener->shortCodeToUrl($shortCode, '')->willReturn( $this->urlShortener->shortCodeToUrl($shortCode, '')->willReturn(
new ShortUrl('http://domain.com/foo/bar') new ShortUrl('http://domain.com/foo/bar'),
)->shouldBeCalledOnce(); )->shouldBeCalledOnce();
$this->visitTracker->track(Argument::cetera())->shouldBeCalledOnce(); $this->visitTracker->track(Argument::cetera())->shouldBeCalledOnce();

View file

@ -70,7 +70,7 @@ class QrCodeActionTest extends TestCase
$resp = $this->action->process( $resp = $this->action->process(
(new ServerRequest())->withAttribute('shortCode', $shortCode), (new ServerRequest())->withAttribute('shortCode', $shortCode),
$delegate->reveal() $delegate->reveal(),
); );
$this->assertInstanceOf(QrCodeResponse::class, $resp); $this->assertInstanceOf(QrCodeResponse::class, $resp);

View file

@ -33,7 +33,7 @@ class RedirectActionTest extends TestCase
$this->action = new RedirectAction( $this->action = new RedirectAction(
$this->urlShortener->reveal(), $this->urlShortener->reveal(),
$this->visitTracker->reveal(), $this->visitTracker->reveal(),
new Options\AppOptions(['disableTrackParam' => 'foobar']) new Options\AppOptions(['disableTrackParam' => 'foobar']),
); );
} }
@ -46,7 +46,7 @@ class RedirectActionTest extends TestCase
$shortCode = 'abc123'; $shortCode = 'abc123';
$shortUrl = new ShortUrl('http://domain.com/foo/bar?some=thing'); $shortUrl = new ShortUrl('http://domain.com/foo/bar?some=thing');
$shortCodeToUrl = $this->urlShortener->shortCodeToUrl($shortCode, '')->willReturn($shortUrl); $shortCodeToUrl = $this->urlShortener->shortCodeToUrl($shortCode, '')->willReturn($shortUrl);
$track = $this->visitTracker->track(Argument::cetera())->will(function () { $track = $this->visitTracker->track(Argument::cetera())->will(function (): void {
}); });
$request = (new ServerRequest())->withAttribute('shortCode', $shortCode)->withQueryParams($query); $request = (new ServerRequest())->withAttribute('shortCode', $shortCode)->withQueryParams($query);

View file

@ -17,7 +17,7 @@ class ConfigProviderTest extends TestCase
} }
/** @test */ /** @test */
public function properConfigIsReturned() public function properConfigIsReturned(): void
{ {
$config = $this->configProvider->__invoke(); $config = $this->configProvider->__invoke();

View file

@ -10,7 +10,7 @@ use Shlinkio\Shlink\Core\Entity\Tag;
class TagTest extends TestCase class TagTest extends TestCase
{ {
/** @test */ /** @test */
public function jsonSerializationOfTagsReturnsItsStringRepresentation() public function jsonSerializationOfTagsReturnsItsStringRepresentation(): void
{ {
$tag = new Tag('This is my name'); $tag = new Tag('This is my name');
$this->assertEquals((string) $tag, $tag->jsonSerialize()); $this->assertEquals((string) $tag, $tag->jsonSerialize());

View file

@ -73,9 +73,9 @@ class NotFoundRedirectHandlerTest extends TestCase
'', '',
$this->prophesize(MiddlewareInterface::class)->reveal(), $this->prophesize(MiddlewareInterface::class)->reveal(),
['GET'], ['GET'],
RedirectAction::class RedirectAction::class,
) ),
) ),
) )
->withUri(new Uri('/abc123')), ->withUri(new Uri('/abc123')),
'invalidShortUrl', 'invalidShortUrl',

View file

@ -49,7 +49,7 @@ class NotFoundTemplateHandlerTest extends TestCase
yield [ yield [
$request->withAttribute( $request->withAttribute(
RouteResult::class, RouteResult::class,
RouteResult::fromRoute(new Route('', $this->prophesize(MiddlewareInterface::class)->reveal())) RouteResult::fromRoute(new Route('', $this->prophesize(MiddlewareInterface::class)->reveal())),
), ),
NotFoundTemplateHandler::INVALID_SHORT_CODE_TEMPLATE, NotFoundTemplateHandler::INVALID_SHORT_CODE_TEMPLATE,
]; ];

View file

@ -47,7 +47,7 @@ class LocateShortUrlVisitTest extends TestCase
$this->em->reveal(), $this->em->reveal(),
$this->logger->reveal(), $this->logger->reveal(),
$this->dbUpdater->reveal(), $this->dbUpdater->reveal(),
$this->eventDispatcher->reveal() $this->eventDispatcher->reveal(),
); );
} }
@ -59,7 +59,7 @@ class LocateShortUrlVisitTest extends TestCase
$logWarning = $this->logger->warning('Tried to locate visit with id "{visitId}", but it does not exist.', [ $logWarning = $this->logger->warning('Tried to locate visit with id "{visitId}", but it does not exist.', [
'visitId' => 123, 'visitId' => 123,
]); ]);
$dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function () { $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void {
}); });
($this->locateVisit)($event); ($this->locateVisit)($event);
@ -76,16 +76,16 @@ class LocateShortUrlVisitTest extends TestCase
{ {
$event = new ShortUrlVisited('123'); $event = new ShortUrlVisited('123');
$findVisit = $this->em->find(Visit::class, '123')->willReturn( $findVisit = $this->em->find(Visit::class, '123')->willReturn(
new Visit(new ShortUrl(''), new Visitor('', '', '1.2.3.4')) new Visit(new ShortUrl(''), new Visitor('', '', '1.2.3.4')),
); );
$resolveLocation = $this->ipLocationResolver->resolveIpLocation(Argument::cetera())->willThrow( $resolveLocation = $this->ipLocationResolver->resolveIpLocation(Argument::cetera())->willThrow(
WrongIpException::class WrongIpException::class,
); );
$logWarning = $this->logger->warning( $logWarning = $this->logger->warning(
Argument::containingString('Tried to locate visit with id "{visitId}", but its address seems to be wrong.'), Argument::containingString('Tried to locate visit with id "{visitId}", but its address seems to be wrong.'),
Argument::type('array') Argument::type('array'),
); );
$dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function () { $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void {
}); });
($this->locateVisit)($event); ($this->locateVisit)($event);
@ -105,10 +105,10 @@ class LocateShortUrlVisitTest extends TestCase
{ {
$event = new ShortUrlVisited('123'); $event = new ShortUrlVisited('123');
$findVisit = $this->em->find(Visit::class, '123')->willReturn($visit); $findVisit = $this->em->find(Visit::class, '123')->willReturn($visit);
$flush = $this->em->flush()->will(function () { $flush = $this->em->flush()->will(function (): void {
}); });
$resolveIp = $this->ipLocationResolver->resolveIpLocation(Argument::any()); $resolveIp = $this->ipLocationResolver->resolveIpLocation(Argument::any());
$dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function () { $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void {
}); });
($this->locateVisit)($event); ($this->locateVisit)($event);
@ -139,10 +139,10 @@ class LocateShortUrlVisitTest extends TestCase
$event = new ShortUrlVisited('123'); $event = new ShortUrlVisited('123');
$findVisit = $this->em->find(Visit::class, '123')->willReturn($visit); $findVisit = $this->em->find(Visit::class, '123')->willReturn($visit);
$flush = $this->em->flush()->will(function () { $flush = $this->em->flush()->will(function (): void {
}); });
$resolveIp = $this->ipLocationResolver->resolveIpLocation($ipAddr)->willReturn($location); $resolveIp = $this->ipLocationResolver->resolveIpLocation($ipAddr)->willReturn($location);
$dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function () { $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void {
}); });
($this->locateVisit)($event); ($this->locateVisit)($event);
@ -165,11 +165,11 @@ class LocateShortUrlVisitTest extends TestCase
$event = new ShortUrlVisited('123'); $event = new ShortUrlVisited('123');
$findVisit = $this->em->find(Visit::class, '123')->willReturn($visit); $findVisit = $this->em->find(Visit::class, '123')->willReturn($visit);
$flush = $this->em->flush()->will(function () { $flush = $this->em->flush()->will(function (): void {
}); });
$resolveIp = $this->ipLocationResolver->resolveIpLocation($ipAddr)->willReturn($location); $resolveIp = $this->ipLocationResolver->resolveIpLocation($ipAddr)->willReturn($location);
$checkUpdateDb = $this->dbUpdater->checkDbUpdate(Argument::cetera())->willThrow($e); $checkUpdateDb = $this->dbUpdater->checkDbUpdate(Argument::cetera())->willThrow($e);
$dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function () { $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void {
}); });
($this->locateVisit)($event); ($this->locateVisit)($event);
@ -181,7 +181,7 @@ class LocateShortUrlVisitTest extends TestCase
$checkUpdateDb->shouldHaveBeenCalledOnce(); $checkUpdateDb->shouldHaveBeenCalledOnce();
$this->logger->warning( $this->logger->warning(
'GeoLite2 database update failed. Proceeding with old version. {e}', 'GeoLite2 database update failed. Proceeding with old version. {e}',
['e' => $e] ['e' => $e],
)->shouldHaveBeenCalledOnce(); )->shouldHaveBeenCalledOnce();
$dispatch->shouldHaveBeenCalledOnce(); $dispatch->shouldHaveBeenCalledOnce();
} }
@ -196,15 +196,15 @@ class LocateShortUrlVisitTest extends TestCase
$event = new ShortUrlVisited('123'); $event = new ShortUrlVisited('123');
$findVisit = $this->em->find(Visit::class, '123')->willReturn($visit); $findVisit = $this->em->find(Visit::class, '123')->willReturn($visit);
$flush = $this->em->flush()->will(function () { $flush = $this->em->flush()->will(function (): void {
}); });
$resolveIp = $this->ipLocationResolver->resolveIpLocation($ipAddr)->willReturn($location); $resolveIp = $this->ipLocationResolver->resolveIpLocation($ipAddr)->willReturn($location);
$checkUpdateDb = $this->dbUpdater->checkDbUpdate(Argument::cetera())->willThrow($e); $checkUpdateDb = $this->dbUpdater->checkDbUpdate(Argument::cetera())->willThrow($e);
$logError = $this->logger->error( $logError = $this->logger->error(
'GeoLite2 database download failed. It is not possible to locate visit with id {visitId}. {e}', 'GeoLite2 database download failed. It is not possible to locate visit with id {visitId}. {e}',
['e' => $e, 'visitId' => 123] ['e' => $e, 'visitId' => 123],
); );
$dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function () { $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void {
}); });
($this->locateVisit)($event); ($this->locateVisit)($event);

View file

@ -43,7 +43,7 @@ class DeleteShortUrlExceptionTest extends TestCase
return [$number, $shortCode = generateRandomShortCode(6), sprintf( return [$number, $shortCode = generateRandomShortCode(6), sprintf(
'Impossible to delete short URL with short code "%s" since it has more than "%s" visits.', 'Impossible to delete short URL with short code "%s" since it has more than "%s" visits.',
$shortCode, $shortCode,
$number $number,
)]; )];
}); });
} }

View file

@ -26,7 +26,7 @@ class QrCodeCacheMiddlewareTest extends TestCase
} }
/** @test */ /** @test */
public function noCachedPathFallsBackToNextMiddleware() public function noCachedPathFallsBackToNextMiddleware(): void
{ {
$delegate = $this->prophesize(RequestHandlerInterface::class); $delegate = $this->prophesize(RequestHandlerInterface::class);
$delegate->handle(Argument::any())->willReturn(new Response())->shouldBeCalledOnce(); $delegate->handle(Argument::any())->willReturn(new Response())->shouldBeCalledOnce();
@ -37,7 +37,7 @@ class QrCodeCacheMiddlewareTest extends TestCase
} }
/** @test */ /** @test */
public function cachedPathReturnsCacheContent() public function cachedPathReturnsCacheContent(): void
{ {
$isCalled = false; $isCalled = false;
$uri = (new Uri())->withPath('/foo'); $uri = (new Uri())->withPath('/foo');

View file

@ -21,11 +21,12 @@ class ShortUrlRepositoryAdapterTest extends TestCase
} }
/** /**
* @param string|array|null $orderBy
* @test * @test
* @dataProvider provideFilteringArgs * @dataProvider provideFilteringArgs
*/ */
public function getItemsFallsBackToFindList( public function getItemsFallsBackToFindList(
$searchTerm = null, ?string $searchTerm = null,
array $tags = [], array $tags = [],
?DateRange $dateRange = null, ?DateRange $dateRange = null,
$orderBy = null $orderBy = null
@ -40,8 +41,11 @@ class ShortUrlRepositoryAdapterTest extends TestCase
* @test * @test
* @dataProvider provideFilteringArgs * @dataProvider provideFilteringArgs
*/ */
public function countFallsBackToCountList($searchTerm = null, array $tags = [], ?DateRange $dateRange = null): void public function countFallsBackToCountList(
{ ?string $searchTerm = null,
array $tags = [],
?DateRange $dateRange = null
): void {
$adapter = new ShortUrlRepositoryAdapter($this->repo->reveal(), $searchTerm, $tags, null, $dateRange); $adapter = new ShortUrlRepositoryAdapter($this->repo->reveal(), $searchTerm, $tags, null, $dateRange);
$this->repo->countList($searchTerm, $tags, $dateRange)->shouldBeCalledOnce(); $this->repo->countList($searchTerm, $tags, $dateRange)->shouldBeCalledOnce();

View file

@ -29,7 +29,7 @@ class DeleteShortUrlServiceTest extends TestCase
public function setUp(): void public function setUp(): void
{ {
$shortUrl = (new ShortUrl(''))->setVisits( $shortUrl = (new ShortUrl(''))->setVisits(
new ArrayCollection(map(range(0, 10), fn () => new Visit(new ShortUrl(''), Visitor::emptyInstance()))) new ArrayCollection(map(range(0, 10), fn () => new Visit(new ShortUrl(''), Visitor::emptyInstance()))),
); );
$this->shortCode = $shortUrl->getShortCode(); $this->shortCode = $shortUrl->getShortCode();
@ -48,7 +48,7 @@ class DeleteShortUrlServiceTest extends TestCase
$this->expectException(DeleteShortUrlException::class); $this->expectException(DeleteShortUrlException::class);
$this->expectExceptionMessage(sprintf( $this->expectExceptionMessage(sprintf(
'Impossible to delete short URL with short code "%s" since it has more than "5" visits.', 'Impossible to delete short URL with short code "%s" since it has more than "5" visits.',
$this->shortCode $this->shortCode,
)); ));
$service->deleteByShortCode($this->shortCode); $service->deleteByShortCode($this->shortCode);

View file

@ -97,7 +97,7 @@ class ShortUrlServiceTest extends TestCase
Chronos::parse('2017-01-01 00:00:00')->toAtomString(), Chronos::parse('2017-01-01 00:00:00')->toAtomString(),
Chronos::parse('2017-01-05 00:00:00')->toAtomString(), Chronos::parse('2017-01-05 00:00:00')->toAtomString(),
null, null,
5 5,
)); ));
$this->assertSame($shortUrl, $result); $this->assertSame($shortUrl, $result);

View file

@ -42,7 +42,7 @@ class UrlShortenerTest extends TestCase
$this->em->flush()->willReturn(null); $this->em->flush()->willReturn(null);
$this->em->commit()->willReturn(null); $this->em->commit()->willReturn(null);
$this->em->beginTransaction()->willReturn(null); $this->em->beginTransaction()->willReturn(null);
$this->em->persist(Argument::any())->will(function ($arguments) { $this->em->persist(Argument::any())->will(function ($arguments): void {
/** @var ShortUrl $shortUrl */ /** @var ShortUrl $shortUrl */
[$shortUrl] = $arguments; [$shortUrl] = $arguments;
$shortUrl->setId('10'); $shortUrl->setId('10');
@ -59,7 +59,7 @@ class UrlShortenerTest extends TestCase
$this->urlShortener = new UrlShortener( $this->urlShortener = new UrlShortener(
$this->urlValidator->reveal(), $this->urlValidator->reveal(),
$this->em->reveal(), $this->em->reveal(),
new UrlShortenerOptions(['validate_url' => $urlValidationEnabled]) new UrlShortenerOptions(['validate_url' => $urlValidationEnabled]),
); );
} }
@ -69,7 +69,7 @@ class UrlShortenerTest extends TestCase
$shortUrl = $this->urlShortener->urlToShortCode( $shortUrl = $this->urlShortener->urlToShortCode(
new Uri('http://foobar.com/12345/hello?foo=bar'), new Uri('http://foobar.com/12345/hello?foo=bar'),
[], [],
ShortUrlMeta::createEmpty() ShortUrlMeta::createEmpty(),
); );
$this->assertEquals('http://foobar.com/12345/hello?foo=bar', $shortUrl->getLongUrl()); $this->assertEquals('http://foobar.com/12345/hello?foo=bar', $shortUrl->getLongUrl());
@ -85,7 +85,7 @@ class UrlShortenerTest extends TestCase
function () use (&$callIndex, $expectedCalls) { function () use (&$callIndex, $expectedCalls) {
$callIndex++; $callIndex++;
return $callIndex < $expectedCalls; return $callIndex < $expectedCalls;
} },
); );
$repo->findBy(Argument::cetera())->willReturn([]); $repo->findBy(Argument::cetera())->willReturn([]);
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal()); $getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
@ -93,7 +93,7 @@ class UrlShortenerTest extends TestCase
$shortUrl = $this->urlShortener->urlToShortCode( $shortUrl = $this->urlShortener->urlToShortCode(
new Uri('http://foobar.com/12345/hello?foo=bar'), new Uri('http://foobar.com/12345/hello?foo=bar'),
[], [],
ShortUrlMeta::createEmpty() ShortUrlMeta::createEmpty(),
); );
$this->assertEquals('http://foobar.com/12345/hello?foo=bar', $shortUrl->getLongUrl()); $this->assertEquals('http://foobar.com/12345/hello?foo=bar', $shortUrl->getLongUrl());
@ -116,7 +116,7 @@ class UrlShortenerTest extends TestCase
$this->urlShortener->urlToShortCode( $this->urlShortener->urlToShortCode(
new Uri('http://foobar.com/12345/hello?foo=bar'), new Uri('http://foobar.com/12345/hello?foo=bar'),
[], [],
ShortUrlMeta::createEmpty() ShortUrlMeta::createEmpty(),
); );
} }
@ -124,13 +124,15 @@ class UrlShortenerTest extends TestCase
public function validatorIsCalledWhenUrlValidationIsEnabled(): void public function validatorIsCalledWhenUrlValidationIsEnabled(): void
{ {
$this->setUrlShortener(true); $this->setUrlShortener(true);
$validateUrl = $this->urlValidator->validateUrl('http://foobar.com/12345/hello?foo=bar')->will(function () { $validateUrl = $this->urlValidator->validateUrl('http://foobar.com/12345/hello?foo=bar')->will(
}); function (): void {
},
);
$this->urlShortener->urlToShortCode( $this->urlShortener->urlToShortCode(
new Uri('http://foobar.com/12345/hello?foo=bar'), new Uri('http://foobar.com/12345/hello?foo=bar'),
[], [],
ShortUrlMeta::createEmpty() ShortUrlMeta::createEmpty(),
); );
$validateUrl->shouldHaveBeenCalledOnce(); $validateUrl->shouldHaveBeenCalledOnce();
@ -151,7 +153,7 @@ class UrlShortenerTest extends TestCase
$this->urlShortener->urlToShortCode( $this->urlShortener->urlToShortCode(
new Uri('http://foobar.com/12345/hello?foo=bar'), new Uri('http://foobar.com/12345/hello?foo=bar'),
[], [],
ShortUrlMeta::createFromRawData(['customSlug' => 'custom-slug']) ShortUrlMeta::createFromRawData(['customSlug' => 'custom-slug']),
); );
} }
@ -183,7 +185,7 @@ class UrlShortenerTest extends TestCase
yield [$url, [], ShortUrlMeta::createFromRawData(['findIfExists' => true]), new ShortUrl($url)]; yield [$url, [], ShortUrlMeta::createFromRawData(['findIfExists' => true]), new ShortUrl($url)];
yield [$url, [], ShortUrlMeta::createFromRawData( yield [$url, [], ShortUrlMeta::createFromRawData(
['findIfExists' => true, 'customSlug' => 'foo'] ['findIfExists' => true, 'customSlug' => 'foo'],
), new ShortUrl($url)]; ), new ShortUrl($url)];
yield [ yield [
$url, $url,

View file

@ -42,21 +42,21 @@ class VisitServiceTest extends TestCase
{ {
$unlocatedVisits = map( $unlocatedVisits = map(
range(1, 200), range(1, 200),
fn (int $i) => new Visit(new ShortUrl(sprintf('short_code_%s', $i)), Visitor::emptyInstance()) fn (int $i) => new Visit(new ShortUrl(sprintf('short_code_%s', $i)), Visitor::emptyInstance()),
); );
$repo = $this->prophesize(VisitRepository::class); $repo = $this->prophesize(VisitRepository::class);
$findUnlocatedVisits = $repo->findUnlocatedVisits(false)->willReturn($unlocatedVisits); $findUnlocatedVisits = $repo->findUnlocatedVisits(false)->willReturn($unlocatedVisits);
$getRepo = $this->em->getRepository(Visit::class)->willReturn($repo->reveal()); $getRepo = $this->em->getRepository(Visit::class)->willReturn($repo->reveal());
$persist = $this->em->persist(Argument::type(Visit::class))->will(function () { $persist = $this->em->persist(Argument::type(Visit::class))->will(function (): void {
}); });
$flush = $this->em->flush()->will(function () { $flush = $this->em->flush()->will(function (): void {
}); });
$clear = $this->em->clear()->will(function () { $clear = $this->em->clear()->will(function (): void {
}); });
$this->visitService->locateUnlocatedVisits(fn () => Location::emptyInstance(), function () { $this->visitService->locateUnlocatedVisits(fn () => Location::emptyInstance(), function (): void {
$args = func_get_args(); $args = func_get_args();
$this->assertInstanceOf(VisitLocation::class, array_shift($args)); $this->assertInstanceOf(VisitLocation::class, array_shift($args));
@ -84,14 +84,14 @@ class VisitServiceTest extends TestCase
$findUnlocatedVisits = $repo->findUnlocatedVisits(false)->willReturn($unlocatedVisits); $findUnlocatedVisits = $repo->findUnlocatedVisits(false)->willReturn($unlocatedVisits);
$getRepo = $this->em->getRepository(Visit::class)->willReturn($repo->reveal()); $getRepo = $this->em->getRepository(Visit::class)->willReturn($repo->reveal());
$persist = $this->em->persist(Argument::type(Visit::class))->will(function () { $persist = $this->em->persist(Argument::type(Visit::class))->will(function (): void {
}); });
$flush = $this->em->flush()->will(function () { $flush = $this->em->flush()->will(function (): void {
}); });
$clear = $this->em->clear()->will(function () { $clear = $this->em->clear()->will(function (): void {
}); });
$this->visitService->locateUnlocatedVisits(function () use ($isNonLocatableAddress) { $this->visitService->locateUnlocatedVisits(function () use ($isNonLocatableAddress): void {
throw $isNonLocatableAddress throw $isNonLocatableAddress
? new IpCannotBeLocatedException('Cannot be located') ? new IpCannotBeLocatedException('Cannot be located')
: IpCannotBeLocatedException::forError(new Exception('')); : IpCannotBeLocatedException::forError(new Exception(''));

View file

@ -45,7 +45,7 @@ class UrlValidatorTest extends TestCase
$request = $this->httpClient->request( $request = $this->httpClient->request(
RequestMethodInterface::METHOD_GET, RequestMethodInterface::METHOD_GET,
$expectedUrl, $expectedUrl,
[RequestOptions::ALLOW_REDIRECTS => ['max' => 15]] [RequestOptions::ALLOW_REDIRECTS => ['max' => 15]],
)->willReturn(new Response()); )->willReturn(new Response());
$this->urlValidator->validateUrl($expectedUrl); $this->urlValidator->validateUrl($expectedUrl);

View file

@ -43,8 +43,6 @@ abstract class AbstractCreateShortUrlAction extends AbstractRestAction
} }
/** /**
* @param Request $request
* @return CreateShortUrlData
* @throws ValidationException * @throws ValidationException
*/ */
abstract protected function buildShortUrlData(Request $request): CreateShortUrlData; abstract protected function buildShortUrlData(Request $request): CreateShortUrlData;

View file

@ -16,8 +16,6 @@ class CreateShortUrlAction extends AbstractCreateShortUrlAction
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_POST]; protected const ROUTE_ALLOWED_METHODS = [self::METHOD_POST];
/** /**
* @param Request $request
* @return CreateShortUrlData
* @throws ValidationException * @throws ValidationException
*/ */
protected function buildShortUrlData(Request $request): CreateShortUrlData protected function buildShortUrlData(Request $request): CreateShortUrlData
@ -35,7 +33,7 @@ class CreateShortUrlAction extends AbstractCreateShortUrlAction
$postData['customSlug'] ?? null, $postData['customSlug'] ?? null,
$postData['maxVisits'] ?? null, $postData['maxVisits'] ?? null,
$postData['findIfExists'] ?? null, $postData['findIfExists'] ?? null,
$postData['domain'] ?? null $postData['domain'] ?? null,
); );
return new CreateShortUrlData(new Uri($postData['longUrl']), (array) ($postData['tags'] ?? []), $meta); return new CreateShortUrlData(new Uri($postData['longUrl']), (array) ($postData['tags'] ?? []), $meta);

View file

@ -37,8 +37,6 @@ class ListShortUrlsAction extends AbstractRestAction
} }
/** /**
* @param Request $request
* @return Response
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
public function handle(Request $request): Response public function handle(Request $request): Response
@ -46,7 +44,7 @@ class ListShortUrlsAction extends AbstractRestAction
$params = $this->queryToListParams($request->getQueryParams()); $params = $this->queryToListParams($request->getQueryParams());
$shortUrls = $this->shortUrlService->listShortUrls(...$params); $shortUrls = $this->shortUrlService->listShortUrls(...$params);
return new JsonResponse(['shortUrls' => $this->serializePaginator($shortUrls, new ShortUrlDataTransformer( return new JsonResponse(['shortUrls' => $this->serializePaginator($shortUrls, new ShortUrlDataTransformer(
$this->domainConfig $this->domainConfig,
))]); ))]);
} }
@ -69,7 +67,7 @@ class ListShortUrlsAction extends AbstractRestAction
{ {
return new DateRange( return new DateRange(
isset($query['startDate']) ? Chronos::parse($query['startDate']) : null, isset($query['startDate']) ? Chronos::parse($query['startDate']) : null,
isset($query['endDate']) ? Chronos::parse($query['endDate']) : null isset($query['endDate']) ? Chronos::parse($query['endDate']) : null,
); );
} }
} }

View file

@ -32,8 +32,6 @@ class ResolveShortUrlAction extends AbstractRestAction
} }
/** /**
* @param Request $request
* @return Response
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
public function handle(Request $request): Response public function handle(Request $request): Response

View file

@ -30,8 +30,6 @@ class SingleStepCreateShortUrlAction extends AbstractCreateShortUrlAction
} }
/** /**
* @param Request $request
* @return CreateShortUrlData
* @throws ValidationException * @throws ValidationException
*/ */
protected function buildShortUrlData(Request $request): CreateShortUrlData protected function buildShortUrlData(Request $request): CreateShortUrlData

View file

@ -28,9 +28,7 @@ class CreateTagsAction extends AbstractRestAction
* Process an incoming server request and return a response, optionally delegating * Process an incoming server request and return a response, optionally delegating
* to the next middleware component to create the response. * to the next middleware component to create the response.
* *
* @param ServerRequestInterface $request
* *
* @return ResponseInterface
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function handle(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface

View file

@ -28,9 +28,7 @@ class DeleteTagsAction extends AbstractRestAction
* Process an incoming server request and return a response, optionally delegating * Process an incoming server request and return a response, optionally delegating
* to the next middleware component to create the response. * to the next middleware component to create the response.
* *
* @param ServerRequestInterface $request
* *
* @return ResponseInterface
*/ */
public function handle(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface
{ {

View file

@ -28,9 +28,7 @@ class ListTagsAction extends AbstractRestAction
* Process an incoming server request and return a response, optionally delegating * Process an incoming server request and return a response, optionally delegating
* to the next middleware component to create the response. * to the next middleware component to create the response.
* *
* @param ServerRequestInterface $request
* *
* @return ResponseInterface
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function handle(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface

View file

@ -29,9 +29,7 @@ class UpdateTagAction extends AbstractRestAction
* Process an incoming server request and return a response, optionally delegating * Process an incoming server request and return a response, optionally delegating
* to the next middleware component to create the response. * to the next middleware component to create the response.
* *
* @param ServerRequestInterface $request
* *
* @return ResponseInterface
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function handle(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface

View file

@ -8,5 +8,5 @@ use Zend\ServiceManager\AbstractPluginManager;
class AuthenticationPluginManager extends AbstractPluginManager implements AuthenticationPluginManagerInterface class AuthenticationPluginManager extends AbstractPluginManager implements AuthenticationPluginManagerInterface
{ {
protected $instanceOf = Plugin\AuthenticationPluginInterface::class; protected $instanceOf = Plugin\AuthenticationPluginInterface::class; // phpcs:ignore
} }

View file

@ -43,7 +43,7 @@ class RequestToHttpAuthPlugin implements RequestToHttpAuthPluginInterface
return array_reduce( return array_reduce(
self::SUPPORTED_AUTH_HEADERS, self::SUPPORTED_AUTH_HEADERS,
fn (bool $carry, string $header) => $carry || $request->hasHeader($header), fn (bool $carry, string $header) => $carry || $request->hasHeader($header),
false false,
); );
} }

View file

@ -21,7 +21,7 @@ class ConfigProvider
$this->loadConfig = Closure::fromCallable($loadConfig ?? fn (string $glob) => loadConfigFromGlob($glob)); $this->loadConfig = Closure::fromCallable($loadConfig ?? fn (string $glob) => loadConfigFromGlob($glob));
} }
public function __invoke() public function __invoke(): array
{ {
$config = ($this->loadConfig)(__DIR__ . '/../config/{,*.}config.php'); $config = ($this->loadConfig)(__DIR__ . '/../config/{,*.}config.php');
return $this->applyRoutesPrefix($config); return $this->applyRoutesPrefix($config);

View file

@ -22,7 +22,7 @@ class MissingAuthenticationException extends RuntimeException implements Problem
{ {
$e = new self(sprintf( $e = new self(sprintf(
'Expected one of the following authentication headers, ["%s"], but none were provided', 'Expected one of the following authentication headers, ["%s"], but none were provided',
implode('", "', $expectedTypes) implode('", "', $expectedTypes),
)); ));
$e->detail = $e->getMessage(); $e->detail = $e->getMessage();

View file

@ -23,10 +23,7 @@ class BodyParserMiddleware implements MiddlewareInterface, RequestMethodInterfac
* Process an incoming server request and return a response, optionally delegating * Process an incoming server request and return a response, optionally delegating
* to the next middleware component to create the response. * to the next middleware component to create the response.
* *
* @param Request $request
* @param RequestHandlerInterface $handler
* *
* @return Response
*/ */
public function process(Request $request, RequestHandlerInterface $handler): Response public function process(Request $request, RequestHandlerInterface $handler): Response
{ {
@ -55,8 +52,6 @@ class BodyParserMiddleware implements MiddlewareInterface, RequestMethodInterfac
} }
/** /**
* @param Request $request
* @return string
*/ */
private function getRequestContentType(Request $request): string private function getRequestContentType(Request $request): string
{ {
@ -66,8 +61,6 @@ class BodyParserMiddleware implements MiddlewareInterface, RequestMethodInterfac
} }
/** /**
* @param Request $request
* @return Request
*/ */
private function parseFromJson(Request $request): Request private function parseFromJson(Request $request): Request
{ {
@ -81,8 +74,6 @@ class BodyParserMiddleware implements MiddlewareInterface, RequestMethodInterfac
} }
/** /**
* @param Request $request
* @return Request
*/ */
private function parseFromUrlEncoded(Request $request): Request private function parseFromUrlEncoded(Request $request): Request
{ {

View file

@ -9,7 +9,7 @@ use Zend\Expressive\Router\Middleware\ImplicitOptionsMiddleware;
class EmptyResponseImplicitOptionsMiddlewareFactory class EmptyResponseImplicitOptionsMiddlewareFactory
{ {
public function __invoke() public function __invoke(): ImplicitOptionsMiddleware
{ {
return new ImplicitOptionsMiddleware(fn () => new EmptyResponse()); return new ImplicitOptionsMiddleware(fn () => new EmptyResponse());
} }

View file

@ -16,37 +16,36 @@ class ShortUrlsFixture extends AbstractFixture
/** /**
* Load data fixtures with the passed EntityManager * Load data fixtures with the passed EntityManager
* *
* @param ObjectManager $manager
*/ */
public function load(ObjectManager $manager): void public function load(ObjectManager $manager): void
{ {
$abcShortUrl = $this->setShortUrlDate( $abcShortUrl = $this->setShortUrlDate(
new ShortUrl('https://shlink.io', ShortUrlMeta::createFromRawData(['customSlug' => 'abc123'])), new ShortUrl('https://shlink.io', ShortUrlMeta::createFromRawData(['customSlug' => 'abc123'])),
'2018-05-01' '2018-05-01',
); );
$manager->persist($abcShortUrl); $manager->persist($abcShortUrl);
$defShortUrl = $this->setShortUrlDate(new ShortUrl( $defShortUrl = $this->setShortUrlDate(new ShortUrl(
'https://blog.alejandrocelaya.com/2017/12/09/acmailer-7-0-the-most-important-release-in-a-long-time/', 'https://blog.alejandrocelaya.com/2017/12/09/acmailer-7-0-the-most-important-release-in-a-long-time/',
ShortUrlMeta::createFromParams(Chronos::parse('2020-05-01'), null, 'def456') ShortUrlMeta::createFromParams(Chronos::parse('2020-05-01'), null, 'def456'),
), '2019-01-01 00:00:10'); ), '2019-01-01 00:00:10');
$manager->persist($defShortUrl); $manager->persist($defShortUrl);
$customShortUrl = $this->setShortUrlDate(new ShortUrl( $customShortUrl = $this->setShortUrlDate(new ShortUrl(
'https://shlink.io', 'https://shlink.io',
ShortUrlMeta::createFromParams(null, null, 'custom', 2) ShortUrlMeta::createFromParams(null, null, 'custom', 2),
), '2019-01-01 00:00:20'); ), '2019-01-01 00:00:20');
$manager->persist($customShortUrl); $manager->persist($customShortUrl);
$withDomainShortUrl = $this->setShortUrlDate(new ShortUrl( $withDomainShortUrl = $this->setShortUrlDate(new ShortUrl(
'https://blog.alejandrocelaya.com/2019/04/27/considerations-to-properly-use-open-source-software-projects/', 'https://blog.alejandrocelaya.com/2019/04/27/considerations-to-properly-use-open-source-software-projects/',
ShortUrlMeta::createFromRawData(['domain' => 'example.com', 'customSlug' => 'ghi789']) ShortUrlMeta::createFromRawData(['domain' => 'example.com', 'customSlug' => 'ghi789']),
), '2019-01-01 00:00:30'); ), '2019-01-01 00:00:30');
$manager->persist($withDomainShortUrl); $manager->persist($withDomainShortUrl);
$withDomainAndSlugShortUrl = $this->setShortUrlDate(new ShortUrl( $withDomainAndSlugShortUrl = $this->setShortUrlDate(new ShortUrl(
'https://google.com', 'https://google.com',
ShortUrlMeta::createFromRawData(['domain' => 'some-domain.com', 'customSlug' => 'custom-with-domain']) ShortUrlMeta::createFromRawData(['domain' => 'some-domain.com', 'customSlug' => 'custom-with-domain']),
), '2018-10-20'); ), '2018-10-20');
$manager->persist($withDomainAndSlugShortUrl); $manager->persist($withDomainAndSlugShortUrl);

View file

@ -18,7 +18,7 @@ class AuthenticationTest extends ApiTestCase
{ {
$expectedDetail = sprintf( $expectedDetail = sprintf(
'Expected one of the following authentication headers, ["%s"], but none were provided', 'Expected one of the following authentication headers, ["%s"], but none were provided',
implode('", "', RequestToHttpAuthPlugin::SUPPORTED_AUTH_HEADERS) implode('", "', RequestToHttpAuthPlugin::SUPPORTED_AUTH_HEADERS),
); );
$resp = $this->callApi(self::METHOD_GET, '/short-urls'); $resp = $this->callApi(self::METHOD_GET, '/short-urls');

View file

@ -25,7 +25,7 @@ class HealthActionTest extends TestCase
} }
/** @test */ /** @test */
public function passResponseIsReturnedWhenConnectionSucceeds() public function passResponseIsReturnedWhenConnectionSucceeds(): void
{ {
$ping = $this->conn->ping()->willReturn(true); $ping = $this->conn->ping()->willReturn(true);
@ -45,7 +45,7 @@ class HealthActionTest extends TestCase
} }
/** @test */ /** @test */
public function failResponseIsReturnedWhenConnectionFails() public function failResponseIsReturnedWhenConnectionFails(): void
{ {
$ping = $this->conn->ping()->willReturn(false); $ping = $this->conn->ping()->willReturn(false);
@ -65,7 +65,7 @@ class HealthActionTest extends TestCase
} }
/** @test */ /** @test */
public function failResponseIsReturnedWhenConnectionThrowsException() public function failResponseIsReturnedWhenConnectionThrowsException(): void
{ {
$ping = $this->conn->ping()->willThrow(Exception::class); $ping = $this->conn->ping()->willThrow(Exception::class);

View file

@ -52,7 +52,7 @@ class CreateShortUrlActionTest extends TestCase
$shorten = $this->urlShortener->urlToShortCode( $shorten = $this->urlShortener->urlToShortCode(
Argument::type(Uri::class), Argument::type(Uri::class),
Argument::type('array'), Argument::type('array'),
$expectedMeta $expectedMeta,
)->willReturn($shortUrl); )->willReturn($shortUrl);
$request = ServerRequestFactory::fromGlobals()->withParsedBody($body); $request = ServerRequestFactory::fromGlobals()->withParsedBody($body);

View file

@ -25,7 +25,7 @@ class DeleteShortUrlActionTest extends TestCase
/** @test */ /** @test */
public function emptyResponseIsReturnedIfProperlyDeleted(): void public function emptyResponseIsReturnedIfProperlyDeleted(): void
{ {
$deleteByShortCode = $this->service->deleteByShortCode(Argument::any())->will(function () { $deleteByShortCode = $this->service->deleteByShortCode(Argument::any())->will(function (): void {
}); });
$resp = $this->action->handle(new ServerRequest()); $resp = $this->action->handle(new ServerRequest());

View file

@ -44,7 +44,7 @@ class EditShortUrlActionTest extends TestCase
'maxVisits' => 5, 'maxVisits' => 5,
]); ]);
$updateMeta = $this->shortUrlService->updateMetadataByShortCode(Argument::cetera())->willReturn( $updateMeta = $this->shortUrlService->updateMetadataByShortCode(Argument::cetera())->willReturn(
new ShortUrl('') new ShortUrl(''),
); );
$resp = $this->action->handle($request); $resp = $this->action->handle($request);

View file

@ -39,7 +39,7 @@ class EditShortUrlTagsActionTest extends TestCase
$response = $this->action->handle( $response = $this->action->handle(
(new ServerRequest())->withAttribute('shortCode', 'abc123') (new ServerRequest())->withAttribute('shortCode', 'abc123')
->withParsedBody(['tags' => []]) ->withParsedBody(['tags' => []]),
); );
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
} }

View file

@ -50,7 +50,7 @@ class ListShortUrlsActionTest extends TestCase
$expectedSearchTerm, $expectedSearchTerm,
$expectedTags, $expectedTags,
$expectedOrderBy, $expectedOrderBy,
$expectedDateRange $expectedDateRange,
)->willReturn(new Paginator(new ArrayAdapter())); )->willReturn(new Paginator(new ArrayAdapter()));
/** @var JsonResponse $response */ /** @var JsonResponse $response */

Some files were not shown because too many files have changed in this diff Show more