Merge pull request #2358 from acelaya-forks/feature/phpunit-12

Update to PHPUnit 12
This commit is contained in:
Alejandro Celaya 2025-02-13 21:59:00 +01:00 committed by GitHub
commit 81e07bf08d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 62 additions and 101 deletions

View File

@ -63,16 +63,16 @@
"require-dev": { "require-dev": {
"devizzent/cebe-php-openapi": "^1.1.2", "devizzent/cebe-php-openapi": "^1.1.2",
"devster/ubench": "^2.1", "devster/ubench": "^2.1",
"phpstan/phpstan": "^2.0", "phpstan/phpstan": "^2.1",
"phpstan/phpstan-doctrine": "^2.0", "phpstan/phpstan-doctrine": "^2.0",
"phpstan/phpstan-phpunit": "^2.0", "phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-symfony": "^2.0", "phpstan/phpstan-symfony": "^2.0",
"phpunit/php-code-coverage": "^11.0", "phpunit/php-code-coverage": "^12.0",
"phpunit/phpcov": "^10.0", "phpunit/phpcov": "^11.0",
"phpunit/phpunit": "^11.5", "phpunit/phpunit": "^12.0",
"roave/security-advisories": "dev-master", "roave/security-advisories": "dev-master",
"shlinkio/php-coding-standard": "~2.4.0", "shlinkio/php-coding-standard": "~2.4.0",
"shlinkio/shlink-test-utils": "^4.2", "shlinkio/shlink-test-utils": "^4.3.1",
"symfony/var-dumper": "^7.2", "symfony/var-dumper": "^7.2",
"veewee/composer-run-parallel": "^1.4" "veewee/composer-run-parallel": "^1.4"
}, },

View File

