From 650a2869824616dee643cfadc0fc4b0a1f6f5e14 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Thu, 9 Feb 2023 09:32:38 +0100 Subject: [PATCH] Update to PHPUnit 10 --- composer.json | 63 +++++++++---------- .../CLI/test-cli/Command/ListApiKeysTest.php | 2 +- .../test-cli/Command/ListShortUrlsTest.php | 2 +- module/CLI/test/ApiKey/RoleResolverTest.php | 15 ++--- .../test/Command/Api/ListKeysCommandTest.php | 16 ++--- .../Command/Db/CreateDatabaseCommandTest.php | 2 +- .../Domain/DomainRedirectsCommandTest.php | 2 +- .../Command/Domain/ListDomainsCommandTest.php | 2 +- .../ShortUrl/CreateShortUrlCommandTest.php | 4 +- .../ShortUrl/DeleteShortUrlCommandTest.php | 2 +- .../ShortUrl/ListShortUrlsCommandTest.php | 6 +- .../Visit/DownloadGeoLiteDbCommandTest.php | 4 +- .../Command/Visit/LocateVisitsCommandTest.php | 6 +- ...GeolocationDbUpdateFailedExceptionTest.php | 2 +- .../test/GeoLite/GeolocationDbUpdaterTest.php | 6 +- module/Core/test-api/Action/RedirectTest.php | 2 +- .../Adapter/TagsPaginatorAdapterTest.php | 2 +- .../Tag/Repository/TagRepositoryTest.php | 2 +- .../VisitLocationRepositoryTest.php | 2 +- module/Core/test/Action/QrCodeActionTest.php | 6 +- module/Core/test/Action/RobotsActionTest.php | 2 +- module/Core/test/Config/EnvVarsTest.php | 4 +- .../Config/NotFoundRedirectResolverTest.php | 32 +++++----- .../PostProcessor/BasePathPrefixerTest.php | 2 +- .../MultiSegmentSlugProcessorTest.php | 2 +- .../ShortUrlMethodsProcessorTest.php | 2 +- module/Core/test/Domain/DomainServiceTest.php | 4 +- .../NotFoundRedirectHandlerTest.php | 38 +++++------ .../NotFoundTemplateHandlerTest.php | 16 ++--- .../CloseDbConnectionEventListenerTest.php | 2 +- .../test/EventDispatcher/LocateVisitTest.php | 4 +- .../Mercure/NotifyVisitToMercureTest.php | 2 +- .../NotifyVisitToWebHooksTest.php | 4 +- .../PublishingUpdatesGeneratorTest.php | 4 +- .../NotifyNewShortUrlToRabbitMqTest.php | 2 +- .../RabbitMq/NotifyVisitToRabbitMqTest.php | 26 ++++---- .../NotifyNewShortUrlToRedisTest.php | 2 +- .../RedisPubSub/NotifyVisitToRedisTest.php | 2 +- .../EventDispatcher/UpdateGeoLiteDbTest.php | 6 +- .../Exception/DeleteShortUrlExceptionTest.php | 2 +- .../ForbiddenTagOperationExceptionTest.php | 2 +- .../Exception/InvalidUrlExceptionTest.php | 2 +- .../IpCannotBeLocatedExceptionTest.php | 2 +- .../Exception/NonUniqueSlugExceptionTest.php | 2 +- .../ShortUrlNotFoundExceptionTest.php | 2 +- .../Exception/ValidationExceptionTest.php | 2 +- module/Core/test/Functions/FunctionsTest.php | 2 +- .../Importer/ImportedLinksProcessorTest.php | 4 +- .../test/ShortUrl/Entity/ShortUrlTest.php | 6 +- .../Helper/ShortCodeUniquenessHelperTest.php | 2 +- .../Helper/ShortUrlRedirectionBuilderTest.php | 2 +- .../Helper/ShortUrlStringifierTest.php | 2 +- .../ShortUrlTitleResolutionHelperTest.php | 2 +- .../ExtraPathRedirectMiddlewareTest.php | 9 +-- .../TrimTrailingSlashMiddlewareTest.php | 2 +- .../ShortUrl/Model/ShortUrlCreationTest.php | 8 +-- .../ShortUrl/Model/ShortUrlEditionTest.php | 2 +- .../test/ShortUrl/Model/ShortUrlModeTest.php | 2 +- .../DeviceLongUrlsValidatorTest.php | 2 +- .../Adapter/ShortUrlRepositoryAdapterTest.php | 2 +- ...ersistenceShortUrlRelationResolverTest.php | 4 +- .../SimpleShortUrlRelationResolverTest.php | 2 +- .../test/ShortUrl/ShortUrlResolverTest.php | 2 +- .../test/ShortUrl/ShortUrlServiceTest.php | 11 ++-- .../ShortUrlDataTransformerTest.php | 2 +- .../Core/test/ShortUrl/UrlShortenerTest.php | 2 +- module/Core/test/Tag/TagServiceTest.php | 4 +- module/Core/test/Util/ApiKeyHelpersTrait.php | 2 +- .../test/Util/DoctrineBatchHelperTest.php | 2 +- .../test/Util/RedirectResponseHelperTest.php | 2 +- .../test/Visit/Entity/VisitLocationTest.php | 2 +- module/Core/test/Visit/Entity/VisitTest.php | 4 +- .../Visit/Geolocation/VisitLocatorTest.php | 4 +- .../Geolocation/VisitToLocationHelperTest.php | 2 +- module/Core/test/Visit/Model/VisitorTest.php | 16 ++--- .../NonOrphanVisitsPaginatorAdapterTest.php | 2 +- .../OrphanVisitsPaginatorAdapterTest.php | 2 +- module/Core/test/Visit/RequestTrackerTest.php | 2 +- .../OrphanVisitDataTransformerTest.php | 2 +- .../Core/test/Visit/VisitsStatsHelperTest.php | 21 ++++--- module/Core/test/Visit/VisitsTrackerTest.php | 4 +- .../test-api/Action/CreateShortUrlTest.php | 20 +++--- .../test-api/Action/DeleteShortUrlTest.php | 2 +- .../Rest/test-api/Action/DeleteTagsTest.php | 2 +- .../test-api/Action/DomainRedirectsTest.php | 4 +- .../Rest/test-api/Action/DomainVisitsTest.php | 6 +- .../Rest/test-api/Action/EditShortUrlTest.php | 15 +++-- .../Rest/test-api/Action/GlobalVisitsTest.php | 2 +- .../Rest/test-api/Action/ListDomainsTest.php | 2 +- .../test-api/Action/ListShortUrlsTest.php | 4 +- module/Rest/test-api/Action/ListTagsTest.php | 2 +- .../test-api/Action/NonOrphanVisitsTest.php | 2 +- .../Rest/test-api/Action/OrphanVisitsTest.php | 2 +- module/Rest/test-api/Action/RenameTagTest.php | 2 +- .../test-api/Action/ResolveShortUrlTest.php | 2 +- .../test-api/Action/ShortUrlVisitsTest.php | 4 +- .../Action/SingleStepCreateShortUrlTest.php | 2 +- module/Rest/test-api/Action/TagVisitsTest.php | 4 +- module/Rest/test-api/Action/TagsStatsTest.php | 2 +- module/Rest/test-api/Action/UpdateTagTest.php | 6 +- .../Rest/test-api/Action/VisitStatsTest.php | 2 +- .../Middleware/AuthenticationTest.php | 4 +- module/Rest/test-api/Middleware/CorsTest.php | 4 +- .../Utils/NotFoundUrlHelpersTrait.php | 2 +- .../Domain/DomainRedirectsActionTest.php | 4 +- .../Request/DomainRedirectsRequestTest.php | 4 +- .../test/Action/MercureInfoActionTest.php | 4 +- .../ShortUrl/CreateShortUrlActionTest.php | 2 +- .../ShortUrl/ListShortUrlsActionTest.php | 2 +- .../test/Action/Tag/DeleteTagsActionTest.php | 2 +- .../test/Action/Tag/ListTagsActionTest.php | 2 +- .../test/Action/Tag/UpdateTagActionTest.php | 2 +- .../Action/Visit/DomainVisitsActionTest.php | 2 +- .../ApiKey/InitialApiKeyDelegatorTest.php | 2 +- module/Rest/test/ApiKey/RoleTest.php | 10 +-- module/Rest/test/ConfigProviderTest.php | 2 +- ...sCompatibleProblemDetailsExceptionTest.php | 2 +- .../MissingAuthenticationExceptionTest.php | 4 +- .../AuthenticationMiddlewareTest.php | 14 ++--- .../Middleware/BodyParserMiddlewareTest.php | 2 +- .../Middleware/CrossDomainMiddlewareTest.php | 4 +- ...rdsCompatibleProblemDetailsHandlerTest.php | 2 +- ...ortUrlContentNegotiationMiddlewareTest.php | 4 +- .../DefaultShortCodesLengthMiddlewareTest.php | 2 +- ...DefaultDomainFromRequestMiddlewareTest.php | 2 +- .../ShortUrl/OverrideDomainMiddlewareTest.php | 4 +- .../Rest/test/Service/ApiKeyServiceTest.php | 4 +- phpunit-api.xml | 3 +- phpunit-cli.xml | 3 +- phpunit-db.xml | 3 +- phpunit.xml.dist | 3 +- 131 files changed, 335 insertions(+), 315 deletions(-) diff --git a/composer.json b/composer.json index 228a2c5f..202ed25e 100644 --- a/composer.json +++ b/composer.json @@ -20,63 +20,62 @@ "akrabat/ip-address-middleware": "^2.1", "cakephp/chronos": "^2.3", "doctrine/migrations": "^3.5", - "doctrine/orm": "^2.13.3", - "endroid/qr-code": "^4.6", + "doctrine/orm": "^2.14", + "endroid/qr-code": "^4.7", "geoip2/geoip2": "^2.13", "guzzlehttp/guzzle": "^7.5", "happyr/doctrine-specification": "^2.0", "jaybizzle/crawler-detect": "^1.2.112", - "laminas/laminas-config": "^3.7", - "laminas/laminas-config-aggregator": "^1.11", - "laminas/laminas-diactoros": "^2.19", - "laminas/laminas-inputfilter": "^2.22", - "laminas/laminas-servicemanager": "^3.19", - "laminas/laminas-stdlib": "^3.15", - "lcobucci/jwt": "^4.2", + "laminas/laminas-config": "^3.8", + "laminas/laminas-config-aggregator": "^1.13", + "laminas/laminas-diactoros": "^2.24", + "laminas/laminas-inputfilter": "^2.24", + "laminas/laminas-servicemanager": "^3.20", + "laminas/laminas-stdlib": "^3.16", + "lcobucci/jwt": "^4.3", "league/uri": "^6.8", "lstrojny/functional-php": "^1.17", - "mezzio/mezzio": "^3.13", - "mezzio/mezzio-fastroute": "^3.7", - "mezzio/mezzio-problem-details": "^1.7", - "mezzio/mezzio-swoole": "^4.5", + "mezzio/mezzio": "^3.15", + "mezzio/mezzio-fastroute": "^3.8", + "mezzio/mezzio-problem-details": "^1.11", + "mezzio/mezzio-swoole": "^4.6", "mlocati/ip-lib": "^1.18", "mobiledetect/mobiledetectlib": "^3.74", "ocramius/proxy-manager": "^2.14", - "pagerfanta/core": "^3.6", + "pagerfanta/core": "^3.7", "php-middleware/request-id": "^4.1", "pugx/shortid-php": "^1.1", - "ramsey/uuid": "^4.5", + "ramsey/uuid": "^4.7", "shlinkio/shlink-common": "^5.3.1", "shlinkio/shlink-config": "^2.4", "shlinkio/shlink-event-dispatcher": "^2.6", "shlinkio/shlink-importer": "^5.0", "shlinkio/shlink-installer": "^8.3", "shlinkio/shlink-ip-geolocation": "^3.2", - "spiral/roadrunner": "^2.11", - "spiral/roadrunner-jobs": "^2.5", - "symfony/console": "^6.1", - "symfony/filesystem": "^6.1", - "symfony/lock": "^6.1", - "symfony/process": "^6.1", - "symfony/string": "^6.1" + "spiral/roadrunner": "^2.12", + "spiral/roadrunner-jobs": "^2.7", + "symfony/console": "^6.2", + "symfony/filesystem": "^6.2", + "symfony/lock": "^6.2", + "symfony/process": "^6.2", + "symfony/string": "^6.2" }, "require-dev": { "cebe/php-openapi": "^1.7", "devster/ubench": "^2.1", - "dms/phpunit-arraysubset-asserts": "^0.4.0", - "infection/infection": "^0.26.15", + "infection/infection": "^0.26.19", "openswoole/ide-helper": "~4.11.5", - "phpstan/phpstan": "^1.8", + "phpstan/phpstan": "^1.9", "phpstan/phpstan-doctrine": "^1.3", - "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", "phpstan/phpstan-symfony": "^1.2", - "phpunit/php-code-coverage": "^9.2", - "phpunit/phpunit": "^9.5", + "phpunit/php-code-coverage": "^10.0", + "phpunit/phpunit": "^10.0", "roave/security-advisories": "dev-master", "shlinkio/php-coding-standard": "~2.3.0", - "shlinkio/shlink-test-utils": "^3.4", - "symfony/var-dumper": "^6.1", - "veewee/composer-run-parallel": "^1.1" + "shlinkio/shlink-test-utils": "^3.5", + "symfony/var-dumper": "^6.2", + "veewee/composer-run-parallel": "^1.2" }, "autoload": { "psr-4": { @@ -133,7 +132,7 @@ "test:cli": "APP_ENV=test DB_DRIVER=maria TEST_ENV=cli php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-cli.xml --log-junit=build/coverage-cli/junit.xml", "test:cli:ci": "GENERATE_COVERAGE=yes composer test:cli", "test:cli:pretty": "GENERATE_COVERAGE=pretty composer test:cli", - "infect:ci:base": "infection --threads=max --only-covered --only-covering-test-cases --skip-initial-tests", + "infect:ci:base": "infection --threads=max --only-covered --skip-initial-tests", "infect:ci:unit": "@infect:ci:base --coverage=build/coverage-unit --min-msi=80", "infect:ci:db": "@infect:ci:base --coverage=build/coverage-db --min-msi=95 --configuration=infection-db.json5", "infect:ci:api": "@infect:ci:base --coverage=build/coverage-api --min-msi=80 --configuration=infection-api.json5", diff --git a/module/CLI/test-cli/Command/ListApiKeysTest.php b/module/CLI/test-cli/Command/ListApiKeysTest.php index 96b60e92..0788ddff 100644 --- a/module/CLI/test-cli/Command/ListApiKeysTest.php +++ b/module/CLI/test-cli/Command/ListApiKeysTest.php @@ -23,7 +23,7 @@ class ListApiKeysTest extends CliTestCase self::assertEquals(ExitCodes::EXIT_SUCCESS, $exitCode); } - public function provideFlags(): iterable + public static function provideFlags(): iterable { $expiredApiKeyDate = Chronos::now()->subDay()->startOfDay()->toAtomString(); $enabledOnlyOutput = << [[], <<domainService->expects($this->exactly($expectedDomainCalls))->method('getOrCreate')->with( 'example.com', - )->willReturn($this->domainWithId(Domain::withAuthority('example.com'))); + )->willReturn(self::domainWithId(Domain::withAuthority('example.com'))); $result = $this->resolver->determineRoles($input); self::assertEquals($expectedRoles, $result); } - public function provideRoles(): iterable + public static function provideRoles(): iterable { - $domain = $this->domainWithId(Domain::withAuthority('example.com')); - $buildInput = function (array $definition): InputInterface { - $input = $this->createStub(InputInterface::class); + $domain = self::domainWithId(Domain::withAuthority('example.com')); + $buildInput = static fn (array $definition) => function (TestCase $test) use ($definition): InputInterface { + $input = $test->createStub(InputInterface::class); $input->method('getOption')->willReturnMap( map($definition, static fn (mixed $returnValue, string $param) => [$param, $returnValue]), ); @@ -114,7 +115,7 @@ class RoleResolverTest extends TestCase $this->resolver->determineRoles($input); } - private function domainWithId(Domain $domain): Domain + private static function domainWithId(Domain $domain): Domain { $domain->setId('1'); return $domain; diff --git a/module/CLI/test/Command/Api/ListKeysCommandTest.php b/module/CLI/test/Command/Api/ListKeysCommandTest.php index f4101ec6..acf37b73 100644 --- a/module/CLI/test/Command/Api/ListKeysCommandTest.php +++ b/module/CLI/test/Command/Api/ListKeysCommandTest.php @@ -43,7 +43,7 @@ class ListKeysCommandTest extends TestCase self::assertEquals($expected, $output); } - public function provideKeysAndOutputs(): iterable + public static function provideKeysAndOutputs(): iterable { $dateInThePast = Chronos::createFromFormat('Y-m-d H:i:s', '2020-01-01 00:00:00'); @@ -84,14 +84,14 @@ class ListKeysCommandTest extends TestCase yield 'with roles' => [ [ $apiKey1 = ApiKey::create(), - $apiKey2 = $this->apiKeyWithRoles([RoleDefinition::forAuthoredShortUrls()]), - $apiKey3 = $this->apiKeyWithRoles( - [RoleDefinition::forDomain($this->domainWithId(Domain::withAuthority('example.com')))], + $apiKey2 = self::apiKeyWithRoles([RoleDefinition::forAuthoredShortUrls()]), + $apiKey3 = self::apiKeyWithRoles( + [RoleDefinition::forDomain(self::domainWithId(Domain::withAuthority('example.com')))], ), $apiKey4 = ApiKey::create(), - $apiKey5 = $this->apiKeyWithRoles([ + $apiKey5 = self::apiKeyWithRoles([ RoleDefinition::forAuthoredShortUrls(), - RoleDefinition::forDomain($this->domainWithId(Domain::withAuthority('example.com'))), + RoleDefinition::forDomain(self::domainWithId(Domain::withAuthority('example.com'))), ]), $apiKey6 = ApiKey::create(), ], @@ -141,7 +141,7 @@ class ListKeysCommandTest extends TestCase ]; } - private function apiKeyWithRoles(array $roles): ApiKey + private static function apiKeyWithRoles(array $roles): ApiKey { $apiKey = ApiKey::create(); foreach ($roles as $role) { @@ -151,7 +151,7 @@ class ListKeysCommandTest extends TestCase return $apiKey; } - private function domainWithId(Domain $domain): Domain + private static function domainWithId(Domain $domain): Domain { $domain->setId('1'); return $domain; diff --git a/module/CLI/test/Command/Db/CreateDatabaseCommandTest.php b/module/CLI/test/Command/Db/CreateDatabaseCommandTest.php index bf1eac98..e71b166f 100644 --- a/module/CLI/test/Command/Db/CreateDatabaseCommandTest.php +++ b/module/CLI/test/Command/Db/CreateDatabaseCommandTest.php @@ -124,7 +124,7 @@ class CreateDatabaseCommandTest extends TestCase self::assertStringContainsString('Database properly created!', $output); } - public function provideEmptyDatabase(): iterable + public static function provideEmptyDatabase(): iterable { yield 'no tables' => [[]]; yield 'migrations table' => [[MIGRATIONS_TABLE]]; diff --git a/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php b/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php index 1bf5cec3..7425c929 100644 --- a/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php +++ b/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php @@ -60,7 +60,7 @@ class DomainRedirectsCommandTest extends TestCase self::assertEquals(3, substr_count($output, '(Leave empty for no redirect)')); } - public function provideDomains(): iterable + public static function provideDomains(): iterable { yield 'no domain' => [null]; yield 'domain without redirects' => [Domain::withAuthority('')]; diff --git a/module/CLI/test/Command/Domain/ListDomainsCommandTest.php b/module/CLI/test/Command/Domain/ListDomainsCommandTest.php index 0275ba87..20682090 100644 --- a/module/CLI/test/Command/Domain/ListDomainsCommandTest.php +++ b/module/CLI/test/Command/Domain/ListDomainsCommandTest.php @@ -57,7 +57,7 @@ class ListDomainsCommandTest extends TestCase self::assertEquals(ExitCodes::EXIT_SUCCESS, $this->commandTester->getStatusCode()); } - public function provideInputsAndOutputs(): iterable + public static function provideInputsAndOutputs(): iterable { $withoutRedirectsOutput = <<commandTester->getStatusCode()); } - public function provideDomains(): iterable + public static function provideDomains(): iterable { yield 'no domain' => [[], null]; yield 'non-default domain foo' => [['--domain' => 'foo.com'], 'foo.com']; @@ -166,7 +166,7 @@ class CreateShortUrlCommandTest extends TestCase $this->commandTester->execute($options); } - public function provideFlags(): iterable + public static function provideFlags(): iterable { yield 'no flags' => [[], null]; yield 'validate-url' => [['--validate-url' => true], true]; diff --git a/module/CLI/test/Command/ShortUrl/DeleteShortUrlCommandTest.php b/module/CLI/test/Command/ShortUrl/DeleteShortUrlCommandTest.php index 09d48d12..e5980bbf 100644 --- a/module/CLI/test/Command/ShortUrl/DeleteShortUrlCommandTest.php +++ b/module/CLI/test/Command/ShortUrl/DeleteShortUrlCommandTest.php @@ -98,7 +98,7 @@ class DeleteShortUrlCommandTest extends TestCase self::assertStringContainsString($expectedMessage, $output); } - public function provideRetryDeleteAnswers(): iterable + public static function provideRetryDeleteAnswers(): iterable { yield 'answering yes to retry' => [['yes'], 2, 'Short URL with short code "abc123" successfully deleted.']; yield 'answering no to retry' => [['no'], 1, 'Short URL was not deleted.']; diff --git a/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php b/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php index 9b45869f..27f2cf10 100644 --- a/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php +++ b/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php @@ -137,7 +137,7 @@ class ListShortUrlsCommandTest extends TestCase } } - public function provideOptionalFlags(): iterable + public static function provideOptionalFlags(): iterable { $apiKey = ApiKey::fromMeta(ApiKeyMeta::withName('my api key')); $key = $apiKey->toString(); @@ -200,7 +200,7 @@ class ListShortUrlsCommandTest extends TestCase $this->commandTester->execute($commandArgs); } - public function provideArgs(): iterable + public static function provideArgs(): iterable { yield [[], 1, null, [], TagsMode::ANY->value]; yield [['--page' => $page = 3], $page, null, [], TagsMode::ANY->value]; @@ -255,7 +255,7 @@ class ListShortUrlsCommandTest extends TestCase $this->commandTester->execute($commandArgs); } - public function provideOrderBy(): iterable + public static function provideOrderBy(): iterable { yield [[], null]; yield [['--order-by' => 'visits'], 'visits']; diff --git a/module/CLI/test/Command/Visit/DownloadGeoLiteDbCommandTest.php b/module/CLI/test/Command/Visit/DownloadGeoLiteDbCommandTest.php index 742fa31b..701728ac 100644 --- a/module/CLI/test/Command/Visit/DownloadGeoLiteDbCommandTest.php +++ b/module/CLI/test/Command/Visit/DownloadGeoLiteDbCommandTest.php @@ -61,7 +61,7 @@ class DownloadGeoLiteDbCommandTest extends TestCase self::assertSame($expectedExitCode, $exitCode); } - public function provideFailureParams(): iterable + public static function provideFailureParams(): iterable { yield 'existing db' => [ true, @@ -93,7 +93,7 @@ class DownloadGeoLiteDbCommandTest extends TestCase self::assertSame(ExitCodes::EXIT_SUCCESS, $exitCode); } - public function provideSuccessParams(): iterable + public static function provideSuccessParams(): iterable { yield 'up to date db' => [fn () => GeolocationResult::CHECK_SKIPPED, '[INFO] GeoLite2 db file is up to date.']; yield 'outdated db' => [function (callable $beforeDownload): GeolocationResult { diff --git a/module/CLI/test/Command/Visit/LocateVisitsCommandTest.php b/module/CLI/test/Command/Visit/LocateVisitsCommandTest.php index 44638249..0694f865 100644 --- a/module/CLI/test/Command/Visit/LocateVisitsCommandTest.php +++ b/module/CLI/test/Command/Visit/LocateVisitsCommandTest.php @@ -100,7 +100,7 @@ class LocateVisitsCommandTest extends TestCase } } - public function provideArgs(): iterable + public static function provideArgs(): iterable { yield 'no args' => [1, 0, 0, false, []]; yield 'retry' => [1, 1, 0, false, ['--retry' => true]]; @@ -131,7 +131,7 @@ class LocateVisitsCommandTest extends TestCase self::assertStringContainsString($message, $output); } - public function provideIgnoredAddresses(): iterable + public static function provideIgnoredAddresses(): iterable { yield 'empty address' => [IpCannotBeLocatedException::forEmptyAddress(), 'Ignored visit with no IP address']; yield 'localhost address' => [IpCannotBeLocatedException::forLocalhost(), 'Ignored localhost address']; @@ -226,7 +226,7 @@ class LocateVisitsCommandTest extends TestCase $this->commandTester->execute(['--all' => true, '--retry' => true]); } - public function provideAbortInputs(): iterable + public static function provideAbortInputs(): iterable { yield 'n' => [['n']]; yield 'no' => [['no']]; diff --git a/module/CLI/test/Exception/GeolocationDbUpdateFailedExceptionTest.php b/module/CLI/test/Exception/GeolocationDbUpdateFailedExceptionTest.php index 470aed2c..556d45f2 100644 --- a/module/CLI/test/Exception/GeolocationDbUpdateFailedExceptionTest.php +++ b/module/CLI/test/Exception/GeolocationDbUpdateFailedExceptionTest.php @@ -46,7 +46,7 @@ class GeolocationDbUpdateFailedExceptionTest extends TestCase self::assertEquals($prev, $e->getPrevious()); } - public function providePrev(): iterable + public static function providePrev(): iterable { yield 'no prev' => [null]; yield 'RuntimeException' => [new RuntimeException('prev')]; diff --git a/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php b/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php index 8d6188e9..47f6a2e9 100644 --- a/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php +++ b/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php @@ -84,7 +84,7 @@ class GeolocationDbUpdaterTest extends TestCase } } - public function provideBigDays(): iterable + public static function provideBigDays(): iterable { yield [36]; yield [50]; @@ -109,7 +109,7 @@ class GeolocationDbUpdaterTest extends TestCase self::assertEquals(GeolocationResult::DB_IS_UP_TO_DATE, $result); } - public function provideSmallDays(): iterable + public static function provideSmallDays(): iterable { $generateParamsWithTimestamp = static function (int $days) { $timestamp = Chronos::now()->subDays($days)->getTimestamp(); @@ -164,7 +164,7 @@ class GeolocationDbUpdaterTest extends TestCase self::assertEquals(GeolocationResult::CHECK_SKIPPED, $result); } - public function provideTrackingOptions(): iterable + public static function provideTrackingOptions(): iterable { yield 'disableTracking' => [new TrackingOptions(disableTracking: true)]; yield 'disableIpTracking' => [new TrackingOptions(disableIpTracking: true)]; diff --git a/module/Core/test-api/Action/RedirectTest.php b/module/Core/test-api/Action/RedirectTest.php index 73b6a1cc..6b4ad649 100644 --- a/module/Core/test-api/Action/RedirectTest.php +++ b/module/Core/test-api/Action/RedirectTest.php @@ -22,7 +22,7 @@ class RedirectTest extends ApiTestCase self::assertEquals($expectedRedirect, $response->getHeaderLine('Location')); } - public function provideUserAgents(): iterable + public static function provideUserAgents(): iterable { yield 'android' => [ANDROID_USER_AGENT, 'https://blog.alejandrocelaya.com/android']; yield 'ios' => [IOS_USER_AGENT, 'https://blog.alejandrocelaya.com/ios']; diff --git a/module/Core/test-db/Tag/Paginator/Adapter/TagsPaginatorAdapterTest.php b/module/Core/test-db/Tag/Paginator/Adapter/TagsPaginatorAdapterTest.php index 385f2335..76cefb46 100644 --- a/module/Core/test-db/Tag/Paginator/Adapter/TagsPaginatorAdapterTest.php +++ b/module/Core/test-db/Tag/Paginator/Adapter/TagsPaginatorAdapterTest.php @@ -52,7 +52,7 @@ class TagsPaginatorAdapterTest extends DatabaseTestCase self::assertEquals($expectedTotalCount, $adapter->getNbResults()); } - public function provideFilters(): iterable + public static function provideFilters(): iterable { yield [null, null, 0, 10, ['another', 'bar', 'baz', 'foo'], 4]; yield [null, null, 2, 10, ['baz', 'foo'], 4]; diff --git a/module/Core/test-db/Tag/Repository/TagRepositoryTest.php b/module/Core/test-db/Tag/Repository/TagRepositoryTest.php index 97873b20..31716815 100644 --- a/module/Core/test-db/Tag/Repository/TagRepositoryTest.php +++ b/module/Core/test-db/Tag/Repository/TagRepositoryTest.php @@ -109,7 +109,7 @@ class TagRepositoryTest extends DatabaseTestCase } } - public function provideFilters(): iterable + public static function provideFilters(): iterable { $defaultList = [ ['another', 0, 0, 0], diff --git a/module/Core/test-db/Visit/Repository/VisitLocationRepositoryTest.php b/module/Core/test-db/Visit/Repository/VisitLocationRepositoryTest.php index 6b7c1e0d..ad50403a 100644 --- a/module/Core/test-db/Visit/Repository/VisitLocationRepositoryTest.php +++ b/module/Core/test-db/Visit/Repository/VisitLocationRepositoryTest.php @@ -56,7 +56,7 @@ class VisitLocationRepositoryTest extends DatabaseTestCase self::assertCount(6, [...$all]); } - public function provideBlockSize(): iterable + public static function provideBlockSize(): iterable { return map(range(1, 10), fn (int $value) => [$value]); } diff --git a/module/Core/test/Action/QrCodeActionTest.php b/module/Core/test/Action/QrCodeActionTest.php index 684e9217..de0f1f6a 100644 --- a/module/Core/test/Action/QrCodeActionTest.php +++ b/module/Core/test/Action/QrCodeActionTest.php @@ -87,7 +87,7 @@ class QrCodeActionTest extends TestCase self::assertEquals($expectedContentType, $resp->getHeaderLine('Content-Type')); } - public function provideQueries(): iterable + public static function provideQueries(): iterable { yield 'no format, png default' => ['png', [], 'image/png']; yield 'no format, svg default' => ['svg', [], 'image/svg+xml']; @@ -122,7 +122,7 @@ class QrCodeActionTest extends TestCase self::assertEquals($expectedSize, $size); } - public function provideRequestsWithSize(): iterable + public static function provideRequestsWithSize(): iterable { yield 'different margin and size defaults' => [ new QrCodeOptions(size: 660, margin: 40), @@ -215,7 +215,7 @@ class QrCodeActionTest extends TestCase self::assertEquals($color, $expectedColor); } - public function provideRoundBlockSize(): iterable + public static function provideRoundBlockSize(): iterable { yield 'no round block param' => [new QrCodeOptions(), null, self::WHITE]; yield 'no round block param, but disabled by default' => [ diff --git a/module/Core/test/Action/RobotsActionTest.php b/module/Core/test/Action/RobotsActionTest.php index db1f7f90..7c1fcea5 100644 --- a/module/Core/test/Action/RobotsActionTest.php +++ b/module/Core/test/Action/RobotsActionTest.php @@ -39,7 +39,7 @@ class RobotsActionTest extends TestCase self::assertEquals('text/plain', $response->getHeaderLine('Content-Type')); } - public function provideShortCodes(): iterable + public static function provideShortCodes(): iterable { yield 'three short codes' => [['foo', 'bar', 'baz'], <<existsInEnv()); } - public function provideExistingEnvVars(): iterable + public static function provideExistingEnvVars(): iterable { yield 'DB_NAME' => [EnvVars::DB_NAME, true]; yield 'BASE_PATH' => [EnvVars::BASE_PATH, true]; @@ -49,7 +49,7 @@ class EnvVarsTest extends TestCase self::assertEquals($expected, $envVar->loadFromEnv($default)); } - public function provideEnvVarsValues(): iterable + public static function provideEnvVarsValues(): iterable { yield 'DB_NAME without default' => [EnvVars::DB_NAME, 'shlink', null]; yield 'DB_NAME with default' => [EnvVars::DB_NAME, 'shlink', 'foobar']; diff --git a/module/Core/test/Config/NotFoundRedirectResolverTest.php b/module/Core/test/Config/NotFoundRedirectResolverTest.php index 53531b15..fb3cf3ec 100644 --- a/module/Core/test/Config/NotFoundRedirectResolverTest.php +++ b/module/Core/test/Config/NotFoundRedirectResolverTest.php @@ -13,7 +13,6 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\UriInterface; -use Psr\Http\Server\MiddlewareInterface; use Psr\Log\NullLogger; use Shlinkio\Shlink\Core\Action\RedirectAction; use Shlinkio\Shlink\Core\Config\NotFoundRedirectResolver; @@ -21,6 +20,8 @@ use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface; +use function Laminas\Stratigility\middleware; + class NotFoundRedirectResolverTest extends TestCase { private NotFoundRedirectResolver $resolver; @@ -52,47 +53,47 @@ class NotFoundRedirectResolverTest extends TestCase self::assertSame($expectedResp, $resp); } - public function provideRedirects(): iterable + public static function provideRedirects(): iterable { yield 'base URL with trailing slash' => [ $uri = new Uri('/'), - $this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), + self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), new NotFoundRedirectOptions(baseUrl: 'baseUrl'), 'baseUrl', ]; yield 'base URL with domain placeholder' => [ $uri = new Uri('https://s.test'), - $this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), + self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), new NotFoundRedirectOptions(baseUrl: 'https://redirect-here.com/{DOMAIN}'), 'https://redirect-here.com/s.test', ]; yield 'base URL with domain placeholder in query' => [ $uri = new Uri('https://s.test'), - $this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), + self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), new NotFoundRedirectOptions(baseUrl: 'https://redirect-here.com/?domain={DOMAIN}'), 'https://redirect-here.com/?domain=s.test', ]; yield 'base URL without trailing slash' => [ $uri = new Uri(''), - $this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), + self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), new NotFoundRedirectOptions(baseUrl: 'baseUrl'), 'baseUrl', ]; yield 'regular 404' => [ $uri = new Uri('/foo/bar'), - $this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), + self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), new NotFoundRedirectOptions(regular404: 'regular404'), 'regular404', ]; yield 'regular 404 with path placeholder in query' => [ $uri = new Uri('/foo/bar'), - $this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), + self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), new NotFoundRedirectOptions(regular404: 'https://redirect-here.com/?path={ORIGINAL_PATH}'), 'https://redirect-here.com/?path=%2Ffoo%2Fbar', ]; yield 'regular 404 with multiple placeholders' => [ $uri = new Uri('https://s.test/foo/bar'), - $this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), + self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)), new NotFoundRedirectOptions( regular404: 'https://redirect-here.com/{ORIGINAL_PATH}/{DOMAIN}/?d={DOMAIN}&p={ORIGINAL_PATH}', ), @@ -100,13 +101,13 @@ class NotFoundRedirectResolverTest extends TestCase ]; yield 'invalid short URL' => [ new Uri('/foo'), - $this->notFoundType($this->requestForRoute(RedirectAction::class)), + self::notFoundType(self::requestForRoute(RedirectAction::class)), new NotFoundRedirectOptions(invalidShortUrl: 'invalidShortUrl'), 'invalidShortUrl', ]; yield 'invalid short URL with path placeholder' => [ new Uri('/foo'), - $this->notFoundType($this->requestForRoute(RedirectAction::class)), + self::notFoundType(self::requestForRoute(RedirectAction::class)), new NotFoundRedirectOptions(invalidShortUrl: 'https://redirect-here.com/{ORIGINAL_PATH}'), 'https://redirect-here.com/foo', ]; @@ -115,7 +116,7 @@ class NotFoundRedirectResolverTest extends TestCase /** @test */ public function noResponseIsReturnedIfNoConditionsMatch(): void { - $notFoundType = $this->notFoundType($this->requestForRoute('foo')); + $notFoundType = self::notFoundType(self::requestForRoute('foo')); $this->helper->expects($this->never())->method('buildRedirectResponse'); $result = $this->resolver->resolveRedirectResponse($notFoundType, new NotFoundRedirectOptions(), new Uri()); @@ -123,12 +124,12 @@ class NotFoundRedirectResolverTest extends TestCase self::assertNull($result); } - private function notFoundType(ServerRequestInterface $req): NotFoundType + private static function notFoundType(ServerRequestInterface $req): NotFoundType { return NotFoundType::fromRequest($req, ''); } - private function requestForRoute(string $routeName): ServerRequestInterface + private static function requestForRoute(string $routeName): ServerRequestInterface { return ServerRequestFactory::fromGlobals() ->withAttribute( @@ -136,7 +137,8 @@ class NotFoundRedirectResolverTest extends TestCase RouteResult::fromRoute( new Route( 'foo', - $this->createMock(MiddlewareInterface::class), + middleware(function (): void { + }), ['GET'], $routeName, ), diff --git a/module/Core/test/Config/PostProcessor/BasePathPrefixerTest.php b/module/Core/test/Config/PostProcessor/BasePathPrefixerTest.php index 90c1449a..8aa4a964 100644 --- a/module/Core/test/Config/PostProcessor/BasePathPrefixerTest.php +++ b/module/Core/test/Config/PostProcessor/BasePathPrefixerTest.php @@ -31,7 +31,7 @@ class BasePathPrefixerTest extends TestCase self::assertEquals($expectedMiddlewares, $middlewares); } - public function provideConfig(): iterable + public static function provideConfig(): iterable { yield 'with empty options' => [['routes' => []], [], []]; yield 'with non-empty options' => [ diff --git a/module/Core/test/Config/PostProcessor/MultiSegmentSlugProcessorTest.php b/module/Core/test/Config/PostProcessor/MultiSegmentSlugProcessorTest.php index cef07a86..37850890 100644 --- a/module/Core/test/Config/PostProcessor/MultiSegmentSlugProcessorTest.php +++ b/module/Core/test/Config/PostProcessor/MultiSegmentSlugProcessorTest.php @@ -25,7 +25,7 @@ class MultiSegmentSlugProcessorTest extends TestCase self::assertEquals($expectedRoutes, ($this->processor)($config)['routes'] ?? []); } - public function provideConfigs(): iterable + public static function provideConfigs(): iterable { yield [[], []]; yield [['url_shortener' => []], []]; diff --git a/module/Core/test/Config/PostProcessor/ShortUrlMethodsProcessorTest.php b/module/Core/test/Config/PostProcessor/ShortUrlMethodsProcessorTest.php index b73253f7..30ea35fb 100644 --- a/module/Core/test/Config/PostProcessor/ShortUrlMethodsProcessorTest.php +++ b/module/Core/test/Config/PostProcessor/ShortUrlMethodsProcessorTest.php @@ -29,7 +29,7 @@ class ShortUrlMethodsProcessorTest extends TestCase self::assertEquals($expectedRoutes, ($this->processor)($config)['routes'] ?? null); } - public function provideConfigs(): iterable + public static function provideConfigs(): iterable { $buildConfigWithStatus = static fn (int $status, ?array $expectedAllowedMethods) => [[ 'routes' => [ diff --git a/module/Core/test/Domain/DomainServiceTest.php b/module/Core/test/Domain/DomainServiceTest.php index 46d3e567..0b160e51 100644 --- a/module/Core/test/Domain/DomainServiceTest.php +++ b/module/Core/test/Domain/DomainServiceTest.php @@ -44,7 +44,7 @@ class DomainServiceTest extends TestCase self::assertEquals($expectedResult, $result); } - public function provideExcludedDomains(): iterable + public static function provideExcludedDomains(): iterable { $default = DomainItem::forDefaultDomain('default.com', new EmptyNotFoundRedirectConfig()); $adminApiKey = ApiKey::create(); @@ -190,7 +190,7 @@ class DomainServiceTest extends TestCase self::assertEquals('baz.com', $result->invalidShortUrlRedirect()); } - public function provideFoundDomains(): iterable + public static function provideFoundDomains(): iterable { $domain = Domain::withAuthority(''); $adminApiKey = ApiKey::create(); diff --git a/module/Core/test/ErrorHandler/NotFoundRedirectHandlerTest.php b/module/Core/test/ErrorHandler/NotFoundRedirectHandlerTest.php index c6debfb5..5d22660d 100644 --- a/module/Core/test/ErrorHandler/NotFoundRedirectHandlerTest.php +++ b/module/Core/test/ErrorHandler/NotFoundRedirectHandlerTest.php @@ -6,6 +6,7 @@ namespace ShlinkioTest\Shlink\Core\ErrorHandler; use Laminas\Diactoros\Response; use Laminas\Diactoros\ServerRequestFactory; +use PHPUnit\Framework\Assert; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ServerRequestInterface; @@ -58,40 +59,39 @@ class NotFoundRedirectHandlerTest extends TestCase self::assertSame($expectedResp, $result); } - public function provideNonRedirectScenarios(): iterable + public static function provideNonRedirectScenarios(): iterable { yield 'no domain' => [function ( MockObject&DomainServiceInterface $domainService, MockObject&NotFoundRedirectResolverInterface $resolver, ): void { - $domainService->expects($this->once())->method('findByAuthority')->withAnyParameters()->willReturn( + $domainService->expects(self::once())->method('findByAuthority')->withAnyParameters()->willReturn( null, ); - $resolver->expects($this->once())->method('resolveRedirectResponse')->with( - $this->isInstanceOf(NotFoundType::class), - $this->isInstanceOf(NotFoundRedirectOptions::class), - $this->isInstanceOf(UriInterface::class), + $resolver->expects(self::once())->method('resolveRedirectResponse')->with( + self::isInstanceOf(NotFoundType::class), + self::isInstanceOf(NotFoundRedirectOptions::class), + self::isInstanceOf(UriInterface::class), )->willReturn(null); }]; yield 'non-redirecting domain' => [function ( MockObject&DomainServiceInterface $domainService, MockObject&NotFoundRedirectResolverInterface $resolver, ): void { - $domainService->expects($this->once())->method('findByAuthority')->withAnyParameters()->willReturn( + $domainService->expects(self::once())->method('findByAuthority')->withAnyParameters()->willReturn( Domain::withAuthority(''), ); - $resolver->expects($this->exactly(2))->method('resolveRedirectResponse')->withConsecutive( - [ - $this->isInstanceOf(NotFoundType::class), - $this->isInstanceOf(Domain::class), - $this->isInstanceOf(UriInterface::class), - ], - [ - $this->isInstanceOf(NotFoundType::class), - $this->isInstanceOf(NotFoundRedirectOptions::class), - $this->isInstanceOf(UriInterface::class), - ], - )->willReturn(null); + $callCount = 0; + $resolver->expects(self::exactly(2))->method('resolveRedirectResponse')->willReturnCallback( + function (mixed $arg1, mixed $arg2, mixed $arg3) use (&$callCount) { + Assert::assertInstanceOf(NotFoundType::class, $arg1); + Assert::assertInstanceOf($callCount === 0 ? Domain::class : NotFoundRedirectOptions::class, $arg2); + Assert::assertInstanceOf(UriInterface::class, $arg3); + + $callCount++; + return null; + }, + ); }]; } diff --git a/module/Core/test/ErrorHandler/NotFoundTemplateHandlerTest.php b/module/Core/test/ErrorHandler/NotFoundTemplateHandlerTest.php index 800dc4e0..f50d91bf 100644 --- a/module/Core/test/ErrorHandler/NotFoundTemplateHandlerTest.php +++ b/module/Core/test/ErrorHandler/NotFoundTemplateHandlerTest.php @@ -11,11 +11,12 @@ use Mezzio\Router\Route; use Mezzio\Router\RouteResult; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ServerRequestInterface; -use Psr\Http\Server\MiddlewareInterface; use Shlinkio\Shlink\Core\Action\RedirectAction; use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; use Shlinkio\Shlink\Core\ErrorHandler\NotFoundTemplateHandler; +use function Laminas\Stratigility\middleware; + class NotFoundTemplateHandlerTest extends TestCase { private NotFoundTemplateHandler $handler; @@ -44,19 +45,20 @@ class NotFoundTemplateHandlerTest extends TestCase self::assertTrue($this->readFileCalled); } - public function provideTemplates(): iterable + public static function provideTemplates(): iterable { $request = ServerRequestFactory::fromGlobals()->withUri(new Uri('/foo')); - yield 'base url' => [$this->withNotFoundType($request, '/foo'), NotFoundTemplateHandler::NOT_FOUND_TEMPLATE]; - yield 'regular not found' => [$this->withNotFoundType($request), NotFoundTemplateHandler::NOT_FOUND_TEMPLATE]; + yield 'base url' => [self::withNotFoundType($request, '/foo'), NotFoundTemplateHandler::NOT_FOUND_TEMPLATE]; + yield 'regular not found' => [self::withNotFoundType($request), NotFoundTemplateHandler::NOT_FOUND_TEMPLATE]; yield 'invalid short code' => [ - $this->withNotFoundType($request->withAttribute( + self::withNotFoundType($request->withAttribute( RouteResult::class, RouteResult::fromRoute( new Route( 'foo', - $this->createMock(MiddlewareInterface::class), + middleware(function (): void { + }), ['GET'], RedirectAction::class, ), @@ -66,7 +68,7 @@ class NotFoundTemplateHandlerTest extends TestCase ]; } - private function withNotFoundType(ServerRequestInterface $req, string $baseUrl = ''): ServerRequestInterface + private static function withNotFoundType(ServerRequestInterface $req, string $baseUrl = ''): ServerRequestInterface { $type = NotFoundType::fromRequest($req, $baseUrl); return $req->withAttribute(NotFoundType::class, $type); diff --git a/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerTest.php b/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerTest.php index 430f08a9..bbcf3994 100644 --- a/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerTest.php +++ b/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerTest.php @@ -46,7 +46,7 @@ class CloseDbConnectionEventListenerTest extends TestCase self::assertTrue($wrappedWasCalled); } - public function provideWrapped(): iterable + public static function provideWrapped(): iterable { yield 'does not throw exception' => (static function (): array { $wrappedWasCalled = false; diff --git a/module/Core/test/EventDispatcher/LocateVisitTest.php b/module/Core/test/EventDispatcher/LocateVisitTest.php index d538bff0..e6c9deac 100644 --- a/module/Core/test/EventDispatcher/LocateVisitTest.php +++ b/module/Core/test/EventDispatcher/LocateVisitTest.php @@ -146,7 +146,7 @@ class LocateVisitTest extends TestCase self::assertEquals($visit->getVisitLocation(), VisitLocation::fromGeolocation(Location::emptyInstance())); } - public function provideNonLocatableVisits(): iterable + public static function provideNonLocatableVisits(): iterable { $shortUrl = ShortUrl::createFake(); @@ -180,7 +180,7 @@ class LocateVisitTest extends TestCase self::assertEquals($visit->getVisitLocation(), VisitLocation::fromGeolocation($location)); } - public function provideIpAddresses(): iterable + public static function provideIpAddresses(): iterable { yield 'no original IP address' => [ Visit::forValidShortUrl(ShortUrl::createFake(), new Visitor('', '', '1.2.3.4', '')), diff --git a/module/Core/test/EventDispatcher/Mercure/NotifyVisitToMercureTest.php b/module/Core/test/EventDispatcher/Mercure/NotifyVisitToMercureTest.php index 23450fd3..d5b048f9 100644 --- a/module/Core/test/EventDispatcher/Mercure/NotifyVisitToMercureTest.php +++ b/module/Core/test/EventDispatcher/Mercure/NotifyVisitToMercureTest.php @@ -121,7 +121,7 @@ class NotifyVisitToMercureTest extends TestCase ($this->listener)(new VisitLocated($visitId)); } - public function provideOrphanVisits(): iterable + public static function provideOrphanVisits(): iterable { $visitor = Visitor::emptyInstance(); diff --git a/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php b/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php index 17b26a74..0a9234e3 100644 --- a/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php +++ b/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php @@ -120,13 +120,13 @@ class NotifyVisitToWebHooksTest extends TestCase $this->createListener($webhooks)(new VisitLocated('1')); } - public function provideVisits(): iterable + public static function provideVisits(): iterable { yield 'regular visit' => [ Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()), ['shortUrl', 'visit'], ]; - yield 'orphan visit' => [Visit::forBasePath(Visitor::emptyInstance()), ['visit'],]; + yield 'orphan visit' => [Visit::forBasePath(Visitor::emptyInstance()), ['visit']]; } private function createListener(array $webhooks, bool $notifyOrphanVisits = true): NotifyVisitToWebHooks diff --git a/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php b/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php index 924996f9..d77fc52a 100644 --- a/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php +++ b/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php @@ -77,7 +77,7 @@ class PublishingUpdatesGeneratorTest extends TestCase ], $update->payload); } - public function provideMethod(): iterable + public static function provideMethod(): iterable { yield 'newVisitUpdate' => ['newVisitUpdate', 'https://shlink.io/new-visit', 'the cool title']; yield 'newShortUrlVisitUpdate' => ['newShortUrlVisitUpdate', 'https://shlink.io/new-visit/foo', null]; @@ -105,7 +105,7 @@ class PublishingUpdatesGeneratorTest extends TestCase ], $update->payload); } - public function provideOrphanVisits(): iterable + public static function provideOrphanVisits(): iterable { $visitor = Visitor::emptyInstance(); diff --git a/module/Core/test/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMqTest.php b/module/Core/test/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMqTest.php index 52e9630d..3aec06f7 100644 --- a/module/Core/test/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMqTest.php +++ b/module/Core/test/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMqTest.php @@ -102,7 +102,7 @@ class NotifyNewShortUrlToRabbitMqTest extends TestCase ($this->listener())(new ShortUrlCreated($shortUrlId)); } - public function provideExceptions(): iterable + public static function provideExceptions(): iterable { yield [new RuntimeException('RuntimeException Error')]; yield [new Exception('Exception Error')]; diff --git a/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php b/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php index 6211ad2b..b851a725 100644 --- a/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php +++ b/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php @@ -91,7 +91,7 @@ class NotifyVisitToRabbitMqTest extends TestCase ($this->listener())(new VisitLocated($visitId)); } - public function provideVisits(): iterable + public static function provideVisits(): iterable { $visitor = Visitor::emptyInstance(); @@ -130,7 +130,7 @@ class NotifyVisitToRabbitMqTest extends TestCase ($this->listener())(new VisitLocated($visitId)); } - public function provideExceptions(): iterable + public static function provideExceptions(): iterable { yield [new RuntimeException('RuntimeException Error')]; yield [new Exception('Exception Error')]; @@ -155,14 +155,14 @@ class NotifyVisitToRabbitMqTest extends TestCase ($this->listener(new RabbitMqOptions(true, $legacy)))(new VisitLocated($visitId)); } - public function provideLegacyPayloads(): iterable + public static function provideLegacyPayloads(): iterable { yield 'legacy non-orphan visit' => [ true, $visit = Visit::forValidShortUrl(ShortUrl::withLongUrl('longUrl'), Visitor::emptyInstance()), noop(...), function (MockObject & PublishingHelperInterface $helper) use ($visit): void { - $helper->method('publishUpdate')->with($this->callback(function (Update $update) use ($visit): bool { + $helper->method('publishUpdate')->with(self::callback(function (Update $update) use ($visit): bool { $payload = $update->payload; Assert::assertEquals($payload, $visit->jsonSerialize()); Assert::assertArrayNotHasKey('visitedUrl', $payload); @@ -179,7 +179,7 @@ class NotifyVisitToRabbitMqTest extends TestCase Visit::forBasePath(Visitor::emptyInstance()), noop(...), function (MockObject & PublishingHelperInterface $helper): void { - $helper->method('publishUpdate')->with($this->callback(function (Update $update): bool { + $helper->method('publishUpdate')->with(self::callback(function (Update $update): bool { $payload = $update->payload; Assert::assertArrayHasKey('visitedUrl', $payload); Assert::assertArrayHasKey('type', $payload); @@ -193,14 +193,14 @@ class NotifyVisitToRabbitMqTest extends TestCase Visit::forValidShortUrl(ShortUrl::withLongUrl('longUrl'), Visitor::emptyInstance()), function (MockObject & PublishingUpdatesGeneratorInterface $updatesGenerator): void { $update = Update::forTopicAndPayload('', []); - $updatesGenerator->expects($this->never())->method('newOrphanVisitUpdate'); - $updatesGenerator->expects($this->once())->method('newVisitUpdate')->withAnyParameters()->willReturn( + $updatesGenerator->expects(self::never())->method('newOrphanVisitUpdate'); + $updatesGenerator->expects(self::once())->method('newVisitUpdate')->withAnyParameters()->willReturn( $update, ); - $updatesGenerator->expects($this->once())->method('newShortUrlVisitUpdate')->willReturn($update); + $updatesGenerator->expects(self::once())->method('newShortUrlVisitUpdate')->willReturn($update); }, function (MockObject & PublishingHelperInterface $helper): void { - $helper->expects($this->exactly(2))->method('publishUpdate')->with($this->isInstanceOf(Update::class)); + $helper->expects(self::exactly(2))->method('publishUpdate')->with(self::isInstanceOf(Update::class)); }, ]; yield 'non-legacy orphan visit' => [ @@ -208,12 +208,12 @@ class NotifyVisitToRabbitMqTest extends TestCase Visit::forBasePath(Visitor::emptyInstance()), function (MockObject & PublishingUpdatesGeneratorInterface $updatesGenerator): void { $update = Update::forTopicAndPayload('', []); - $updatesGenerator->expects($this->once())->method('newOrphanVisitUpdate')->willReturn($update); - $updatesGenerator->expects($this->never())->method('newVisitUpdate'); - $updatesGenerator->expects($this->never())->method('newShortUrlVisitUpdate'); + $updatesGenerator->expects(self::once())->method('newOrphanVisitUpdate')->willReturn($update); + $updatesGenerator->expects(self::never())->method('newVisitUpdate'); + $updatesGenerator->expects(self::never())->method('newShortUrlVisitUpdate'); }, function (MockObject & PublishingHelperInterface $helper): void { - $helper->expects($this->once())->method('publishUpdate')->with($this->isInstanceOf(Update::class)); + $helper->expects(self::once())->method('publishUpdate')->with(self::isInstanceOf(Update::class)); }, ]; } diff --git a/module/Core/test/EventDispatcher/RedisPubSub/NotifyNewShortUrlToRedisTest.php b/module/Core/test/EventDispatcher/RedisPubSub/NotifyNewShortUrlToRedisTest.php index a913de15..2b9300a1 100644 --- a/module/Core/test/EventDispatcher/RedisPubSub/NotifyNewShortUrlToRedisTest.php +++ b/module/Core/test/EventDispatcher/RedisPubSub/NotifyNewShortUrlToRedisTest.php @@ -69,7 +69,7 @@ class NotifyNewShortUrlToRedisTest extends TestCase $this->createListener()(new ShortUrlCreated($shortUrlId)); } - public function provideExceptions(): iterable + public static function provideExceptions(): iterable { yield [new RuntimeException('RuntimeException Error')]; yield [new Exception('Exception Error')]; diff --git a/module/Core/test/EventDispatcher/RedisPubSub/NotifyVisitToRedisTest.php b/module/Core/test/EventDispatcher/RedisPubSub/NotifyVisitToRedisTest.php index f50cf906..2562c9de 100644 --- a/module/Core/test/EventDispatcher/RedisPubSub/NotifyVisitToRedisTest.php +++ b/module/Core/test/EventDispatcher/RedisPubSub/NotifyVisitToRedisTest.php @@ -68,7 +68,7 @@ class NotifyVisitToRedisTest extends TestCase $this->createListener()(new VisitLocated($visitId)); } - public function provideExceptions(): iterable + public static function provideExceptions(): iterable { yield [new RuntimeException('RuntimeException Error')]; yield [new Exception('Exception Error')]; diff --git a/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php b/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php index 5b496123..174bc21a 100644 --- a/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php +++ b/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php @@ -67,7 +67,7 @@ class UpdateGeoLiteDbTest extends TestCase ($this->listener)(); } - public function provideFlags(): iterable + public static function provideFlags(): iterable { yield 'existing old db' => [true, 'Updating GeoLite2 db file...']; yield 'not existing old db' => [false, 'Downloading GeoLite2 db file...']; @@ -101,7 +101,7 @@ class UpdateGeoLiteDbTest extends TestCase ($this->listener)(); } - public function provideDownloaded(): iterable + public static function provideDownloaded(): iterable { yield [100, 0, true, null]; yield [100, 0, false, null]; @@ -129,7 +129,7 @@ class UpdateGeoLiteDbTest extends TestCase ($this->listener)(); } - public function provideGeolocationResults(): iterable + public static function provideGeolocationResults(): iterable { return map(GeolocationResult::cases(), static fn (GeolocationResult $value) => [ $value, diff --git a/module/Core/test/Exception/DeleteShortUrlExceptionTest.php b/module/Core/test/Exception/DeleteShortUrlExceptionTest.php index bfdce269..bc6d073d 100644 --- a/module/Core/test/Exception/DeleteShortUrlExceptionTest.php +++ b/module/Core/test/Exception/DeleteShortUrlExceptionTest.php @@ -41,7 +41,7 @@ class DeleteShortUrlExceptionTest extends TestCase self::assertEquals(422, $e->getStatus()); } - public function provideThresholds(): array + public static function provideThresholds(): array { return map(range(5, 50, 5), function (int $number) { return [$number, $shortCode = generateRandomShortCode(6), sprintf( diff --git a/module/Core/test/Exception/ForbiddenTagOperationExceptionTest.php b/module/Core/test/Exception/ForbiddenTagOperationExceptionTest.php index b064cf91..1f26a92a 100644 --- a/module/Core/test/Exception/ForbiddenTagOperationExceptionTest.php +++ b/module/Core/test/Exception/ForbiddenTagOperationExceptionTest.php @@ -29,7 +29,7 @@ class ForbiddenTagOperationExceptionTest extends TestCase self::assertEquals(403, $e->getStatus()); } - public function provideExceptions(): iterable + public static function provideExceptions(): iterable { yield 'deletion' => [ForbiddenTagOperationException::forDeletion(), 'You are not allowed to delete tags']; yield 'renaming' => [ForbiddenTagOperationException::forRenaming(), 'You are not allowed to rename tags']; diff --git a/module/Core/test/Exception/InvalidUrlExceptionTest.php b/module/Core/test/Exception/InvalidUrlExceptionTest.php index e9b0d75a..a3ad8e21 100644 --- a/module/Core/test/Exception/InvalidUrlExceptionTest.php +++ b/module/Core/test/Exception/InvalidUrlExceptionTest.php @@ -34,7 +34,7 @@ class InvalidUrlExceptionTest extends TestCase self::assertEquals($prev, $e->getPrevious()); } - public function providePrevious(): iterable + public static function providePrevious(): iterable { yield 'null previous' => [null]; yield 'instance previous' => [new Exception('Previous error', 10)]; diff --git a/module/Core/test/Exception/IpCannotBeLocatedExceptionTest.php b/module/Core/test/Exception/IpCannotBeLocatedExceptionTest.php index 2089daba..aafd55e2 100644 --- a/module/Core/test/Exception/IpCannotBeLocatedExceptionTest.php +++ b/module/Core/test/Exception/IpCannotBeLocatedExceptionTest.php @@ -53,7 +53,7 @@ class IpCannotBeLocatedExceptionTest extends TestCase self::assertEquals(UnlocatableIpType::ERROR, $e->type); } - public function provideErrors(): iterable + public static function provideErrors(): iterable { yield 'Simple exception with positive code' => [new Exception('Some message', 100)]; yield 'Runtime exception with negative code' => [new RuntimeException('Something went wrong', -50)]; diff --git a/module/Core/test/Exception/NonUniqueSlugExceptionTest.php b/module/Core/test/Exception/NonUniqueSlugExceptionTest.php index 77a71df3..d6eb4b31 100644 --- a/module/Core/test/Exception/NonUniqueSlugExceptionTest.php +++ b/module/Core/test/Exception/NonUniqueSlugExceptionTest.php @@ -30,7 +30,7 @@ class NonUniqueSlugExceptionTest extends TestCase self::assertEquals($expectedAdditional, $e->getAdditionalData()); } - public function provideMessages(): iterable + public static function provideMessages(): iterable { yield 'without domain' => [ 'Provided slug "foo" is already in use.', diff --git a/module/Core/test/Exception/ShortUrlNotFoundExceptionTest.php b/module/Core/test/Exception/ShortUrlNotFoundExceptionTest.php index 9557044b..4a00d97c 100644 --- a/module/Core/test/Exception/ShortUrlNotFoundExceptionTest.php +++ b/module/Core/test/Exception/ShortUrlNotFoundExceptionTest.php @@ -34,7 +34,7 @@ class ShortUrlNotFoundExceptionTest extends TestCase self::assertEquals($expectedAdditional, $e->getAdditionalData()); } - public function provideMessages(): iterable + public static function provideMessages(): iterable { yield 'without domain' => [ 'No URL found with short code "abc123"', diff --git a/module/Core/test/Exception/ValidationExceptionTest.php b/module/Core/test/Exception/ValidationExceptionTest.php index b34badf3..bdee7373 100644 --- a/module/Core/test/Exception/ValidationExceptionTest.php +++ b/module/Core/test/Exception/ValidationExceptionTest.php @@ -46,7 +46,7 @@ class ValidationExceptionTest extends TestCase self::assertStringContainsString($expectedStringRepresentation, (string) $e); } - public function provideExceptions(): iterable + public static function provideExceptions(): iterable { return [[null], [new RuntimeException()], [new LogicException()]]; } diff --git a/module/Core/test/Functions/FunctionsTest.php b/module/Core/test/Functions/FunctionsTest.php index ad45812f..db645562 100644 --- a/module/Core/test/Functions/FunctionsTest.php +++ b/module/Core/test/Functions/FunctionsTest.php @@ -26,7 +26,7 @@ class FunctionsTest extends TestCase self::assertEquals($expectedValues, enumValues($enum)); } - public function provideEnums(): iterable + public static function provideEnums(): iterable { yield EnvVars::class => [EnvVars::class, map(EnvVars::cases(), static fn (EnvVars $envVar) => $envVar->value)]; yield VisitType::class => [ diff --git a/module/Core/test/Importer/ImportedLinksProcessorTest.php b/module/Core/test/Importer/ImportedLinksProcessorTest.php index f1b2f3bb..47188a9b 100644 --- a/module/Core/test/Importer/ImportedLinksProcessorTest.php +++ b/module/Core/test/Importer/ImportedLinksProcessorTest.php @@ -188,7 +188,7 @@ class ImportedLinksProcessorTest extends TestCase $this->processor->process($this->io, ImportResult::withShortUrls([$importedUrl]), $this->buildParams()); } - public function provideUrlsWithVisits(): iterable + public static function provideUrlsWithVisits(): iterable { $now = Chronos::now(); $createImportedUrl = static fn (array $visits) => @@ -262,7 +262,7 @@ class ImportedLinksProcessorTest extends TestCase ); } - public function provideOrphanVisits(): iterable + public static function provideOrphanVisits(): iterable { yield 'import orphan disable without visits' => [false, [], null, 0]; yield 'import orphan enabled without visits' => [true, [], null, 0]; diff --git a/module/Core/test/ShortUrl/Entity/ShortUrlTest.php b/module/Core/test/ShortUrl/Entity/ShortUrlTest.php index 8b40baca..36ff3a4e 100644 --- a/module/Core/test/ShortUrl/Entity/ShortUrlTest.php +++ b/module/Core/test/ShortUrl/Entity/ShortUrlTest.php @@ -41,7 +41,7 @@ class ShortUrlTest extends TestCase $shortUrl->regenerateShortCode(ShortUrlMode::STRICT); } - public function provideInvalidShortUrls(): iterable + public static function provideInvalidShortUrls(): iterable { yield 'with custom slug' => [ ShortUrl::create(ShortUrlCreation::fromRawData(['customSlug' => 'custom-slug', 'longUrl' => 'longUrl'])), @@ -68,7 +68,7 @@ class ShortUrlTest extends TestCase self::assertNotEquals($firstShortCode, $secondShortCode); } - public function provideValidShortUrls(): iterable + public static function provideValidShortUrls(): iterable { yield 'no custom slug' => [ShortUrl::createFake()]; yield 'imported with custom slug' => [ShortUrl::fromImport( @@ -90,7 +90,7 @@ class ShortUrlTest extends TestCase self::assertEquals($expectedLength, strlen($shortUrl->getShortCode())); } - public function provideLengths(): iterable + public static function provideLengths(): iterable { yield [null, DEFAULT_SHORT_CODES_LENGTH]; yield from map(range(4, 10), fn (int $value) => [$value, $value]); diff --git a/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php b/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php index ae0d9363..758efe0e 100644 --- a/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php +++ b/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php @@ -55,7 +55,7 @@ class ShortCodeUniquenessHelperTest extends TestCase self::assertTrue($result); } - public function provideDomains(): iterable + public static function provideDomains(): iterable { yield 'no domain' => [null, null]; yield 'domain' => [Domain::withAuthority($authority = 's.test'), $authority]; diff --git a/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php b/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php index 341ff6bf..ecea4437 100644 --- a/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php +++ b/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php @@ -50,7 +50,7 @@ class ShortUrlRedirectionBuilderTest extends TestCase self::assertEquals($expectedUrl, $result); } - public function provideData(): iterable + public static function provideData(): iterable { $request = static fn (array $query = []) => ServerRequestFactory::fromGlobals()->withQueryParams($query); diff --git a/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php b/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php index fc8c7579..c2996a1c 100644 --- a/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php +++ b/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php @@ -26,7 +26,7 @@ class ShortUrlStringifierTest extends TestCase self::assertEquals($expected, $stringifier->stringify($shortUrl)); } - public function provideConfigAndShortUrls(): iterable + public static function provideConfigAndShortUrls(): iterable { $shortUrlWithShortCode = fn (string $shortCode, ?string $domain = null) => ShortUrl::create( ShortUrlCreation::fromRawData([ diff --git a/module/Core/test/ShortUrl/Helper/ShortUrlTitleResolutionHelperTest.php b/module/Core/test/ShortUrl/Helper/ShortUrlTitleResolutionHelperTest.php index 2d48b294..da9014ca 100644 --- a/module/Core/test/ShortUrl/Helper/ShortUrlTitleResolutionHelperTest.php +++ b/module/Core/test/ShortUrl/Helper/ShortUrlTitleResolutionHelperTest.php @@ -42,7 +42,7 @@ class ShortUrlTitleResolutionHelperTest extends TestCase ); } - public function provideTitles(): iterable + public static function provideTitles(): iterable { yield 'no title' => [null, 1, 0]; yield 'title' => ['link title', 0, 1]; diff --git a/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php b/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php index c157403e..cc16cdb8 100644 --- a/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php +++ b/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php @@ -12,7 +12,6 @@ use Mezzio\Router\RouteResult; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ServerRequestInterface; -use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use Shlinkio\Shlink\Core\Action\RedirectAction; use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; @@ -26,6 +25,7 @@ use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface; use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface; use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface; +use function Laminas\Stratigility\middleware; use function str_starts_with; class ExtraPathRedirectMiddlewareTest extends TestCase @@ -68,7 +68,7 @@ class ExtraPathRedirectMiddlewareTest extends TestCase $this->middleware($options)->process($request, $this->handler); } - public function provideNonRedirectingRequests(): iterable + public static function provideNonRedirectingRequests(): iterable { $baseReq = ServerRequestFactory::fromGlobals(); $buildReq = static fn (?NotFoundType $type): ServerRequestInterface => @@ -84,7 +84,8 @@ class ExtraPathRedirectMiddlewareTest extends TestCase RouteResult::class, RouteResult::fromRoute(new Route( '/foo', - $this->createMock(MiddlewareInterface::class), + middleware(function (): void { + }), ['GET'], RedirectAction::class, )), @@ -170,7 +171,7 @@ class ExtraPathRedirectMiddlewareTest extends TestCase $this->middleware($options)->process($request, $this->handler); } - public function provideResolves(): iterable + public static function provideResolves(): iterable { yield [false, 1, '/bar/baz']; yield [true, 3, null]; diff --git a/module/Core/test/ShortUrl/Middleware/TrimTrailingSlashMiddlewareTest.php b/module/Core/test/ShortUrl/Middleware/TrimTrailingSlashMiddlewareTest.php index eb078902..1f1835ad 100644 --- a/module/Core/test/ShortUrl/Middleware/TrimTrailingSlashMiddlewareTest.php +++ b/module/Core/test/ShortUrl/Middleware/TrimTrailingSlashMiddlewareTest.php @@ -43,7 +43,7 @@ class TrimTrailingSlashMiddlewareTest extends TestCase $this->middleware($trailingSlashEnabled)->process($inputRequest, $this->requestHandler); } - public function provideRequests(): iterable + public static function provideRequests(): iterable { yield 'trailing slash disabled' => [ false, diff --git a/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php b/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php index 904dab01..ce39436a 100644 --- a/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php +++ b/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php @@ -31,7 +31,7 @@ class ShortUrlCreationTest extends TestCase ShortUrlCreation::fromRawData($data); } - public function provideInvalidData(): iterable + public static function provideInvalidData(): iterable { yield [[]]; yield [[ @@ -136,7 +136,7 @@ class ShortUrlCreationTest extends TestCase self::assertNull($creation->maxVisits); } - public function provideCustomSlugs(): iterable + public static function provideCustomSlugs(): iterable { yield ['🔥', '🔥']; yield ['🦣 🍅', '🦣-🍅']; @@ -175,7 +175,7 @@ class ShortUrlCreationTest extends TestCase self::assertEquals($expectedTitle, $creation->title); } - public function provideTitles(): iterable + public static function provideTitles(): iterable { yield [null, null]; yield ['foo', 'foo']; @@ -201,7 +201,7 @@ class ShortUrlCreationTest extends TestCase self::assertSame($expectedDomain, $creation->domain); } - public function provideDomains(): iterable + public static function provideDomains(): iterable { yield 'null domain' => [null, null]; yield 'empty domain' => ['', null]; diff --git a/module/Core/test/ShortUrl/Model/ShortUrlEditionTest.php b/module/Core/test/ShortUrl/Model/ShortUrlEditionTest.php index e03bb1ac..af199ef2 100644 --- a/module/Core/test/ShortUrl/Model/ShortUrlEditionTest.php +++ b/module/Core/test/ShortUrl/Model/ShortUrlEditionTest.php @@ -27,7 +27,7 @@ class ShortUrlEditionTest extends TestCase self::assertEquals($expectedDevicesToRemove, $edition->devicesToRemove); } - public function provideDeviceLongUrls(): iterable + public static function provideDeviceLongUrls(): iterable { yield 'null' => [null, [], []]; yield 'empty' => [[], [], []]; diff --git a/module/Core/test/ShortUrl/Model/ShortUrlModeTest.php b/module/Core/test/ShortUrl/Model/ShortUrlModeTest.php index 18aa2d54..3ee82b70 100644 --- a/module/Core/test/ShortUrl/Model/ShortUrlModeTest.php +++ b/module/Core/test/ShortUrl/Model/ShortUrlModeTest.php @@ -18,7 +18,7 @@ class ShortUrlModeTest extends TestCase self::assertSame($expected, ShortUrlMode::tryDeprecated($mode)); } - public function provideModes(): iterable + public static function provideModes(): iterable { yield 'invalid' => ['invalid', null]; yield 'foo' => ['foo', null]; diff --git a/module/Core/test/ShortUrl/Model/Validation/DeviceLongUrlsValidatorTest.php b/module/Core/test/ShortUrl/Model/Validation/DeviceLongUrlsValidatorTest.php index 8bac2f98..bfc7500f 100644 --- a/module/Core/test/ShortUrl/Model/Validation/DeviceLongUrlsValidatorTest.php +++ b/module/Core/test/ShortUrl/Model/Validation/DeviceLongUrlsValidatorTest.php @@ -29,7 +29,7 @@ class DeviceLongUrlsValidatorTest extends TestCase self::assertEquals(['NOT_ARRAY' => 'Provided value is not an array.'], $this->validator->getMessages()); } - public function provideNonArrayValues(): iterable + public static function provideNonArrayValues(): iterable { yield 'int' => [0]; yield 'float' => [100.45]; diff --git a/module/Core/test/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapterTest.php b/module/Core/test/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapterTest.php index 684c1528..17af8dce 100644 --- a/module/Core/test/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapterTest.php +++ b/module/Core/test/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapterTest.php @@ -79,7 +79,7 @@ class ShortUrlRepositoryAdapterTest extends TestCase $adapter->getNbResults(); } - public function provideFilteringArgs(): iterable + public static function provideFilteringArgs(): iterable { yield []; yield ['search']; diff --git a/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php b/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php index fedfd96f..1c9a8214 100644 --- a/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php +++ b/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php @@ -55,7 +55,7 @@ class PersistenceShortUrlRelationResolverTest extends TestCase self::assertEquals($authority, $result->authority); } - public function provideFoundDomains(): iterable + public static function provideFoundDomains(): iterable { $authority = 's.test'; @@ -89,7 +89,7 @@ class PersistenceShortUrlRelationResolverTest extends TestCase self::assertEquals($expectedTags, $result->toArray()); } - public function provideTags(): iterable + public static function provideTags(): iterable { yield 'no duplicated tags' => [['foo', 'bar', 'baz'], [new Tag('foo'), new Tag('bar'), new Tag('baz')]]; yield 'duplicated tags' => [['foo', 'bar', 'bar'], [new Tag('foo'), new Tag('bar')]]; diff --git a/module/Core/test/ShortUrl/Resolver/SimpleShortUrlRelationResolverTest.php b/module/Core/test/ShortUrl/Resolver/SimpleShortUrlRelationResolverTest.php index 443710bb..9c2b5041 100644 --- a/module/Core/test/ShortUrl/Resolver/SimpleShortUrlRelationResolverTest.php +++ b/module/Core/test/ShortUrl/Resolver/SimpleShortUrlRelationResolverTest.php @@ -34,7 +34,7 @@ class SimpleShortUrlRelationResolverTest extends TestCase } } - public function provideDomains(): iterable + public static function provideDomains(): iterable { yield 'empty domain' => [null]; yield 'non-empty domain' => ['domain.com']; diff --git a/module/Core/test/ShortUrl/ShortUrlResolverTest.php b/module/Core/test/ShortUrl/ShortUrlResolverTest.php index 9c42fefb..87391857 100644 --- a/module/Core/test/ShortUrl/ShortUrlResolverTest.php +++ b/module/Core/test/ShortUrl/ShortUrlResolverTest.php @@ -113,7 +113,7 @@ class ShortUrlResolverTest extends TestCase $this->urlResolver->resolveEnabledShortUrl(ShortUrlIdentifier::fromShortCodeAndDomain($shortCode)); } - public function provideDisabledShortUrls(): iterable + public static function provideDisabledShortUrls(): iterable { $now = Chronos::now(); diff --git a/module/Core/test/ShortUrl/ShortUrlServiceTest.php b/module/Core/test/ShortUrl/ShortUrlServiceTest.php index 7851aa9b..104d4ee9 100644 --- a/module/Core/test/ShortUrl/ShortUrlServiceTest.php +++ b/module/Core/test/ShortUrl/ShortUrlServiceTest.php @@ -8,6 +8,7 @@ use Cake\Chronos\Chronos; use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\Rule\InvocationOrder; +use PHPUnit\Framework\MockObject\Rule\InvokedCount; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\Core\Model\DeviceType; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; @@ -93,23 +94,23 @@ class ShortUrlServiceTest extends TestCase self::assertEquals($resolveDeviceLongUrls(), $shortUrl->deviceLongUrls()); } - public function provideShortUrlEdits(): iterable + public static function provideShortUrlEdits(): iterable { - yield 'no long URL' => [$this->never(), ShortUrlEdition::fromRawData([ + yield 'no long URL' => [new InvokedCount(0), ShortUrlEdition::fromRawData([ 'validSince' => Chronos::parse('2017-01-01 00:00:00')->toAtomString(), 'validUntil' => Chronos::parse('2017-01-05 00:00:00')->toAtomString(), 'maxVisits' => 5, ]), null]; - yield 'long URL and API key' => [$this->once(), ShortUrlEdition::fromRawData([ + yield 'long URL and API key' => [new InvokedCount(1), ShortUrlEdition::fromRawData([ 'validSince' => Chronos::parse('2017-01-01 00:00:00')->toAtomString(), 'maxVisits' => 10, 'longUrl' => 'modifiedLongUrl', ]), ApiKey::create()]; - yield 'long URL with validation' => [$this->once(), ShortUrlEdition::fromRawData([ + yield 'long URL with validation' => [new InvokedCount(1), ShortUrlEdition::fromRawData([ 'longUrl' => 'modifiedLongUrl', 'validateUrl' => true, ]), null]; - yield 'device redirects' => [$this->never(), ShortUrlEdition::fromRawData([ + yield 'device redirects' => [new InvokedCount(0), ShortUrlEdition::fromRawData([ 'deviceLongUrls' => [ DeviceType::IOS->value => 'iosLongUrl', DeviceType::ANDROID->value => 'androidLongUrl', diff --git a/module/Core/test/ShortUrl/Transformer/ShortUrlDataTransformerTest.php b/module/Core/test/ShortUrl/Transformer/ShortUrlDataTransformerTest.php index 6159294b..0e38bd11 100644 --- a/module/Core/test/ShortUrl/Transformer/ShortUrlDataTransformerTest.php +++ b/module/Core/test/ShortUrl/Transformer/ShortUrlDataTransformerTest.php @@ -33,7 +33,7 @@ class ShortUrlDataTransformerTest extends TestCase self::assertEquals($expectedMeta, $meta); } - public function provideShortUrls(): iterable + public static function provideShortUrls(): iterable { $maxVisits = random_int(1, 1000); $now = Chronos::now(); diff --git a/module/Core/test/ShortUrl/UrlShortenerTest.php b/module/Core/test/ShortUrl/UrlShortenerTest.php index d59de634..771bac5f 100644 --- a/module/Core/test/ShortUrl/UrlShortenerTest.php +++ b/module/Core/test/ShortUrl/UrlShortenerTest.php @@ -95,7 +95,7 @@ class UrlShortenerTest extends TestCase self::assertSame($expected, $result); } - public function provideExistingShortUrls(): iterable + public static function provideExistingShortUrls(): iterable { $url = 'http://foo.com'; diff --git a/module/Core/test/Tag/TagServiceTest.php b/module/Core/test/Tag/TagServiceTest.php index 069bca20..5db5f53c 100644 --- a/module/Core/test/Tag/TagServiceTest.php +++ b/module/Core/test/Tag/TagServiceTest.php @@ -74,7 +74,7 @@ class TagServiceTest extends TestCase self::assertEquals($expected, $result->getCurrentPageResults()); } - public function provideApiKeysAndSearchTerm(): iterable + public static function provideApiKeysAndSearchTerm(): iterable { yield 'no API key, no filter' => [ null, @@ -156,7 +156,7 @@ class TagServiceTest extends TestCase self::assertEquals($newName, (string) $tag); } - public function provideValidRenames(): iterable + public static function provideValidRenames(): iterable { yield 'same names' => ['foo', 'foo', 1]; yield 'different names names' => ['foo', 'bar', 0]; diff --git a/module/Core/test/Util/ApiKeyHelpersTrait.php b/module/Core/test/Util/ApiKeyHelpersTrait.php index 6624c8dd..fc6af8af 100644 --- a/module/Core/test/Util/ApiKeyHelpersTrait.php +++ b/module/Core/test/Util/ApiKeyHelpersTrait.php @@ -8,7 +8,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; trait ApiKeyHelpersTrait { - public function provideAdminApiKeys(): iterable + public static function provideAdminApiKeys(): iterable { yield 'no API key' => [null]; yield 'admin API key' => [ApiKey::create()]; diff --git a/module/Core/test/Util/DoctrineBatchHelperTest.php b/module/Core/test/Util/DoctrineBatchHelperTest.php index 2fc0f985..b190952b 100644 --- a/module/Core/test/Util/DoctrineBatchHelperTest.php +++ b/module/Core/test/Util/DoctrineBatchHelperTest.php @@ -43,7 +43,7 @@ class DoctrineBatchHelperTest extends TestCase } } - public function provideIterables(): iterable + public static function provideIterables(): iterable { yield [[], 100, 1]; yield [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3, 4]; diff --git a/module/Core/test/Util/RedirectResponseHelperTest.php b/module/Core/test/Util/RedirectResponseHelperTest.php index 0e7ec018..9eb574b9 100644 --- a/module/Core/test/Util/RedirectResponseHelperTest.php +++ b/module/Core/test/Util/RedirectResponseHelperTest.php @@ -33,7 +33,7 @@ class RedirectResponseHelperTest extends TestCase self::assertEquals($expectedCacheControl ?? '', $response->getHeaderLine('Cache-Control')); } - public function provideRedirectConfigs(): iterable + public static function provideRedirectConfigs(): iterable { yield 'status 302' => [302, 20, 302, null]; yield 'status 307' => [307, 20, 307, null]; diff --git a/module/Core/test/Visit/Entity/VisitLocationTest.php b/module/Core/test/Visit/Entity/VisitLocationTest.php index ee9e570d..c7bdec36 100644 --- a/module/Core/test/Visit/Entity/VisitLocationTest.php +++ b/module/Core/test/Visit/Entity/VisitLocationTest.php @@ -22,7 +22,7 @@ class VisitLocationTest extends TestCase self::assertEquals($isEmpty, $location->isEmpty()); } - public function provideArgs(): iterable + public static function provideArgs(): iterable { yield [['', '', '', '', 0.0, 0.0, ''], true]; yield [['', '', '', '', 0.0, 0.0, 'dd'], false]; diff --git a/module/Core/test/Visit/Entity/VisitTest.php b/module/Core/test/Visit/Entity/VisitTest.php index 5ae22005..d4cbe743 100644 --- a/module/Core/test/Visit/Entity/VisitTest.php +++ b/module/Core/test/Visit/Entity/VisitTest.php @@ -29,7 +29,7 @@ class VisitTest extends TestCase ], $visit->jsonSerialize()); } - public function provideUserAgents(): iterable + public static function provideUserAgents(): iterable { yield 'Chrome' => [ 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', @@ -56,7 +56,7 @@ class VisitTest extends TestCase self::assertEquals($expectedAddress, $visit->getRemoteAddr()); } - public function provideAddresses(): iterable + public static function provideAddresses(): iterable { yield 'anonymized null address' => [true, null, null]; yield 'non-anonymized null address' => [false, null, null]; diff --git a/module/Core/test/Visit/Geolocation/VisitLocatorTest.php b/module/Core/test/Visit/Geolocation/VisitLocatorTest.php index ba0d70c4..cd5daac0 100644 --- a/module/Core/test/Visit/Geolocation/VisitLocatorTest.php +++ b/module/Core/test/Visit/Geolocation/VisitLocatorTest.php @@ -72,7 +72,7 @@ class VisitLocatorTest extends TestCase }); } - public function provideMethodNames(): iterable + public static function provideMethodNames(): iterable { yield 'locateUnlocatedVisits' => ['locateUnlocatedVisits', 'findUnlocatedVisits']; yield 'locateVisitsWithEmptyLocation' => ['locateVisitsWithEmptyLocation', 'findVisitsWithEmptyLocation']; @@ -120,7 +120,7 @@ class VisitLocatorTest extends TestCase ); } - public function provideIsNonLocatableAddress(): iterable + public static function provideIsNonLocatableAddress(): iterable { yield 'locateUnlocatedVisits - locatable address' => ['locateUnlocatedVisits', 'findUnlocatedVisits', false]; yield 'locateUnlocatedVisits - non-locatable address' => ['locateUnlocatedVisits', 'findUnlocatedVisits', true]; diff --git a/module/Core/test/Visit/Geolocation/VisitToLocationHelperTest.php b/module/Core/test/Visit/Geolocation/VisitToLocationHelperTest.php index 7d0fb7f1..cbcebeba 100644 --- a/module/Core/test/Visit/Geolocation/VisitToLocationHelperTest.php +++ b/module/Core/test/Visit/Geolocation/VisitToLocationHelperTest.php @@ -39,7 +39,7 @@ class VisitToLocationHelperTest extends TestCase $this->helper->resolveVisitLocation($visit); } - public function provideNonLocatableVisits(): iterable + public static function provideNonLocatableVisits(): iterable { yield [Visit::forBasePath(Visitor::emptyInstance()), IpCannotBeLocatedException::forEmptyAddress()]; yield [ diff --git a/module/Core/test/Visit/Model/VisitorTest.php b/module/Core/test/Visit/Model/VisitorTest.php index 90d238a5..9cde5c44 100644 --- a/module/Core/test/Visit/Model/VisitorTest.php +++ b/module/Core/test/Visit/Model/VisitorTest.php @@ -29,7 +29,7 @@ class VisitorTest extends TestCase self::assertEquals($remoteAddress, $visitor->remoteAddress); } - public function provideParams(): iterable + public static function provideParams(): iterable { yield 'all values are bigger' => [ [str_repeat('a', 1000), str_repeat('b', 2000), str_repeat('c', 500), ''], @@ -49,8 +49,8 @@ class VisitorTest extends TestCase ]; yield 'random strings' => [ [ - $userAgent = $this->generateRandomString(2000), - $referer = $this->generateRandomString(50), + $userAgent = self::generateRandomString(2000), + $referer = self::generateRandomString(50), null, '', ], @@ -62,7 +62,7 @@ class VisitorTest extends TestCase ]; } - private function generateRandomString(int $length): string + private static function generateRandomString(int $length): string { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); @@ -77,10 +77,10 @@ class VisitorTest extends TestCase public function newNormalizedInstanceIsCreatedFromTrackingOptions(): void { $visitor = new Visitor( - $this->generateRandomString(2000), - $this->generateRandomString(2000), - $this->generateRandomString(2000), - $this->generateRandomString(2000), + self::generateRandomString(2000), + self::generateRandomString(2000), + self::generateRandomString(2000), + self::generateRandomString(2000), ); $normalizedVisitor = $visitor->normalizeForTrackingOptions(new TrackingOptions( disableIpTracking: true, diff --git a/module/Core/test/Visit/Paginator/Adapter/NonOrphanVisitsPaginatorAdapterTest.php b/module/Core/test/Visit/Paginator/Adapter/NonOrphanVisitsPaginatorAdapterTest.php index ec256eeb..11d526e6 100644 --- a/module/Core/test/Visit/Paginator/Adapter/NonOrphanVisitsPaginatorAdapterTest.php +++ b/module/Core/test/Visit/Paginator/Adapter/NonOrphanVisitsPaginatorAdapterTest.php @@ -67,7 +67,7 @@ class NonOrphanVisitsPaginatorAdapterTest extends TestCase self::assertEquals($list, $result); } - public function provideLimitAndOffset(): iterable + public static function provideLimitAndOffset(): iterable { yield [1, 5]; yield [10, 4]; diff --git a/module/Core/test/Visit/Paginator/Adapter/OrphanVisitsPaginatorAdapterTest.php b/module/Core/test/Visit/Paginator/Adapter/OrphanVisitsPaginatorAdapterTest.php index 6b91a20b..e15b9f23 100644 --- a/module/Core/test/Visit/Paginator/Adapter/OrphanVisitsPaginatorAdapterTest.php +++ b/module/Core/test/Visit/Paginator/Adapter/OrphanVisitsPaginatorAdapterTest.php @@ -59,7 +59,7 @@ class OrphanVisitsPaginatorAdapterTest extends TestCase self::assertEquals($list, $result); } - public function provideLimitAndOffset(): iterable + public static function provideLimitAndOffset(): iterable { yield [1, 5]; yield [10, 4]; diff --git a/module/Core/test/Visit/RequestTrackerTest.php b/module/Core/test/Visit/RequestTrackerTest.php index 0e1705ee..5285e967 100644 --- a/module/Core/test/Visit/RequestTrackerTest.php +++ b/module/Core/test/Visit/RequestTrackerTest.php @@ -57,7 +57,7 @@ class RequestTrackerTest extends TestCase $this->requestTracker->trackIfApplicable($shortUrl, $request); } - public function provideNonTrackingRequests(): iterable + public static function provideNonTrackingRequests(): iterable { yield 'forwarded from head' => [ServerRequestFactory::fromGlobals()->withAttribute( ImplicitHeadMiddleware::FORWARDED_HTTP_METHOD_ATTRIBUTE, diff --git a/module/Core/test/Visit/Transformer/OrphanVisitDataTransformerTest.php b/module/Core/test/Visit/Transformer/OrphanVisitDataTransformerTest.php index 2f38a17a..dd1a7e84 100644 --- a/module/Core/test/Visit/Transformer/OrphanVisitDataTransformerTest.php +++ b/module/Core/test/Visit/Transformer/OrphanVisitDataTransformerTest.php @@ -34,7 +34,7 @@ class OrphanVisitDataTransformerTest extends TestCase self::assertEquals($expectedResult, $result); } - public function provideVisits(): iterable + public static function provideVisits(): iterable { yield 'base path visit' => [ $visit = Visit::forBasePath(Visitor::emptyInstance()), diff --git a/module/Core/test/Visit/VisitsStatsHelperTest.php b/module/Core/test/Visit/VisitsStatsHelperTest.php index 0ed06e7d..a89cd0cb 100644 --- a/module/Core/test/Visit/VisitsStatsHelperTest.php +++ b/module/Core/test/Visit/VisitsStatsHelperTest.php @@ -6,6 +6,7 @@ namespace ShlinkioTest\Shlink\Core\Visit; use Doctrine\ORM\EntityManagerInterface; use Laminas\Stdlib\ArrayUtils; +use PHPUnit\Framework\Assert; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\Core\Domain\Entity\Domain; @@ -53,13 +54,17 @@ class VisitsStatsHelperTest extends TestCase public function returnsExpectedVisitsStats(int $expectedCount): void { $repo = $this->createMock(VisitRepository::class); - $repo->expects($this->exactly(2))->method('countNonOrphanVisits')->withConsecutive( - [new VisitsCountFiltering()], - [new VisitsCountFiltering(excludeBots: true)], - )->willReturn($expectedCount * 3); - $repo->expects($this->exactly(2))->method('countOrphanVisits')->withConsecutive( - [$this->isInstanceOf(VisitsCountFiltering::class)], - [$this->isInstanceOf(VisitsCountFiltering::class)], + $callCount = 0; + $repo->expects($this->exactly(2))->method('countNonOrphanVisits')->willReturnCallback( + function (VisitsCountFiltering $options) use ($expectedCount, &$callCount) { + Assert::assertEquals($callCount !== 0, $options->excludeBots); + $callCount++; + + return $expectedCount * 3; + }, + ); + $repo->expects($this->exactly(2))->method('countOrphanVisits')->with( + $this->isInstanceOf(VisitsCountFiltering::class), )->willReturn($expectedCount); $this->em->expects($this->once())->method('getRepository')->with(Visit::class)->willReturn($repo); @@ -68,7 +73,7 @@ class VisitsStatsHelperTest extends TestCase self::assertEquals(new VisitsStats($expectedCount * 3, $expectedCount), $stats); } - public function provideCounts(): iterable + public static function provideCounts(): iterable { return map(range(0, 50, 5), fn (int $value) => [$value]); } diff --git a/module/Core/test/Visit/VisitsTrackerTest.php b/module/Core/test/Visit/VisitsTrackerTest.php index 9c27d5df..a924310a 100644 --- a/module/Core/test/Visit/VisitsTrackerTest.php +++ b/module/Core/test/Visit/VisitsTrackerTest.php @@ -56,7 +56,7 @@ class VisitsTrackerTest extends TestCase $this->visitsTracker(new TrackingOptions(disableTracking: true))->{$method}(...$args); } - public function provideTrackingMethodNames(): iterable + public static function provideTrackingMethodNames(): iterable { yield 'track' => ['track', [ShortUrl::createFake(), Visitor::emptyInstance()]]; yield 'trackInvalidShortUrlVisit' => ['trackInvalidShortUrlVisit', [Visitor::emptyInstance()]]; @@ -77,7 +77,7 @@ class VisitsTrackerTest extends TestCase $this->visitsTracker(new TrackingOptions(trackOrphanVisits: false))->{$method}(Visitor::emptyInstance()); } - public function provideOrphanTrackingMethodNames(): iterable + public static function provideOrphanTrackingMethodNames(): iterable { yield 'trackInvalidShortUrlVisit' => ['trackInvalidShortUrlVisit']; yield 'trackBaseUrlVisit' => ['trackBaseUrlVisit']; diff --git a/module/Rest/test-api/Action/CreateShortUrlTest.php b/module/Rest/test-api/Action/CreateShortUrlTest.php index 0bb02c9e..6422d666 100644 --- a/module/Rest/test-api/Action/CreateShortUrlTest.php +++ b/module/Rest/test-api/Action/CreateShortUrlTest.php @@ -72,7 +72,7 @@ class CreateShortUrlTest extends ApiTestCase self::assertEquals($expectedType, $payload['type']); } - public function provideDuplicatedSlugApiVersions(): iterable + public static function provideDuplicatedSlugApiVersions(): iterable { yield ['1', 'INVALID_SLUG']; yield ['2', 'INVALID_SLUG']; @@ -91,7 +91,7 @@ class CreateShortUrlTest extends ApiTestCase self::assertEquals($expectedTags, $tags); } - public function provideTags(): iterable + public static function provideTags(): iterable { yield 'simple tags' => [$simpleTags = ['foo', 'bar', 'baz'], $simpleTags]; yield 'tags with spaces' => [['fo o', ' bar', 'b az'], ['fo-o', 'bar', 'b-az']]; @@ -116,7 +116,7 @@ class CreateShortUrlTest extends ApiTestCase self::assertEquals(self::STATUS_NOT_FOUND, $lastResp->getStatusCode()); } - public function provideMaxVisits(): array + public static function provideMaxVisits(): array { return map(range(10, 15), fn(int $i) => [$i]); } @@ -165,7 +165,7 @@ class CreateShortUrlTest extends ApiTestCase self::assertEquals($firstShortCode, $secondShortCode); } - public function provideMatchingBodies(): iterable + public static function provideMatchingBodies(): iterable { $longUrl = 'https://www.alejandrocelaya.com'; @@ -202,7 +202,7 @@ class CreateShortUrlTest extends ApiTestCase self::assertEquals(self::STATUS_BAD_REQUEST, $secondStatusCode); } - public function provideConflictingSlugs(): iterable + public static function provideConflictingSlugs(): iterable { yield 'without domain' => ['custom', null]; yield 'with domain' => ['custom-with-domain', 'some-domain.com']; @@ -236,7 +236,7 @@ class CreateShortUrlTest extends ApiTestCase self::assertEquals($payload['longUrl'], $longUrl); } - public function provideIdn(): iterable + public static function provideIdn(): iterable { yield ['http://tést.shlink.io']; // Redirects to https://shlink.io yield ['http://test.shlink.io']; // Redirects to http://tést.shlink.io @@ -261,7 +261,7 @@ class CreateShortUrlTest extends ApiTestCase self::assertEquals($url, $payload['url']); } - public function provideInvalidUrls(): iterable + public static function provideInvalidUrls(): iterable { yield 'API version 2' => ['https://this-has-to-be-invalid.com', '2', 'INVALID_URL']; yield 'API version 3' => ['https://this-has-to-be-invalid.com', '3', 'https://shlink.io/api/error/invalid-url']; @@ -287,7 +287,7 @@ class CreateShortUrlTest extends ApiTestCase self::assertEquals('Invalid data', $payload['title']); } - public function provideInvalidArgumentApiVersions(): iterable + public static function provideInvalidArgumentApiVersions(): iterable { yield 'missing long url v2' => [[], '2', 'INVALID_ARGUMENT']; yield 'missing long url v3' => [[], '3', 'https://shlink.io/api/error/invalid-data']; @@ -338,7 +338,7 @@ class CreateShortUrlTest extends ApiTestCase self::assertEquals('example.com', $returnedDomain); } - public function provideDomains(): iterable + public static function provideDomains(): iterable { yield 'no domain' => [null]; yield 'invalid domain' => ['this-will-be-overwritten.com']; @@ -355,7 +355,7 @@ class CreateShortUrlTest extends ApiTestCase self::assertEquals(self::STATUS_OK, $statusCode); } - public function provideTwitterUrls(): iterable + public static function provideTwitterUrls(): iterable { yield ['https://twitter.com/shlinkio']; yield ['https://mobile.twitter.com/shlinkio']; diff --git a/module/Rest/test-api/Action/DeleteShortUrlTest.php b/module/Rest/test-api/Action/DeleteShortUrlTest.php index f8ba6ef1..9b040d41 100644 --- a/module/Rest/test-api/Action/DeleteShortUrlTest.php +++ b/module/Rest/test-api/Action/DeleteShortUrlTest.php @@ -50,7 +50,7 @@ class DeleteShortUrlTest extends ApiTestCase self::assertEquals($expectedType, $payload['type']); } - public function provideApiVersions(): iterable + public static function provideApiVersions(): iterable { yield ['1', 'INVALID_SHORTCODE']; yield ['2', 'INVALID_SHORTCODE']; diff --git a/module/Rest/test-api/Action/DeleteTagsTest.php b/module/Rest/test-api/Action/DeleteTagsTest.php index c81d7906..c76d8d13 100644 --- a/module/Rest/test-api/Action/DeleteTagsTest.php +++ b/module/Rest/test-api/Action/DeleteTagsTest.php @@ -29,7 +29,7 @@ class DeleteTagsTest extends ApiTestCase self::assertEquals('Forbidden tag operation', $payload['title']); } - public function provideNonAdminApiKeys(): iterable + public static function provideNonAdminApiKeys(): iterable { yield 'author' => ['author_api_key', '2', 'FORBIDDEN_OPERATION']; yield 'domain' => ['domain_api_key', '2', 'FORBIDDEN_OPERATION']; diff --git a/module/Rest/test-api/Action/DomainRedirectsTest.php b/module/Rest/test-api/Action/DomainRedirectsTest.php index 7abd4d5e..ab055267 100644 --- a/module/Rest/test-api/Action/DomainRedirectsTest.php +++ b/module/Rest/test-api/Action/DomainRedirectsTest.php @@ -27,7 +27,7 @@ class DomainRedirectsTest extends ApiTestCase self::assertEquals('Invalid data', $payload['title']); } - public function provideInvalidDomains(): iterable + public static function provideInvalidDomains(): iterable { yield 'no domain' => [[]]; yield 'empty domain' => [['domain' => '']]; @@ -50,7 +50,7 @@ class DomainRedirectsTest extends ApiTestCase self::assertEquals($expectedResponse, $payload); } - public function provideRequests(): iterable + public static function provideRequests(): iterable { yield 'new domain' => [[ 'domain' => 'my-new-domain.com', diff --git a/module/Rest/test-api/Action/DomainVisitsTest.php b/module/Rest/test-api/Action/DomainVisitsTest.php index c6c31ebb..9dc339bd 100644 --- a/module/Rest/test-api/Action/DomainVisitsTest.php +++ b/module/Rest/test-api/Action/DomainVisitsTest.php @@ -32,7 +32,7 @@ class DomainVisitsTest extends ApiTestCase self::assertCount($expectedVisitsAmount, $payload['visits']['data']); } - public function provideDomains(): iterable + public static function provideDomains(): iterable { yield 'example.com with admin API key' => ['valid_api_key', 'example.com', false, 0]; yield 'DEFAULT with admin API key' => ['valid_api_key', 'DEFAULT', false, 7]; @@ -59,7 +59,7 @@ class DomainVisitsTest extends ApiTestCase self::assertEquals($domain, $payload['authority']); } - public function provideApiKeysAndTags(): iterable + public static function provideApiKeysAndTags(): iterable { yield 'admin API key with invalid domain' => ['valid_api_key', 'invalid_domain.com']; yield 'domain API key with not-owned valid domain' => ['domain_api_key', 'this_domain_is_detached.com']; @@ -78,7 +78,7 @@ class DomainVisitsTest extends ApiTestCase self::assertEquals($expectedType, $payload['type']); } - public function provideApiVersions(): iterable + public static function provideApiVersions(): iterable { yield ['1', 'DOMAIN_NOT_FOUND']; yield ['2', 'DOMAIN_NOT_FOUND']; diff --git a/module/Rest/test-api/Action/EditShortUrlTest.php b/module/Rest/test-api/Action/EditShortUrlTest.php index 74fdebc5..63ee2b12 100644 --- a/module/Rest/test-api/Action/EditShortUrlTest.php +++ b/module/Rest/test-api/Action/EditShortUrlTest.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace ShlinkioApiTest\Shlink\Rest\Action; use Cake\Chronos\Chronos; -use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts; use GuzzleHttp\Psr7\Query; use GuzzleHttp\RequestOptions; use Laminas\Diactoros\Uri; @@ -16,7 +15,6 @@ use function sprintf; class EditShortUrlTest extends ApiTestCase { - use ArraySubsetAsserts; use NotFoundUrlHelpersTrait; /** @@ -47,7 +45,14 @@ class EditShortUrlTest extends ApiTestCase self::assertArraySubset($meta, $metaAfterEditing); } - public function provideMeta(): iterable + private static function assertArraySubset(array $a, array $b): void + { + foreach ($a as $key => $expectedValue) { + self::assertEquals($expectedValue, $b[$key]); + } + } + + public static function provideMeta(): iterable { $now = Chronos::now(); @@ -92,7 +97,7 @@ class EditShortUrlTest extends ApiTestCase } } - public function provideLongUrls(): iterable + public static function provideLongUrls(): iterable { yield 'valid URL' => ['https://shlink.io', self::STATUS_OK, null]; yield 'invalid URL' => ['htt:foo', self::STATUS_BAD_REQUEST, 'INVALID_URL']; @@ -162,7 +167,7 @@ class EditShortUrlTest extends ApiTestCase self::assertEquals(100, $editedShortUrl['meta']['maxVisits'] ?? null); } - public function provideDomains(): iterable + public static function provideDomains(): iterable { yield 'domain' => [ 'example.com', diff --git a/module/Rest/test-api/Action/GlobalVisitsTest.php b/module/Rest/test-api/Action/GlobalVisitsTest.php index 1b71f976..775c1869 100644 --- a/module/Rest/test-api/Action/GlobalVisitsTest.php +++ b/module/Rest/test-api/Action/GlobalVisitsTest.php @@ -24,7 +24,7 @@ class GlobalVisitsTest extends ApiTestCase self::assertEquals(3, $payload['visits']['orphanVisitsCount']); } - public function provideApiKeys(): iterable + public static function provideApiKeys(): iterable { yield 'admin API key' => ['valid_api_key', 7]; yield 'domain API key' => ['domain_api_key', 0]; diff --git a/module/Rest/test-api/Action/ListDomainsTest.php b/module/Rest/test-api/Action/ListDomainsTest.php index 42f011c7..00ef789e 100644 --- a/module/Rest/test-api/Action/ListDomainsTest.php +++ b/module/Rest/test-api/Action/ListDomainsTest.php @@ -30,7 +30,7 @@ class ListDomainsTest extends ApiTestCase ], $respPayload); } - public function provideApiKeysAndDomains(): iterable + public static function provideApiKeysAndDomains(): iterable { yield 'admin API key' => ['valid_api_key', [ [ diff --git a/module/Rest/test-api/Action/ListShortUrlsTest.php b/module/Rest/test-api/Action/ListShortUrlsTest.php index 5cddfc50..7bdd2a45 100644 --- a/module/Rest/test-api/Action/ListShortUrlsTest.php +++ b/module/Rest/test-api/Action/ListShortUrlsTest.php @@ -168,7 +168,7 @@ class ListShortUrlsTest extends ApiTestCase ], $respPayload); } - public function provideFilteredLists(): iterable + public static function provideFilteredLists(): iterable { // FIXME Cannot use enums in constants in PHP 8.1. Change this once support for PHP 8.1 is dropped $withDeviceLongUrls = static fn (array $shortUrl, ?array $longUrls = null) => [ @@ -321,7 +321,7 @@ class ListShortUrlsTest extends ApiTestCase ], $respPayload); } - public function provideInvalidFiltering(): iterable + public static function provideInvalidFiltering(): iterable { yield [['tagsMode' => 'invalid'], ['tagsMode']]; yield [['orderBy' => 'invalid'], ['orderBy']]; diff --git a/module/Rest/test-api/Action/ListTagsTest.php b/module/Rest/test-api/Action/ListTagsTest.php index 4c627e7c..47246188 100644 --- a/module/Rest/test-api/Action/ListTagsTest.php +++ b/module/Rest/test-api/Action/ListTagsTest.php @@ -21,7 +21,7 @@ class ListTagsTest extends ApiTestCase self::assertEquals(['tags' => $expectedTags], $payload); } - public function provideQueries(): iterable + public static function provideQueries(): iterable { yield 'admin API key' => ['valid_api_key', [], [ 'data' => ['bar', 'baz', 'foo'], diff --git a/module/Rest/test-api/Action/NonOrphanVisitsTest.php b/module/Rest/test-api/Action/NonOrphanVisitsTest.php index c53e29cc..57df805b 100644 --- a/module/Rest/test-api/Action/NonOrphanVisitsTest.php +++ b/module/Rest/test-api/Action/NonOrphanVisitsTest.php @@ -24,7 +24,7 @@ class NonOrphanVisitsTest extends ApiTestCase self::assertCount($returnedItems, $payload['visits']['data'] ?? []); } - public function provideQueries(): iterable + public static function provideQueries(): iterable { yield 'all data' => [[], 7, 7]; yield 'middle page' => [['page' => 2, 'itemsPerPage' => 3], 7, 3]; diff --git a/module/Rest/test-api/Action/OrphanVisitsTest.php b/module/Rest/test-api/Action/OrphanVisitsTest.php index eee35d73..28823b7b 100644 --- a/module/Rest/test-api/Action/OrphanVisitsTest.php +++ b/module/Rest/test-api/Action/OrphanVisitsTest.php @@ -57,7 +57,7 @@ class OrphanVisitsTest extends ApiTestCase self::assertEquals($expectedVisits, $visits); } - public function provideQueries(): iterable + public static function provideQueries(): iterable { yield 'all data' => [[], 3, 3, [self::INVALID_SHORT_URL, self::REGULAR_NOT_FOUND, self::BASE_URL]]; yield 'limit items' => [['itemsPerPage' => 2], 3, 2, [self::INVALID_SHORT_URL, self::REGULAR_NOT_FOUND]]; diff --git a/module/Rest/test-api/Action/RenameTagTest.php b/module/Rest/test-api/Action/RenameTagTest.php index 7ed4ff4f..7461938f 100644 --- a/module/Rest/test-api/Action/RenameTagTest.php +++ b/module/Rest/test-api/Action/RenameTagTest.php @@ -30,7 +30,7 @@ class RenameTagTest extends ApiTestCase self::assertEquals('Forbidden tag operation', $payload['title']); } - public function provideNonAdminApiKeys(): iterable + public static function provideNonAdminApiKeys(): iterable { yield 'author' => ['author_api_key']; yield 'domain' => ['domain_api_key']; diff --git a/module/Rest/test-api/Action/ResolveShortUrlTest.php b/module/Rest/test-api/Action/ResolveShortUrlTest.php index 216e35e9..7adcdaab 100644 --- a/module/Rest/test-api/Action/ResolveShortUrlTest.php +++ b/module/Rest/test-api/Action/ResolveShortUrlTest.php @@ -34,7 +34,7 @@ class ResolveShortUrlTest extends ApiTestCase self::assertEquals(self::STATUS_OK, $fetchResp->getStatusCode()); } - public function provideDisabledMeta(): iterable + public static function provideDisabledMeta(): iterable { $now = Chronos::now(); diff --git a/module/Rest/test-api/Action/ShortUrlVisitsTest.php b/module/Rest/test-api/Action/ShortUrlVisitsTest.php index a9e571da..003a68bd 100644 --- a/module/Rest/test-api/Action/ShortUrlVisitsTest.php +++ b/module/Rest/test-api/Action/ShortUrlVisitsTest.php @@ -66,7 +66,7 @@ class ShortUrlVisitsTest extends ApiTestCase self::assertCount($expectedAmountOfVisits, $payload['visits']['data'] ?? []); } - public function provideDomains(): iterable + public static function provideDomains(): iterable { yield 'domain' => ['example.com', 0]; yield 'no domain' => [null, 2]; @@ -95,7 +95,7 @@ class ShortUrlVisitsTest extends ApiTestCase self::assertCount($expectedAmountOfVisits, $payload['visits']['data'] ?? []); } - public function provideVisitsForBots(): iterable + public static function provideVisitsForBots(): iterable { yield 'bots excluded' => [true, 1]; yield 'bots not excluded' => [false, 2]; diff --git a/module/Rest/test-api/Action/SingleStepCreateShortUrlTest.php b/module/Rest/test-api/Action/SingleStepCreateShortUrlTest.php index 0c5ab1b4..2db43f63 100644 --- a/module/Rest/test-api/Action/SingleStepCreateShortUrlTest.php +++ b/module/Rest/test-api/Action/SingleStepCreateShortUrlTest.php @@ -22,7 +22,7 @@ class SingleStepCreateShortUrlTest extends ApiTestCase self::assertEquals($expectedContentType, $resp->getHeaderLine('Content-Type')); } - public function provideFormats(): iterable + public static function provideFormats(): iterable { yield 'txt format' => ['txt', 'text/plain']; yield 'json format' => ['json', 'application/json']; diff --git a/module/Rest/test-api/Action/TagVisitsTest.php b/module/Rest/test-api/Action/TagVisitsTest.php index 544fcccf..afb95bac 100644 --- a/module/Rest/test-api/Action/TagVisitsTest.php +++ b/module/Rest/test-api/Action/TagVisitsTest.php @@ -32,7 +32,7 @@ class TagVisitsTest extends ApiTestCase self::assertCount($expectedVisitsAmount, $payload['visits']['data']); } - public function provideTags(): iterable + public static function provideTags(): iterable { yield 'foo with admin API key' => ['valid_api_key', 'foo', false, 5]; yield 'foo with admin API key and no bots' => ['valid_api_key', 'foo', true, 4]; @@ -62,7 +62,7 @@ class TagVisitsTest extends ApiTestCase self::assertEquals('Tag not found', $payload['title']); } - public function provideApiKeysAndTags(): iterable + public static function provideApiKeysAndTags(): iterable { yield 'admin API key with invalid tag' => ['valid_api_key', 'invalid_tag']; yield 'domain API key with valid tag not used' => ['domain_api_key', 'bar']; diff --git a/module/Rest/test-api/Action/TagsStatsTest.php b/module/Rest/test-api/Action/TagsStatsTest.php index 573f1c38..c388e18f 100644 --- a/module/Rest/test-api/Action/TagsStatsTest.php +++ b/module/Rest/test-api/Action/TagsStatsTest.php @@ -45,7 +45,7 @@ class TagsStatsTest extends ApiTestCase self::assertArrayHasKey('data', $tags); } - public function provideQueries(): iterable + public static function provideQueries(): iterable { yield 'admin API key' => ['valid_api_key', [], [ [ diff --git a/module/Rest/test-api/Action/UpdateTagTest.php b/module/Rest/test-api/Action/UpdateTagTest.php index 414e7670..5625898e 100644 --- a/module/Rest/test-api/Action/UpdateTagTest.php +++ b/module/Rest/test-api/Action/UpdateTagTest.php @@ -29,7 +29,7 @@ class UpdateTagTest extends ApiTestCase self::assertEquals('Invalid data', $payload['title']); } - public function provideInvalidBody(): iterable + public static function provideInvalidBody(): iterable { yield [[]]; yield [['oldName' => 'foo']]; @@ -57,7 +57,7 @@ class UpdateTagTest extends ApiTestCase self::assertEquals('Tag not found', $payload['title']); } - public function provideTagNotFoundApiVersions(): iterable + public static function provideTagNotFoundApiVersions(): iterable { yield 'version 1' => ['1', 'TAG_NOT_FOUND']; yield 'version 2' => ['2', 'TAG_NOT_FOUND']; @@ -85,7 +85,7 @@ class UpdateTagTest extends ApiTestCase self::assertEquals('Tag conflict', $payload['title']); } - public function provideTagConflictsApiVersions(): iterable + public static function provideTagConflictsApiVersions(): iterable { yield 'version 1' => ['1', 'TAG_CONFLICT']; yield 'version 2' => ['2', 'TAG_CONFLICT']; diff --git a/module/Rest/test-api/Action/VisitStatsTest.php b/module/Rest/test-api/Action/VisitStatsTest.php index 424eba73..8ecd2833 100644 --- a/module/Rest/test-api/Action/VisitStatsTest.php +++ b/module/Rest/test-api/Action/VisitStatsTest.php @@ -20,7 +20,7 @@ class VisitStatsTest extends ApiTestCase self::assertEquals(['visits' => $expectedPayload], $payload); } - public function provideApiKeysAndResults(): iterable + public static function provideApiKeysAndResults(): iterable { yield 'valid API key' => ['valid_api_key', [ 'nonOrphanVisits' => [ diff --git a/module/Rest/test-api/Middleware/AuthenticationTest.php b/module/Rest/test-api/Middleware/AuthenticationTest.php index 51128079..be85965b 100644 --- a/module/Rest/test-api/Middleware/AuthenticationTest.php +++ b/module/Rest/test-api/Middleware/AuthenticationTest.php @@ -28,7 +28,7 @@ class AuthenticationTest extends ApiTestCase self::assertEquals('Invalid authorization', $payload['title']); } - public function provideApiVersions(): iterable + public static function provideApiVersions(): iterable { yield 'version 1' => ['1', 'INVALID_AUTHORIZATION']; yield 'version 2' => ['2', 'INVALID_AUTHORIZATION']; @@ -60,7 +60,7 @@ class AuthenticationTest extends ApiTestCase self::assertEquals('Invalid API key', $payload['title']); } - public function provideInvalidApiKeys(): iterable + public static function provideInvalidApiKeys(): iterable { yield 'key which does not exist' => ['invalid', '2', 'INVALID_API_KEY']; yield 'key which is expired' => ['expired_api_key', '2', 'INVALID_API_KEY']; diff --git a/module/Rest/test-api/Middleware/CorsTest.php b/module/Rest/test-api/Middleware/CorsTest.php index b09e2b3b..d913d7ec 100644 --- a/module/Rest/test-api/Middleware/CorsTest.php +++ b/module/Rest/test-api/Middleware/CorsTest.php @@ -41,7 +41,7 @@ class CorsTest extends ApiTestCase self::assertFalse($resp->hasHeader('Access-Control-Allow-Headers')); } - public function provideOrigins(): iterable + public static function provideOrigins(): iterable { yield 'foo.com' => ['foo.com', '/short-urls', 200]; yield 'bar.io' => ['bar.io', '/foo/bar', 404]; @@ -69,7 +69,7 @@ class CorsTest extends ApiTestCase self::assertEquals($allowedHeaders, $resp->getHeaderLine('Access-Control-Allow-Headers')); } - public function providePreflightEndpoints(): iterable + public static function providePreflightEndpoints(): iterable { yield 'invalid route' => ['/foo/bar', 'GET,POST,PUT,PATCH,DELETE']; // TODO This won't work with multi-segment yield 'short URLs route' => ['/short-urls', 'GET,POST']; diff --git a/module/Rest/test-api/Utils/NotFoundUrlHelpersTrait.php b/module/Rest/test-api/Utils/NotFoundUrlHelpersTrait.php index 1c415208..9645f707 100644 --- a/module/Rest/test-api/Utils/NotFoundUrlHelpersTrait.php +++ b/module/Rest/test-api/Utils/NotFoundUrlHelpersTrait.php @@ -11,7 +11,7 @@ use function sprintf; trait NotFoundUrlHelpersTrait { - public function provideInvalidUrls(): iterable + public static function provideInvalidUrls(): iterable { yield 'invalid shortcode' => ['invalid', null, 'No URL found with short code "invalid"', 'valid_api_key']; yield 'invalid shortcode without domain' => [ diff --git a/module/Rest/test/Action/Domain/DomainRedirectsActionTest.php b/module/Rest/test/Action/Domain/DomainRedirectsActionTest.php index df5fed43..3027a0c2 100644 --- a/module/Rest/test/Action/Domain/DomainRedirectsActionTest.php +++ b/module/Rest/test/Action/Domain/DomainRedirectsActionTest.php @@ -44,7 +44,7 @@ class DomainRedirectsActionTest extends TestCase $this->action->handle($request); } - public function provideInvalidBodies(): iterable + public static function provideInvalidBodies(): iterable { yield 'no domain' => [[]]; yield 'empty domain' => [['domain' => '']]; @@ -91,7 +91,7 @@ class DomainRedirectsActionTest extends TestCase self::assertEquals($expectedResult, $payload->jsonSerialize()); } - public function provideDomainsAndRedirects(): iterable + public static function provideDomainsAndRedirects(): iterable { yield 'full overwrite' => [Domain::withAuthority(''), [ DomainRedirectsInputFilter::BASE_URL_REDIRECT => 'foo', diff --git a/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php b/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php index 51509047..05f7af55 100644 --- a/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php +++ b/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php @@ -22,7 +22,7 @@ class DomainRedirectsRequestTest extends TestCase DomainRedirectsRequest::fromRawData($data); } - public function provideInvalidData(): iterable + public static function provideInvalidData(): iterable { yield 'missing domain' => [[]]; yield 'invalid domain' => [['domain' => 'foo:bar:baz']]; @@ -49,7 +49,7 @@ class DomainRedirectsRequestTest extends TestCase self::assertEquals($expectedInvalidShortUrlRedirect, $notFound->invalidShortUrlRedirect); } - public function provideValidData(): iterable + public static function provideValidData(): iterable { yield 'no values' => [['domain' => 'foo'], null, 'foo', null, null, null]; yield 'some values' => [['domain' => 'foo', 'regular404Redirect' => 'bar'], null, 'foo', null, 'bar', null]; diff --git a/module/Rest/test/Action/MercureInfoActionTest.php b/module/Rest/test/Action/MercureInfoActionTest.php index ada836c1..ebc1eb24 100644 --- a/module/Rest/test/Action/MercureInfoActionTest.php +++ b/module/Rest/test/Action/MercureInfoActionTest.php @@ -37,7 +37,7 @@ class MercureInfoActionTest extends TestCase $action->handle(ServerRequestFactory::fromGlobals()); } - public function provideNoHostConfigs(): iterable + public static function provideNoHostConfigs(): iterable { yield 'host not defined' => [[]]; yield 'host is null' => [['public_hub_url' => null]]; @@ -76,7 +76,7 @@ class MercureInfoActionTest extends TestCase ); } - public function provideDays(): iterable + public static function provideDays(): iterable { yield 'days not defined' => [null]; yield 'days defined' => [10]; diff --git a/module/Rest/test/Action/ShortUrl/CreateShortUrlActionTest.php b/module/Rest/test/Action/ShortUrl/CreateShortUrlActionTest.php index 15ce5389..bc09a570 100644 --- a/module/Rest/test/Action/ShortUrl/CreateShortUrlActionTest.php +++ b/module/Rest/test/Action/ShortUrl/CreateShortUrlActionTest.php @@ -85,7 +85,7 @@ class CreateShortUrlActionTest extends TestCase $this->action->handle($request); } - public function provideInvalidDomains(): iterable + public static function provideInvalidDomains(): iterable { yield ['localhost:80000']; yield ['127.0.0.1']; diff --git a/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php b/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php index 329c9717..f2f77713 100644 --- a/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php +++ b/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php @@ -70,7 +70,7 @@ class ListShortUrlsActionTest extends TestCase self::assertEquals(200, $response->getStatusCode()); } - public function provideFilteringData(): iterable + public static function provideFilteringData(): iterable { yield [[], 1, null, [], null]; yield [['page' => 10], 10, null, [], null]; diff --git a/module/Rest/test/Action/Tag/DeleteTagsActionTest.php b/module/Rest/test/Action/Tag/DeleteTagsActionTest.php index 63d30c4b..9532e19b 100644 --- a/module/Rest/test/Action/Tag/DeleteTagsActionTest.php +++ b/module/Rest/test/Action/Tag/DeleteTagsActionTest.php @@ -41,7 +41,7 @@ class DeleteTagsActionTest extends TestCase self::assertEquals(204, $response->getStatusCode()); } - public function provideTags(): iterable + public static function provideTags(): iterable { yield 'three tags' => [['foo', 'bar', 'baz']]; yield 'two tags' => [['some', 'thing']]; diff --git a/module/Rest/test/Action/Tag/ListTagsActionTest.php b/module/Rest/test/Action/Tag/ListTagsActionTest.php index dc4c2c06..774a4924 100644 --- a/module/Rest/test/Action/Tag/ListTagsActionTest.php +++ b/module/Rest/test/Action/Tag/ListTagsActionTest.php @@ -61,7 +61,7 @@ class ListTagsActionTest extends TestCase ], $payload); } - public function provideNoStatsQueries(): iterable + public static function provideNoStatsQueries(): iterable { yield 'no query' => [[]]; yield 'withStats is false' => [['withStats' => 'withStats']]; diff --git a/module/Rest/test/Action/Tag/UpdateTagActionTest.php b/module/Rest/test/Action/Tag/UpdateTagActionTest.php index d08d00e2..d62d17eb 100644 --- a/module/Rest/test/Action/Tag/UpdateTagActionTest.php +++ b/module/Rest/test/Action/Tag/UpdateTagActionTest.php @@ -39,7 +39,7 @@ class UpdateTagActionTest extends TestCase $this->action->handle($request); } - public function provideParams(): iterable + public static function provideParams(): iterable { yield 'old name only' => [['oldName' => 'foo']]; yield 'new name only' => [['newName' => 'foo']]; diff --git a/module/Rest/test/Action/Visit/DomainVisitsActionTest.php b/module/Rest/test/Action/Visit/DomainVisitsActionTest.php index e4b714e4..8ab4e09b 100644 --- a/module/Rest/test/Action/Visit/DomainVisitsActionTest.php +++ b/module/Rest/test/Action/Visit/DomainVisitsActionTest.php @@ -46,7 +46,7 @@ class DomainVisitsActionTest extends TestCase self::assertEquals(200, $response->getStatusCode()); } - public function provideDomainAuthorities(): iterable + public static function provideDomainAuthorities(): iterable { yield 'no default domain' => ['foo.com', 'foo.com']; yield 'default domain' => ['the_default.com', 'DEFAULT']; diff --git a/module/Rest/test/ApiKey/InitialApiKeyDelegatorTest.php b/module/Rest/test/ApiKey/InitialApiKeyDelegatorTest.php index cf32ba10..8b65138a 100644 --- a/module/Rest/test/ApiKey/InitialApiKeyDelegatorTest.php +++ b/module/Rest/test/ApiKey/InitialApiKeyDelegatorTest.php @@ -48,7 +48,7 @@ class InitialApiKeyDelegatorTest extends TestCase self::assertSame($result, $app); } - public function provideConfigs(): iterable + public static function provideConfigs(): iterable { yield 'no api key' => [[], 0]; yield 'null api key' => [['initial_api_key' => null], 0]; diff --git a/module/Rest/test/ApiKey/RoleTest.php b/module/Rest/test/ApiKey/RoleTest.php index 715b89b8..1f6059c8 100644 --- a/module/Rest/test/ApiKey/RoleTest.php +++ b/module/Rest/test/ApiKey/RoleTest.php @@ -26,7 +26,7 @@ class RoleTest extends TestCase self::assertEquals($expected, Role::toSpec($apiKeyRole)); } - public function provideRoles(): iterable + public static function provideRoles(): iterable { $apiKey = ApiKey::create(); @@ -49,7 +49,7 @@ class RoleTest extends TestCase self::assertEquals($expected, Role::toInlinedSpec($apiKeyRole)); } - public function provideInlinedRoles(): iterable + public static function provideInlinedRoles(): iterable { $apiKey = ApiKey::create(); @@ -72,7 +72,7 @@ class RoleTest extends TestCase self::assertEquals($expectedDomainId, Role::domainIdFromMeta($meta)); } - public function provideMetasWithDomainId(): iterable + public static function provideMetasWithDomainId(): iterable { yield 'empty meta' => [[], '-1']; yield 'meta without domain_id' => [['foo' => 'bar'], '-1']; @@ -88,7 +88,7 @@ class RoleTest extends TestCase self::assertEquals($expectedAuthority, Role::domainAuthorityFromMeta($meta)); } - public function provideMetasWithAuthority(): iterable + public static function provideMetasWithAuthority(): iterable { yield 'empty meta' => [[], '']; yield 'meta without authority' => [['foo' => 'bar'], '']; @@ -104,7 +104,7 @@ class RoleTest extends TestCase self::assertEquals($expectedFriendlyName, $role->toFriendlyName()); } - public function provideRoleNames(): iterable + public static function provideRoleNames(): iterable { yield Role::AUTHORED_SHORT_URLS->value => [Role::AUTHORED_SHORT_URLS, 'Author only']; yield Role::DOMAIN_SPECIFIC->value => [Role::DOMAIN_SPECIFIC, 'Domain only']; diff --git a/module/Rest/test/ConfigProviderTest.php b/module/Rest/test/ConfigProviderTest.php index 1f7044f9..7245bb24 100644 --- a/module/Rest/test/ConfigProviderTest.php +++ b/module/Rest/test/ConfigProviderTest.php @@ -39,7 +39,7 @@ class ConfigProviderTest extends TestCase self::assertEquals($expected, ConfigProvider::applyRoutesPrefix($routes)); } - public function provideRoutesConfig(): iterable + public static function provideRoutesConfig(): iterable { yield 'health action present' => [ [ diff --git a/module/Rest/test/Exception/BackwardsCompatibleProblemDetailsExceptionTest.php b/module/Rest/test/Exception/BackwardsCompatibleProblemDetailsExceptionTest.php index c63cee71..fec123f6 100644 --- a/module/Rest/test/Exception/BackwardsCompatibleProblemDetailsExceptionTest.php +++ b/module/Rest/test/Exception/BackwardsCompatibleProblemDetailsExceptionTest.php @@ -94,7 +94,7 @@ class BackwardsCompatibleProblemDetailsExceptionTest extends TestCase } } - public function provideTypes(): iterable + public static function provideTypes(): iterable { yield ['foo', 'foo', true]; yield ['bar', 'bar', true]; diff --git a/module/Rest/test/Exception/MissingAuthenticationExceptionTest.php b/module/Rest/test/Exception/MissingAuthenticationExceptionTest.php index ab79ba2f..64a4b6c9 100644 --- a/module/Rest/test/Exception/MissingAuthenticationExceptionTest.php +++ b/module/Rest/test/Exception/MissingAuthenticationExceptionTest.php @@ -31,7 +31,7 @@ class MissingAuthenticationExceptionTest extends TestCase self::assertEquals(['expectedHeaders' => $expectedHeaders], $e->getAdditionalData()); } - public function provideExpectedHeaders(): iterable + public static function provideExpectedHeaders(): iterable { yield [['foo', 'bar']]; yield [['something']]; @@ -55,7 +55,7 @@ class MissingAuthenticationExceptionTest extends TestCase self::assertEquals(['param' => $param], $e->getAdditionalData()); } - public function provideExpectedParam(): iterable + public static function provideExpectedParam(): iterable { yield ['foo']; yield ['bar']; diff --git a/module/Rest/test/Middleware/AuthenticationMiddlewareTest.php b/module/Rest/test/Middleware/AuthenticationMiddlewareTest.php index 62ca5aef..5ae64d1f 100644 --- a/module/Rest/test/Middleware/AuthenticationMiddlewareTest.php +++ b/module/Rest/test/Middleware/AuthenticationMiddlewareTest.php @@ -54,9 +54,9 @@ class AuthenticationMiddlewareTest extends TestCase $this->middleware->process($request, $this->handler); } - public function provideRequestsWithoutAuth(): iterable + public static function provideRequestsWithoutAuth(): iterable { - $dummyMiddleware = $this->getDummyMiddleware(); + $dummyMiddleware = self::getDummyMiddleware(); yield 'no route result' => [new ServerRequest()]; yield 'failure route result' => [(new ServerRequest())->withAttribute( @@ -91,11 +91,11 @@ class AuthenticationMiddlewareTest extends TestCase $this->middleware->process($request, $this->handler); } - public function provideRequestsWithoutApiKey(): iterable + public static function provideRequestsWithoutApiKey(): iterable { $baseRequest = fn (string $routeName) => ServerRequestFactory::fromGlobals()->withAttribute( RouteResult::class, - RouteResult::fromRoute(new Route($routeName, $this->getDummyMiddleware())), // @phpstan-ignore-line + RouteResult::fromRoute(new Route($routeName, self::getDummyMiddleware())), // @phpstan-ignore-line ); $apiKeyMessage = 'Expected one of the following authentication headers, ["X-Api-Key"], but none were provided'; $queryMessage = 'Expected authentication to be provided in "apiKey" query param'; @@ -116,7 +116,7 @@ class AuthenticationMiddlewareTest extends TestCase $request = ServerRequestFactory::fromGlobals() ->withAttribute( RouteResult::class, - RouteResult::fromRoute(new Route('bar', $this->getDummyMiddleware()), []), + RouteResult::fromRoute(new Route('bar', self::getDummyMiddleware()), []), ) ->withHeader('X-Api-Key', $apiKey); @@ -138,7 +138,7 @@ class AuthenticationMiddlewareTest extends TestCase $request = ServerRequestFactory::fromGlobals() ->withAttribute( RouteResult::class, - RouteResult::fromRoute(new Route('bar', $this->getDummyMiddleware()), []), + RouteResult::fromRoute(new Route('bar', self::getDummyMiddleware()), []), ) ->withHeader('X-Api-Key', $key); @@ -152,7 +152,7 @@ class AuthenticationMiddlewareTest extends TestCase $this->middleware->process($request, $this->handler); } - private function getDummyMiddleware(): MiddlewareInterface + private static function getDummyMiddleware(): MiddlewareInterface { return middleware(fn () => new Response\EmptyResponse()); } diff --git a/module/Rest/test/Middleware/BodyParserMiddlewareTest.php b/module/Rest/test/Middleware/BodyParserMiddlewareTest.php index 429a35ea..5de57bdb 100644 --- a/module/Rest/test/Middleware/BodyParserMiddlewareTest.php +++ b/module/Rest/test/Middleware/BodyParserMiddlewareTest.php @@ -37,7 +37,7 @@ class BodyParserMiddlewareTest extends TestCase $this->assertHandlingRequestJustFallsBackToNext($request); } - public function provideIgnoredRequestMethods(): iterable + public static function provideIgnoredRequestMethods(): iterable { yield 'GET' => ['GET']; yield 'HEAD' => ['HEAD']; diff --git a/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php b/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php index de87f34f..2fcceccd 100644 --- a/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php +++ b/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php @@ -100,7 +100,7 @@ class CrossDomainMiddlewareTest extends TestCase self::assertEquals(204, $response->getStatusCode()); } - public function provideRouteResults(): iterable + public static function provideRouteResults(): iterable { yield 'no allow header in response' => [null, 'GET,POST,PUT,PATCH,DELETE']; yield 'allow header in response' => ['POST,GET', 'POST,GET']; @@ -126,7 +126,7 @@ class CrossDomainMiddlewareTest extends TestCase self::assertEquals($expectedStatus, $response->getStatusCode()); } - public function provideMethods(): iterable + public static function provideMethods(): iterable { yield 'POST 200' => ['POST', 200, 200]; yield 'POST 400' => ['POST', 400, 400]; diff --git a/module/Rest/test/Middleware/ErrorHandler/BackwardsCompatibleProblemDetailsHandlerTest.php b/module/Rest/test/Middleware/ErrorHandler/BackwardsCompatibleProblemDetailsHandlerTest.php index 40ba6965..4c350401 100644 --- a/module/Rest/test/Middleware/ErrorHandler/BackwardsCompatibleProblemDetailsHandlerTest.php +++ b/module/Rest/test/Middleware/ErrorHandler/BackwardsCompatibleProblemDetailsHandlerTest.php @@ -40,7 +40,7 @@ class BackwardsCompatibleProblemDetailsHandlerTest extends TestCase $this->handler->process($request, $handler); } - public function provideExceptions(): iterable + public static function provideExceptions(): iterable { $baseRequest = ServerRequestFactory::fromGlobals(); diff --git a/module/Rest/test/Middleware/ShortUrl/CreateShortUrlContentNegotiationMiddlewareTest.php b/module/Rest/test/Middleware/ShortUrl/CreateShortUrlContentNegotiationMiddlewareTest.php index adfaf43e..46cf4eb0 100644 --- a/module/Rest/test/Middleware/ShortUrl/CreateShortUrlContentNegotiationMiddlewareTest.php +++ b/module/Rest/test/Middleware/ShortUrl/CreateShortUrlContentNegotiationMiddlewareTest.php @@ -58,7 +58,7 @@ class CreateShortUrlContentNegotiationMiddlewareTest extends TestCase self::assertEquals($expectedContentType, $response->getHeaderLine('Content-type')); } - public function provideData(): iterable + public static function provideData(): iterable { yield [null, [], 'application/json']; yield [null, ['format' => 'json'], 'application/json']; @@ -88,7 +88,7 @@ class CreateShortUrlContentNegotiationMiddlewareTest extends TestCase self::assertEquals($expectedBody, (string) $response->getBody()); } - public function provideTextBodies(): iterable + public static function provideTextBodies(): iterable { yield 'shortUrl key' => [['shortUrl' => 'foobar'], 'foobar']; yield 'error key' => [['error' => 'FOO_BAR'], 'FOO_BAR']; diff --git a/module/Rest/test/Middleware/ShortUrl/DefaultShortCodesLengthMiddlewareTest.php b/module/Rest/test/Middleware/ShortUrl/DefaultShortCodesLengthMiddlewareTest.php index d8fb3092..7300d3a3 100644 --- a/module/Rest/test/Middleware/ShortUrl/DefaultShortCodesLengthMiddlewareTest.php +++ b/module/Rest/test/Middleware/ShortUrl/DefaultShortCodesLengthMiddlewareTest.php @@ -45,7 +45,7 @@ class DefaultShortCodesLengthMiddlewareTest extends TestCase $this->middleware->process($request, $this->handler); } - public function provideBodies(): iterable + public static function provideBodies(): iterable { yield 'value provided' => [[ShortUrlInputFilter::SHORT_CODE_LENGTH => 6], 6]; yield 'value not provided' => [[], 8]; diff --git a/module/Rest/test/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddlewareTest.php b/module/Rest/test/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddlewareTest.php index cc3ff21c..b0fa8189 100644 --- a/module/Rest/test/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddlewareTest.php +++ b/module/Rest/test/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddlewareTest.php @@ -43,7 +43,7 @@ class DropDefaultDomainFromRequestMiddlewareTest extends TestCase $this->middleware->process($req, $this->next); } - public function provideQueryParams(): iterable + public static function provideQueryParams(): iterable { yield [[], []]; yield [['foo' => 'bar'], ['foo' => 'bar']]; diff --git a/module/Rest/test/Middleware/ShortUrl/OverrideDomainMiddlewareTest.php b/module/Rest/test/Middleware/ShortUrl/OverrideDomainMiddlewareTest.php index f91e9818..23d0ed8f 100644 --- a/module/Rest/test/Middleware/ShortUrl/OverrideDomainMiddlewareTest.php +++ b/module/Rest/test/Middleware/ShortUrl/OverrideDomainMiddlewareTest.php @@ -70,7 +70,7 @@ class OverrideDomainMiddlewareTest extends TestCase $this->middleware->process($request, $this->handler); } - public function provideBodies(): iterable + public static function provideBodies(): iterable { yield 'no domain provided' => [ Domain::withAuthority('foo.com'), @@ -117,7 +117,7 @@ class OverrideDomainMiddlewareTest extends TestCase $this->middleware->process($request, $this->handler); } - public function provideMethods(): iterable + public static function provideMethods(): iterable { yield 'GET' => ['GET']; yield 'PUT' => ['PUT']; diff --git a/module/Rest/test/Service/ApiKeyServiceTest.php b/module/Rest/test/Service/ApiKeyServiceTest.php index a592313d..c424f086 100644 --- a/module/Rest/test/Service/ApiKeyServiceTest.php +++ b/module/Rest/test/Service/ApiKeyServiceTest.php @@ -48,7 +48,7 @@ class ApiKeyServiceTest extends TestCase } } - public function provideCreationDate(): iterable + public static function provideCreationDate(): iterable { $domain = Domain::withAuthority(''); $domain->setId('123'); @@ -79,7 +79,7 @@ class ApiKeyServiceTest extends TestCase self::assertSame($invalidKey, $result->apiKey); } - public function provideInvalidApiKeys(): iterable + public static function provideInvalidApiKeys(): iterable { yield 'non-existent api key' => [null]; yield 'disabled api key' => [ApiKey::create()->disable()]; diff --git a/phpunit-api.xml b/phpunit-api.xml index 6dd527de..62ba2179 100644 --- a/phpunit-api.xml +++ b/phpunit-api.xml @@ -4,6 +4,7 @@ xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="./config/test/bootstrap_api_tests.php" colors="true" + cacheDirectory="build/.phpunit/api-tests.cache" > @@ -11,7 +12,7 @@ - + ./module/Core/src ./module/Rest/src diff --git a/phpunit-cli.xml b/phpunit-cli.xml index 49ba781e..1a129b78 100644 --- a/phpunit-cli.xml +++ b/phpunit-cli.xml @@ -4,6 +4,7 @@ xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="./config/test/bootstrap_cli_tests.php" colors="true" + cacheDirectory="build/.phpunit/cli-tests.cache" > @@ -11,7 +12,7 @@ - + ./module/CLI/src ./module/Core/src diff --git a/phpunit-db.xml b/phpunit-db.xml index b2dd8008..0d2f4dd8 100644 --- a/phpunit-db.xml +++ b/phpunit-db.xml @@ -4,6 +4,7 @@ xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="./config/test/bootstrap_db_tests.php" colors="true" + cacheDirectory="build/.phpunit/db-tests.cache" > @@ -11,7 +12,7 @@ - + ./module/*/src/Repository ./module/*/src/**/Repository diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 29c60b6b..29116d0d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -4,6 +4,7 @@ xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="./vendor/autoload.php" colors="true" + cacheDirectory="build/.phpunit/unit-tests.cache" > @@ -17,7 +18,7 @@ - + ./module/*/src