From 03e9117f1302ee978e4570b1d980d29f362aa029 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 8 Feb 2026 13:04:40 +0100 Subject: [PATCH 1/2] Add support for PHPUnit 13 --- CHANGELOG.md | 17 +++++++++++++++++ composer.json | 23 ++++++++++------------- phpunit-api.xml | 2 ++ phpunit-cli.xml | 2 ++ phpunit-db.xml | 2 ++ 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9120101f6..a640aa803 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org). +## [Unreleased] +### Added +* *Nothing* + +### Changed +* [#2573](https://github.com/shlinkio/shlink/issues/2573) Update to PHPUnit 13 + +### Deprecated +* *Nothing* + +### Removed +* *Nothing* + +### Fixed +* *Nothing* + + ## [5.0.0] - 2026-01-09 ### Added * [#2431](https://github.com/shlinkio/shlink/issues/2431) Add new date-based conditions for the dynamic rules redirections system, that allow to perform redirections based on an ISO-8601 date value. diff --git a/composer.json b/composer.json index e21a021fa..f30d6e58c 100644 --- a/composer.json +++ b/composer.json @@ -41,12 +41,12 @@ "pagerfanta/core": "^3.8", "ramsey/uuid": "^4.7", "shlinkio/doctrine-specification": "^2.2", - "shlinkio/shlink-common": "dev-main#d4ae052 as 8.0.0", - "shlinkio/shlink-config": "dev-main#fb186e4 as 4.1.0", - "shlinkio/shlink-event-dispatcher": "dev-main#54d4701 as 4.4.0", - "shlinkio/shlink-importer": "dev-main#63753cf as 5.7.0", - "shlinkio/shlink-installer": "dev-develop#a225b16 as 10.0.0", - "shlinkio/shlink-ip-geolocation": "dev-main#e0c45b2 as 5.0.0", + "shlinkio/shlink-common": "^8.0.0", + "shlinkio/shlink-config": "^4.1.0", + "shlinkio/shlink-event-dispatcher": "^4.4.0", + "shlinkio/shlink-importer": "^5.7.0", + "shlinkio/shlink-installer": "^10.0.0", + "shlinkio/shlink-ip-geolocation": "^5.0.0", "shlinkio/shlink-json": "^1.3", "spiral/roadrunner": "^2025.1", "spiral/roadrunner-cli": "^2.7", @@ -65,17 +65,14 @@ "phpstan/phpstan-doctrine": "^2.0", "phpstan/phpstan-phpunit": "^2.0.5", "phpstan/phpstan-symfony": "^2.0", - "phpunit/php-code-coverage": "^12.0", - "phpunit/phpcov": "^11.0", - "phpunit/phpunit": "^12.0.10", + "phpunit/php-code-coverage": "^13.0", + "phpunit/phpcov": "^12.0", + "phpunit/phpunit": "^13.0", "shlinkio/php-coding-standard": "~2.5.0", - "shlinkio/shlink-test-utils": "^4.4", + "shlinkio/shlink-test-utils": "^4.5", "symfony/var-dumper": "^8.0", "veewee/composer-run-parallel": "^1.4" }, - "conflict": { - "symfony/var-exporter": ">=6.3.9,<=6.4.0" - }, "autoload": { "psr-4": { "Shlinkio\\Shlink\\CLI\\": "module/CLI/src", diff --git a/phpunit-api.xml b/phpunit-api.xml index dc6823223..7b9eee657 100644 --- a/phpunit-api.xml +++ b/phpunit-api.xml @@ -7,6 +7,8 @@ cacheDirectory="build/.phpunit/api-tests.cache" displayDetailsOnTestsThatTriggerWarnings="true" displayDetailsOnTestsThatTriggerDeprecations="true" + displayDetailsOnPhpunitNotices="true" + displayDetailsOnTestsThatTriggerNotices="true" > diff --git a/phpunit-cli.xml b/phpunit-cli.xml index 186a95110..f16b5ad3f 100644 --- a/phpunit-cli.xml +++ b/phpunit-cli.xml @@ -7,6 +7,8 @@ cacheDirectory="build/.phpunit/cli-tests.cache" displayDetailsOnTestsThatTriggerWarnings="true" displayDetailsOnTestsThatTriggerDeprecations="true" + displayDetailsOnPhpunitNotices="true" + displayDetailsOnTestsThatTriggerNotices="true" > diff --git a/phpunit-db.xml b/phpunit-db.xml index f63a2d7e0..32d19d4bd 100644 --- a/phpunit-db.xml +++ b/phpunit-db.xml @@ -7,6 +7,8 @@ cacheDirectory="build/.phpunit/db-tests.cache" displayDetailsOnTestsThatTriggerWarnings="true" displayDetailsOnTestsThatTriggerDeprecations="true" + displayDetailsOnPhpunitNotices="true" + displayDetailsOnTestsThatTriggerNotices="true" > From 197cfa8811294a3ff26042413a80e0751f9eaefa Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 9 Feb 2026 12:35:39 +0100 Subject: [PATCH 2/2] Apply fixes for PHPUnit 13 --- .../ShortUrl/CreateShortUrlCommandTest.php | 6 +++--- .../RedirectRule/RedirectRuleHandlerTest.php | 6 +++--- module/CLI/test/Util/CliTestUtils.php | 2 -- module/Core/test/Domain/DomainServiceTest.php | 6 ++---- .../Importer/ImportedLinksProcessorTest.php | 2 +- .../Core/test/Matomo/MatomoVisitSenderTest.php | 17 +++++++---------- phpunit-api.xml | 1 + phpunit-cli.xml | 1 + phpunit-db.xml | 1 + phpunit.xml.dist | 1 + 10 files changed, 20 insertions(+), 23 deletions(-) diff --git a/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php b/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php index 805dc2530..b9367ddc1 100644 --- a/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php +++ b/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php @@ -50,7 +50,7 @@ public function properShortCodeIsCreatedIfLongUrlIsCorrect(): void $this->urlShortener->expects($this->once())->method('shorten')->withAnyParameters()->willReturn( UrlShorteningResult::withoutErrorOnEventDispatching($shortUrl), ); - $this->stringifier->method('stringify')->with($shortUrl)->willReturn('stringified_short_url'); + $this->stringifier->method('stringify')->willReturnMap([[$shortUrl, 'stringified_short_url']]); $this->commandTester->execute([ 'long-url' => 'http://domain.com/foo/bar', @@ -70,7 +70,7 @@ public function longUrlIsAskedIfNotProvided(): void $this->urlShortener->expects($this->once())->method('shorten')->withAnyParameters()->willReturn( UrlShorteningResult::withoutErrorOnEventDispatching($shortUrl), ); - $this->stringifier->method('stringify')->with($shortUrl)->willReturn('stringified_short_url'); + $this->stringifier->method('stringify')->willReturnMap([[$shortUrl, 'stringified_short_url']]); $this->commandTester->setInputs([$shortUrl->getLongUrl()]); $this->commandTester->execute([]); @@ -101,7 +101,7 @@ public function properlyProcessesProvidedTags(): void return true; }), )->willReturn(UrlShorteningResult::withoutErrorOnEventDispatching($shortUrl)); - $this->stringifier->method('stringify')->with($shortUrl)->willReturn('stringified_short_url'); + $this->stringifier->method('stringify')->willReturnMap([[$shortUrl, 'stringified_short_url']]); $this->commandTester->execute([ 'long-url' => 'http://domain.com/foo/bar', diff --git a/module/CLI/test/RedirectRule/RedirectRuleHandlerTest.php b/module/CLI/test/RedirectRule/RedirectRuleHandlerTest.php index fce949543..cc55dbd0a 100644 --- a/module/CLI/test/RedirectRule/RedirectRuleHandlerTest.php +++ b/module/CLI/test/RedirectRule/RedirectRuleHandlerTest.php @@ -113,7 +113,7 @@ public function newRulesCanBeAdded( array $expectedConditions, bool $continue = false, ): void { - $this->io->expects($this->any())->method('ask')->willReturnCallback( + $this->io->method('ask')->willReturnCallback( fn (string $message): string|int => match ($message) { 'Rule priority (the lower the value, the higher the priority)' => 2, // Add in between existing rules 'Long URL to redirect when the rule matches' => 'https://example.com/new-two', @@ -127,7 +127,7 @@ public function newRulesCanBeAdded( default => '', }, ); - $this->io->expects($this->any())->method('choice')->willReturnCallback( + $this->io->method('choice')->willReturnCallback( function (string $message) use (&$callIndex, $type): string { $callIndex++; @@ -241,7 +241,7 @@ function () use (&$callIndex): string { #[Test] public function existingRulesCanBeReArranged(): void { - $this->io->expects($this->any())->method('ask')->willReturnCallback( + $this->io->method('ask')->willReturnCallback( fn (string $message): string|int => match ($message) { 'Rule priority (the lower the value, the higher the priority)' => 1, default => '', diff --git a/module/CLI/test/Util/CliTestUtils.php b/module/CLI/test/Util/CliTestUtils.php index 2e0e642b8..02c6c9da1 100644 --- a/module/CLI/test/Util/CliTestUtils.php +++ b/module/CLI/test/Util/CliTestUtils.php @@ -4,7 +4,6 @@ namespace ShlinkioTest\Shlink\CLI\Util; -use PHPUnit\Framework\Assert; use PHPUnit\Framework\MockObject\Generator\Generator; use PHPUnit\Framework\MockObject\Stub; use Symfony\Component\Console\Application; @@ -32,7 +31,6 @@ public static function createCommandStub(string $name): Stub & Command $command->method('isEnabled')->willReturn(true); $command->method('getAliases')->willReturn([]); $command->method('getDefinition')->willReturn(new InputDefinition()); - $command->method('setApplication')->with(Assert::isInstanceOf(Application::class)); return $command; } diff --git a/module/Core/test/Domain/DomainServiceTest.php b/module/Core/test/Domain/DomainServiceTest.php index 1677022aa..980d5a4cf 100644 --- a/module/Core/test/Domain/DomainServiceTest.php +++ b/module/Core/test/Domain/DomainServiceTest.php @@ -111,7 +111,7 @@ public static function provideExcludedDomains(): iterable #[Test, AllowMockObjectsWithoutExpectations] public function getDomainThrowsExceptionWhenDomainIsNotFound(): void { - $this->em->method('find')->with(Domain::class, '123')->willReturn(null); + $this->em->method('find')->willReturnMap([[Domain::class, '123', null]]); $this->expectException(DomainNotFoundException::class); @@ -122,7 +122,7 @@ public function getDomainThrowsExceptionWhenDomainIsNotFound(): void public function getDomainReturnsEntityWhenFound(): void { $domain = Domain::withAuthority(''); - $this->em->method('find')->with(Domain::class, '123')->willReturn($domain); + $this->em->method('find')->willReturnMap([[Domain::class, '123', $domain]]); $result = $this->domainService->getDomain('123'); @@ -136,7 +136,6 @@ public function getOrCreateAlwaysPersistsDomain(Domain|null $foundDomain, ApiKey $this->repo->expects($this->once())->method('findOneByAuthority')->with($authority, $apiKey)->willReturn( $foundDomain, ); - $this->em->method('persist')->with($foundDomain ?? $this->isInstanceOf(Domain::class)); $result = $this->domainService->getOrCreate($authority, $apiKey); @@ -168,7 +167,6 @@ public function configureNotFoundRedirectsConfiguresFetchedDomain( $this->repo->expects($this->once())->method('findOneByAuthority')->with($authority, $apiKey)->willReturn( $foundDomain, ); - $this->em->method('persist')->with($foundDomain ?? $this->isInstanceOf(Domain::class)); $result = $this->domainService->configureNotFoundRedirects($authority, NotFoundRedirects::withRedirects( 'foo.com', diff --git a/module/Core/test/Importer/ImportedLinksProcessorTest.php b/module/Core/test/Importer/ImportedLinksProcessorTest.php index ac82e1a44..f87dc723e 100644 --- a/module/Core/test/Importer/ImportedLinksProcessorTest.php +++ b/module/Core/test/Importer/ImportedLinksProcessorTest.php @@ -229,7 +229,7 @@ public function properAmountOfVisitsIsImported( $this->em->expects($this->exactly($amountOfPersistedVisits + ($foundShortUrl === null ? 1 : 0)))->method( 'persist', )->with($this->callback(fn (object $arg) => $arg instanceof ShortUrl || $arg instanceof Visit)); - $this->em->expects($this->any())->method('find')->willReturn(null); + $this->em->method('find')->willReturn(null); $this->io->expects($this->once())->method('text')->with($this->stringContains($expectedOutput)); $this->processor->process($this->io, ImportResult::withShortUrls([$importedUrl]), $this->buildParams()); diff --git a/module/Core/test/Matomo/MatomoVisitSenderTest.php b/module/Core/test/Matomo/MatomoVisitSenderTest.php index 0693f8aa6..9655d3a4f 100644 --- a/module/Core/test/Matomo/MatomoVisitSenderTest.php +++ b/module/Core/test/Matomo/MatomoVisitSenderTest.php @@ -116,15 +116,12 @@ public static function provideTrackerMethods(): iterable #[Test, DataProvider('provideUrlsToTrack')] public function properUrlIsTracked(Visit $visit, string $expectedTrackedUrl): void { - $tracker = $this->createMock(MatomoTracker::class); - $tracker->expects($this->once())->method('setUrl')->with($expectedTrackedUrl)->willReturn($tracker); - $tracker->expects($this->once())->method('setUserAgent')->willReturn($tracker); - $tracker->expects($this->once())->method('setUrlReferrer')->willReturn($tracker); - $tracker->expects($this->any())->method('setCustomTrackingParameter')->willReturn($tracker); - $tracker->expects($this->once())->method('doTrackPageView'); - $tracker->expects($this->once())->method('setForceVisitDateTime')->with( - $visit->date->setTimezone('UTC')->toDateTimeString(), - ); + $tracker = $this->createStub(MatomoTracker::class); + $tracker->method('setUrl')->willReturn($tracker); + $tracker->method('setUserAgent')->willReturn($tracker); + $tracker->method('setUrlReferrer')->willReturn($tracker); + $tracker->method('setCustomTrackingParameter')->willReturn($tracker); + $tracker->method('doTrackPageView'); $this->trackerBuilder->expects($this->once())->method('buildMatomoTracker')->willReturn($tracker); @@ -156,7 +153,7 @@ public function multipleVisitsCanBeSent(): void $visitor = Visitor::empty(); $bot = Visitor::botInstance(); - $this->visitIterationRepository->method('findAllVisits')->with($dateRange)->willReturn([ + $this->visitIterationRepository->method('findAllVisits')->willReturn([ Visit::forBasePath($bot), Visit::forValidShortUrl(ShortUrl::createFake(), $visitor), Visit::forInvalidShortUrl($visitor), diff --git a/phpunit-api.xml b/phpunit-api.xml index 7b9eee657..d63fb8549 100644 --- a/phpunit-api.xml +++ b/phpunit-api.xml @@ -8,6 +8,7 @@ displayDetailsOnTestsThatTriggerWarnings="true" displayDetailsOnTestsThatTriggerDeprecations="true" displayDetailsOnPhpunitNotices="true" + displayDetailsOnPhpunitDeprecations="true" displayDetailsOnTestsThatTriggerNotices="true" > diff --git a/phpunit-cli.xml b/phpunit-cli.xml index f16b5ad3f..a8c153d45 100644 --- a/phpunit-cli.xml +++ b/phpunit-cli.xml @@ -8,6 +8,7 @@ displayDetailsOnTestsThatTriggerWarnings="true" displayDetailsOnTestsThatTriggerDeprecations="true" displayDetailsOnPhpunitNotices="true" + displayDetailsOnPhpunitDeprecations="true" displayDetailsOnTestsThatTriggerNotices="true" > diff --git a/phpunit-db.xml b/phpunit-db.xml index 32d19d4bd..6a274b9fe 100644 --- a/phpunit-db.xml +++ b/phpunit-db.xml @@ -8,6 +8,7 @@ displayDetailsOnTestsThatTriggerWarnings="true" displayDetailsOnTestsThatTriggerDeprecations="true" displayDetailsOnPhpunitNotices="true" + displayDetailsOnPhpunitDeprecations="true" displayDetailsOnTestsThatTriggerNotices="true" > diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 76df50d39..c19ba8d30 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -8,6 +8,7 @@ displayDetailsOnTestsThatTriggerWarnings="true" displayDetailsOnTestsThatTriggerDeprecations="true" displayDetailsOnPhpunitNotices="true" + displayDetailsOnPhpunitDeprecations="true" displayDetailsOnTestsThatTriggerNotices="true" >