@ -15,7 +15,6 @@ use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface; use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface;
use ShlinkioTest\Shlink\CLI\Util\CliTestUtils; use ShlinkioTest\Shlink\CLI\Util\CliTestUtils;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;
class GenerateKeyCommandTest extends TestCase class GenerateKeyCommandTest extends TestCase
@ -27,7 +26,7 @@ class GenerateKeyCommandTest extends TestCase
{ {
$this->apiKeyService = $this->createMock(ApiKeyServiceInterface::class); $this->apiKeyService = $this->createMock(ApiKeyServiceInterface::class);
$roleResolver = $this->createMock(RoleResolverInterface::class); $roleResolver = $this->createMock(RoleResolverInterface::class);
$roleResolver->method('determineRoles')->with($this->isInstanceOf(InputInterface::class))->willReturn([]); $roleResolver->method('determineRoles')->willReturn([]);
$command = new GenerateKeyCommand($this->apiKeyService, $roleResolver); $command = new GenerateKeyCommand($this->apiKeyService, $roleResolver);
$this->commandTester = CliTestUtils::testerForCommand($command); $this->commandTester = CliTestUtils::testerForCommand($command);

View File

@ -40,11 +40,11 @@ class CreateDatabaseCommandTest extends TestCase
{ {
$locker = $this->createMock(LockFactory::class); $locker = $this->createMock(LockFactory::class);
$lock = $this->createMock(SharedLockInterface::class); $lock = $this->createMock(SharedLockInterface::class);
$lock->method('acquire')->withAnyParameters()->willReturn(true); $lock->method('acquire')->willReturn(true);
$locker->method('createLock')->withAnyParameters()->willReturn($lock); $locker->method('createLock')->willReturn($lock);
$phpExecutableFinder = $this->createMock(PhpExecutableFinder::class); $phpExecutableFinder = $this->createMock(PhpExecutableFinder::class);
$phpExecutableFinder->method('find')->with($this->isFalse())->willReturn('/usr/local/bin/php'); $phpExecutableFinder->method('find')->willReturn('/usr/local/bin/php');
$this->processHelper = $this->createMock(ProcessRunnerInterface::class); $this->processHelper = $this->createMock(ProcessRunnerInterface::class);
$this->schemaManager = $this->createMock(AbstractSchemaManager::class); $this->schemaManager = $this->createMock(AbstractSchemaManager::class);
@ -60,7 +60,7 @@ class CreateDatabaseCommandTest extends TestCase
$em->method('getMetadataFactory')->willReturn($this->metadataFactory); $em->method('getMetadataFactory')->willReturn($this->metadataFactory);
$noDbNameConn = $this->createMock(Connection::class); $noDbNameConn = $this->createMock(Connection::class);
$noDbNameConn->method('createSchemaManager')->withAnyParameters()->willReturn($this->schemaManager); $noDbNameConn->method('createSchemaManager')->willReturn($this->schemaManager);
$command = new CreateDatabaseCommand($locker, $this->processHelper, $phpExecutableFinder, $em, $noDbNameConn); $command = new CreateDatabaseCommand($locker, $this->processHelper, $phpExecutableFinder, $em, $noDbNameConn);
$this->commandTester = CliTestUtils::testerForCommand($command); $this->commandTester = CliTestUtils::testerForCommand($command);

View File

@ -25,11 +25,11 @@ class MigrateDatabaseCommandTest extends TestCase
{ {
$locker = $this->createMock(LockFactory::class); $locker = $this->createMock(LockFactory::class);
$lock = $this->createMock(SharedLockInterface::class); $lock = $this->createMock(SharedLockInterface::class);
$lock->method('acquire')->withAnyParameters()->willReturn(true); $lock->method('acquire')->willReturn(true);
$locker->method('createLock')->withAnyParameters()->willReturn($lock); $locker->method('createLock')->willReturn($lock);
$phpExecutableFinder = $this->createMock(PhpExecutableFinder::class); $phpExecutableFinder = $this->createMock(PhpExecutableFinder::class);
$phpExecutableFinder->method('find')->with($this->isFalse())->willReturn('/usr/local/bin/php'); $phpExecutableFinder->method('find')->willReturn('/usr/local/bin/php');
$this->processHelper = $this->createMock(ProcessRunnerInterface::class); $this->processHelper = $this->createMock(ProcessRunnerInterface::class);

View File

@ -70,7 +70,7 @@ class CreateShortUrlCommandTest extends TestCase
$this->urlShortener->expects($this->once())->method('shorten')->withAnyParameters()->willThrowException( $this->urlShortener->expects($this->once())->method('shorten')->withAnyParameters()->willThrowException(
NonUniqueSlugException::fromSlug('my-slug'), NonUniqueSlugException::fromSlug('my-slug'),
); );
$this->stringifier->method('stringify')->with($this->isInstanceOf(ShortUrl::class))->willReturn(''); $this->stringifier->method('stringify')->willReturn('');
$this->commandTester->execute(['longUrl' => 'http://domain.com/invalid', '--custom-slug' => 'my-slug']); $this->commandTester->execute(['longUrl' => 'http://domain.com/invalid', '--custom-slug' => 'my-slug']);
$output = $this->commandTester->getDisplay(); $output = $this->commandTester->getDisplay();
@ -112,7 +112,7 @@ class CreateShortUrlCommandTest extends TestCase
return true; return true;
}), }),
)->willReturn(UrlShorteningResult::withoutErrorOnEventDispatching(ShortUrl::createFake())); )->willReturn(UrlShorteningResult::withoutErrorOnEventDispatching(ShortUrl::createFake()));
$this->stringifier->method('stringify')->with($this->isInstanceOf(ShortUrl::class))->willReturn(''); $this->stringifier->method('stringify')->willReturn('');
$input['longUrl'] = 'http://domain.com/foo/bar'; $input['longUrl'] = 'http://domain.com/foo/bar';
$this->commandTester->execute($input); $this->commandTester->execute($input);
@ -139,7 +139,7 @@ class CreateShortUrlCommandTest extends TestCase
return true; return true;
}), }),
)->willReturn(UrlShorteningResult::withoutErrorOnEventDispatching($shortUrl)); )->willReturn(UrlShorteningResult::withoutErrorOnEventDispatching($shortUrl));
$this->stringifier->method('stringify')->with($this->isInstanceOf(ShortUrl::class))->willReturn(''); $this->stringifier->method('stringify')->willReturn('');
$options['longUrl'] = 'http://domain.com/foo/bar'; $options['longUrl'] = 'http://domain.com/foo/bar';
$this->commandTester->execute($options); $this->commandTester->execute($options);

View File

