chore: upgrade phpunit to 12.5

This commit is contained in:
fromme committed 2026-10-01 10:07:05 +02:00
1 parent da039d0527
commit 849da8d471
53 files changed
+827 -851

No files matched your search

+2 -2
View File
@@ -12,11 +12,11 @@
###> phpunit/phpunit ###
/phpunit.xml
.phpunit.result.cache
/.phpunit.cache/
###< phpunit/phpunit ###
###> symfony/phpunit-bridge ###
.phpunit.result.cache
/.phpunit.cache/
/phpunit.xml
###< symfony/phpunit-bridge ###
+3 -9
View File
@@ -5,15 +5,9 @@ if (!ini_get('date.timezone')) {
ini_set('date.timezone', 'UTC');
}
if (is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) {
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
PHPUnit\TextUI\Command::main();
} else {
if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) {
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
if (!is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) {
echo "Unable to find PHPUnit in `vendor/phpunit/phpunit/`. Run `composer install`.\n";
exit(1);
}
require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php';
}
require dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit';
+1 -1
View File
@@ -138,7 +138,7 @@
"fakerphp/faker": "*",
"friendsofphp/php-cs-fixer": "^3.84",
"marcocesarato/php-conventional-changelog": "^1.17",
"phpunit/phpunit": "^9.5",
"phpunit/phpunit": "^12.5",
"rector/rector": "^2.6",
"symfony/browser-kit": "7.4.*",
"symfony/css-selector": "7.4.*",
Generated
+603 -620
View File
File diff suppressed because it is too large. Load diff
+18 -10
View File
@@ -1,20 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<!-- https://docs.phpunit.de/en/12.5/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="tests/bootstrap.php"
convertDeprecationsToExceptions="false"
cacheDirectory=".phpunit.cache"
failOnDeprecation="true"
failOnNotice="true"
failOnWarning="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
displayDetailsOnPhpunitDeprecations="true"
displayDetailsOnPhpunitNotices="true"
>
<php>
<ini name="display_errors" value="1" />
<ini name="error_reporting" value="-1" />
<server name="APP_ENV" value="test" force="true" />
<server name="SHELL_VERBOSITY" value="-1" />
<server name="SYMFONY_PHPUNIT_REMOVE" value="" />
<server name="SYMFONY_PHPUNIT_VERSION" value="9.5" />
</php>
<testsuites>
@@ -23,13 +29,15 @@
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<!-- Symfony triggers its deprecations with @trigger_error(); without
ignoreSuppressionOfDeprecations PHPUnit would swallow them all. -->
<source ignoreSuppressionOfDeprecations="true">
<include>
<directory suffix=".php">src</directory>
<directory>src</directory>
</include>
</coverage>
</source>
<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
</listeners>
<extensions>
<bootstrap class="Symfony\Bridge\PhpUnit\SymfonyExtension" />
</extensions>
</phpunit>
+6 -11
View File
@@ -15,10 +15,12 @@ use App\Entity\Teamer;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
#[AllowMockObjectsWithoutExpectations]
class UserDataHandlerTest extends TestCase
{
private EntityManagerInterface&MockObject $entityManager;
@@ -30,9 +32,7 @@ class UserDataHandlerTest extends TestCase
$this->logger = $this->createMock(LoggerInterface::class);
}
/**
* @dataProvider collectRolesProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('collectRolesProvider')]
public function testCollectRolesImportsAdministrativeRolesAsPendingOnly(CrmAttributesResponse $crmAttributes, array $expectedRoles): void
{
$handler = new UserDataHandler($this->entityManager, $this->logger);
@@ -86,9 +86,8 @@ class UserDataHandlerTest extends TestCase
/**
* The role policy has to be identical whichever identity source claims the role, so
* toPendingRoles() must agree with collectPendingRoles() on equivalent input.
*
* @dataProvider toPendingRolesProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('toPendingRolesProvider')]
public function testToPendingRolesMatchesTheCrmPolicy(array $claimedRoles, CrmAttributesResponse $crmAttributes, array $expectedRoles): void
{
$handler = new UserDataHandler($this->entityManager, $this->logger);
@@ -231,9 +230,7 @@ class UserDataHandlerTest extends TestCase
$this->assertSame('[email protected]', $teamer->getCommunication()?->getEmail());
}
/**
* @dataProvider pendingRolesProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('pendingRolesProvider')]
public function testUpdateLocalUserRefreshesThePendingRoles(
array $roles,
array $claimedRoles,
@@ -441,9 +438,7 @@ class UserDataHandlerTest extends TestCase
$this->assertSame([User::PENDING_ROLES['ROLE_HOUSE_MANAGER']], $user->getPendingRoles());
}
/**
* @dataProvider unapprovableRoleProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('unapprovableRoleProvider')]
public function testApproveRoleRefusesARoleWithoutANomination(array $roles, string $role): void
{
$user = (new User())
+5 -4
View File
@@ -11,6 +11,7 @@ use App\MyEp\Import\TravelExport;
use App\MyEp\Import\TravelExportClient;
use Doctrine\DBAL\Connection;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Symfony\Component\Console\Command\Command;
@@ -87,7 +88,7 @@ class MyEpImportCommandTest extends TestCase
public function testItRefusesToRunWhenTheExportCannotBeRead(): void
{
$client = $this->createMock(TravelExportClient::class);
$client = $this->createStub(TravelExportClient::class);
$client->method('fetchAll')->willThrowException(new ApiException('gateway timeout'));
$tester = new CommandTester(new MyEpImportCommand(
@@ -184,7 +185,7 @@ class MyEpImportCommandTest extends TestCase
int $skipped = 0,
int $pickupsWithoutMasterData = 0,
): CommandTester {
$client = $this->createMock(TravelExportClient::class);
$client = $this->createStub(TravelExportClient::class);
$client->method('fetchAll')->willReturn(
new TravelExport($rows, $skipped, $pickupsWithoutMasterData, '2026-09-29T03:20:00+02:00')
);
@@ -212,9 +213,9 @@ class MyEpImportCommandTest extends TestCase
return $connection;
}
private function writingConnection(int $existingId): Connection&MockObject
private function writingConnection(int $existingId): Connection&Stub
{
$connection = $this->createMock(Connection::class);
$connection = $this->createStub(Connection::class);
$connection->method('fetchOne')->willReturn($existingId);
return $connection;
+4 -12
View File
@@ -14,9 +14,7 @@ class SeasonCalendarTest extends TestCase
return new SeasonCalendar('11-01', '04-01');
}
/**
* @dataProvider winterDates
*/
#[\PHPUnit\Framework\Attributes\DataProvider('winterDates')]
public function testSeasonYearForTheWrappingWinterWindow(string $date, ?int $expected): void
{
$this->assertSame($expected, $this->winter()->seasonYearFor(new \DateTimeImmutable($date)));
@@ -44,9 +42,7 @@ class SeasonCalendarTest extends TestCase
$this->assertSame('außerhalb der Saison', $calendar->label(null));
}
/**
* @dataProvider summerDates
*/
#[\PHPUnit\Framework\Attributes\DataProvider('summerDates')]
public function testSeasonYearForANonWrappingWindow(string $date, ?int $expected): void
{
$calendar = new SeasonCalendar('06-01', '09-01');
@@ -71,9 +67,7 @@ class SeasonCalendarTest extends TestCase
(new SeasonCalendar('xx-yy', '04-01'))->seasonYearFor(new \DateTimeImmutable('2025-01-01'));
}
/**
* @dataProvider currentOrUpcomingDates
*/
#[\PHPUnit\Framework\Attributes\DataProvider('currentOrUpcomingDates')]
public function testCurrentOrUpcomingSeasonYear(string $date, int $expected): void
{
$this->assertSame(
@@ -117,9 +111,7 @@ class SeasonCalendarTest extends TestCase
$this->assertSame('2025-09-30', $end->format('Y-m-d'));
}
/**
* @dataProvider provideUpcomingSeasonDates
*/
#[\PHPUnit\Framework\Attributes\DataProvider('provideUpcomingSeasonDates')]
public function testTheCurrentOrUpcomingSeasonYear(string $date, int $expected): void
{
$calendar = new SeasonCalendar('11-01', '04-01');
+1 -3
View File
@@ -31,9 +31,7 @@ class SeasonTaskTest extends TestCase
$this->assertSame($labels, array_unique($labels));
}
/**
* @dataProvider entries
*/
#[\PHPUnit\Framework\Attributes\DataProvider('entries')]
public function testTheAgreedEntryList(
SeasonTask $task,
string $label,
@@ -67,10 +67,10 @@ class DestinationTraitTest extends TestCase
*/
private function harness(?Hotel $hotel, array $pickups = []): object
{
$hotelProvider = $this->createMock(HotelDataProvider::class);
$hotelProvider = $this->createStub(HotelDataProvider::class);
$hotelProvider->method('get')->willReturn($hotel);
$pickupProvider = $this->createMock(PickupDataProvider::class);
$pickupProvider = $this->createStub(PickupDataProvider::class);
$pickupProvider->method('get')->willReturnCallback(fn ($id) => $pickups[$id] ?? null);
return new class($hotelProvider, $pickupProvider) {
@@ -79,9 +79,8 @@ class ApplicationFormControllerTest extends WebTestCase
* date element straight to json_encode sends an object, and its keys are the whole diagnosis.
*
* Never the value itself - a rejected payload is still personal data.
*
* @dataProvider unusableBirthDateTypes
*/
#[\PHPUnit\Framework\Attributes\DataProvider('unusableBirthDateTypes')]
public function testARejectionNamesTheShapeThatArrived(mixed $birthDate, string $received): void
{
$this->post(['birthDate' => $birthDate] + $this->payload());
@@ -258,9 +257,7 @@ class ApplicationFormControllerTest extends WebTestCase
$this->assertSame([], $submission->getDetails());
}
/**
* @dataProvider requiredFields
*/
#[\PHPUnit\Framework\Attributes\DataProvider('requiredFields')]
public function testAPayloadMissingARequiredFieldIsRejected(string $field): void
{
$payload = $this->payload();
@@ -277,9 +274,8 @@ class ApplicationFormControllerTest extends WebTestCase
/**
* An empty string is the shape a form posts for a field the visitor left blank, and it is as
* unusable as an absent key - except for eu, where "" is a lawful no and has its own case.
*
* @dataProvider requiredFields
*/
#[\PHPUnit\Framework\Attributes\DataProvider('requiredFields')]
public function testAPayloadWithAnEmptyRequiredFieldIsRejected(string $field): void
{
if ('eu' === $field) {
@@ -315,9 +311,8 @@ class ApplicationFormControllerTest extends WebTestCase
* The one field whose format is nailed down: provisioning parses it as a date, so the day the
* TYPO3 side switches a form back to a free-text birthday has to be a 400 here rather than a
* failure in front of a reviewer weeks later.
*
* @dataProvider unusableBirthDates
*/
#[\PHPUnit\Framework\Attributes\DataProvider('unusableBirthDates')]
public function testAnUnusableBirthDateIsRejected(string $birthDate): void
{
$this->post(['birthDate' => $birthDate] + $this->payload());
@@ -380,9 +375,8 @@ class ApplicationFormControllerTest extends WebTestCase
/**
* Case is the sender's business, not a reason to lose an application: every spelling a form
* can post lands on the same stored value.
*
* @dataProvider genderSpellings
*/
#[\PHPUnit\Framework\Attributes\DataProvider('genderSpellings')]
public function testAGenderIsReadWhateverItsCase(string $posted, string $stored): void
{
$this->post(['gender' => $posted] + $this->payload());
+4 -6
View File
@@ -44,9 +44,7 @@ class EmailTextMailRenderingTest extends KernelTestCase
EmailTextKey::APPLICATION_FORM_FOLLOW_UP,
];
/**
* @dataProvider provideKeys
*/
#[\PHPUnit\Framework\Attributes\DataProvider('provideKeys')]
public function testTheMailRenders(EmailTextKey $key): void
{
self::bootKernel();
@@ -63,7 +61,7 @@ class EmailTextMailRenderingTest extends KernelTestCase
// Renders the delivered wording: the test environment has no database, and the
// defaults are what a mail falls back to anyway.
$repository = $this->createMock(EmailTextRepository::class);
$repository = $this->createStub(EmailTextRepository::class);
$repository->method('findByKey')->willReturn(null);
$text = (new EmailTextRenderer(
@@ -152,7 +150,7 @@ class EmailTextMailRenderingTest extends KernelTestCase
self::bootKernel();
$container = self::getContainer();
$repository = $this->createMock(EmailTextRepository::class);
$repository = $this->createStub(EmailTextRepository::class);
$repository->method('findByKey')->willReturn(null);
$renderer = new EmailTextRenderer(
@@ -173,7 +171,7 @@ class EmailTextMailRenderingTest extends KernelTestCase
self::bootKernel();
$container = self::getContainer();
$repository = $this->createMock(EmailTextRepository::class);
$repository = $this->createStub(EmailTextRepository::class);
$repository->method('findByKey')->willReturn(null);
$text = (new EmailTextRenderer(
+3 -3
View File
@@ -228,7 +228,7 @@ class EmailTextRendererTest extends KernelTestCase
*/
public function testGivenValuesAreRenderedInsteadOfTheStoredOnes(): void
{
$repository = $this->createMock(EmailTextRepository::class);
$repository = $this->createStub(EmailTextRepository::class);
$repository
->method('findByKey')
->willReturn($this->emailText(subject: 'Gespeichert', body: 'Gespeicherter Text'))
@@ -264,7 +264,7 @@ class EmailTextRendererTest extends KernelTestCase
$renderer = new EmailTextRenderer(
self::getContainer()->get(EmailTextCatalog::class),
$this->createMock(EmailTextRepository::class),
$this->createStub(EmailTextRepository::class),
self::getContainer()->get(MailBodyRenderer::class)
);
@@ -286,7 +286,7 @@ class EmailTextRendererTest extends KernelTestCase
*/
private function render(?EmailText $emailText, array $placeholders): \App\Model\RenderedEmailTextDto
{
$repository = $this->createMock(EmailTextRepository::class);
$repository = $this->createStub(EmailTextRepository::class);
$repository
->method('findByKey')
->willReturn($emailText)
@@ -13,16 +13,19 @@ use App\EventListener\DatevEmailSubscriber;
use App\Model\EmailPathAttachmentDto;
use App\Service\Upload\UploadHandler;
use Flagception\Manager\FeatureManagerInterface;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
#[AllowMockObjectsWithoutExpectations]
class DatevEmailSubscriberTest extends TestCase
{
private Mailer&MockObject $mailer;
private UploadHandler&MockObject $uploadHandler;
private LoggerInterface&MockObject $logger;
private FeatureManagerInterface&MockObject $featureManager;
private FeatureManagerInterface&Stub $featureManager;
private DatevEmailSubscriber $subscriber;
protected function setUp(): void
@@ -30,8 +33,8 @@ class DatevEmailSubscriberTest extends TestCase
$this->mailer = $this->createMock(Mailer::class);
$this->uploadHandler = $this->createMock(UploadHandler::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->featureManager = $this->createMock(FeatureManagerInterface::class);
$this->featureManager->method('isActive')->with('datev_email')->willReturn(true);
$this->featureManager = $this->createStub(FeatureManagerInterface::class);
$this->featureManager->method('isActive')->willReturnCallback(static fn (string $name): bool => 'datev_email' === $name);
$this->subscriber = new DatevEmailSubscriber(
$this->mailer,
@@ -53,7 +56,7 @@ class DatevEmailSubscriberTest extends TestCase
public function testSkipsNonInvoiceDocuments(): void
{
$document = $this->createMock(Upload::class);
$document = $this->createStub(Upload::class);
$document->method('getType')->willReturn(Upload::TYPE_CONTRACT);
$this->mailer
@@ -66,7 +69,7 @@ class DatevEmailSubscriberTest extends TestCase
public function testSkipsDocumentWithoutDisposition(): void
{
$document = $this->createMock(Upload::class);
$document = $this->createStub(Upload::class);
$document->method('getType')->willReturn(Upload::TYPE_INVOICE);
$document->method('getDisposition')->willReturn(null);
$document->method('getId')->willReturn(1);
@@ -86,10 +89,10 @@ class DatevEmailSubscriberTest extends TestCase
public function testSkipsDispositionWithoutTeamer(): void
{
$disposition = $this->createMock(Disposition::class);
$disposition = $this->createStub(Disposition::class);
$disposition->method('getTeamer')->willReturn(null);
$document = $this->createMock(Upload::class);
$document = $this->createStub(Upload::class);
$document->method('getType')->willReturn(Upload::TYPE_INVOICE);
$document->method('getDisposition')->willReturn($disposition);
$document->method('getId')->willReturn(2);
@@ -109,13 +112,13 @@ class DatevEmailSubscriberTest extends TestCase
public function testSkipsMissingAttachmentFile(): void
{
$teamer = $this->createMock(Teamer::class);
$teamer = $this->createStub(Teamer::class);
$teamer->method('getFullName')->willReturn('Doe, John');
$disposition = $this->createMock(Disposition::class);
$disposition = $this->createStub(Disposition::class);
$disposition->method('getTeamer')->willReturn($teamer);
$document = $this->createMock(Upload::class);
$document = $this->createStub(Upload::class);
$document->method('getType')->willReturn(Upload::TYPE_INVOICE);
$document->method('getDisposition')->willReturn($disposition);
$document->method('getId')->willReturn(3);
@@ -145,14 +148,14 @@ class DatevEmailSubscriberTest extends TestCase
public function testSendsEmailWithAttachment(): void
{
$teamer = $this->createMock(Teamer::class);
$teamer = $this->createStub(Teamer::class);
$teamer->method('getFullName')->willReturn('Doe, John');
$teamer->method('__toString')->willReturn('Doe, John');
$disposition = $this->createMock(Disposition::class);
$disposition = $this->createStub(Disposition::class);
$disposition->method('getTeamer')->willReturn($teamer);
$document = $this->createMock(Upload::class);
$document = $this->createStub(Upload::class);
$document->method('getDisposition')->willReturn($disposition);
$document->method('getType')->willReturn(Upload::TYPE_INVOICE);
$document->method('getId')->willReturn(42);
@@ -21,6 +21,7 @@ use App\EventListener\EmailNotificationSubscriber;
use App\Model\ApplicationStatusDto;
use App\Repository\UserRepository;
use App\Service\Pdf\ContractRenderer;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -28,6 +29,7 @@ use PHPUnit\Framework\TestCase;
* A deleted teamer must never be mailed again - this is the point of the deletion, so
* every handler that writes to a teamer is covered here.
*/
#[AllowMockObjectsWithoutExpectations]
class EmailNotificationSubscriberTest extends TestCase
{
private Mailer&MockObject $mailer;
@@ -41,9 +43,9 @@ class EmailNotificationSubscriberTest extends TestCase
$this->subscriber = new EmailNotificationSubscriber(
$this->mailer,
$this->createMock(UserRepository::class),
$this->createStub(UserRepository::class),
$this->contractRenderer,
$this->createMock(MailPlaceholderFactory::class),
$this->createStub(MailPlaceholderFactory::class),
7,
);
}
@@ -16,12 +16,15 @@ use App\EventListener\InvalidateApplicationsListener;
use App\Repository\ApplicationRepository;
use Carbon\CarbonPeriodImmutable;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Contracts\EventDispatcher\Event;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
#[AllowMockObjectsWithoutExpectations]
class InvalidateApplicationsListenerTest extends TestCase
{
private ApplicationRepository&MockObject $applicationRepository;
@@ -38,7 +41,7 @@ class InvalidateApplicationsListenerTest extends TestCase
{
$this->applicationRepository = $this->createMock(ApplicationRepository::class);
$this->entityManager = $this->createMock(EntityManagerInterface::class);
$eventDispatcher = $this->createMock(EventDispatcherInterface::class);
$eventDispatcher = $this->createStub(EventDispatcherInterface::class);
$this->removedApplications = [];
$this->dispatchedEvents = [];
@@ -62,13 +65,13 @@ class InvalidateApplicationsListenerTest extends TestCase
$this->applicationRepository,
$this->entityManager,
$eventDispatcher,
$this->createMock(LoggerInterface::class)
$this->createStub(LoggerInterface::class)
);
}
public function testIgnoresNonContractDocuments(): void
{
$document = $this->createMock(Upload::class);
$document = $this->createStub(Upload::class);
$document->method('getType')->willReturn(Upload::TYPE_INVOICE);
$this->applicationRepository->expects($this->never())->method('findOverlappingForTeamer');
@@ -188,51 +191,51 @@ class InvalidateApplicationsListenerTest extends TestCase
}
}
private function createTeamer(bool $allowOverlapping = false): Teamer&MockObject
private function createTeamer(bool $allowOverlapping = false): Teamer&Stub
{
$teamer = $this->createMock(Teamer::class);
$teamer = $this->createStub(Teamer::class);
$teamer->method('isAllowOverlappingApplications')->willReturn($allowOverlapping);
$teamer->method('getUuid')->willReturn('teamer-uuid');
return $teamer;
}
private function createContract(?CarbonPeriodImmutable $period, Teamer $teamer): Upload&MockObject
private function createContract(?CarbonPeriodImmutable $period, Teamer $teamer): Upload&Stub
{
$assignment = $this->createMock(Assignment::class);
$assignment = $this->createStub(Assignment::class);
if (null === $period) {
$assignment->method('getDestination')->willReturn(null);
} else {
$destination = $this->createMock(Destination::class);
$destination = $this->createStub(Destination::class);
$destination->method('getDateFrom')->willReturn($period->getStartDate()->toDateTimeImmutable());
$destination->method('getDateTo')->willReturn($period->getEndDate()->toDateTimeImmutable());
$assignment->method('getDestination')->willReturn($destination);
}
$disposition = $this->createMock(Disposition::class);
$disposition = $this->createStub(Disposition::class);
$disposition->method('getAssignment')->willReturn($assignment);
$disposition->method('getTeamer')->willReturn($teamer);
$document = $this->createMock(Upload::class);
$document = $this->createStub(Upload::class);
$document->method('getType')->willReturn(Upload::TYPE_CONTRACT);
$document->method('getDisposition')->willReturn($disposition);
return $document;
}
private function createApplication(): Application&MockObject
private function createApplication(): Application&Stub
{
$destination = $this->createMock(Destination::class);
$destination = $this->createStub(Destination::class);
$destination->method('getHotelCode')->willReturn('TST');
$destination->method('getDateFrom')->willReturn(new \DateTimeImmutable('2025-01-12'));
$destination->method('getDateTo')->willReturn(new \DateTimeImmutable('2025-01-18'));
$assignment = $this->createMock(Assignment::class);
$assignment = $this->createStub(Assignment::class);
$assignment->method('getDestination')->willReturn($destination);
$assignment->method('getUuid')->willReturn('assignment-uuid');
$application = $this->createMock(Application::class);
$application = $this->createStub(Application::class);
$application->method('getUuid')->willReturn('application-uuid');
$application->method('getAssignment')->willReturn($assignment);
@@ -24,6 +24,7 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\Event\PostFlushEventArgs;
use Doctrine\ORM\UnitOfWork;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -32,6 +33,7 @@ use PHPUnit\Framework\TestCase;
* profile change overwrites its own history - so the thing worth pinning is *when* a row
* gets written and when it must not.
*/
#[AllowMockObjectsWithoutExpectations]
class StatisticsChangeSetListenerTest extends TestCase
{
private StatisticsRecorder&MockObject $recorder;
@@ -501,7 +503,7 @@ class StatisticsChangeSetListenerTest extends TestCase
$byEntity[$entity] = $changeSet;
}
$unitOfWork = $this->createMock(UnitOfWork::class);
$unitOfWork = $this->createStub(UnitOfWork::class);
$unitOfWork->method('getScheduledEntityUpdates')->willReturn($entities);
$unitOfWork->method('getScheduledEntityInsertions')->willReturn($insertions);
$unitOfWork->method('getScheduledEntityDeletions')->willReturn($deletions);
@@ -510,7 +512,7 @@ class StatisticsChangeSetListenerTest extends TestCase
->willReturnCallback(static fn (object $entity): array => $byEntity[$entity] ?? [])
;
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager = $this->createStub(EntityManagerInterface::class);
$entityManager->method('getUnitOfWork')->willReturn($unitOfWork);
return new OnFlushEventArgs($entityManager);
@@ -518,7 +520,7 @@ class StatisticsChangeSetListenerTest extends TestCase
private function postFlushArgs(): PostFlushEventArgs
{
return new PostFlushEventArgs($this->createMock(EntityManagerInterface::class));
return new PostFlushEventArgs($this->createStub(EntityManagerInterface::class));
}
/**
+1
View File
@@ -14,6 +14,7 @@ use Symfony\Component\Form\Test\TypeTestCase;
* The rows attribute is deliberately not part of it: textarea_autosize_controller.js
* overwrites rows on connect, which is why the floor travels as min_rows instead.
*/
#[\PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations]
class AutosizeTextareaTypeTest extends TypeTestCase
{
public function testTheControllerAndItsResizeActionAreWiredUp(): void
+1 -1
View File
@@ -58,7 +58,7 @@ class InjectUserProcessorTest extends TestCase
private function process(?InMemoryUser $user, string $sapi = 'fpm-fcgi'): LogRecord
{
$security = $this->createMock(Security::class);
$security = $this->createStub(Security::class);
$security->method('getUser')->willReturn($user);
$processor = new InjectUserProcessor($security, $sapi);
+1 -1
View File
@@ -20,7 +20,7 @@ class UserDataProcessorTest extends TestCase
{
public function testAnApiFirewallUserGetsNoIdInsteadOfAnError(): void
{
$security = $this->createMock(Security::class);
$security = $this->createStub(Security::class);
$security->method('getUser')->willReturn(new InMemoryUser('api', null, ['ROLE_API']));
$security->method('getToken')->willReturn(null);
+1 -2
View File
@@ -58,9 +58,8 @@ class TeamerMenuBackItemTest extends KernelTestCase
/**
* The regression guard: reachable e.g. after the status update in
* Admin\Teamer\SkillsController, which redirects without carrying "r" forward.
*
* @dataProvider builderProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('builderProvider')]
public function testWithoutAnyReturnUrlTheOverviewIsLinked(string $builderClass): void
{
$this->pushRequest();
+2 -5
View File
@@ -27,9 +27,7 @@ class DestinationDtoTest extends TestCase
$this->assertSame(['at', 'ch', 'fr', 'it', 'de', 'nl'], DestinationDto::countryCodes());
}
/**
* @dataProvider isoCountryCodes
*/
#[\PHPUnit\Framework\Attributes\DataProvider('isoCountryCodes')]
public function testAnIsoCountryCodeIsAccepted(string $code): void
{
$this->assertCount(0, $this->validateCountry($code));
@@ -37,9 +35,8 @@ class DestinationDtoTest extends TestCase
/**
* The four that the form offered and the constraint refused.
*
* @dataProvider busProNetCountryAbbreviations
*/
#[\PHPUnit\Framework\Attributes\DataProvider('busProNetCountryAbbreviations')]
public function testABusProNetAbbreviationIsNoLongerAccepted(string $abbreviation): void
{
$this->assertCount(1, $this->validateCountry($abbreviation));
+1 -2
View File
@@ -14,9 +14,8 @@ class ApiClientTest extends TestCase
/**
* The whole point of the calendar-month argument: the app never has to know that the
* API counts from zero.
*
* @dataProvider provideMonths
*/
#[\PHPUnit\Framework\Attributes\DataProvider('provideMonths')]
public function testItTranslatesTheCalendarMonthIntoTheApiIndex(int $month, string $expectedPath): void
{
$requested = null;
+9 -6
View File
@@ -13,7 +13,9 @@ use App\Entity\User;
use App\RequiredTeamerCheck\RequiredTeamerCheckRegistry;
use App\Security\BpnAuthenticator;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -23,14 +25,15 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
#[AllowMockObjectsWithoutExpectations]
class BpnAuthenticatorTest extends TestCase
{
private ApiClient&MockObject $apiClient;
private ApiClient&Stub $apiClient;
private UserDataHandler&MockObject $userDataHandler;
protected function setUp(): void
{
$this->apiClient = $this->createMock(ApiClient::class);
$this->apiClient = $this->createStub(ApiClient::class);
$this->userDataHandler = $this->createMock(UserDataHandler::class);
}
@@ -148,12 +151,12 @@ class BpnAuthenticatorTest extends TestCase
private function loadUser(): ?User
{
$authenticator = new BpnAuthenticator(
$this->createMock(UrlGeneratorInterface::class),
$this->createMock(EntityManagerInterface::class),
$this->createStub(UrlGeneratorInterface::class),
$this->createStub(EntityManagerInterface::class),
$this->apiClient,
$this->createMock(LoggerInterface::class),
$this->createStub(LoggerInterface::class),
$this->userDataHandler,
$this->createMock(RequiredTeamerCheckRegistry::class),
$this->createStub(RequiredTeamerCheckRegistry::class),
);
$request = new Request(request: [
+8 -6
View File
@@ -13,6 +13,7 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Flagception\Manager\FeatureManagerInterface;
use League\OAuth2\Client\Token\AccessToken;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
@@ -25,6 +26,7 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
#[AllowMockObjectsWithoutExpectations]
class MyEpAuthenticatorTest extends TestCase
{
private EntityManagerInterface&MockObject $entityManager;
@@ -425,21 +427,21 @@ class MyEpAuthenticatorTest extends TestCase
private function createAuthenticator(array $userinfo, bool $featureActive = true, ?MockHttpClient $httpClient = null): MyEpAuthenticator
{
$client = $this->createMock(MyEpClient::class);
$client = $this->createStub(MyEpClient::class);
$client->method('fetchAccessToken')->willReturn(new AccessToken(['access_token' => 'token']));
$featureManager = $this->createMock(FeatureManagerInterface::class);
$featureManager = $this->createStub(FeatureManagerInterface::class);
$featureManager->method('isActive')->willReturn($featureActive);
return new MyEpAuthenticator(
$client,
$httpClient ?? $this->userinfoClient($userinfo),
new UserDataHandler($this->entityManager, $this->createMock(LoggerInterface::class)),
new UserDataHandler($this->entityManager, $this->createStub(LoggerInterface::class)),
$this->entityManager,
$this->createMock(UrlGeneratorInterface::class),
$this->createMock(LoggerInterface::class),
$this->createStub(UrlGeneratorInterface::class),
$this->createStub(LoggerInterface::class),
$featureManager,
$this->createMock(RequiredTeamerCheckRegistry::class),
$this->createStub(RequiredTeamerCheckRegistry::class),
);
}
}
+2 -2
View File
@@ -137,13 +137,13 @@ class MyEpClientTest extends TestCase
private function createClient(): MyEpClient
{
$urlGenerator = $this->createMock(UrlGeneratorInterface::class);
$urlGenerator = $this->createStub(UrlGeneratorInterface::class);
$urlGenerator
->method('generate')
->willReturn('https://myep-team.example.org/myep-auth/check')
;
return new MyEpClient($urlGenerator, $this->createMock(LoggerInterface::class), [
return new MyEpClient($urlGenerator, $this->createStub(LoggerInterface::class), [
'myep_oauth2_client_id' => 'client-id',
'myep_oauth2_client_secret' => 'client-secret',
'myep_oauth2_url_authorize' => 'https://my.example.org/authorize',
@@ -19,10 +19,7 @@ class DriverLicenseRequiredCheckTest extends TestCase
$this->check = new DriverLicenseRequiredCheck();
}
/**
* @dataProvider mixedRoleProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('mixedRoleProvider')]
public function testDoesNotApplyToExcludedMixedRoleUsersWithTeamerRole(string $excludedRole): void
{
$user = $this->createTeamerUser();
@@ -31,7 +28,7 @@ class DriverLicenseRequiredCheckTest extends TestCase
$this->assertFalse($this->check->appliesTo($user));
}
public function mixedRoleProvider(): array
public static function mixedRoleProvider(): array
{
return [
['ROLE_TEAM_ADMIN'],
@@ -19,9 +19,7 @@ class FinancialDataRequiredCheckTest extends TestCase
$this->check = new FinancialDataRequiredCheck();
}
/**
* @dataProvider mixedRoleProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('mixedRoleProvider')]
public function testDoesNotApplyToExcludedMixedRoleUsersWithTeamerRole(string $excludedRole): void
{
$user = $this->createTeamerUser();
@@ -30,7 +28,7 @@ class FinancialDataRequiredCheckTest extends TestCase
$this->assertFalse($this->check->appliesTo($user));
}
public function mixedRoleProvider(): array
public static function mixedRoleProvider(): array
{
return [
['ROLE_TEAM_ADMIN'],
@@ -76,9 +74,7 @@ class FinancialDataRequiredCheckTest extends TestCase
$this->assertFalse($this->check->isSatisfied($user));
}
/**
* @dataProvider missingBankAccountFieldProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('missingBankAccountFieldProvider')]
public function testIsNotSatisfiedWhenBankAccountFieldIsMissing(string $setter): void
{
$bankAccount = $this->createBankAccount();
@@ -93,7 +89,7 @@ class FinancialDataRequiredCheckTest extends TestCase
$this->assertFalse($this->check->isSatisfied($user));
}
public function missingBankAccountFieldProvider(): array
public static function missingBankAccountFieldProvider(): array
{
return [
['setIban'],
@@ -19,9 +19,7 @@ class MealPreferenceRequiredCheckTest extends TestCase
$this->check = new MealPreferenceRequiredCheck();
}
/**
* @dataProvider mixedRoleProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('mixedRoleProvider')]
public function testDoesNotApplyToExcludedMixedRoleUsersWithTeamerRole(string $excludedRole): void
{
$user = $this->createTeamerUser();
@@ -30,7 +28,7 @@ class MealPreferenceRequiredCheckTest extends TestCase
$this->assertFalse($this->check->appliesTo($user));
}
public function mixedRoleProvider(): array
public static function mixedRoleProvider(): array
{
return [
['ROLE_TEAM_ADMIN'],
@@ -30,9 +30,7 @@ class PersonalDataVerificationRequiredCheckTest extends TestCase
$this->assertTrue($this->createCheck()->appliesTo($user));
}
/**
* @dataProvider mixedRoleProvider
*/
#[\PHPUnit\Framework\Attributes\DataProvider('mixedRoleProvider')]
public function testDoesNotApplyToExcludedMixedRoleUsersWithTeamerRole(string $excludedRole): void
{
$user = (new User())->setRoles([$excludedRole, 'ROLE_TEAMER']);
@@ -40,7 +38,7 @@ class PersonalDataVerificationRequiredCheckTest extends TestCase
$this->assertFalse($this->createCheck()->appliesTo($user));
}
public function mixedRoleProvider(): array
public static function mixedRoleProvider(): array
{
return [
['ROLE_TEAM_ADMIN'],
+9 -14
View File
@@ -10,7 +10,7 @@ use App\Entity\Disposition;
use App\Entity\Teamer;
use App\Entity\User;
use App\Security\Voter\DispositionVoter;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
@@ -23,16 +23,14 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
*/
class DispositionVoterTest extends TestCase
{
private Security&MockObject $security;
private Security&Stub $security;
protected function setUp(): void
{
$this->security = $this->createMock(Security::class);
$this->security = $this->createStub(Security::class);
}
/**
* @dataProvider documentAndFeedbackAttributes
*/
#[\PHPUnit\Framework\Attributes\DataProvider('documentAndFeedbackAttributes')]
public function testAnAdminIsDeniedOnASkipFormalitiesAssignment(string $attribute): void
{
$this->security->method('isGranted')->willReturn(true);
@@ -46,9 +44,8 @@ class DispositionVoterTest extends TestCase
/**
* The same admin on a normal assignment must still get through - the flag is the only thing
* that may take these away.
*
* @dataProvider documentAndFeedbackAttributes
*/
#[\PHPUnit\Framework\Attributes\DataProvider('documentAndFeedbackAttributes')]
public function testTheSameAdminIsGrantedOnANormalAssignment(string $attribute): void
{
$this->security->method('isGranted')->willReturn(true);
@@ -91,9 +88,8 @@ class DispositionVoterTest extends TestCase
* transition, because there is none to derive it from: while the Honorarnote is being checked
* the state machine offers nothing at all, and that is exactly when receipts must stay
* manageable.
*
* @dataProvider receiptWindowStatuses
*/
#[\PHPUnit\Framework\Attributes\DataProvider('receiptWindowStatuses')]
public function testTheReceiptWindowIsTheTwoInvoiceStates(string $status, bool $expected): void
{
$this->security->method('isGranted')->willReturn(true);
@@ -139,9 +135,8 @@ class DispositionVoterTest extends TestCase
/**
* The owning teamer gets in without being administrative; anyone else's teamer does not.
*
* @dataProvider receiptOwnership
*/
#[\PHPUnit\Framework\Attributes\DataProvider('receiptOwnership')]
public function testOnlyTheOwningTeamerMayManageTheirReceipts(bool $owning, bool $expected): void
{
$this->security
@@ -158,7 +153,7 @@ class DispositionVoterTest extends TestCase
$user = (new User())->setTeamer($owning ? $teamer : new Teamer());
$token = $this->createMock(TokenInterface::class);
$token = $this->createStub(TokenInterface::class);
$token->method('getUser')->willReturn($user);
$this->assertSame(
@@ -181,7 +176,7 @@ class DispositionVoterTest extends TestCase
private function vote(string $attribute, Disposition $disposition): int
{
return (new DispositionVoter($this->security))->vote(
$this->createMock(TokenInterface::class),
$this->createStub(TokenInterface::class),
$disposition,
[$attribute],
);
+5 -6
View File
@@ -9,7 +9,7 @@ use App\Entity\Teamer;
use App\Entity\Upload;
use App\Entity\User;
use App\Security\Voter\UploadVoter;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
@@ -22,11 +22,11 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
*/
class UploadVoterTest extends TestCase
{
private Security&MockObject $security;
private Security&Stub $security;
protected function setUp(): void
{
$this->security = $this->createMock(Security::class);
$this->security = $this->createStub(Security::class);
$this->security
->method('isGranted')
->willReturnCallback(static fn (string $role): bool => 'ROLE_TEAMER' === $role)
@@ -68,9 +68,8 @@ class UploadVoterTest extends TestCase
/**
* Downloading is all the new rule grants: the file stays the office's, so the teamer it was
* issued to may not delete it or reach it through any other attribute.
*
* @dataProvider otherAttributes
*/
#[\PHPUnit\Framework\Attributes\DataProvider('otherAttributes')]
public function testTheNewRuleGrantsNothingButDownloading(string $attribute): void
{
$teamer = new Teamer();
@@ -124,7 +123,7 @@ class UploadVoterTest extends TestCase
private function vote(string $attribute, Upload $upload, Teamer $teamer): int
{
$token = $this->createMock(TokenInterface::class);
$token = $this->createStub(TokenInterface::class);
$token->method('getUser')->willReturn((new User())->setTeamer($teamer));
return (new UploadVoter($this->security))->vote($token, $upload, [$attribute]);
+5 -6
View File
@@ -6,7 +6,7 @@ namespace App\Tests\Security\Voter;
use App\Entity\User;
use App\Security\Voter\UserVoter;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
@@ -14,11 +14,11 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
class UserVoterTest extends TestCase
{
private Security&MockObject $security;
private Security&Stub $security;
protected function setUp(): void
{
$this->security = $this->createMock(Security::class);
$this->security = $this->createStub(Security::class);
}
public function testSuperAdminMayEditOtherUsers(): void
@@ -59,10 +59,9 @@ class UserVoterTest extends TestCase
{
$this->security
->method('isGranted')
->with('IS_IMPERSONATOR')
->willReturn($isImpersonator);
->willReturnCallback(static fn (mixed $attribute): bool => 'IS_IMPERSONATOR' === $attribute && $isImpersonator);
$token = $this->createMock(TokenInterface::class);
$token = $this->createStub(TokenInterface::class);
$token
->method('getUser')
->willReturn($currentUser);
@@ -22,9 +22,7 @@ use Symfony\Component\HttpFoundation\RequestStack;
*/
class AbstractFilterHandlerTest extends TestCase
{
/**
* @dataProvider legacyCountries
*/
#[\PHPUnit\Framework\Attributes\DataProvider('legacyCountries')]
public function testALegacyCountryIsTranslatedToItsIsoCode(?string $stored, ?string $expected): void
{
$this->assertSame($expected, $this->handler()->translate($stored));
@@ -67,7 +65,7 @@ class AbstractFilterHandlerTest extends TestCase
private function handler(): object
{
return new class($this->createMock(RequestStack::class), $this->createMock(EntityManagerInterface::class)) extends AbstractFilterHandler {
return new class($this->createStub(RequestStack::class), $this->createStub(EntityManagerInterface::class)) extends AbstractFilterHandler {
protected string $modelClass = AssignmentFilterDto::class;
public function translate(?string $country): ?string
@@ -87,6 +87,6 @@ class TeamerFilterHandlerTest extends TestCase
$requestStack = new RequestStack();
$requestStack->push($request);
return new TeamerFilterHandler($requestStack, $this->createMock(EntityManagerInterface::class));
return new TeamerFilterHandler($requestStack, $this->createStub(EntityManagerInterface::class));
}
}
@@ -11,7 +11,7 @@ use App\Entity\Teamer;
use App\Repository\DispositionRepository;
use App\Service\Cron\DispositionStatusService;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
@@ -24,14 +24,14 @@ use Psr\Log\NullLogger;
*/
class DispositionStatusServiceTest extends TestCase
{
private DispositionRepository&MockObject $repository;
private DispositionRepository&Stub $repository;
private DispositionStatusService $service;
protected function setUp(): void
{
$this->repository = $this->createMock(DispositionRepository::class);
$this->repository = $this->createStub(DispositionRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager = $this->createStub(EntityManagerInterface::class);
$entityManager
->method('getRepository')
->willReturn($this->repository)
@@ -17,6 +17,7 @@ use App\Repository\SeasonAssignmentTaskRepository;
use App\Service\Cron\SeasonTaskReminderService;
use App\Service\Season\SeasonAssignmentLabeler;
use App\Service\Season\SeasonTaskDeadlineResolver;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
@@ -26,6 +27,7 @@ use Psr\Log\NullLogger;
* anyone twice. That property, and what does and does not silence a reminder, is what is pinned
* here - the queries behind them are asserted in the repository test.
*/
#[AllowMockObjectsWithoutExpectations]
class SeasonTaskReminderServiceTest extends TestCase
{
private SeasonAssignmentTaskRepository&MockObject $repository;
@@ -14,6 +14,7 @@ use App\Entity\Embeddable\Communication;
use App\Entity\Teamer;
use App\Repository\DispositionRepository;
use App\Service\Cron\UploadReminderService;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
@@ -25,6 +26,7 @@ use Psr\Log\NullLogger;
* arithmetic the service hands over, because a reminder that asks for the wrong day is just as
* silent as the broken queries these replaced.
*/
#[AllowMockObjectsWithoutExpectations]
class UploadReminderServiceTest extends TestCase
{
private const CONTRACT_DEADLINE_DAYS = 5;
@@ -11,6 +11,7 @@ use App\Entity\Teamer;
use App\Entity\TeamerWorkMonth;
use App\Repository\TeamerWorkMonthRepository;
use App\Service\Cron\WorkMonthReminderService;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
@@ -19,6 +20,7 @@ use Psr\Log\NullLogger;
* Pins the rules the reminder applies: which day it runs on, how long it waits after an
* import, and who it can actually reach. The query itself is the repository's business.
*/
#[AllowMockObjectsWithoutExpectations]
class WorkMonthReminderServiceTest extends TestCase
{
private TeamerWorkMonthRepository&MockObject $repository;
+8 -11
View File
@@ -12,10 +12,9 @@ use App\Entity\JobProfile;
use App\Entity\Teamer;
use App\Entity\Upload;
use App\Service\Pdf\InvoiceApprover;
use App\Service\Pdf\InvoiceRenderer;
use App\Service\Pdf\Pdf;
use App\Service\Upload\UploadHandler;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -27,7 +26,7 @@ class InvoiceApproverTest extends WebTestCase
private string $pdfPath;
private string $origPath;
private Filesystem $filesystem;
private UploadHandler&MockObject $uploadHandler;
private UploadHandler&Stub $uploadHandler;
protected function setUp(): void
{
@@ -38,7 +37,7 @@ class InvoiceApproverTest extends WebTestCase
$this->pdfPath = $this->invoiceDir.'/test_approver_backup.pdf';
$this->origPath = $this->invoiceDir.'/test_approver_backup.orig.pdf';
$this->filesystem = new Filesystem();
$this->uploadHandler = $this->createMock(UploadHandler::class);
$this->uploadHandler = $this->createStub(UploadHandler::class);
$this->filesystem->mkdir($this->invoiceDir);
}
@@ -81,10 +80,7 @@ class InvoiceApproverTest extends WebTestCase
private function createApprover(): InvoiceApprover
{
$translator = $this->createMock(TranslatorInterface::class);
/** @var TranslatorInterface $translator */
return new InvoiceApprover($translator, ['project_dir' => $this->projectDir], $this->uploadHandler);
return new InvoiceApprover($this->createStub(TranslatorInterface::class), ['project_dir' => $this->projectDir], $this->uploadHandler);
}
private function createDispositionWithInvoicePdf(): Disposition
@@ -109,7 +105,7 @@ class InvoiceApproverTest extends WebTestCase
$jobProfile->setName('Testprofil');
$jobProfile->setCostUnit('200');
$assignment = $this->createMock(Assignment::class);
$assignment = $this->createStub(Assignment::class);
$assignment->method('getDestination')->willReturn($destination);
$assignment->method('getJobProfile')->willReturn($jobProfile);
@@ -134,8 +130,9 @@ class InvoiceApproverTest extends WebTestCase
;
$disposition->addDocument($invoice);
$this->uploadHandler->method('getResolvedUploadFilepath')->with($invoice)->willReturn($this->pdfPath);
$this->uploadHandler->method('getUploadFilepath')->with($invoice)->willReturn($this->pdfPath);
$filepath = fn (Upload $upload): string => $invoice === $upload ? $this->pdfPath : throw new \LogicException('Unexpected upload');
$this->uploadHandler->method('getResolvedUploadFilepath')->willReturnCallback($filepath);
$this->uploadHandler->method('getUploadFilepath')->willReturnCallback($filepath);
return $disposition;
}
+6 -5
View File
@@ -25,7 +25,7 @@ class InvoiceRendererTest extends WebTestCase
public function testRendersInvoice(): void
{
$projectDir = static::getContainer()->getParameter('kernel.project_dir');
$translator = $this->createMock(TranslatorInterface::class);
$translator = $this->createStub(TranslatorInterface::class);
/** @var TranslatorInterface $translator */
$renderer = new InvoiceRenderer($translator, ['project_dir' => $projectDir]);
@@ -82,7 +82,7 @@ class InvoiceRendererTest extends WebTestCase
->setEmail('[email protected]')
;
$assignment = $this->createMock(Assignment::class);
$assignment = $this->createStub(Assignment::class);
$assignment->method('getId')->willReturn(1234);
$assignment->method('getDestination')->willReturn($destination);
$assignment->method('getJobProfile')->willReturn($jobProfile);
@@ -108,9 +108,10 @@ class InvoiceRendererTest extends WebTestCase
$disposition->addDocument($invoice);
$invoicePath = $projectDir.'/uploads/invoice/a/abcdef0123456789.pdf';
$uploadHandler = $this->createMock(UploadHandler::class);
$uploadHandler->method('getResolvedUploadFilepath')->with($invoice)->willReturn($invoicePath);
$uploadHandler->method('getUploadFilepath')->with($invoice)->willReturn($invoicePath);
$uploadHandler = $this->createStub(UploadHandler::class);
$filepath = static fn (Upload $upload): string => $invoice === $upload ? $invoicePath : throw new \LogicException('Unexpected upload');
$uploadHandler->method('getResolvedUploadFilepath')->willReturnCallback($filepath);
$uploadHandler->method('getUploadFilepath')->willReturnCallback($filepath);
/** @var TranslatorInterface $translator */
$approver = new InvoiceApprover($translator, ['project_dir' => $projectDir], $uploadHandler);
@@ -18,24 +18,27 @@ use App\Saas\Model\EmployeeDirectory;
use App\Saas\ResponseParser;
use App\Service\Saas\WorkHoursSynchronizer;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
#[AllowMockObjectsWithoutExpectations]
class WorkHoursSynchronizerTest extends TestCase
{
private ApiClient&MockObject $apiClient;
private EmployeeDataProvider&MockObject $employeeDataProvider;
private TeamerWorkMonthRepository&MockObject $workMonthRepository;
private EmployeeDataProvider&Stub $employeeDataProvider;
private TeamerWorkMonthRepository&Stub $workMonthRepository;
private EntityManagerInterface&MockObject $entityManager;
private WorkHoursSynchronizer $synchronizer;
protected function setUp(): void
{
$this->apiClient = $this->createMock(ApiClient::class);
$this->workMonthRepository = $this->createMock(TeamerWorkMonthRepository::class);
$this->workMonthRepository = $this->createStub(TeamerWorkMonthRepository::class);
$this->entityManager = $this->createMock(EntityManagerInterface::class);
$this->employeeDataProvider = $this->createMock(EmployeeDataProvider::class);
$this->employeeDataProvider = $this->createStub(EmployeeDataProvider::class);
// Registered by default; the tests that care say otherwise.
$this->employeeDataProvider->method('getDirectory')->willReturn(
@@ -48,7 +51,7 @@ class WorkHoursSynchronizerTest extends TestCase
$this->apiClient,
new ResponseParser(),
$this->employeeDataProvider,
$this->createMock(TeamerRepository::class),
$this->createStub(TeamerRepository::class),
$this->workMonthRepository,
$this->entityManager,
new NullLogger(),
@@ -85,7 +88,7 @@ class WorkHoursSynchronizerTest extends TestCase
*/
public function testATeamerMissingFromTheRosterIsSkippedWithoutAnyRequest(): void
{
$provider = $this->createMock(EmployeeDataProvider::class);
$provider = $this->createStub(EmployeeDataProvider::class);
$provider->method('getDirectory')->willReturn(
EmployeeDirectory::fromEmployees([new Employee('[email protected]', 'e-9', 'Service', false)])
);
@@ -97,7 +100,7 @@ class WorkHoursSynchronizerTest extends TestCase
$apiClient,
new ResponseParser(),
$provider,
$this->createMock(TeamerRepository::class),
$this->createStub(TeamerRepository::class),
$this->workMonthRepository,
$this->entityManager,
new NullLogger(),
@@ -115,7 +118,7 @@ class WorkHoursSynchronizerTest extends TestCase
*/
public function testAnUnreachableRosterDoesNotSkipEveryone(): void
{
$provider = $this->createMock(EmployeeDataProvider::class);
$provider = $this->createStub(EmployeeDataProvider::class);
$provider->method('getDirectory')->willReturn(EmployeeDirectory::fromEmployees([]));
$this->apiClient->method('getTimeAccount')->willReturn($this->payload());
@@ -125,7 +128,7 @@ class WorkHoursSynchronizerTest extends TestCase
$this->apiClient,
new ResponseParser(),
$provider,
$this->createMock(TeamerRepository::class),
$this->createStub(TeamerRepository::class),
$this->workMonthRepository,
$this->entityManager,
new NullLogger(),
@@ -29,7 +29,7 @@ class SeasonChecklistBuilderTest extends TestCase
->setDocument($document)
);
$builder = new SeasonChecklistBuilder($this->createMock(SeasonTaskDeadlineResolver::class));
$builder = new SeasonChecklistBuilder($this->createStub(SeasonTaskDeadlineResolver::class));
$rows = $builder->build($seasonAssignment);
@@ -44,7 +44,7 @@ class SeasonChecklistBuilderTest extends TestCase
(new SeasonAssignmentTask())->setTaskKey(SeasonTask::MASTER_DATA->value)
);
$builder = new SeasonChecklistBuilder($this->createMock(SeasonTaskDeadlineResolver::class));
$builder = new SeasonChecklistBuilder($this->createStub(SeasonTaskDeadlineResolver::class));
$rows = $builder->build($seasonAssignment);
@@ -22,7 +22,7 @@ class SeasonChecklistStatusTest extends TestCase
protected function setUp(): void
{
$this->builder = new SeasonChecklistBuilder($this->createMock(SeasonTaskDeadlineResolver::class));
$this->builder = new SeasonChecklistBuilder($this->createStub(SeasonTaskDeadlineResolver::class));
}
public function testItIsOpenWhileAnEntryRequiringAReturnIsOpen(): void
@@ -12,7 +12,9 @@ use App\Entity\Upload;
use App\Repository\SeasonTaskDocumentRepository;
use App\Service\Season\SeasonTaskSynchronizer;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
/**
@@ -20,16 +22,17 @@ use PHPUnit\Framework\TestCase;
* that is what is asserted: new entries appear on assignments that already exist, and rows of
* an entry that was removed are left alone rather than deleted.
*/
#[AllowMockObjectsWithoutExpectations]
class SeasonTaskSynchronizerTest extends TestCase
{
private EntityManagerInterface&MockObject $entityManager;
private SeasonTaskDocumentRepository&MockObject $seasonTaskDocumentRepository;
private SeasonTaskDocumentRepository&Stub $seasonTaskDocumentRepository;
private SeasonTaskSynchronizer $synchronizer;
protected function setUp(): void
{
$this->entityManager = $this->createMock(EntityManagerInterface::class);
$this->seasonTaskDocumentRepository = $this->createMock(SeasonTaskDocumentRepository::class);
$this->seasonTaskDocumentRepository = $this->createStub(SeasonTaskDocumentRepository::class);
$this->synchronizer = new SeasonTaskSynchronizer(
$this->entityManager,
@@ -12,21 +12,24 @@ use App\Enum\StatisticsEventName;
use App\Service\Statistics\StatisticsRecorder;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception\DatabaseRequired;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\SecurityBundle\Security;
#[AllowMockObjectsWithoutExpectations]
class StatisticsRecorderTest extends TestCase
{
private Connection&MockObject $connection;
private Security&MockObject $security;
private Security&Stub $security;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->connection = $this->createMock(Connection::class);
$this->security = $this->createMock(Security::class);
$this->security = $this->createStub(Security::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
@@ -8,10 +8,12 @@ use App\Entity\Teamer;
use App\Entity\User;
use App\Service\Teamer\AccountDeletionHandler;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
#[AllowMockObjectsWithoutExpectations]
class AccountDeletionHandlerTest extends TestCase
{
private EntityManagerInterface&MockObject $entityManager;
@@ -23,7 +25,7 @@ class AccountDeletionHandlerTest extends TestCase
$this->handler = new AccountDeletionHandler(
$this->entityManager,
$this->createMock(LoggerInterface::class),
$this->createStub(LoggerInterface::class),
);
}
@@ -8,17 +8,17 @@ use App\Config\SeasonCalendar;
use App\Entity\Teamer;
use App\Repository\DispositionRepository;
use App\Service\Teamer\SeasonDispositionCounter;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
class SeasonDispositionCounterTest extends TestCase
{
private DispositionRepository&MockObject $dispositionRepository;
private DispositionRepository&Stub $dispositionRepository;
private SeasonDispositionCounter $counter;
protected function setUp(): void
{
$this->dispositionRepository = $this->createMock(DispositionRepository::class);
$this->dispositionRepository = $this->createStub(DispositionRepository::class);
$this->counter = new SeasonDispositionCounter(
$this->dispositionRepository,
@@ -15,20 +15,23 @@ use App\Model\TeamerMailingRecipient;
use App\Model\TeamerMailingRecipientsDto;
use App\Repository\TeamerRepository;
use App\Service\Teamer\TeamerMailingService;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
#[AllowMockObjectsWithoutExpectations]
class TeamerMailingServiceTest extends TestCase
{
private TeamerRepository&MockObject $teamerRepository;
private TeamerRepository&Stub $teamerRepository;
private Mailer&MockObject $mailer;
private TeamerMailingService $service;
private static int $nextId = 1;
protected function setUp(): void
{
$this->teamerRepository = $this->createMock(TeamerRepository::class);
$this->teamerRepository = $this->createStub(TeamerRepository::class);
$this->mailer = $this->createMock(Mailer::class);
// The real renderer, not a mock: what the mailing puts in front of a teamer is
@@ -37,7 +40,7 @@ class TeamerMailingServiceTest extends TestCase
$this->teamerRepository,
$this->mailer,
new MailBodyRenderer(),
$this->createMock(LoggerInterface::class),
$this->createStub(LoggerInterface::class),
'mailing',
);
}
@@ -17,6 +17,7 @@ use App\Entity\User;
use App\Service\Teamer\TeamerProvisioner;
use App\Service\Teamer\TeamerProvisioningException;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
@@ -28,6 +29,7 @@ use Psr\Log\NullLogger;
* client: what runs, in which order, what is persisted before the next step, and what a retry does
* after a failure halfway.
*/
#[AllowMockObjectsWithoutExpectations]
class TeamerProvisionerTest extends TestCase
{
private const SELECTION_ID = 1070;
@@ -366,7 +368,7 @@ class TeamerProvisionerTest extends TestCase
return new TeamerProvisioner(
$this->apiClient,
$this->userDataHandler,
$this->createMock(EntityManagerInterface::class),
$this->createStub(EntityManagerInterface::class),
new NullLogger(),
self::SELECTION_ID,
);
+3 -3
View File
@@ -110,9 +110,9 @@ class UploadHandlerTest extends TestCase
private function handler(string $replacementFile = self::REPLACEMENT_FILE): UploadHandler
{
return new UploadHandler(
$this->createMock(RequestStack::class),
$this->createMock(OrphanageManager::class),
$this->createMock(Sanitizer::class),
$this->createStub(RequestStack::class),
$this->createStub(OrphanageManager::class),
$this->createStub(Sanitizer::class),
new NullLogger(),
$this->featureManager,
$this->projectDir,
@@ -84,7 +84,7 @@ class ResolvableHotelValidatorTest extends ConstraintValidatorTestCase
*/
private function provider(array $hotels): object
{
$provider = $this->createMock(HotelDataProvider::class);
$provider = $this->createStub(HotelDataProvider::class);
$provider->method('getAll')->willReturn($hotels);
return $provider;
@@ -10,6 +10,7 @@ use App\Entity\Teamer;
use App\Repository\SeasonAssignmentRepository;
use App\Validator\Constraints\SeasonAssignment as SeasonAssignmentConstraint;
use App\Validator\Constraints\SeasonAssignmentValidator;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
@@ -18,6 +19,7 @@ use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
* pinned here is which season window a given assignment is counted against, and the cases that
* must not be refused - an unstaffed assignment, and the assignment being edited itself.
*/
#[AllowMockObjectsWithoutExpectations]
class SeasonAssignmentValidatorTest extends ConstraintValidatorTestCase
{
private SeasonAssignmentRepository&MockObject $repository;