@ -47,7 +47,7 @@ class LocateVisitsCommandTest extends TestCase
$locker = $this->createMock(Lock\LockFactory::class); $locker = $this->createMock(Lock\LockFactory::class);
$this->lock = $this->createMock(Lock\SharedLockInterface::class); $this->lock = $this->createMock(Lock\SharedLockInterface::class);
$locker->method('createLock')->with($this->isString(), 600.0, false)->willReturn($this->lock); $locker->method('createLock')->willReturn($this->lock);
$command = new LocateVisitsCommand($this->visitService, $this->visitToLocation, $locker); $command = new LocateVisitsCommand($this->visitService, $this->visitToLocation, $locker);
@ -67,7 +67,7 @@ class LocateVisitsCommandTest extends TestCase
$location = VisitLocation::fromGeolocation(Location::empty()); $location = VisitLocation::fromGeolocation(Location::empty());
$mockMethodBehavior = $this->invokeHelperMethods($visit, $location); $mockMethodBehavior = $this->invokeHelperMethods($visit, $location);
$this->lock->method('acquire')->with($this->isFalse())->willReturn(true); $this->lock->method('acquire')->willReturn(true);
$this->visitService->expects($this->exactly($expectedUnlocatedCalls)) $this->visitService->expects($this->exactly($expectedUnlocatedCalls))
->method('locateUnlocatedVisits') ->method('locateUnlocatedVisits')
->withAnyParameters() ->withAnyParameters()
@ -83,7 +83,7 @@ class LocateVisitsCommandTest extends TestCase
$this->visitToLocation->expects( $this->visitToLocation->expects(
$this->exactly($expectedUnlocatedCalls + $expectedEmptyCalls + $expectedAllCalls), $this->exactly($expectedUnlocatedCalls + $expectedEmptyCalls + $expectedAllCalls),
)->method('resolveVisitLocation')->withAnyParameters()->willReturn(Location::emptyInstance()); )->method('resolveVisitLocation')->withAnyParameters()->willReturn(Location::emptyInstance());
$this->downloadDbCommand->method('run')->withAnyParameters()->willReturn(ExitCode::EXIT_SUCCESS); $this->downloadDbCommand->method('run')->willReturn(ExitCode::EXIT_SUCCESS);
$this->commandTester->setInputs(['y']); $this->commandTester->setInputs(['y']);
$this->commandTester->execute($args); $this->commandTester->execute($args);
@ -108,15 +108,15 @@ class LocateVisitsCommandTest extends TestCase
public function localhostAndEmptyAddressesAreIgnored(IpCannotBeLocatedException $e, string $message): void public function localhostAndEmptyAddressesAreIgnored(IpCannotBeLocatedException $e, string $message): void
{ {
$visit = Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::empty()); $visit = Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::empty());
$location = VisitLocation::fromGeolocation(Location::emptyInstance()); $location = VisitLocation::fromGeolocation(Location::empty());
$this->lock->method('acquire')->with($this->isFalse())->willReturn(true); $this->lock->method('acquire')->willReturn(true);
$this->visitService->expects($this->once()) $this->visitService->expects($this->once())
->method('locateUnlocatedVisits') ->method('locateUnlocatedVisits')
->withAnyParameters() ->withAnyParameters()
->willReturnCallback($this->invokeHelperMethods($visit, $location)); ->willReturnCallback($this->invokeHelperMethods($visit, $location));
$this->visitToLocation->expects($this->once())->method('resolveVisitLocation')->willThrowException($e); $this->visitToLocation->expects($this->once())->method('resolveVisitLocation')->willThrowException($e);
$this->downloadDbCommand->method('run')->withAnyParameters()->willReturn(ExitCode::EXIT_SUCCESS); $this->downloadDbCommand->method('run')->willReturn(ExitCode::EXIT_SUCCESS);
$this->commandTester->execute([], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE]); $this->commandTester->execute([], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE]);
@ -137,7 +137,7 @@ class LocateVisitsCommandTest extends TestCase
$visit = Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::fromParams(remoteAddress: '1.2.3.4')); $visit = Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::fromParams(remoteAddress: '1.2.3.4'));
$location = VisitLocation::fromGeolocation(Location::emptyInstance()); $location = VisitLocation::fromGeolocation(Location::emptyInstance());
$this->lock->method('acquire')->with($this->isFalse())->willReturn(true); $this->lock->method('acquire')->willReturn(true);
$this->visitService->expects($this->once()) $this->visitService->expects($this->once())
->method('locateUnlocatedVisits') ->method('locateUnlocatedVisits')
->withAnyParameters() ->withAnyParameters()
@ -145,7 +145,7 @@ class LocateVisitsCommandTest extends TestCase
$this->visitToLocation->expects($this->once())->method('resolveVisitLocation')->willThrowException( $this->visitToLocation->expects($this->once())->method('resolveVisitLocation')->willThrowException(
IpCannotBeLocatedException::forError(WrongIpException::fromIpAddress('1.2.3.4')), IpCannotBeLocatedException::forError(WrongIpException::fromIpAddress('1.2.3.4')),
); );
$this->downloadDbCommand->method('run')->withAnyParameters()->willReturn(ExitCode::EXIT_SUCCESS); $this->downloadDbCommand->method('run')->willReturn(ExitCode::EXIT_SUCCESS);
$this->commandTester->execute([], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE]); $this->commandTester->execute([], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE]);
@ -165,11 +165,11 @@ class LocateVisitsCommandTest extends TestCase
#[Test] #[Test]
public function noActionIsPerformedIfLockIsAcquired(): void public function noActionIsPerformedIfLockIsAcquired(): void
{ {
$this->lock->method('acquire')->with($this->isFalse())->willReturn(false); $this->lock->method('acquire')->willReturn(false);
$this->visitService->expects($this->never())->method('locateUnlocatedVisits'); $this->visitService->expects($this->never())->method('locateUnlocatedVisits');
$this->visitToLocation->expects($this->never())->method('resolveVisitLocation'); $this->visitToLocation->expects($this->never())->method('resolveVisitLocation');
$this->downloadDbCommand->method('run')->withAnyParameters()->willReturn(ExitCode::EXIT_SUCCESS); $this->downloadDbCommand->method('run')->willReturn(ExitCode::EXIT_SUCCESS);
$this->commandTester->execute([], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE]); $this->commandTester->execute([], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE]);
$output = $this->commandTester->getDisplay(); $output = $this->commandTester->getDisplay();
@ -183,8 +183,8 @@ class LocateVisitsCommandTest extends TestCase
#[Test] #[Test]
public function showsProperMessageWhenGeoLiteUpdateFails(): void public function showsProperMessageWhenGeoLiteUpdateFails(): void
{ {
$this->lock->method('acquire')->with($this->isFalse())->willReturn(true); $this->lock->method('acquire')->willReturn(true);
$this->downloadDbCommand->method('run')->withAnyParameters()->willReturn(ExitCode::EXIT_FAILURE); $this->downloadDbCommand->method('run')->willReturn(ExitCode::EXIT_FAILURE);
$this->visitService->expects($this->never())->method('locateUnlocatedVisits'); $this->visitService->expects($this->never())->method('locateUnlocatedVisits');
$this->commandTester->execute([]); $this->commandTester->execute([]);
@ -196,8 +196,8 @@ class LocateVisitsCommandTest extends TestCase
#[Test] #[Test]
public function providingAllFlagOnItsOwnDisplaysNotice(): void public function providingAllFlagOnItsOwnDisplaysNotice(): void
{ {
$this->lock->method('acquire')->with($this->isFalse())->willReturn(true); $this->lock->method('acquire')->willReturn(true);
$this->downloadDbCommand->method('run')->withAnyParameters()->willReturn(ExitCode::EXIT_SUCCESS); $this->downloadDbCommand->method('run')->willReturn(ExitCode::EXIT_SUCCESS);
$this->commandTester->execute(['--all' => true]); $this->commandTester->execute(['--all' => true]);
$output = $this->commandTester->getDisplay(); $output = $this->commandTester->getDisplay();
@ -208,7 +208,7 @@ class LocateVisitsCommandTest extends TestCase
#[Test, DataProvider('provideAbortInputs')] #[Test, DataProvider('provideAbortInputs')]
public function processingAllCancelsCommandIfUserDoesNotActivelyAgreeToConfirmation(array $inputs): void public function processingAllCancelsCommandIfUserDoesNotActivelyAgreeToConfirmation(array $inputs): void
{ {
$this->downloadDbCommand->method('run')->withAnyParameters()->willReturn(ExitCode::EXIT_SUCCESS); $this->downloadDbCommand->method('run')->willReturn(ExitCode::EXIT_SUCCESS);
$this->expectException(RuntimeException::class); $this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Execution aborted'); $this->expectExceptionMessage('Execution aborted');

View File

@ -25,11 +25,8 @@ class CliTestUtils
$command = $generator->testDouble( $command = $generator->testDouble(
Command::class, Command::class,
mockObject: true, mockObject: true,
markAsMockObject: true,
callOriginalConstructor: false, callOriginalConstructor: false,
callOriginalClone: false, callOriginalClone: false,
cloneArguments: false,
allowMockingUnknownTypes: false,
); );
$command->method('getName')->willReturn($name); $command->method('getName')->willReturn($name);
$command->method('isEnabled')->willReturn(true); $command->method('isEnabled')->willReturn(true);

View File

@ -27,8 +27,8 @@ class ProcessRunnerTest extends TestCase
$this->helper = $this->createMock(ProcessHelper::class); $this->helper = $this->createMock(ProcessHelper::class);
$this->formatter = $this->createMock(DebugFormatterHelper::class); $this->formatter = $this->createMock(DebugFormatterHelper::class);
$helperSet = $this->createMock(HelperSet::class); $helperSet = $this->createMock(HelperSet::class);
$helperSet->method('get')->with('debug_formatter')->willReturn($this->formatter); $helperSet->method('get')->willReturn($this->formatter);
$this->helper->method('getHelperSet')->with()->willReturn($helperSet); $this->helper->method('getHelperSet')->willReturn($helperSet);
$this->process = $this->createMock(Process::class); $this->process = $this->createMock(Process::class);
$this->output = $this->createMock(OutputInterface::class); $this->output = $this->createMock(OutputInterface::class);

View File

@ -79,9 +79,7 @@ class QrCodeActionTest extends TestCase
string $expectedContentType, string $expectedContentType,
): void { ): void {
$code = 'abc123'; $code = 'abc123';
$this->urlResolver->method('resolveEnabledShortUrl')->with( $this->urlResolver->method('resolveEnabledShortUrl')->willReturn(ShortUrl::createFake());
ShortUrlIdentifier::fromShortCodeAndDomain($code, ''),
)->willReturn(ShortUrl::createFake());
$handler = $this->createMock(RequestHandlerInterface::class); $handler = $this->createMock(RequestHandlerInterface::class);
$req = (new ServerRequest())->withAttribute('shortCode', $code)->withQueryParams($query); $req = (new ServerRequest())->withAttribute('shortCode', $code)->withQueryParams($query);
@ -109,9 +107,7 @@ class QrCodeActionTest extends TestCase
int $expectedSize, int $expectedSize,
): void { ): void {
$code = 'abc123'; $code = 'abc123';
$this->urlResolver->method('resolveEnabledShortUrl')->with( $this->urlResolver->method('resolveEnabledShortUrl')->willReturn(ShortUrl::createFake());
ShortUrlIdentifier::fromShortCodeAndDomain($code, ''),
)->willReturn(ShortUrl::createFake());
$handler = $this->createMock(RequestHandlerInterface::class); $handler = $this->createMock(RequestHandlerInterface::class);
$resp = $this->action($defaultOptions)->process($req->withAttribute('shortCode', $code), $handler); $resp = $this->action($defaultOptions)->process($req->withAttribute('shortCode', $code), $handler);
@ -199,9 +195,7 @@ class QrCodeActionTest extends TestCase
->withQueryParams(['size' => 250, 'roundBlockSize' => $roundBlockSize]) ->withQueryParams(['size' => 250, 'roundBlockSize' => $roundBlockSize])
->withAttribute('shortCode', $code); ->withAttribute('shortCode', $code);
$this->urlResolver->method('resolveEnabledShortUrl')->with( $this->urlResolver->method('resolveEnabledShortUrl')->willReturn(ShortUrl::withLongUrl('https://shlink.io'));
ShortUrlIdentifier::fromShortCodeAndDomain($code, ''),
)->willReturn(ShortUrl::withLongUrl('https://shlink.io'));
$handler = $this->createMock(RequestHandlerInterface::class); $handler = $this->createMock(RequestHandlerInterface::class);
$resp = $this->action($defaultOptions)->process($req, $handler); $resp = $this->action($defaultOptions)->process($req, $handler);
@ -242,9 +236,7 @@ class QrCodeActionTest extends TestCase
->withQueryParams(['color' => $queryColor]) ->withQueryParams(['color' => $queryColor])
->withAttribute('shortCode', $code); ->withAttribute('shortCode', $code);
$this->urlResolver->method('resolveEnabledShortUrl')->with( $this->urlResolver->method('resolveEnabledShortUrl')->willReturn(ShortUrl::withLongUrl('https://shlink.io'));
ShortUrlIdentifier::fromShortCodeAndDomain($code),
)->willReturn(ShortUrl::withLongUrl('https://shlink.io'));
$handler = $this->createMock(RequestHandlerInterface::class); $handler = $this->createMock(RequestHandlerInterface::class);
$resp = $this->action( $resp = $this->action(
@ -306,9 +298,7 @@ class QrCodeActionTest extends TestCase
->withAttribute('shortCode', $code) ->withAttribute('shortCode', $code)
->withQueryParams($query); ->withQueryParams($query);
$this->urlResolver->method('resolveEnabledShortUrl')->with( $this->urlResolver->method('resolveEnabledShortUrl')->willReturn(ShortUrl::withLongUrl('https://shlink.io'));
ShortUrlIdentifier::fromShortCodeAndDomain($code),
)->willReturn(ShortUrl::withLongUrl('https://shlink.io'));
$handler = $this->createMock(RequestHandlerInterface::class); $handler = $this->createMock(RequestHandlerInterface::class);
$resp = $this->action(new QrCodeOptions(size: 250, logoUrl: $logoUrl))->process($req, $handler); $resp = $this->action(new QrCodeOptions(size: 250, logoUrl: $logoUrl))->process($req, $handler);

View File

@ -37,7 +37,7 @@ class RedirectActionTest extends TestCase
$this->redirectRespHelper = $this->createMock(RedirectResponseHelperInterface::class); $this->redirectRespHelper = $this->createMock(RedirectResponseHelperInterface::class);
$redirectBuilder = $this->createMock(ShortUrlRedirectionBuilderInterface::class); $redirectBuilder = $this->createMock(ShortUrlRedirectionBuilderInterface::class);
$redirectBuilder->method('buildShortUrlRedirect')->withAnyParameters()->willReturn(self::LONG_URL); $redirectBuilder->method('buildShortUrlRedirect')->willReturn(self::LONG_URL);
$this->action = new RedirectAction( $this->action = new RedirectAction(
$this->urlResolver, $this->urlResolver,

View File

@ -43,7 +43,7 @@ class GeolocationDbUpdaterTest extends TestCase
$this->dbUpdater = $this->createMock(DbUpdaterInterface::class); $this->dbUpdater = $this->createMock(DbUpdaterInterface::class);
$this->lock = $this->createMock(Lock\SharedLockInterface::class); $this->lock = $this->createMock(Lock\SharedLockInterface::class);
$this->lock->method('acquire')->with($this->isTrue())->willReturn(true); $this->lock->method('acquire')->willReturn(true);
$this->em = $this->createMock(EntityManagerInterface::class); $this->em = $this->createMock(EntityManagerInterface::class);
$this->repo = $this->createMock(EntityRepository::class); $this->repo = $this->createMock(EntityRepository::class);
@ -291,7 +291,7 @@ class GeolocationDbUpdaterTest extends TestCase
private function geolocationDbUpdater(TrackingOptions|null $options = null): GeolocationDbUpdater private function geolocationDbUpdater(TrackingOptions|null $options = null): GeolocationDbUpdater
{ {
$locker = $this->createMock(Lock\LockFactory::class); $locker = $this->createMock(Lock\LockFactory::class);
$locker->method('createLock')->with($this->isString())->willReturn($this->lock); $locker->method('createLock')->willReturn($this->lock);
return new GeolocationDbUpdater($this->dbUpdater, $locker, $options ?? new TrackingOptions(), $this->em, 3); return new GeolocationDbUpdater($this->dbUpdater, $locker, $options ?? new TrackingOptions(), $this->em, 3);
} }

View File

@ -104,7 +104,7 @@ class ImportedLinksProcessorTest extends TestCase
]; ];
$expectedCalls = count($urls); $expectedCalls = count($urls);
$this->em->method('getRepository')->with(ShortUrl::class)->willReturn($this->repo); $this->em->method('getRepository')->willReturn($this->repo);
$this->repo->expects($this->exactly($expectedCalls))->method('findOneByImportedUrl')->willReturn(null); $this->repo->expects($this->exactly($expectedCalls))->method('findOneByImportedUrl')->willReturn(null);
$this->shortCodeHelper->expects($this->exactly($expectedCalls)) $this->shortCodeHelper->expects($this->exactly($expectedCalls))
->method('ensureShortCodeUniqueness') ->method('ensureShortCodeUniqueness')
@ -138,7 +138,7 @@ class ImportedLinksProcessorTest extends TestCase
new ImportedShlinkUrl(ImportSource::BITLY, 'https://baz', [], Chronos::now(), null, 'baz', null), new ImportedShlinkUrl(ImportSource::BITLY, 'https://baz', [], Chronos::now(), null, 'baz', null),
]; ];
$this->em->method('getRepository')->with(ShortUrl::class)->willReturn($this->repo); $this->em->method('getRepository')->willReturn($this->repo);
$this->repo->expects($this->exactly(3))->method('findOneByImportedUrl')->willReturn(null); $this->repo->expects($this->exactly(3))->method('findOneByImportedUrl')->willReturn(null);
$this->shortCodeHelper->expects($this->exactly(3))->method('ensureShortCodeUniqueness')->willReturn(true); $this->shortCodeHelper->expects($this->exactly(3))->method('ensureShortCodeUniqueness')->willReturn(true);
$this->em->expects($this->exactly(3))->method('persist')->with( $this->em->expects($this->exactly(3))->method('persist')->with(
@ -167,7 +167,7 @@ class ImportedLinksProcessorTest extends TestCase
new ImportedShlinkUrl(ImportSource::BITLY, 'https://baz3', [], Chronos::now(), null, 'baz3', null), new ImportedShlinkUrl(ImportSource::BITLY, 'https://baz3', [], Chronos::now(), null, 'baz3', null),
]; ];
$this->em->method('getRepository')->with(ShortUrl::class)->willReturn($this->repo); $this->em->method('getRepository')->willReturn($this->repo);
$this->repo->expects($this->exactly(count($urls)))->method('findOneByImportedUrl')->willReturnCallback( $this->repo->expects($this->exactly(count($urls)))->method('findOneByImportedUrl')->willReturnCallback(
fn (ImportedShlinkUrl $url): ShortUrl|null => contains( fn (ImportedShlinkUrl $url): ShortUrl|null => contains(
$url->longUrl, $url->longUrl,
@ -195,7 +195,7 @@ class ImportedLinksProcessorTest extends TestCase
new ImportedShlinkUrl(ImportSource::BITLY, 'https://baz3', [], Chronos::now(), null, 'baz3', 'bar'), new ImportedShlinkUrl(ImportSource::BITLY, 'https://baz3', [], Chronos::now(), null, 'baz3', 'bar'),
]; ];
$this->em->method('getRepository')->with(ShortUrl::class)->willReturn($this->repo); $this->em->method('getRepository')->willReturn($this->repo);
$this->repo->expects($this->exactly(count($urls)))->method('findOneByImportedUrl')->willReturn(null); $this->repo->expects($this->exactly(count($urls)))->method('findOneByImportedUrl')->willReturn(null);
$this->shortCodeHelper->expects($this->exactly(7))->method('ensureShortCodeUniqueness')->willReturnCallback( $this->shortCodeHelper->expects($this->exactly(7))->method('ensureShortCodeUniqueness')->willReturnCallback(
fn ($_, bool $hasCustomSlug) => ! $hasCustomSlug, fn ($_, bool $hasCustomSlug) => ! $hasCustomSlug,
@ -219,7 +219,7 @@ class ImportedLinksProcessorTest extends TestCase
int $amountOfPersistedVisits, int $amountOfPersistedVisits,
ShortUrl|null $foundShortUrl, ShortUrl|null $foundShortUrl,
): void { ): void {
$this->em->method('getRepository')->with(ShortUrl::class)->willReturn($this->repo); $this->em->method('getRepository')->willReturn($this->repo);
$this->repo->expects($this->once())->method('findOneByImportedUrl')->willReturn($foundShortUrl); $this->repo->expects($this->once())->method('findOneByImportedUrl')->willReturn($foundShortUrl);
$this->shortCodeHelper->expects($this->exactly($foundShortUrl === null ? 1 : 0)) $this->shortCodeHelper->expects($this->exactly($foundShortUrl === null ? 1 : 0))
->method('ensureShortCodeUniqueness') ->method('ensureShortCodeUniqueness')
@ -276,7 +276,7 @@ class ImportedLinksProcessorTest extends TestCase
#[Test, DataProvider('provideFoundShortUrls')] #[Test, DataProvider('provideFoundShortUrls')]
public function visitsArePersistedWithProperShortUrl(ShortUrl $originalShortUrl, ShortUrl|null $foundShortUrl): void public function visitsArePersistedWithProperShortUrl(ShortUrl $originalShortUrl, ShortUrl|null $foundShortUrl): void
{ {
$this->em->method('getRepository')->with(ShortUrl::class)->willReturn($this->repo); $this->em->method('getRepository')->willReturn($this->repo);
$this->repo->expects($this->once())->method('findOneByImportedUrl')->willReturn($originalShortUrl); $this->repo->expects($this->once())->method('findOneByImportedUrl')->willReturn($originalShortUrl);
if (!$originalShortUrl->getId()) { if (!$originalShortUrl->getId()) {
$this->em->expects($this->never())->method('find'); $this->em->expects($this->never())->method('find');

View File

@ -116,7 +116,7 @@ class PersistenceShortUrlRelationResolverTest extends TestCase
{ {
$repo = $this->createMock(DomainRepository::class); $repo = $this->createMock(DomainRepository::class);
$repo->expects($this->exactly(3))->method('findOneBy')->with($this->isArray())->willReturn(null); $repo->expects($this->exactly(3))->method('findOneBy')->with($this->isArray())->willReturn(null);
$this->em->method('getRepository')->with(Domain::class)->willReturn($repo); $this->em->method('getRepository')->willReturn($repo);
$authority = 'foo.com'; $authority = 'foo.com';
$domain1 = $this->resolver->resolveDomain($authority); $domain1 = $this->resolver->resolveDomain($authority);
@ -135,7 +135,7 @@ class PersistenceShortUrlRelationResolverTest extends TestCase
{ {
$tagRepo = $this->createMock(TagRepository::class); $tagRepo = $this->createMock(TagRepository::class);
$tagRepo->expects($this->exactly(6))->method('findOneBy')->with($this->isArray())->willReturn(null); $tagRepo->expects($this->exactly(6))->method('findOneBy')->with($this->isArray())->willReturn(null);
$this->em->method('getRepository')->with(Tag::class)->willReturn($tagRepo); $this->em->method('getRepository')->willReturn($tagRepo);
$tags = ['foo', 'bar']; $tags = ['foo', 'bar'];
[$foo1, $bar1] = $this->resolver->resolveTags($tags); [$foo1, $bar1] = $this->resolver->resolveTags($tags);

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace ShlinkioTest\Shlink\Core\ShortUrl; namespace ShlinkioTest\Shlink\Core\ShortUrl;
use Cake\Chronos\Chronos; use Cake\Chronos\Chronos;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface;
use Laminas\ServiceManager\Exception\ServiceNotFoundException; use Laminas\ServiceManager\Exception\ServiceNotFoundException;
use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\Test;
@ -24,7 +24,7 @@ use Shlinkio\Shlink\Core\ShortUrl\UrlShortener;
class UrlShortenerTest extends TestCase class UrlShortenerTest extends TestCase
{ {
private UrlShortener $urlShortener; private UrlShortener $urlShortener;
private MockObject & EntityManager $em; private MockObject & EntityManagerInterface $em;
private MockObject & ShortUrlTitleResolutionHelperInterface $titleResolutionHelper; private MockObject & ShortUrlTitleResolutionHelperInterface $titleResolutionHelper;
private MockObject & ShortCodeUniquenessHelperInterface $shortCodeHelper; private MockObject & ShortCodeUniquenessHelperInterface $shortCodeHelper;
private MockObject & EventDispatcherInterface $dispatcher; private MockObject & EventDispatcherInterface $dispatcher;
@ -35,12 +35,9 @@ class UrlShortenerTest extends TestCase
$this->titleResolutionHelper = $this->createMock(ShortUrlTitleResolutionHelperInterface::class); $this->titleResolutionHelper = $this->createMock(ShortUrlTitleResolutionHelperInterface::class);
$this->shortCodeHelper = $this->createMock(ShortCodeUniquenessHelperInterface::class); $this->shortCodeHelper = $this->createMock(ShortCodeUniquenessHelperInterface::class);
// FIXME Should use the interface, but it doe snot define wrapInTransaction explicitly $this->em = $this->createMock(EntityManagerInterface::class);
$this->em = $this->createMock(EntityManager::class);
$this->em->method('persist')->willReturnCallback(fn (ShortUrl $shortUrl) => $shortUrl->setId('10')); $this->em->method('persist')->willReturnCallback(fn (ShortUrl $shortUrl) => $shortUrl->setId('10'));
$this->em->method('wrapInTransaction')->with($this->isCallable())->willReturnCallback( $this->em->method('wrapInTransaction')->willReturnCallback(fn (callable $callback) => $callback());
fn (callable $callback) => $callback(),
);
$this->dispatcher = $this->createMock(EventDispatcherInterface::class); $this->dispatcher = $this->createMock(EventDispatcherInterface::class);
$this->repo = $this->createMock(ShortUrlRepositoryInterface::class); $this->repo = $this->createMock(ShortUrlRepositoryInterface::class);

View File

@ -108,14 +108,8 @@ class VisitsStatsHelperTest extends TestCase
range(0, 1), range(0, 1),
); );
$repo2 = $this->createMock(VisitRepository::class); $repo2 = $this->createMock(VisitRepository::class);
$repo2->method('findVisitsByShortCode')->with( $repo2->method('findVisitsByShortCode')->willReturn($list);
$identifier, $repo2->method('countVisitsByShortCode')->willReturn(1);
$this->isInstanceOf(VisitsListFiltering::class),
)->willReturn($list);
$repo2->method('countVisitsByShortCode')->with(
$identifier,
$this->isInstanceOf(VisitsCountFiltering::class),
)->willReturn(1);
$this->em->expects($this->exactly(2))->method('getRepository')->willReturnMap([ $this->em->expects($this->exactly(2))->method('getRepository')->willReturnMap([
[ShortUrl::class, $repo], [ShortUrl::class, $repo],
@ -168,10 +162,8 @@ class VisitsStatsHelperTest extends TestCase
range(0, 1), range(0, 1),
); );
$repo2 = $this->createMock(VisitRepository::class); $repo2 = $this->createMock(VisitRepository::class);
$repo2->method('findVisitsByTag')->with($tag, $this->isInstanceOf(VisitsListFiltering::class))->willReturn( $repo2->method('findVisitsByTag')->willReturn($list);
$list, $repo2->method('countVisitsByTag')->willReturn(1);
);
$repo2->method('countVisitsByTag')->with($tag, $this->isInstanceOf(VisitsCountFiltering::class))->willReturn(1);
$this->em->expects($this->exactly(2))->method('getRepository')->willReturnMap([ $this->em->expects($this->exactly(2))->method('getRepository')->willReturnMap([
[Tag::class, $repo], [Tag::class, $repo],
@ -209,14 +201,8 @@ class VisitsStatsHelperTest extends TestCase
range(0, 1), range(0, 1),
); );
$repo2 = $this->createMock(VisitRepository::class); $repo2 = $this->createMock(VisitRepository::class);
$repo2->method('findVisitsByDomain')->with( $repo2->method('findVisitsByDomain')->willReturn($list);
$domain, $repo2->method('countVisitsByDomain')->willReturn(1);
$this->isInstanceOf(VisitsListFiltering::class),
)->willReturn($list);
$repo2->method('countVisitsByDomain')->with(
$domain,
$this->isInstanceOf(VisitsCountFiltering::class),
)->willReturn(1);
$this->em->expects($this->exactly(2))->method('getRepository')->willReturnMap([ $this->em->expects($this->exactly(2))->method('getRepository')->willReturnMap([
[Domain::class, $repo], [Domain::class, $repo],
@ -239,14 +225,8 @@ class VisitsStatsHelperTest extends TestCase
range(0, 1), range(0, 1),
); );
$repo2 = $this->createMock(VisitRepository::class); $repo2 = $this->createMock(VisitRepository::class);
$repo2->method('findVisitsByDomain')->with( $repo2->method('findVisitsByDomain')->willReturn($list);
Domain::DEFAULT_AUTHORITY, $repo2->method('countVisitsByDomain')->willReturn(1);
$this->isInstanceOf(VisitsListFiltering::class),
)->willReturn($list);
$repo2->method('countVisitsByDomain')->with(
Domain::DEFAULT_AUTHORITY,
$this->isInstanceOf(VisitsCountFiltering::class),
)->willReturn(1);
$this->em->expects($this->exactly(2))->method('getRepository')->willReturnMap([ $this->em->expects($this->exactly(2))->method('getRepository')->willReturnMap([
[Domain::class, $repo], [Domain::class, $repo],

View File

@ -30,9 +30,7 @@ class CreateShortUrlContentNegotiationMiddlewareTest extends TestCase
public function whenNoJsonResponseIsReturnedNoFurtherOperationsArePerformed(): void public function whenNoJsonResponseIsReturnedNoFurtherOperationsArePerformed(): void
{ {
$expectedResp = new Response(); $expectedResp = new Response();
$this->requestHandler->method('handle')->with($this->isInstanceOf(ServerRequestInterface::class))->willReturn( $this->requestHandler->method('handle')->willReturn($expectedResp);
$expectedResp,
);
$resp = $this->middleware->process(new ServerRequest(), $this->requestHandler); $resp = $this->middleware->process(new ServerRequest(), $this->requestHandler);