Compare commits

...
2 Commits
Author SHA1 Message Date
Björn Fromme 5396cbb548 feat: upgrade phpunit to 12.5 2026-08-31 09:03:44 +02:00
Björn Fromme 010cfe56b2 feat: upgrade project to symfony 7.4 2026-08-31 09:03:44 +02:00
118 changed files with 2827 additions and 2358 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
type: php
docroot: public
php_version: "8.3"
php_version: "8.4"
webserver_type: apache-fpm
xdebug_enabled: false
additional_hostnames:
+4 -5
View File
@@ -8,11 +8,6 @@
/vendor/
###< symfony/framework-bundle ###
###> phpunit/phpunit ###
/phpunit.xml
.phpunit.result.cache
###< phpunit/phpunit ###
###> symfony/phpunit-bridge ###
.phpunit.result.cache
/phpunit.xml
@@ -37,3 +32,7 @@ yarn-error.log
###> phpstan/phpstan ###
phpstan.neon
###< phpstan/phpstan ###
###> config reference ###
/config/reference.php
###< config reference ###
+38 -38
View File
@@ -4,7 +4,7 @@
"minimum-stability": "stable",
"prefer-stable": true,
"require": {
"php": ">=8.1",
"php": ">=8.4",
"ext-ctype": "*",
"ext-dom": "*",
"ext-iconv": "*",
@@ -29,39 +29,39 @@
"phpstan/phpdoc-parser": "^2.0",
"spatie/crypto": "^2.1",
"symfony/apache-pack": "^1.0",
"symfony/asset": "6.4.*",
"symfony/console": "6.4.*",
"symfony/doctrine-messenger": "6.4.*",
"symfony/dom-crawler": "6.4.*",
"symfony/dotenv": "6.4.*",
"symfony/expression-language": "6.4.*",
"symfony/asset": "7.4.*",
"symfony/console": "7.4.*",
"symfony/doctrine-messenger": "7.4.*",
"symfony/dom-crawler": "7.4.*",
"symfony/dotenv": "7.4.*",
"symfony/expression-language": "7.4.*",
"symfony/flex": "^2",
"symfony/form": "6.4.*",
"symfony/framework-bundle": "6.4.*",
"symfony/html-sanitizer": "6.4.*",
"symfony/http-client": "6.4.*",
"symfony/intl": "6.4.*",
"symfony/lock": "6.4.*",
"symfony/mailer": "6.4.*",
"symfony/mime": "6.4.*",
"symfony/form": "7.4.*",
"symfony/framework-bundle": "7.4.*",
"symfony/html-sanitizer": "7.4.*",
"symfony/http-client": "7.4.*",
"symfony/intl": "7.4.*",
"symfony/lock": "7.4.*",
"symfony/mailer": "7.4.*",
"symfony/mime": "7.4.*",
"symfony/monolog-bundle": "^3.0",
"symfony/notifier": "6.4.*",
"symfony/process": "6.4.*",
"symfony/property-access": "6.4.*",
"symfony/property-info": "6.4.*",
"symfony/runtime": "6.4.*",
"symfony/security-bundle": "6.4.*",
"symfony/serializer": "6.4.*",
"symfony/notifier": "7.4.*",
"symfony/process": "7.4.*",
"symfony/property-access": "7.4.*",
"symfony/property-info": "7.4.*",
"symfony/runtime": "7.4.*",
"symfony/security-bundle": "7.4.*",
"symfony/serializer": "7.4.*",
"symfony/stimulus-bundle": "^2.21",
"symfony/string": "6.4.*",
"symfony/translation": "6.4.*",
"symfony/twig-bundle": "6.4.*",
"symfony/uid": "6.4.*",
"symfony/string": "7.4.*",
"symfony/translation": "7.4.*",
"symfony/twig-bundle": "7.4.*",
"symfony/uid": "7.4.*",
"symfony/ux-twig-component": "^2.36",
"symfony/validator": "6.4.*",
"symfony/web-link": "6.4.*",
"symfony/validator": "7.4.*",
"symfony/web-link": "7.4.*",
"symfony/webpack-encore-bundle": "^2.2",
"symfony/yaml": "6.4.*",
"symfony/yaml": "7.4.*",
"twig/extra-bundle": "^2.12|^3.0",
"twig/html-extra": "^3.15",
"twig/intl-extra": "*",
@@ -77,7 +77,7 @@
},
"sort-packages": true,
"platform": {
"php": "8.3.30"
"php": "8.4.24"
}
},
"autoload": {
@@ -119,7 +119,7 @@
"extra": {
"symfony": {
"allow-contrib": true,
"require": "6.4.*",
"require": "7.4.*",
"docker": true
}
},
@@ -129,14 +129,14 @@
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-doctrine": "^2.0",
"phpstan/phpstan-symfony": "^2.0",
"phpunit/phpunit": "^9.5",
"phpunit/phpunit": "^12",
"rector/rector": "^2.4",
"symfony/browser-kit": "6.4.*",
"symfony/css-selector": "6.4.*",
"symfony/debug-bundle": "6.4.*",
"symfony/browser-kit": "7.4.*",
"symfony/css-selector": "7.4.*",
"symfony/debug-bundle": "7.4.*",
"symfony/maker-bundle": "^1.0",
"symfony/phpunit-bridge": "^7.1",
"symfony/stopwatch": "6.4.*",
"symfony/web-profiler-bundle": "6.4.*"
"symfony/phpunit-bridge": "^7.4",
"symfony/stopwatch": "7.4.*",
"symfony/web-profiler-bundle": "7.4.*"
}
}
Generated
+1584 -1399
View File
File diff suppressed because it is too large. Load diff
+1 -4
View File
@@ -9,8 +9,7 @@ doctrine:
profiling_collect_backtrace: '%kernel.debug%'
use_savepoints: true
orm:
auto_generate_proxy_classes: true
enable_lazy_ghost_objects: true
enable_native_lazy_objects: true
validate_xml_mapping: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
@@ -33,8 +32,6 @@ when@test:
when@prod:
doctrine:
orm:
auto_generate_proxy_classes: false
proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies'
query_cache_driver:
type: pool
pool: doctrine.system_cache_pool
-1
View File
@@ -1,7 +1,6 @@
# see https://symfony.com/doc/current/reference/configuration/framework.html
framework:
secret: '%env(APP_SECRET)%'
annotations: false
http_method_override: false
handle_all_throwables: true
+3
View File
@@ -0,0 +1,3 @@
framework:
property_info:
with_constructor_extractor: true
+3 -1
View File
@@ -14,4 +14,6 @@ when@test:
intercept_redirects: false
framework:
profiler: { collect: false }
profiler:
collect: false
collect_serializer_data: true
+7 -10
View File
@@ -1,20 +1,20 @@
<?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"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnPhpunitDeprecations="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,16 +23,13 @@
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<source>
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
</listeners>
</source>
<extensions>
<bootstrap class="Symfony\Bridge\PhpUnit\SymfonyExtension" />
</extensions>
</phpunit>
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace App\BusProNet;
use Symfony\Component\DomCrawler\Crawler;
/**
* Builds a Crawler over BusPro's XML payloads.
*
* The Crawler constructor parses its content as HTML5, which flattens the
* nesting BusPro's exports and API responses rely on, so XML has to be added
* through addXmlContent() instead.
*/
final class XmlCrawlerFactory
{
public static function create(string $xml): Crawler
{
$crawler = new Crawler();
$crawler->addXmlContent($xml);
return $crawler;
}
}
+2 -1
View File
@@ -4,6 +4,7 @@ namespace App\BusProNet\XmlLoader;
use App\BusProNet\Model\Hotel;
use App\BusProNet\Model\Travel;
use App\BusProNet\XmlCrawlerFactory;
use App\Exception\HotelNotFoundException;
use Psr\Cache\InvalidArgumentException;
use Symfony\Component\DomCrawler\Crawler;
@@ -73,7 +74,7 @@ class HotelLoader extends AbstractLoader
{
$xml = $this->xmlExport->read($filename);
return new Crawler($xml);
return XmlCrawlerFactory::create($xml);
}
public function parseXml(Crawler $node): Hotel
+2 -1
View File
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\BusProNet\XmlLoader;
use App\BusProNet\Model\Insurance;
use App\BusProNet\XmlCrawlerFactory;
use App\BusProNet\XmlParser\InsuranceParser;
use League\Flysystem\FilesystemOperator;
use Psr\Cache\InvalidArgumentException;
@@ -50,6 +51,6 @@ class InsuranceLoader extends AbstractLoader
{
$xml = $this->xmlExport->read($filename);
return new Crawler($xml);
return XmlCrawlerFactory::create($xml);
}
}
+2 -1
View File
@@ -4,6 +4,7 @@ namespace App\BusProNet\XmlLoader;
use App\BusProNet\Model\Pickup;
use App\BusProNet\Model\Travel;
use App\BusProNet\XmlCrawlerFactory;
use Psr\Cache\InvalidArgumentException;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Contracts\Cache\ItemInterface;
@@ -46,7 +47,7 @@ class PickupLoader extends AbstractLoader
{
$xml = $this->xmlExport->read($filename);
return new Crawler($xml);
return XmlCrawlerFactory::create($xml);
}
public function parseXml(Crawler $node): Pickup
+3 -2
View File
@@ -7,6 +7,7 @@ use App\BusProNet\Model\MutableData;
use App\BusProNet\Model\ServiceAvailabilityResponse;
use App\BusProNet\Model\Travel;
use App\BusProNet\Utility\DateCodeUtility;
use App\BusProNet\XmlCrawlerFactory;
use App\BusProNet\XmlParser\TravelParser;
use App\Exception\HotelNotInTravelException;
use App\Exception\TravelNotFoundException;
@@ -71,7 +72,7 @@ class TravelLoader extends AbstractLoader
foreach ($xmlFiles as $file) {
$xml = $this->xmlExport->read($file->path());
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$travelDataNodes = $crawler->filterXPath('//reisen/reise/termin');
$travelDataNodes->each(function (Crawler $node) use (&$mapping, $hotels, $file) {
@@ -218,7 +219,7 @@ class TravelLoader extends AbstractLoader
{
try {
$xml = $this->xmlExport->read($filename);
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$travelNode = $crawler->filterXPath(sprintf('//reise/termin[@idbuspro="%d"]', $dateId));
@@ -4,7 +4,7 @@ namespace App\BusProNet\XmlParser;
use App\BusProNet\ApiClient;
use App\BusProNet\Exception\ResponseParserException;
use Symfony\Component\DomCrawler\Crawler;
use App\BusProNet\XmlCrawlerFactory;
class ApiResponseParser extends AbstractParser
{
@@ -14,7 +14,7 @@ class ApiResponseParser extends AbstractParser
/** @param array<string, mixed> $additionalArgs */
public function parseXmlString(string $type, string $xml, array $additionalArgs = []): mixed
{
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
if (0 === $crawler->count()) {
throw new ResponseParserException('Empty response received from server');
@@ -5,7 +5,8 @@ declare(strict_types=1);
namespace App\Security\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Vote;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
@@ -16,7 +17,7 @@ class AdministrativeAccessVoter extends Voter
public const ADMINISTRATIVE_ACCESS = 'ADMINISTRATIVE_ACCESS';
public function __construct(
private readonly AuthorizationCheckerInterface $authorizationChecker,
private readonly AccessDecisionManagerInterface $accessDecisionManager,
) {
}
@@ -25,9 +26,9 @@ class AdministrativeAccessVoter extends Voter
return self::ADMINISTRATIVE_ACCESS === $attribute;
}
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool
{
return $this->authorizationChecker->isGranted('ROLE_ADMIN')
|| $this->authorizationChecker->isGranted('ROLE_GROUPS_MANAGER');
return $this->accessDecisionManager->decide($token, ['ROLE_ADMIN'])
|| $this->accessDecisionManager->decide($token, ['ROLE_GROUPS_MANAGER']);
}
}
+2 -1
View File
@@ -7,6 +7,7 @@ namespace App\Security\Voter;
use App\BusProNet\Model\Booking;
use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Vote;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
@@ -32,7 +33,7 @@ class BookingVoter extends Voter
return $subject instanceof Booking;
}
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool
{
/** @var User|null $user */
$user = $token->getUser();
+24
View File
@@ -177,6 +177,18 @@
".env"
]
},
"symfony/form": {
"version": "7.4",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "7.2",
"ref": "7d86a6723f4a623f59e2bf966b6aad2fc461d36b"
},
"files": [
"config/packages/csrf.yaml"
]
},
"symfony/framework-bundle": {
"version": "6.4",
"recipe": {
@@ -280,6 +292,18 @@
"tests/bootstrap.php"
]
},
"symfony/property-info": {
"version": "7.4",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "7.3",
"ref": "dae70df71978ae9226ae915ffd5fad817f5ca1f7"
},
"files": [
"config/packages/property_info.yaml"
]
},
"symfony/routing": {
"version": "6.4",
"recipe": {
+8 -10
View File
@@ -1,10 +1,8 @@
{% apply spaceless %}
{% for message in messages %}
{% if message is iterable %}
{% set message = message.id | trans(message.parameters | default({}), message.domain | default(null), message.locale | default(null)) | raw %}
{% else %}
{% set message = message | trans | raw %}
{% endif %}
<div {{ stimulus_controller('toast', { 'text': message, 'class': 'toastify--' ~ level}) }}{{ qa_attribute('toast', level)}}></div>
{% endfor %}
{% endapply %}
{% for message in messages %}
{% if message is iterable %}
{% set message = message.id | trans(message.parameters | default({}), message.domain | default(null), message.locale | default(null)) | raw %}
{% else %}
{% set message = message | trans | raw %}
{% endif %}
<div {{ stimulus_controller('toast', { 'text': message, 'class': 'toastify--' ~ level}) }}{{ qa_attribute('toast', level)}}></div>
{% endfor %}
+15 -10
View File
@@ -17,19 +17,22 @@ use Symfony\Component\Serializer\SerializerInterface;
class ApiClientReceiveTest extends TestCase
{
private ApiClient $apiClient;
private ?ApiClient $apiClient = null;
private LoggerInterface $logger;
protected function setUp(): void
{
$this->logger = $this->createMock(LoggerInterface::class);
$this->logger = $this->createStub(LoggerInterface::class);
}
$this->apiClient = new ApiClient(
$this->createMock(SerializerInterface::class),
$this->createMock(ApiResponseParser::class),
$this->createMock(FilesystemOperator::class),
private function apiClient(): ApiClient
{
return $this->apiClient ??= new ApiClient(
$this->createStub(SerializerInterface::class),
$this->createStub(ApiResponseParser::class),
$this->createStub(FilesystemOperator::class),
$this->logger,
$this->createMock(BookingDataProcessor::class),
$this->createStub(BookingDataProcessor::class),
new RequestStack(),
new RequestIdGenerator(),
[
@@ -43,6 +46,8 @@ class ApiClientReceiveTest extends TestCase
public function testEmptyResponseThrowsImmediateConnectionCloseException(): void
{
$this->logger = $this->createMock(LoggerInterface::class);
$stream = fopen('php://memory', 'r+');
// Write nothing — stream is immediately at EOF
rewind($stream);
@@ -82,18 +87,18 @@ class ApiClientReceiveTest extends TestCase
{
$method = new \ReflectionMethod(ApiClient::class, 'receive');
return $method->invoke($this->apiClient, $socket);
return $method->invoke($this->apiClient(), $socket);
}
private function setOperationStartTime(): void
{
$property = new \ReflectionProperty(ApiClient::class, 'operationStartTime');
$property->setValue($this->apiClient, microtime(true));
$property->setValue($this->apiClient(), microtime(true));
}
private function setSelectedPort(int $port): void
{
$property = new \ReflectionProperty(ApiClient::class, 'selectedPort');
$property->setValue($this->apiClient, $port);
$property->setValue($this->apiClient(), $port);
}
}
@@ -34,7 +34,7 @@ class TravelDataLoaderTest extends TestCase
->with('test_file.xml')
->willReturn($xmlContent);
$hotelLoader = $this->createMock(HotelLoader::class);
$hotelLoader = $this->createStub(HotelLoader::class);
$travelParser = $this->createMock(TravelParser::class);
$expectedTravel = new Travel();
@@ -40,8 +40,8 @@ class BookingDataProcessorTest extends TestCase
protected function setUp(): void
{
// Create a mock InsuranceManager
$insuranceService = $this->createMock(InsuranceManager::class);
$priceCalculatorService = $this->createMock(BookingPriceCalculator::class);
$insuranceService = $this->createStub(InsuranceManager::class);
$priceCalculatorService = $this->createStub(BookingPriceCalculator::class);
// Mock getSelectableInsurances to return empty array (not used in these tests)
$insuranceService->method('getSelectableInsurances')
@@ -851,7 +851,7 @@ class BookingDataProcessorTest extends TestCase
$bookingDto = new BookingDto($this->createMockTravel(), 1);
$bookingDto->participants = [$applicant, $dependent];
$insuranceService = $this->createMock(InsuranceManager::class);
$insuranceService = $this->createStub(InsuranceManager::class);
// Both insurances must already look eligible, otherwise the submit-time
// reconciliation step (added for stale-insurance re-validation) would clear
// them before propagation even runs - this test is only about propagation.
@@ -864,11 +864,11 @@ class BookingDataProcessorTest extends TestCase
1 => null,
]);
$priceCalculatorService = $this->createMock(BookingPriceCalculator::class);
$priceCalculatorService = $this->createStub(BookingPriceCalculator::class);
$priceCalculatorService->method('calculateIndividualParticipantPriceExcludingInsurance')->willReturn(0.0);
$priceCalculatorService->method('resolveInsuranceTravelPrice')->willReturn(0.0);
$payloadBuilder = $this->createMock(BookingPayloadBuilder::class);
$payloadBuilder = $this->createStub(BookingPayloadBuilder::class);
$payloadBuilder->method('buildCreatePayload')->willReturn([]);
$processor = new BookingDataProcessor(
@@ -911,14 +911,14 @@ class BookingDataProcessorTest extends TestCase
$dependent = $formData->participants[1];
$dependent->insurance = $dependentInsurance;
$insuranceService = $this->createMock(InsuranceManager::class);
$insuranceService = $this->createStub(InsuranceManager::class);
$insuranceService->method('getSelectableInsurances')->willReturn([]);
$insuranceService->method('batchAssignInsuranceToParticipants')->willReturn([
0 => $familyInsurance,
1 => null,
]);
$priceCalculatorService = $this->createMock(BookingPriceCalculator::class);
$priceCalculatorService = $this->createStub(BookingPriceCalculator::class);
$priceCalculatorService->method('calculateIndividualParticipantPriceExcludingInsurance')->willReturn(0.0);
$processor = new BookingDataProcessor(
@@ -961,18 +961,18 @@ class BookingDataProcessorTest extends TestCase
$bookingDto = new BookingDto($this->createMockTravel(), 1);
$bookingDto->participants = [$applicant];
$insuranceService = $this->createMock(InsuranceManager::class);
$insuranceService = $this->createStub(InsuranceManager::class);
$insuranceService->method('getSelectableInsurances')->willReturn([$staleInsurance, $correctTierInsurance]);
// Only the higher tier is eligible at the current (updated) price.
$insuranceService->method('getEligibleInsurances')->willReturn([$correctTierInsurance]);
$insuranceService->method('reassignInsuranceForPriceChange')->willReturn($correctTierInsurance);
$insuranceService->method('batchAssignInsuranceToParticipants')->willReturn([0 => $correctTierInsurance]);
$priceCalculatorService = $this->createMock(BookingPriceCalculator::class);
$priceCalculatorService = $this->createStub(BookingPriceCalculator::class);
$priceCalculatorService->method('calculateIndividualParticipantPriceExcludingInsurance')->willReturn(0.0);
$priceCalculatorService->method('resolveInsuranceTravelPrice')->willReturn(2600.0);
$payloadBuilder = $this->createMock(BookingPayloadBuilder::class);
$payloadBuilder = $this->createStub(BookingPayloadBuilder::class);
$payloadBuilder->method('buildCreatePayload')->willReturn([]);
$processor = new BookingDataProcessor(
@@ -1009,17 +1009,17 @@ class BookingDataProcessorTest extends TestCase
$bookingDto = new BookingDto($this->createMockTravel(), 1);
$bookingDto->participants = [$applicant];
$insuranceService = $this->createMock(InsuranceManager::class);
$insuranceService = $this->createStub(InsuranceManager::class);
$insuranceService->method('getSelectableInsurances')->willReturn([$staleInsurance]);
$insuranceService->method('getEligibleInsurances')->willReturn([]);
$insuranceService->method('reassignInsuranceForPriceChange')->willReturn(null);
$insuranceService->method('batchAssignInsuranceToParticipants')->willReturn([0 => null]);
$priceCalculatorService = $this->createMock(BookingPriceCalculator::class);
$priceCalculatorService = $this->createStub(BookingPriceCalculator::class);
$priceCalculatorService->method('calculateIndividualParticipantPriceExcludingInsurance')->willReturn(0.0);
$priceCalculatorService->method('resolveInsuranceTravelPrice')->willReturn(9999.0);
$payloadBuilder = $this->createMock(BookingPayloadBuilder::class);
$payloadBuilder = $this->createStub(BookingPayloadBuilder::class);
$payloadBuilder->method('buildCreatePayload')->willReturn([]);
$processor = new BookingDataProcessor(
@@ -1056,16 +1056,16 @@ class BookingDataProcessorTest extends TestCase
$bookingDto = new BookingDto($this->createMockTravel(), 1);
$bookingDto->participants = [$applicant];
$insuranceService = $this->createMock(InsuranceManager::class);
$insuranceService = $this->createStub(InsuranceManager::class);
$insuranceService->method('getSelectableInsurances')->willReturn([$insurance]);
$insuranceService->method('getEligibleInsurances')->willReturn([$insurance]);
$insuranceService->method('batchAssignInsuranceToParticipants')->willReturn([0 => $insurance]);
$priceCalculatorService = $this->createMock(BookingPriceCalculator::class);
$priceCalculatorService = $this->createStub(BookingPriceCalculator::class);
$priceCalculatorService->method('calculateIndividualParticipantPriceExcludingInsurance')->willReturn(0.0);
$priceCalculatorService->method('resolveInsuranceTravelPrice')->willReturn(500.0);
$payloadBuilder = $this->createMock(BookingPayloadBuilder::class);
$payloadBuilder = $this->createStub(BookingPayloadBuilder::class);
$payloadBuilder->method('buildCreatePayload')->willReturn([]);
$processor = new BookingDataProcessor(
@@ -15,7 +15,7 @@ class BookingStatusRuleRegistryTest extends TestCase
{
public function testReturnsDefaultStatusWhenNoRulesMatch(): void
{
$rule = $this->createMock(BookingStatusRuleInterface::class);
$rule = $this->createStub(BookingStatusRuleInterface::class);
$rule->method('evaluate')->willReturn(false);
$rule->method('getPriority')->willReturn(100);
@@ -27,7 +27,7 @@ class BookingStatusRuleRegistryTest extends TestCase
public function testReturnsMatchingRuleStatus(): void
{
$rule = $this->createMock(BookingStatusRuleInterface::class);
$rule = $this->createStub(BookingStatusRuleInterface::class);
$rule->method('evaluate')->willReturn(true);
$rule->method('getStatus')->willReturn('O');
$rule->method('getPriority')->willReturn(100);
@@ -40,12 +40,12 @@ class BookingStatusRuleRegistryTest extends TestCase
public function testHigherPriorityRuleTakesPrecedence(): void
{
$lowPriorityRule = $this->createMock(BookingStatusRuleInterface::class);
$lowPriorityRule = $this->createStub(BookingStatusRuleInterface::class);
$lowPriorityRule->method('evaluate')->willReturn(true);
$lowPriorityRule->method('getStatus')->willReturn('L');
$lowPriorityRule->method('getPriority')->willReturn(50);
$highPriorityRule = $this->createMock(BookingStatusRuleInterface::class);
$highPriorityRule = $this->createStub(BookingStatusRuleInterface::class);
$highPriorityRule->method('evaluate')->willReturn(true);
$highPriorityRule->method('getStatus')->willReturn('H');
$highPriorityRule->method('getPriority')->willReturn(100);
@@ -66,12 +66,12 @@ class BookingStatusRuleRegistryTest extends TestCase
public function testFirstMatchingRuleWinsForSamePriority(): void
{
$firstMatchingRule = $this->createMock(BookingStatusRuleInterface::class);
$firstMatchingRule = $this->createStub(BookingStatusRuleInterface::class);
$firstMatchingRule->method('evaluate')->willReturn(true);
$firstMatchingRule->method('getStatus')->willReturn('A');
$firstMatchingRule->method('getPriority')->willReturn(100);
$secondMatchingRule = $this->createMock(BookingStatusRuleInterface::class);
$secondMatchingRule = $this->createStub(BookingStatusRuleInterface::class);
$secondMatchingRule->method('evaluate')->willReturn(true);
$secondMatchingRule->method('getStatus')->willReturn('B');
$secondMatchingRule->method('getPriority')->willReturn(100);
@@ -84,12 +84,12 @@ class BookingStatusRuleRegistryTest extends TestCase
public function testNonMatchingHighPriorityRuleDoesNotBlockLowerPriority(): void
{
$highPriorityRule = $this->createMock(BookingStatusRuleInterface::class);
$highPriorityRule = $this->createStub(BookingStatusRuleInterface::class);
$highPriorityRule->method('evaluate')->willReturn(false);
$highPriorityRule->method('getStatus')->willReturn('H');
$highPriorityRule->method('getPriority')->willReturn(100);
$lowPriorityRule = $this->createMock(BookingStatusRuleInterface::class);
$lowPriorityRule = $this->createStub(BookingStatusRuleInterface::class);
$lowPriorityRule->method('evaluate')->willReturn(true);
$lowPriorityRule->method('getStatus')->willReturn('L');
$lowPriorityRule->method('getPriority')->willReturn(50);
@@ -102,7 +102,7 @@ class BookingStatusRuleRegistryTest extends TestCase
public function testSelection1473RuleWinsOverLowerPriorityRule(): void
{
$lowerPriorityRule = $this->createMock(BookingStatusRuleInterface::class);
$lowerPriorityRule = $this->createStub(BookingStatusRuleInterface::class);
$lowerPriorityRule->method('evaluate')->willReturn(true);
$lowerPriorityRule->method('getStatus')->willReturn('X');
$lowerPriorityRule->method('getPriority')->willReturn(100);
@@ -3,13 +3,12 @@
namespace App\Tests\BusProNet\Utility;
use App\BusProNet\Utility\DayTimeUtility;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
class DayTimeUtilityTest extends TestCase
{
/**
* @dataProvider dayTimeProvider
*/
#[DataProvider('dayTimeProvider')]
public function testMapTime(?string $time, ?string $dayTime): void
{
$utility = new DayTimeUtility();
@@ -18,7 +17,7 @@ class DayTimeUtilityTest extends TestCase
$this->assertEquals($dayTime, $result);
}
public function dayTimeProvider(): array
public static function dayTimeProvider(): array
{
return [
[null, null],
+16 -10
View File
@@ -7,7 +7,9 @@ namespace App\Tests\BusProNet\XmlLoader;
use App\BusProNet\Model\Pickup;
use App\BusProNet\Model\Travel;
use App\BusProNet\XmlLoader\PickupLoader;
use League\Flysystem\FilesystemOperator;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\Cache\CacheInterface;
class PickupLoaderTest extends TestCase
{
@@ -15,17 +17,21 @@ class PickupLoaderTest extends TestCase
protected function setUp(): void
{
$this->loader = $this->createPartialMock(PickupLoader::class, ['loadById']);
$this->loader->method('loadById')->willReturnCallback(function (int $id): Pickup {
$pickup = new Pickup();
$pickup->id = $id;
$pickup->code = 'Z'.$id;
$pickup->city = 'City '.$id;
$pickup->postalCode = '0000'.$id;
$pickup->street = 'Street '.$id;
// patchPickupsDetails() is the unit under test; loadById() only has to hand back
// a Pickup per id, so a subclass beats a partial mock over the XML/cache stack.
$this->loader = new class($this->createStub(CacheInterface::class), $this->createStub(FilesystemOperator::class)) extends PickupLoader {
public function loadById(int $id, ?string $filename = 'zustiege.xml'): ?Pickup
{
$pickup = new Pickup();
$pickup->id = $id;
$pickup->code = 'Z'.$id;
$pickup->city = 'City '.$id;
$pickup->postalCode = '0000'.$id;
$pickup->street = 'Street '.$id;
return $pickup;
});
return $pickup;
}
};
}
public function testDropOffsAreOrderedInReverseOfSortedPickups(): void
@@ -4,9 +4,9 @@ declare(strict_types=1);
namespace App\Tests\BusProNet\XmlParser;
use App\BusProNet\XmlCrawlerFactory;
use App\BusProNet\XmlParser\AgencyParser;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
class AgencyParserTest extends TestCase
{
@@ -41,7 +41,7 @@ class AgencyParserTest extends TestCase
</agenturen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$resultNode = $crawler->filterXPath('//ergebnis');
$agencies = $this->parser->parse($resultNode);
@@ -79,7 +79,7 @@ class AgencyParserTest extends TestCase
</agenturen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$resultNode = $crawler->filterXPath('//ergebnis');
$agencies = $this->parser->parse($resultNode);
@@ -102,7 +102,7 @@ class AgencyParserTest extends TestCase
</agenturen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$resultNode = $crawler->filterXPath('//ergebnis');
$agencies = $this->parser->parse($resultNode);
@@ -4,9 +4,9 @@ declare(strict_types=1);
namespace App\Tests\BusProNet\XmlParser;
use App\BusProNet\XmlCrawlerFactory;
use App\BusProNet\XmlParser\BookingInsurancesParser;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
class BookingInsurancesParserTest extends TestCase
{
@@ -22,7 +22,7 @@ class BookingInsurancesParserTest extends TestCase
</ergebnis>
XML;
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$insurancesData = $crawler->filterXPath('//versicherungen/versicherung');
$parser = new BookingInsurancesParser();
@@ -53,7 +53,7 @@ XML;
</ergebnis>
XML;
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$insurancesData = $crawler->filterXPath('//versicherungen/versicherung');
$parser = new BookingInsurancesParser();
@@ -88,7 +88,7 @@ XML;
</ergebnis>
XML;
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$insurancesData = $crawler->filterXPath('//versicherungen/versicherung');
$parser = new BookingInsurancesParser();
@@ -4,9 +4,9 @@ declare(strict_types=1);
namespace App\Tests\BusProNet\XmlParser;
use App\BusProNet\XmlCrawlerFactory;
use App\BusProNet\XmlParser\BookingResponseParser;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
class BookingResponseParserTest extends TestCase
{
@@ -34,7 +34,7 @@ class BookingResponseParserTest extends TestCase
</zahlungsbedingungen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$response = $this->parser->parse($crawler->filter('ergebnis'));
$this->assertTrue($response->isInquiryValid());
@@ -67,7 +67,7 @@ class BookingResponseParserTest extends TestCase
</zahlungsbedingungen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$response = $this->parser->parse($crawler->filter('ergebnis'));
$this->assertTrue($response->isInquiryValid());
@@ -102,7 +102,7 @@ class BookingResponseParserTest extends TestCase
<zahlungsbedingungen></zahlungsbedingungen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$response = $this->parser->parse($crawler->filter('ergebnis'));
$this->assertTrue($response->isInquiryValid());
@@ -140,7 +140,7 @@ class BookingResponseParserTest extends TestCase
</zahlungsbedingungen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$response = $this->parser->parse($crawler->filter('ergebnis'));
// Verify all voucher types are parsed
@@ -169,7 +169,7 @@ class BookingResponseParserTest extends TestCase
</zahlungsbedingungen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$response = $this->parser->parse($crawler->filter('ergebnis'));
$this->assertTrue($response->isInquiryValid());
@@ -200,7 +200,7 @@ class BookingResponseParserTest extends TestCase
</zahlungsbedingungen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$response = $this->parser->parse($crawler->filter('ergebnis'));
// Verify multiple purchase vouchers are parsed
@@ -228,7 +228,7 @@ class BookingResponseParserTest extends TestCase
</zahlungsbedingungen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$response = $this->parser->parse($crawler->filter('ergebnis'));
$this->assertTrue($response->isInquiryValid());
@@ -269,7 +269,7 @@ class BookingResponseParserTest extends TestCase
</zahlungsbedingungen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$response = $this->parser->parse($crawler->filter('ergebnis'));
// Voucher discount should only include AKTION
@@ -305,7 +305,7 @@ class BookingResponseParserTest extends TestCase
</zahlungsbedingungen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$response = $this->parser->parse($crawler->filter('ergebnis'));
// Verify no API-applied discounts
@@ -333,7 +333,7 @@ class BookingResponseParserTest extends TestCase
</zahlungsbedingungen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$response = $this->parser->parse($crawler->filter('ergebnis'));
$this->assertTrue($response->isInquiryValid());
@@ -366,7 +366,7 @@ class BookingResponseParserTest extends TestCase
</zahlungsbedingungen>
</ergebnis>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$response = $this->parser->parse($crawler->filter('ergebnis'));
// Only ERM (Gruppenrabatt) should be counted as API-applied discount
@@ -5,9 +5,9 @@ declare(strict_types=1);
namespace App\Tests\BusProNet\XmlParser;
use App\BusProNet\Model\CrmAttributes;
use App\BusProNet\XmlCrawlerFactory;
use App\BusProNet\XmlParser\CrmAttributesResponseParser;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
class CrmAttributesResponseParserTest extends TestCase
{
@@ -82,7 +82,7 @@ class CrmAttributesResponseParserTest extends TestCase
// A house that is deliberately left out of bpn_crm_house_manager_ids claims nothing —
// matching is by id, never by label.
$parser = new CrmAttributesResponseParser([]);
$attributes = $parser->parse((new Crawler($this->hausleitungXml()))->filterXPath('//ergebnis'));
$attributes = $parser->parse(XmlCrawlerFactory::create($this->hausleitungXml())->filterXPath('//ergebnis'));
self::assertSame([], $attributes->roles);
self::assertSame([], $attributes->hotelCodes);
@@ -108,7 +108,7 @@ class CrmAttributesResponseParserTest extends TestCase
private function parse(string $xmlContent): CrmAttributes
{
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$resultNode = $crawler->filterXPath('//ergebnis');
return $this->parser->parse($resultNode);
@@ -4,9 +4,9 @@ declare(strict_types=1);
namespace App\Tests\BusProNet\XmlParser;
use App\BusProNet\XmlCrawlerFactory;
use App\BusProNet\XmlParser\ExtendedAvailabilitiesParser;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
class ExtendedAvailabilitiesParserTest extends TestCase
{
@@ -28,7 +28,7 @@ class ExtendedAvailabilitiesParserTest extends TestCase
<reise status="Frei" buchungstatusmoeglich="FA" />
</ergebnis>';
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$response = $this->parser->parseServices($crawler);
$services = $response->getServices();
@@ -58,7 +58,7 @@ class ExtendedAvailabilitiesParserTest extends TestCase
</leistungen>
</ergebnis>';
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$response = $this->parser->parseServices($crawler);
$services = $response->getServices();
@@ -78,7 +78,7 @@ class ExtendedAvailabilitiesParserTest extends TestCase
<reise status="Frei" buchungstatusmoeglich="FA" />
</ergebnis>';
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$response = $this->parser->parseServices($crawler);
$this->assertSame('Frei', $response->travelStatus);
@@ -93,7 +93,7 @@ class ExtendedAvailabilitiesParserTest extends TestCase
<reise status="Frei" buchungstatusmoeglich="" />
</ergebnis>';
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$response = $this->parser->parseServices($crawler);
$this->assertSame([], $response->allowedBookingStatus);
@@ -106,7 +106,7 @@ class ExtendedAvailabilitiesParserTest extends TestCase
<leistungen />
</ergebnis>';
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$response = $this->parser->parseServices($crawler);
$this->assertNull($response->travelStatus);
@@ -120,7 +120,7 @@ class ExtendedAvailabilitiesParserTest extends TestCase
<leistungen />
</ergebnis>';
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$response = $this->parser->parseServices($crawler);
$this->assertSame([], $response->getServices());
@@ -4,9 +4,9 @@ declare(strict_types=1);
namespace App\Tests\BusProNet\XmlParser;
use App\BusProNet\XmlCrawlerFactory;
use App\BusProNet\XmlParser\InsuranceParser;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
class InsuranceParserTest extends TestCase
{
@@ -36,7 +36,7 @@ class InsuranceParserTest extends TestCase
</versicherungspakete>
</versicherungsstammdaten>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$insurances = $this->parser->parse($crawler);
// Test all insurances are included (2 regular + 1 complementary + 1 package = 4 total)
@@ -112,7 +112,7 @@ class InsuranceParserTest extends TestCase
</versicherungspakete>
</versicherungsstammdaten>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$insurances = $this->parser->parse($crawler);
$this->assertCount(2, $insurances);
@@ -134,7 +134,7 @@ class InsuranceParserTest extends TestCase
</versicherungen>
</versicherungsstammdaten>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$insurances = $this->parser->parse($crawler);
$this->assertCount(1, $insurances);
@@ -155,7 +155,7 @@ class InsuranceParserTest extends TestCase
</versicherungspakete>
</versicherungsstammdaten>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$insurances = $this->parser->parse($crawler);
$this->assertEmpty($insurances);
@@ -179,7 +179,7 @@ class InsuranceParserTest extends TestCase
</versicherungspakete>
</versicherungsstammdaten>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$insurances = $this->parser->parse($crawler);
// Should include: normal insurance (178917), both complementary insurances (177270, 999999), and package (P1000320)
@@ -4,9 +4,9 @@ declare(strict_types=1);
namespace App\Tests\BusProNet\XmlParser;
use App\BusProNet\XmlCrawlerFactory;
use App\BusProNet\XmlParser\PersonalDataParser;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
class PersonalDataParserTest extends TestCase
{
@@ -46,7 +46,7 @@ class PersonalDataParserTest extends TestCase
private function parse(string $xml): \App\BusProNet\Model\PersonalData
{
return $this->parser->parse(new Crawler($xml));
return $this->parser->parse(XmlCrawlerFactory::create($xml));
}
/**
+12 -12
View File
@@ -4,9 +4,9 @@ declare(strict_types=1);
namespace App\Tests\BusProNet\XmlParser;
use App\BusProNet\XmlCrawlerFactory;
use App\BusProNet\XmlParser\TravelParser;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
class TravelParserTest extends TestCase
{
@@ -68,7 +68,7 @@ class TravelParserTest extends TestCase
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
@@ -135,7 +135,7 @@ class TravelParserTest extends TestCase
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
@@ -166,7 +166,7 @@ class TravelParserTest extends TestCase
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
@@ -201,7 +201,7 @@ class TravelParserTest extends TestCase
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
@@ -240,7 +240,7 @@ class TravelParserTest extends TestCase
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
@@ -284,7 +284,7 @@ class TravelParserTest extends TestCase
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
@@ -319,7 +319,7 @@ class TravelParserTest extends TestCase
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
@@ -347,7 +347,7 @@ class TravelParserTest extends TestCase
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$crawler = XmlCrawlerFactory::create($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
@@ -364,7 +364,7 @@ class TravelParserTest extends TestCase
<zustieg idbuspro="4" zeit="01:00" preis="0,00" />
</zustiege>';
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$defaultDate = new \DateTimeImmutable('2029-12-30');
$pickups = $this->parser->getPickups(
@@ -392,7 +392,7 @@ class TravelParserTest extends TestCase
<zustieg idbuspro="2" zeit="30.12.2029 20:30" preis="0,00" />
</zustiege>';
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$defaultDate = new \DateTimeImmutable('2029-12-30');
$pickups = $this->parser->getPickups(
@@ -413,7 +413,7 @@ class TravelParserTest extends TestCase
<zustieg idbuspro="2" zeit="01:00" preis="0,00" />
</zustiege>';
$crawler = new Crawler($xml);
$crawler = XmlCrawlerFactory::create($xml);
$defaultDate = new \DateTimeImmutable('2029-12-30');
$pickups = $this->parser->getPickups(
@@ -71,24 +71,24 @@ class BpnSyncContingentsCommandTest extends TestCase
$hotelCodes,
);
$accommodationRepository = $this->createMock(AccommodationRepository::class);
$accommodationRepository = $this->createStub(AccommodationRepository::class);
$accommodationRepository->method('findAllWithCalendarCode')->willReturn($accommodations);
$manager = $this->createMock(ContingentSnapshotManager::class);
$manager = $this->createStub(ContingentSnapshotManager::class);
if ([] !== $results) {
$manager->method('sync')->willReturnOnConsecutiveCalls(...$results);
}
$command = new BpnSyncContingentsCommand(
$accommodationRepository,
$this->createMock(ContingentSyncStateRepository::class),
$this->createMock(ContingentDayRepository::class),
$this->createStub(ContingentSyncStateRepository::class),
$this->createStub(ContingentDayRepository::class),
$manager,
new NullLogger(),
);
$application = new Application();
$application->add($command);
$application->addCommand($command);
$tester = new CommandTester($application->find('app:bpn:sync-contingents'));
$tester->execute(['--horizon-months' => '1']);
+29 -25
View File
@@ -27,12 +27,14 @@ class BpnXmlSyncCommandTest extends TestCase
private TravelLoader $travelLoader;
private TravelDataProvider $travelDataService;
private TravelSnapshotManager $travelSnapshotService;
private BpnXmlSnapshotRefreshManager $snapshotRefreshManager;
private BpnXmlSyncManager $syncManager;
private BpnXmlSyncCommand $command;
private ?BpnXmlSyncCommand $command = null;
protected function tearDown(): void
{
if (null === $this->command) {
return;
}
$release = new \ReflectionMethod($this->command, 'release');
$release->setAccessible(true);
$release->invoke($this->command);
@@ -40,30 +42,30 @@ class BpnXmlSyncCommandTest extends TestCase
protected function setUp(): void
{
$this->xmlSource = $this->createMock(FilesystemOperator::class);
$this->xmlExport = $this->createMock(FilesystemOperator::class);
$this->xmlSource = $this->createStub(FilesystemOperator::class);
$this->xmlExport = $this->createStub(FilesystemOperator::class);
$this->cache = $this->createMock(TagAwareCacheInterface::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->logger = $this->createStub(LoggerInterface::class);
$this->travelLoader = $this->createMock(TravelLoader::class);
$this->travelDataService = $this->createMock(TravelDataProvider::class);
$this->travelSnapshotService = $this->createMock(TravelSnapshotManager::class);
$this->snapshotRefreshManager = new BpnXmlSnapshotRefreshManager(
$this->travelLoader,
$this->travelDataService,
$this->travelSnapshotService,
$this->logger,
);
}
$this->syncManager = new BpnXmlSyncManager(
$this->xmlSource,
$this->xmlExport,
$this->cache,
$this->logger,
);
$this->command = new BpnXmlSyncCommand(
$this->syncManager,
$this->snapshotRefreshManager,
private function command(): BpnXmlSyncCommand
{
return $this->command ??= new BpnXmlSyncCommand(
new BpnXmlSyncManager(
$this->xmlSource,
$this->xmlExport,
$this->cache,
$this->logger,
),
new BpnXmlSnapshotRefreshManager(
$this->travelLoader,
$this->travelDataService,
$this->travelSnapshotService,
$this->logger,
),
$this->logger,
);
}
@@ -101,7 +103,7 @@ class BpnXmlSyncCommandTest extends TestCase
->method('invalidateTags')
->with(['xml-sync']);
$tester = new CommandTester($this->command);
$tester = new CommandTester($this->command());
$tester->execute([]);
$this->assertSame(Command::SUCCESS, $tester->getStatusCode());
@@ -121,7 +123,7 @@ class BpnXmlSyncCommandTest extends TestCase
$this->travelSnapshotService->expects($this->never())->method('purgeOrphanedFutureSnapshots');
$this->cache->expects($this->never())->method('invalidateTags');
$tester = new CommandTester($this->command);
$tester = new CommandTester($this->command());
$tester->execute([]);
$this->assertSame(Command::SUCCESS, $tester->getStatusCode());
@@ -129,6 +131,8 @@ class BpnXmlSyncCommandTest extends TestCase
public function testSnapshotSyncIsSkippedAndWarningLoggedWhenFileMapGenerationFails(): void
{
$this->logger = $this->createMock(LoggerInterface::class);
$newerTimestamp = "24.03.2026 12:00:00\nExport\n3 Dateien\n";
$olderTimestamp = "24.03.2026 10:00:00\nExport\n3 Dateien\n";
@@ -153,7 +157,7 @@ class BpnXmlSyncCommandTest extends TestCase
$this->travelSnapshotService->expects($this->never())->method('purgeOrphanedFutureSnapshots');
$this->cache->expects($this->once())->method('invalidateTags')->with(['xml-sync']);
$tester = new CommandTester($this->command);
$tester = new CommandTester($this->command());
$tester->execute([]);
$this->assertSame(Command::SUCCESS, $tester->getStatusCode());
+1 -1
View File
@@ -51,7 +51,7 @@ class DbAnonymizeCommandTest extends TestCase
{
return new DbAnonymizeCommand(
$anonymizer,
$this->createMock(LoggerInterface::class),
$this->createStub(LoggerInterface::class),
$environment,
);
}
@@ -90,7 +90,7 @@ class MailjetNewsletterWebhookCommandTest extends TestCase
$mailjetApiClient,
'https://my.ep-reisen.de',
'secret',
$this->createMock(LoggerInterface::class),
$this->createStub(LoggerInterface::class),
);
}
}
@@ -27,7 +27,10 @@ class PersonalDataControllerTest extends TestCase
{
public function testIndexRendersNewsletterSubscribeCtaWhenNotSubscribed(): void
{
$controller = $this->createController();
$controller = $this->createController(
apiClient: $this->createMock(ApiClient::class),
newsletterManager: $this->createMock(NewsletterManager::class),
);
$controller->apiClient
->expects(self::once())
->method('getPersonalData')
@@ -55,7 +58,10 @@ class PersonalDataControllerTest extends TestCase
public function testIndexStillTracksPendingNewsletterConfirmationWhenSubscribed(): void
{
$controller = $this->createController();
$controller = $this->createController(
apiClient: $this->createMock(ApiClient::class),
newsletterManager: $this->createMock(NewsletterManager::class),
);
$controller->apiClient
->expects(self::once())
->method('getPersonalData')
@@ -82,7 +88,10 @@ class PersonalDataControllerTest extends TestCase
public function testNewsletterActionReturnsHtmxRedirectAndFlash(): void
{
$controller = $this->createController();
$controller = $this->createController(
apiClient: $this->createMock(ApiClient::class),
newsletterManager: $this->createMock(NewsletterManager::class),
);
$controller->apiClient
->expects(self::once())
->method('getPersonalData')
@@ -122,7 +131,10 @@ class PersonalDataControllerTest extends TestCase
public function testNewsletterActionResendsPendingConfirmation(): void
{
$controller = $this->createController();
$controller = $this->createController(
apiClient: $this->createMock(ApiClient::class),
newsletterManager: $this->createMock(NewsletterManager::class),
);
$controller->apiClient
->expects(self::once())
->method('getPersonalData')
@@ -173,7 +185,10 @@ class PersonalDataControllerTest extends TestCase
*/
public function testIndexDoesNotSubmitTheFormWhenPersonalDataCouldNotBeLoaded(): void
{
$controller = $this->createController();
$controller = $this->createController(
apiClient: $this->createMock(ApiClient::class),
form: $this->createMock(FormInterface::class),
);
$controller->apiClient
->expects(self::once())
->method('getPersonalData')
@@ -194,20 +209,25 @@ class PersonalDataControllerTest extends TestCase
self::assertSame('account/personal_data.html.twig', $controller->renderedView);
}
private function createController(): TestablePersonalDataController
{
/**
* Collaborators default to stubs; a test passes its own mock for whatever it sets
* expectations on, and reaches it again through the controller's public property.
*/
private function createController(
?ApiClient $apiClient = null,
?NewsletterManager $newsletterManager = null,
?FormInterface $form = null,
): TestablePersonalDataController {
$user = new User('[email protected]');
$user->setPassword('secret');
$apiClient = $this->createMock(ApiClient::class);
$crypt = $this->createMock(Crypt::class);
$crypt
->method('decrypt')
->with('secret')
->willReturn('secret');
$form = $this->createMock(FormInterface::class);
$form ??= $this->createStub(FormInterface::class);
$form
->method('handleRequest')
->willReturnSelf();
@@ -216,13 +236,13 @@ class PersonalDataControllerTest extends TestCase
->willReturn(false);
return new TestablePersonalDataController(
$apiClient,
$apiClient ?? $this->createStub(ApiClient::class),
$crypt,
$this->createMock(BookingEditDataLoader::class),
$this->createMock(ProfileCompletenessChecker::class),
$this->createMock(EntityManagerInterface::class),
$this->createMock(NewsletterManager::class),
$this->createMock(LoggerInterface::class),
$this->createStub(BookingEditDataLoader::class),
$this->createStub(ProfileCompletenessChecker::class),
$this->createStub(EntityManagerInterface::class),
$newsletterManager ?? $this->createStub(NewsletterManager::class),
$this->createStub(LoggerInterface::class),
$user,
$form,
);
@@ -299,7 +319,7 @@ final class TestablePersonalDataController extends PersonalDataController
$this->flashes[] = [$type, (string) $message];
}
protected function render(string $view, array $parameters = [], Response $response = null): Response
protected function render(string $view, array $parameters = [], ?Response $response = null): Response
{
$this->renderedView = $view;
$this->renderedParameters = $parameters;
@@ -9,6 +9,7 @@ use App\Entity\Groups\Accommodation;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Service\AccommodationBookingService;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\Form\FormInterface;
@@ -34,9 +35,7 @@ class ChangeAccommodationControllerTest extends TestCase
self::assertSame('admin/accommodation_booking/modal_change_accommodation.html.twig', $controller->renderedView);
}
/**
* @dataProvider lockedStatuses
*/
#[DataProvider('lockedStatuses')]
public function testABookingThatHasLeftEntwurfCannotMoveHouse(AccommodationBookingStatus $status): void
{
// The customer may already be looking at the offer under their access link.
@@ -127,7 +126,7 @@ class ChangeAccommodationControllerTest extends TestCase
private function unsubmittedForm(): FormInterface
{
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form->method('handleRequest')->willReturn($form);
$form->method('isSubmitted')->willReturn(false);
@@ -136,7 +135,7 @@ class ChangeAccommodationControllerTest extends TestCase
private function submittedForm(Accommodation $selected): FormInterface
{
$field = $this->createMock(FormInterface::class);
$field = $this->createStub(FormInterface::class);
$field->method('getData')->willReturn($selected);
$form = $this->createMock(FormInterface::class);
@@ -154,7 +153,7 @@ class ChangeAccommodationControllerTest extends TestCase
): TestableChangeAccommodationController {
return new TestableChangeAccommodationController(
$bookingService,
$this->createMock(LoggerInterface::class),
$this->createStub(LoggerInterface::class),
$form,
);
}
@@ -9,6 +9,7 @@ use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Message\CreateClickUpBookingTaskMessage;
use App\Service\AccommodationBookingService;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
@@ -29,7 +30,7 @@ class ConfirmControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('confirmBooking');
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createMock(LoggerInterface::class));
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createStub(LoggerInterface::class));
$response = $controller->index($this->receivedBooking(), Request::create('/admin/accommodation-booking/1/confirm'));
@@ -51,7 +52,7 @@ class ConfirmControllerTest extends TestCase
->with(self::isInstanceOf(CreateClickUpBookingTaskMessage::class))
->willReturnCallback(static fn (object $message): Envelope => new Envelope($message));
$controller = new TestableConfirmController($bookingService, $messageBus, $this->createMock(LoggerInterface::class));
$controller = new TestableConfirmController($bookingService, $messageBus, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/confirm', 'POST'));
@@ -63,16 +64,14 @@ class ConfirmControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('confirmBooking');
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createMock(LoggerInterface::class), tokenValid: false);
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createStub(LoggerInterface::class), tokenValid: false);
$this->expectException(AccessDeniedException::class);
$controller->index($this->receivedBooking(), Request::create('/admin/accommodation-booking/1/confirm', 'POST'));
}
/**
* @dataProvider nonReceivedStatuses
*/
#[DataProvider('nonReceivedStatuses')]
public function testABookingThatIsNotAwaitingValidationCannotBeConfirmed(AccommodationBookingStatus $status): void
{
$booking = $this->receivedBooking();
@@ -81,7 +80,7 @@ class ConfirmControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('confirmBooking');
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createMock(LoggerInterface::class));
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/confirm', 'POST'));
@@ -108,7 +107,7 @@ class ConfirmControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('confirmBooking');
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createMock(LoggerInterface::class));
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/confirm', 'POST'));
@@ -34,14 +34,14 @@ class CreateControllerTest extends TestCase
private function buildController(?UserInterface $user): TestableCreateController
{
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form->method('handleRequest')->willReturn($form);
$form->method('isSubmitted')->willReturn(false);
return new TestableCreateController(
$this->createMock(EntityManagerInterface::class),
$this->createMock(LoggerInterface::class),
$this->createMock(AccommodationBookingService::class),
$this->createStub(EntityManagerInterface::class),
$this->createStub(LoggerInterface::class),
$this->createStub(AccommodationBookingService::class),
$form,
$user,
);
@@ -9,6 +9,7 @@ use App\Entity\Groups\Accommodation;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -53,9 +54,7 @@ class DeleteControllerTest extends TestCase
self::assertSame('success', $controller->flashes[0]['type']);
}
/**
* @dataProvider undeletableStatuses
*/
#[DataProvider('undeletableStatuses')]
public function testOnlyADraftCanBeDeleted(AccommodationBookingStatus $status): void
{
// Anything past Entwurf has been in contact with the customer and is closed by an
@@ -126,7 +125,7 @@ class DeleteControllerTest extends TestCase
): TestableBookingDeleteController {
return new TestableBookingDeleteController(
$entityManager,
$this->createMock(LoggerInterface::class),
$this->createStub(LoggerInterface::class),
$tokenValid,
);
}
@@ -8,6 +8,7 @@ use App\Controller\Admin\AccommodationBooking\DiscardController;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Service\AccommodationBookingService;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -25,7 +26,7 @@ class DiscardControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('discardBooking');
$controller = new TestableDiscardController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableDiscardController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($this->openBooking(), Request::create('/admin/accommodation-booking/1/discard'));
@@ -33,9 +34,7 @@ class DiscardControllerTest extends TestCase
self::assertSame('admin/accommodation_booking/modal_discard.html.twig', $controller->renderedView);
}
/**
* @dataProvider discardableStatuses
*/
#[DataProvider('discardableStatuses')]
public function testPostDiscardsTheBookingAndRedirectsTheBrowser(AccommodationBookingStatus $status): void
{
$booking = $this->openBooking();
@@ -44,7 +43,7 @@ class DiscardControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::once())->method('discardBooking')->with($booking);
$controller = new TestableDiscardController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableDiscardController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/discard', 'POST'));
@@ -62,9 +61,7 @@ class DiscardControllerTest extends TestCase
yield 'received' => [AccommodationBookingStatus::Received];
}
/**
* @dataProvider closedStatuses
*/
#[DataProvider('closedStatuses')]
public function testAClosedBookingCannotBeDiscarded(AccommodationBookingStatus $status): void
{
// A released confirmation is binding, and an Absage is already the end of the line.
@@ -74,7 +71,7 @@ class DiscardControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('discardBooking');
$controller = new TestableDiscardController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableDiscardController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/discard', 'POST'));
@@ -95,7 +92,7 @@ class DiscardControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('discardBooking');
$controller = new TestableDiscardController($bookingService, $this->createMock(LoggerInterface::class), tokenValid: false);
$controller = new TestableDiscardController($bookingService, $this->createStub(LoggerInterface::class), tokenValid: false);
$this->expectException(AccessDeniedException::class);
@@ -13,6 +13,7 @@ use App\Repository\Groups\BoardServiceRepository;
use App\Repository\UserRepository;
use App\Service\AccommodationBookingService;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\Form\FormInterface;
@@ -26,9 +27,7 @@ use Symfony\Component\HttpFoundation\Response;
*/
class EditControllerTest extends TestCase
{
/**
* @dataProvider everyStatus
*/
#[DataProvider('everyStatus')]
public function testSavingNeverNotifiesTheCustomer(AccommodationBookingStatus $status): void
{
// Sending used to be a side effect of saving a status change, which is how an inquiry
@@ -59,7 +58,7 @@ class EditControllerTest extends TestCase
private function submitEdit(AccommodationBooking $booking, AccommodationBookingService $bookingService): void
{
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form->method('handleRequest')->willReturn($form);
$form->method('isSubmitted')->willReturn(true);
$form->method('isValid')->willReturn(true);
@@ -70,10 +69,10 @@ class EditControllerTest extends TestCase
$controller = new TestableEditController(
$entityManager,
$this->createMock(LoggerInterface::class),
$this->createMock(BoardServiceRepository::class),
$this->createMock(AdditionalServiceRepository::class),
$this->createMock(UserRepository::class),
$this->createStub(LoggerInterface::class),
$this->createStub(BoardServiceRepository::class),
$this->createStub(AdditionalServiceRepository::class),
$this->createStub(UserRepository::class),
$bookingService,
$form,
);
@@ -97,7 +96,7 @@ class EditControllerTest extends TestCase
public function testAdminGetsTheGroupsStaffAsBetreuerChoices(): void
{
$staff = [new User('[email protected]')];
$userRepo = $this->createMock(UserRepository::class);
$userRepo = $this->createStub(UserRepository::class);
$userRepo->method('findGroupsStaff')->willReturn($staff);
$controller = $this->buildController($userRepo, granted: true);
@@ -111,7 +110,7 @@ class EditControllerTest extends TestCase
$formerManager = new User('[email protected]');
$staff = [new User('[email protected]')];
$userRepo = $this->createMock(UserRepository::class);
$userRepo = $this->createStub(UserRepository::class);
$userRepo->method('findGroupsStaff')->willReturn($staff);
$booking = new AccommodationBooking();
@@ -127,17 +126,17 @@ class EditControllerTest extends TestCase
{
// An unsubmitted form: index() falls through to render() and only the options
// handed to createForm() are of interest here.
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form->method('handleRequest')->willReturn($form);
$form->method('isSubmitted')->willReturn(false);
return new TestableEditController(
$this->createMock(EntityManagerInterface::class),
$this->createMock(LoggerInterface::class),
$this->createMock(BoardServiceRepository::class),
$this->createMock(AdditionalServiceRepository::class),
$this->createStub(EntityManagerInterface::class),
$this->createStub(LoggerInterface::class),
$this->createStub(BoardServiceRepository::class),
$this->createStub(AdditionalServiceRepository::class),
$userRepo,
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingService::class),
$form,
$granted,
);
@@ -8,6 +8,7 @@ use App\Controller\Admin\AccommodationBooking\GenerateAccessLinkController;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Service\AccommodationBookingService;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -25,7 +26,7 @@ class GenerateAccessLinkControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('generateAccessLink');
$controller = new TestableGenerateAccessLinkController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableGenerateAccessLinkController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($this->requestedBooking(), Request::create('/admin/accommodation-booking/1/generate-access-link'));
@@ -33,9 +34,7 @@ class GenerateAccessLinkControllerTest extends TestCase
self::assertSame('admin/accommodation_booking/modal_generate_access_link.html.twig', $controller->renderedView);
}
/**
* @dataProvider statusesAwaitingAnOffer
*/
#[DataProvider('statusesAwaitingAnOffer')]
public function testPostGeneratesTheLinkAndRedirectsTheBrowser(AccommodationBookingStatus $status): void
{
$booking = $this->requestedBooking();
@@ -44,7 +43,7 @@ class GenerateAccessLinkControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::once())->method('generateAccessLink')->with($booking);
$controller = new TestableGenerateAccessLinkController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableGenerateAccessLinkController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/generate-access-link', 'POST'));
@@ -60,9 +59,7 @@ class GenerateAccessLinkControllerTest extends TestCase
yield 'requested' => [AccommodationBookingStatus::Requested];
}
/**
* @dataProvider statusesPastTheOffer
*/
#[DataProvider('statusesPastTheOffer')]
public function testABookingThatIsNotAwaitingAnOfferGetsNoLink(AccommodationBookingStatus $status): void
{
$booking = $this->requestedBooking();
@@ -71,7 +68,7 @@ class GenerateAccessLinkControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('generateAccessLink');
$controller = new TestableGenerateAccessLinkController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableGenerateAccessLinkController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/generate-access-link', 'POST'));
@@ -94,7 +91,7 @@ class GenerateAccessLinkControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('generateAccessLink');
$controller = new TestableGenerateAccessLinkController($bookingService, $this->createMock(LoggerInterface::class), tokenValid: false);
$controller = new TestableGenerateAccessLinkController($bookingService, $this->createStub(LoggerInterface::class), tokenValid: false);
$this->expectException(AccessDeniedException::class);
@@ -8,6 +8,7 @@ use App\Controller\Admin\AccommodationBooking\PdfController;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Service\AccommodationBookingPdfGenerator;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Response;
@@ -32,9 +33,7 @@ class PdfControllerTest extends TestCase
self::assertSame(Response::HTTP_OK, $response->getStatusCode());
}
/**
* @dataProvider nonConfirmedStatuses
*/
#[DataProvider('nonConfirmedStatuses')]
public function testABookingThatIsNotConfirmedCannotBeDownloaded(AccommodationBookingStatus $status): void
{
$generator = $this->createMock(AccommodationBookingPdfGenerator::class);
@@ -61,7 +60,7 @@ class PdfControllerTest extends TestCase
public function testAFailingGeneratorRedirectsWithAFlash(): void
{
$generator = $this->createMock(AccommodationBookingPdfGenerator::class);
$generator = $this->createStub(AccommodationBookingPdfGenerator::class);
$generator->method('createDownloadResponse')->willThrowException(new \RuntimeException('keine Preise'));
$controller = new TestablePdfController($generator);
@@ -8,6 +8,7 @@ use App\Controller\Admin\AccommodationBooking\SendAccessLinkController;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Service\AccommodationBookingService;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -25,7 +26,7 @@ class SendAccessLinkControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('sendAccessLink');
$controller = new TestableSendAccessLinkController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableSendAccessLinkController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($this->openBooking(), Request::create('/admin/accommodation-booking/1/send-access-link'));
@@ -40,7 +41,7 @@ class SendAccessLinkControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::once())->method('sendAccessLink')->with($booking);
$controller = new TestableSendAccessLinkController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableSendAccessLinkController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/send-access-link', 'POST'));
@@ -55,7 +56,7 @@ class SendAccessLinkControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('sendAccessLink');
$controller = new TestableSendAccessLinkController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableSendAccessLinkController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/send-access-link', 'POST'));
@@ -65,9 +66,8 @@ class SendAccessLinkControllerTest extends TestCase
/**
* Drafts are held back even when a link is on the record — a booking pushed back into
* Entwurf keeps its accessLinkIssuedAt, and it must not be handed out again.
*
* @dataProvider requestMethods
*/
#[DataProvider('requestMethods')]
public function testADraftLinkIsNeverSentEvenIfOneWasIssuedEarlier(string $method): void
{
$booking = $this->openBooking();
@@ -76,7 +76,7 @@ class SendAccessLinkControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('sendAccessLink');
$controller = new TestableSendAccessLinkController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableSendAccessLinkController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/send-access-link', $method));
@@ -98,7 +98,7 @@ class SendAccessLinkControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('sendAccessLink');
$controller = new TestableSendAccessLinkController($bookingService, $this->createMock(LoggerInterface::class), tokenValid: false);
$controller = new TestableSendAccessLinkController($bookingService, $this->createStub(LoggerInterface::class), tokenValid: false);
$this->expectException(AccessDeniedException::class);
@@ -113,7 +113,7 @@ class SendAccessLinkControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('sendAccessLink');
$controller = new TestableSendAccessLinkController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableSendAccessLinkController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/send-access-link', 'POST'));
@@ -8,6 +8,7 @@ use App\Controller\Admin\AccommodationBooking\SendOfferController;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Service\AccommodationBookingService;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -25,7 +26,7 @@ class SendOfferControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('sendOffer');
$controller = new TestableSendOfferController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableSendOfferController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($this->requestedBooking(), Request::create('/admin/accommodation-booking/1/send-offer'));
@@ -33,9 +34,7 @@ class SendOfferControllerTest extends TestCase
self::assertSame('admin/accommodation_booking/modal_send_offer.html.twig', $controller->renderedView);
}
/**
* @dataProvider statusesAwaitingAnOffer
*/
#[DataProvider('statusesAwaitingAnOffer')]
public function testPostSendsTheOfferAndRedirectsTheBrowser(AccommodationBookingStatus $status): void
{
$booking = $this->requestedBooking();
@@ -44,7 +43,7 @@ class SendOfferControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::once())->method('sendOffer')->with($booking);
$controller = new TestableSendOfferController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableSendOfferController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/send-offer', 'POST'));
@@ -61,9 +60,7 @@ class SendOfferControllerTest extends TestCase
yield 'requested' => [AccommodationBookingStatus::Requested];
}
/**
* @dataProvider statusesPastTheOffer
*/
#[DataProvider('statusesPastTheOffer')]
public function testABookingThatIsNotAwaitingAnOfferGetsNone(AccommodationBookingStatus $status): void
{
$booking = $this->requestedBooking();
@@ -72,7 +69,7 @@ class SendOfferControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('sendOffer');
$controller = new TestableSendOfferController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableSendOfferController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/send-offer', 'POST'));
@@ -95,7 +92,7 @@ class SendOfferControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('sendOffer');
$controller = new TestableSendOfferController($bookingService, $this->createMock(LoggerInterface::class), tokenValid: false);
$controller = new TestableSendOfferController($bookingService, $this->createStub(LoggerInterface::class), tokenValid: false);
$this->expectException(AccessDeniedException::class);
@@ -113,7 +110,7 @@ class SendOfferControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('sendOffer');
$controller = new TestableSendOfferController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableSendOfferController($bookingService, $this->createStub(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/send-offer', 'POST'));
@@ -31,7 +31,7 @@ class ApproveRoleControllerTest extends TestCase
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager->expects(self::never())->method('flush');
$controller = new TestableApproveRoleController($entityManager, $this->createMock(LoggerInterface::class));
$controller = new TestableApproveRoleController($entityManager, $this->createStub(LoggerInterface::class));
$response = $controller->index($user, Role::GROUPS_ADMIN, Request::create('/admin/user/1/approve/ROLE_GROUPS_ADMIN'));
@@ -47,7 +47,7 @@ class ApproveRoleControllerTest extends TestCase
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager->expects(self::once())->method('flush');
$controller = new TestableApproveRoleController($entityManager, $this->createMock(LoggerInterface::class));
$controller = new TestableApproveRoleController($entityManager, $this->createStub(LoggerInterface::class));
$response = $controller->index($user, Role::GROUPS_ADMIN, Request::create('/admin/user/1/approve/ROLE_GROUPS_ADMIN', 'POST'));
@@ -61,7 +61,7 @@ class ApproveRoleControllerTest extends TestCase
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager->expects(self::never())->method('flush');
$controller = new TestableApproveRoleController($entityManager, $this->createMock(LoggerInterface::class));
$controller = new TestableApproveRoleController($entityManager, $this->createStub(LoggerInterface::class));
$this->expectException(NotFoundHttpException::class);
@@ -76,7 +76,7 @@ class ApproveRoleControllerTest extends TestCase
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager->expects(self::never())->method('flush');
$controller = new TestableApproveRoleController($entityManager, $this->createMock(LoggerInterface::class), currentUser: $user);
$controller = new TestableApproveRoleController($entityManager, $this->createStub(LoggerInterface::class), currentUser: $user);
$this->expectException(AccessDeniedException::class);
@@ -90,7 +90,7 @@ class ApproveRoleControllerTest extends TestCase
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager->expects(self::once())->method('flush');
$controller = new TestableApproveRoleController($entityManager, $this->createMock(LoggerInterface::class), currentUser: $user);
$controller = new TestableApproveRoleController($entityManager, $this->createStub(LoggerInterface::class), currentUser: $user);
// Only ROLE_ADMIN needs a second pair of eyes — an approver already holds it, so the
// rest grant less than they could grant themselves anyway.
@@ -104,7 +104,7 @@ class ApproveRoleControllerTest extends TestCase
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager->expects(self::never())->method('flush');
$controller = new TestableApproveRoleController($entityManager, $this->createMock(LoggerInterface::class), tokenValid: false);
$controller = new TestableApproveRoleController($entityManager, $this->createStub(LoggerInterface::class), tokenValid: false);
$this->expectException(AccessDeniedException::class);
@@ -119,8 +119,8 @@ class ApproveRoleControllerTest extends TestCase
$tokenStorage->setToken(new PostAuthenticationToken($user, 'main', $user->getRoles()));
$controller = new TestableApproveRoleController(
$this->createMock(EntityManagerInterface::class),
$this->createMock(LoggerInterface::class),
$this->createStub(EntityManagerInterface::class),
$this->createStub(LoggerInterface::class),
currentUser: $user,
tokenStorage: $tokenStorage,
);
@@ -142,8 +142,8 @@ class ApproveRoleControllerTest extends TestCase
$tokenStorage->setToken($originalToken = new PostAuthenticationToken($admin, 'main', $admin->getRoles()));
$controller = new TestableApproveRoleController(
$this->createMock(EntityManagerInterface::class),
$this->createMock(LoggerInterface::class),
$this->createStub(EntityManagerInterface::class),
$this->createStub(LoggerInterface::class),
currentUser: $admin,
tokenStorage: $tokenStorage,
);
@@ -157,10 +157,10 @@ class AccommodationBookingControllerTest extends TestCase
->with(['uuid' => $booking->getUuid()])
->willReturn($booking);
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator = $this->createStub(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->method('compute')->willReturn(null);
$controller = new AccommodationBookingController($bookingRepository, $breakdownCalculator, $this->serializer(), $this->createMock(AccommodationBookingService::class));
$controller = new AccommodationBookingController($bookingRepository, $breakdownCalculator, $this->serializer(), $this->createStub(AccommodationBookingService::class));
$response = $controller->single($booking->getUuid());
$payload = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR);
@@ -183,7 +183,7 @@ class AccommodationBookingControllerTest extends TestCase
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->expects(self::never())->method('compute');
$controller = new AccommodationBookingController($bookingRepository, $breakdownCalculator, $this->serializer(), $this->createMock(AccommodationBookingService::class));
$controller = new AccommodationBookingController($bookingRepository, $breakdownCalculator, $this->serializer(), $this->createStub(AccommodationBookingService::class));
$response = $controller->single('unknown-uuid');
$payload = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR);
@@ -210,7 +210,7 @@ class AccommodationBookingControllerTest extends TestCase
->with(['uuid' => $booking->getUuid()])
->willReturn($booking);
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator = $this->createStub(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->method('compute')->willReturn(null);
$bookingService = $this->createMock(AccommodationBookingService::class);
@@ -256,7 +256,7 @@ class AccommodationBookingControllerTest extends TestCase
->with(['uuid' => $booking->getUuid()])
->willReturn($booking);
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator = $this->createStub(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->method('compute')->willReturn(null);
$bookingService = $this->createMock(AccommodationBookingService::class);
@@ -190,7 +190,7 @@ class ContingentControllerTest extends TestCase
*/
private function callFullSpanCalendar(?array $bounds, array $prices, array $statuses = []): array
{
$priceRepository = $this->createMock(AccommodationPriceRepository::class);
$priceRepository = $this->createStub(AccommodationPriceRepository::class);
$priceRepository->method('findPricedDateBoundsByHotelCode')->willReturn($bounds);
$priceRepository->method('findByHotelCodeAndDateRange')->willReturn($prices);
@@ -214,13 +214,13 @@ class ContingentControllerTest extends TestCase
?array $prices = null,
?AccommodationPriceRepository $priceRepository = null,
): Response {
$accommodationRepository = $this->createMock(AccommodationRepository::class);
$accommodationRepository = $this->createStub(AccommodationRepository::class);
$accommodationRepository->method('findOneBy')->willReturn((new Accommodation())->setCalendarCode('HOTEL1')->setCurrency('EUR'));
$snapshotReader = $this->createMock(ContingentSnapshotReader::class);
$snapshotReader = $this->createStub(ContingentSnapshotReader::class);
$snapshotReader->method('statusesFor')->willReturn($statuses);
$priceRepository ??= $this->createMock(AccommodationPriceRepository::class);
$priceRepository ??= $this->createStub(AccommodationPriceRepository::class);
if (null !== $prices) {
$priceRepository->method('findByHotelCodeAndDateRange')->willReturn($prices);
@@ -231,8 +231,8 @@ class ContingentControllerTest extends TestCase
$priceRepository,
$snapshotReader,
new PriceTimelineBuilder(),
new AccommodationPriceCoverage($this->createMock(AccommodationPriceRepository::class)),
$this->createMock(LoggerInterface::class),
new AccommodationPriceCoverage($this->createStub(AccommodationPriceRepository::class)),
$this->createStub(LoggerInterface::class),
);
// No 'serializer' service registered, so AbstractController::json() falls back to
@@ -245,12 +245,12 @@ class ContingentControllerTest extends TestCase
private function createController(): ContingentController
{
return new ContingentController(
$this->createMock(AccommodationRepository::class),
$this->createMock(AccommodationPriceRepository::class),
$this->createMock(ContingentSnapshotReader::class),
$this->createStub(AccommodationRepository::class),
$this->createStub(AccommodationPriceRepository::class),
$this->createStub(ContingentSnapshotReader::class),
new PriceTimelineBuilder(),
new AccommodationPriceCoverage($this->createMock(AccommodationPriceRepository::class)),
$this->createMock(LoggerInterface::class),
new AccommodationPriceCoverage($this->createStub(AccommodationPriceRepository::class)),
$this->createStub(LoggerInterface::class),
);
}
@@ -24,6 +24,7 @@ use App\Service\BookingEditDraftManager;
use App\Service\BookingEditPreFlightChecker;
use App\Service\BookingEditSubmitter;
use App\Service\BookingSessionManager;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Symfony\Component\Form\FormInterface;
@@ -62,7 +63,7 @@ class IndexControllerTest extends TestCase
];
$bookingData = $this->createBooking();
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form->method('isSubmitted')->willReturn(false);
$fingerprintService = $this->createMock(BookingChangeTracker::class);
@@ -110,13 +111,13 @@ class IndexControllerTest extends TestCase
$controller = new TestableIndexController(
$dataLoader,
$this->createMock(BookingEditDraftManager::class),
$this->createStub(BookingEditDraftManager::class),
$bookingSessionService,
$fingerprintService,
$bookingConfigurator,
$contextFactory,
$preflightChecker,
$this->createMock(BookingEditSubmitter::class),
$this->createStub(BookingEditSubmitter::class),
$user,
$form,
);
@@ -147,7 +148,7 @@ class IndexControllerTest extends TestCase
];
$bookingData = $this->createBooking();
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form->method('isSubmitted')->willReturn(false);
$fingerprintService = $this->createMock(BookingChangeTracker::class);
@@ -187,13 +188,13 @@ class IndexControllerTest extends TestCase
$controller = new TestableIndexController(
$dataLoader,
$this->createMock(BookingEditDraftManager::class),
$this->createMock(BookingSessionManager::class),
$this->createStub(BookingEditDraftManager::class),
$this->createStub(BookingSessionManager::class),
$fingerprintService,
$this->createMock(BookingConfigurator::class),
$this->createStub(BookingConfigurator::class),
$contextFactory,
$preflightChecker,
$this->createMock(BookingEditSubmitter::class),
$this->createStub(BookingEditSubmitter::class),
$user,
$form,
);
@@ -275,10 +276,10 @@ class IndexControllerTest extends TestCase
$controller = new TestableIndexController(
$dataLoader,
$this->createMock(BookingEditDraftManager::class),
$this->createMock(BookingSessionManager::class),
$this->createStub(BookingEditDraftManager::class),
$this->createStub(BookingSessionManager::class),
$fingerprintService,
$this->createMock(BookingConfigurator::class),
$this->createStub(BookingConfigurator::class),
$contextFactory,
$preflightChecker,
$submitter,
@@ -362,10 +363,10 @@ class IndexControllerTest extends TestCase
$controller = new TestableIndexController(
$dataLoader,
$this->createMock(BookingEditDraftManager::class),
$this->createMock(BookingSessionManager::class),
$this->createStub(BookingEditDraftManager::class),
$this->createStub(BookingSessionManager::class),
$fingerprintService,
$this->createMock(BookingConfigurator::class),
$this->createStub(BookingConfigurator::class),
$contextFactory,
$preflightChecker,
$submitter,
@@ -390,7 +391,7 @@ class IndexControllerTest extends TestCase
$bookingDto->participants = [$this->createParticipant()];
$bookingData = $this->createBooking();
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form->method('isSubmitted')->willReturn(false);
$fingerprintService = $this->createMock(BookingChangeTracker::class);
@@ -433,13 +434,13 @@ class IndexControllerTest extends TestCase
$controller = new TestableIndexController(
$dataLoader,
$this->createMock(BookingEditDraftManager::class),
$this->createMock(BookingSessionManager::class),
$this->createStub(BookingEditDraftManager::class),
$this->createStub(BookingSessionManager::class),
$fingerprintService,
$bookingConfigurator,
$contextFactory,
$this->createPreflightChecker($bookingDto),
$this->createMock(BookingEditSubmitter::class),
$this->createStub(BookingEditSubmitter::class),
$user,
$form,
);
@@ -460,7 +461,7 @@ class IndexControllerTest extends TestCase
$bookingDto->participants = [$this->createParticipant()];
$bookingData = $this->createBooking();
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form->method('isSubmitted')->willReturn(false);
$fingerprintService = $this->createMock(BookingChangeTracker::class);
@@ -501,13 +502,13 @@ class IndexControllerTest extends TestCase
$controller = new TestableIndexController(
$dataLoader,
$this->createMock(BookingEditDraftManager::class),
$this->createMock(BookingSessionManager::class),
$this->createStub(BookingEditDraftManager::class),
$this->createStub(BookingSessionManager::class),
$fingerprintService,
$bookingConfigurator,
$contextFactory,
$this->createPreflightChecker($bookingDto),
$this->createMock(BookingEditSubmitter::class),
$this->createStub(BookingEditSubmitter::class),
$user,
$form,
);
@@ -543,13 +544,13 @@ class IndexControllerTest extends TestCase
$dataLoader,
$draftService,
$bookingSessionService,
$this->createMock(BookingChangeTracker::class),
$this->createMock(BookingConfigurator::class),
$this->createMock(BookingEditContextFactory::class),
$this->createMock(BookingEditPreFlightChecker::class),
$this->createMock(BookingEditSubmitter::class),
$this->createStub(BookingChangeTracker::class),
$this->createStub(BookingConfigurator::class),
$this->createStub(BookingEditContextFactory::class),
$this->createStub(BookingEditPreFlightChecker::class),
$this->createStub(BookingEditSubmitter::class),
$user,
$this->createMock(FormInterface::class),
$this->createStub(FormInterface::class),
);
$response = $controller->reloadFromApi(42, $request);
@@ -560,11 +561,11 @@ class IndexControllerTest extends TestCase
}
/**
* @dataProvider submissionResultProvider
*
* @param array<int, array{0: string, 1: string}> $expectedFlashes
*
* @phpstan-param array<int, array{0: string, 1: string}> $expectedFlashes
*/
#[DataProvider('submissionResultProvider')]
public function testIndexAppliesErrorSubmissionResultFlashesAndRedirectsBackToEditPage(
BookingEditSubmissionResult $submissionResult,
array $expectedFlashes,
@@ -673,7 +674,7 @@ class IndexControllerTest extends TestCase
bookingDto: $bookingDto,
bookingData: $bookingData,
mutableData: null,
summaryData: $this->createMock(BookingSummaryDto::class),
summaryData: $this->createStub(BookingSummaryDto::class),
cardsData: [
0 => new ParticipantCardDataDto(
'One',
@@ -755,11 +756,11 @@ class IndexControllerTest extends TestCase
$controller = new TestableIndexController(
$dataLoader,
$this->createMock(BookingEditDraftManager::class),
$this->createMock(BookingSessionManager::class),
$this->createStub(BookingEditDraftManager::class),
$this->createStub(BookingSessionManager::class),
$fingerprintService,
$this->createMock(BookingConfigurator::class),
$this->createMock(BookingEditContextFactory::class),
$this->createStub(BookingConfigurator::class),
$this->createStub(BookingEditContextFactory::class),
$preflightChecker,
$submitter,
$user,
@@ -86,9 +86,9 @@ class ParticipantControllerTest extends TestCase
->with($user, 42, $bookingDto);
$prepopulationService = new ParticipantDataPrefiller(
$this->createMock(ApiClient::class),
$this->createMock(Crypt::class),
$this->createMock(LoggerInterface::class),
$this->createStub(ApiClient::class),
$this->createStub(Crypt::class),
$this->createStub(LoggerInterface::class),
);
$participantFormSupportService = $this->createMock(ParticipantFormSupport::class);
@@ -115,7 +115,7 @@ class ParticipantControllerTest extends TestCase
],
]);
$summaryData = $this->createMock(BookingSummaryDto::class);
$summaryData = $this->createStub(BookingSummaryDto::class);
$context = new BookingEditContext($bookingDto, $bookingData, null, $summaryData);
$contextFactory = $this->createMock(BookingEditContextFactory::class);
@@ -131,7 +131,7 @@ class ParticipantControllerTest extends TestCase
$dataLoader,
$draftService,
$contextFactory,
$this->createMock(BookingConfigurator::class),
$this->createStub(BookingConfigurator::class),
$bookingSessionService,
$prepopulationService,
$participantFormSupportService,
@@ -217,7 +217,7 @@ class ParticipantControllerTest extends TestCase
->with($bookingDto)
->willReturn([]);
$summaryData = $this->createMock(BookingSummaryDto::class);
$summaryData = $this->createStub(BookingSummaryDto::class);
$context = new BookingEditContext($bookingDto, $bookingData, null, $summaryData);
$contextFactory = $this->createMock(BookingEditContextFactory::class);
@@ -230,14 +230,14 @@ class ParticipantControllerTest extends TestCase
->willReturn($context);
$prepopulationService = new ParticipantDataPrefiller(
$this->createMock(ApiClient::class),
$this->createMock(Crypt::class),
$this->createMock(LoggerInterface::class),
$this->createStub(ApiClient::class),
$this->createStub(Crypt::class),
$this->createStub(LoggerInterface::class),
);
$controller = new TestableParticipantController(
$dataLoader,
$this->createMock(BookingEditDraftManager::class),
$this->createStub(BookingEditDraftManager::class),
$contextFactory,
$bookingConfigurator,
$bookingSessionService,
@@ -286,17 +286,17 @@ class ParticipantControllerTest extends TestCase
$bookingDto->originalFingerprint = $changeTracker->generateFingerprint($bookingDto);
$this->assertFalse($changeTracker->isDirty($bookingDto), 'Baseline must start clean');
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form->method('handleRequest')->willReturnSelf();
$form->method('createView')->willReturn(new FormView());
$dataLoader = $this->createMock(BookingEditDataLoader::class);
$dataLoader = $this->createStub(BookingEditDataLoader::class);
$dataLoader->method('fetchBookingData')->willReturn($bookingData);
$bookingSessionService = $this->createMock(BookingSessionManager::class);
$bookingSessionService = $this->createStub(BookingSessionManager::class);
$bookingSessionService->method('getBookingDto')->willReturn($bookingDto);
$participantFormSupportService = $this->createMock(ParticipantFormSupport::class);
$participantFormSupportService = $this->createStub(ParticipantFormSupport::class);
$participantFormSupportService->method('ensureParticipantExists')->willReturn($participant);
$participantFormSupportService->method('createParticipantEditDto')
->willReturn(new ParticipantEditDto($participant, $bookingDto));
@@ -306,21 +306,21 @@ class ParticipantControllerTest extends TestCase
]);
$participantFormSupportService->method('collectAndClearNotifications')->willReturn([]);
$summaryData = $this->createMock(BookingSummaryDto::class);
$contextFactory = $this->createMock(BookingEditContextFactory::class);
$summaryData = $this->createStub(BookingSummaryDto::class);
$contextFactory = $this->createStub(BookingEditContextFactory::class);
$contextFactory->method('createParticipantContext')
->willReturn(new BookingEditContext($bookingDto, $bookingData, null, $summaryData));
$controller = new TestableParticipantController(
$dataLoader,
$this->createMock(BookingEditDraftManager::class),
$this->createStub(BookingEditDraftManager::class),
$contextFactory,
$this->createMock(BookingConfigurator::class),
$this->createStub(BookingConfigurator::class),
$bookingSessionService,
new ParticipantDataPrefiller(
$this->createMock(ApiClient::class),
$this->createMock(Crypt::class),
$this->createMock(LoggerInterface::class),
$this->createStub(ApiClient::class),
$this->createStub(Crypt::class),
$this->createStub(LoggerInterface::class),
),
$participantFormSupportService,
$user,
@@ -53,8 +53,8 @@ class IndexControllerTest extends TestCase
private function makeController(): TestableAccommodationIndexController
{
return new TestableAccommodationIndexController(
$this->createMock(AccommodationBookingService::class),
$this->createMock(AccommodationSessionManager::class),
$this->createStub(AccommodationBookingService::class),
$this->createStub(AccommodationSessionManager::class),
);
}
}
@@ -106,20 +106,20 @@ class Step1CalendarDataTest extends TestCase
string $dateFrom,
string $dateTo,
): array {
$snapshotReader = $this->createMock(ContingentSnapshotReader::class);
$snapshotReader = $this->createStub(ContingentSnapshotReader::class);
$snapshotReader->method('statusesFor')->willReturn($statuses);
$priceRepository = $this->createMock(AccommodationPriceRepository::class);
$priceRepository = $this->createStub(AccommodationPriceRepository::class);
$priceRepository->method('findByHotelCodeAndDateRange')->willReturn($prices);
$controller = new Step1Controller(
$this->createMock(AccommodationBookingService::class),
$this->createMock(AccommodationSessionManager::class),
$this->createStub(AccommodationBookingService::class),
$this->createStub(AccommodationSessionManager::class),
$priceRepository,
new PriceTimelineBuilder(),
$snapshotReader,
$this->createMock(CalendarGridBuilder::class),
$this->createMock(GroupsPriceCalculator::class),
$this->createStub(CalendarGridBuilder::class),
$this->createStub(GroupsPriceCalculator::class),
new AccommodationPriceCoverage($priceRepository),
);
@@ -88,7 +88,7 @@ class Step1ControllerTest extends TestCase
$sessionManager = new AccommodationSessionManager();
$sessionManager->save($request, $dto);
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService = $this->createStub(AccommodationBookingService::class);
$bookingService
->method('applyDates')
->willThrowException(new \InvalidArgumentException('Ungültiges Datumsformat. Erwartet: YYYY-MM-DD.'));
@@ -105,14 +105,14 @@ class Step1ControllerTest extends TestCase
AccommodationBookingService $bookingService,
AccommodationSessionManager $sessionManager,
): TestableAccommodationStep1Controller {
$priceRepository = $this->createMock(AccommodationPriceRepository::class);
$priceRepository = $this->createStub(AccommodationPriceRepository::class);
return new TestableAccommodationStep1Controller(
$bookingService,
$sessionManager,
$priceRepository,
new PriceTimelineBuilder(),
$this->createMock(ContingentSnapshotReader::class),
$this->createStub(ContingentSnapshotReader::class),
new CalendarGridBuilder(),
new GroupsPriceCalculator(new PriceTimelineBuilder(), ['runningCostsEur' => 0, 'runningCostsChf' => 0, 'undersubscription30Eur' => 0, 'undersubscription30Chf' => 0, 'undersubscription40Eur' => 0, 'undersubscription40Chf' => 0]),
new AccommodationPriceCoverage($priceRepository),
@@ -38,7 +38,7 @@ class Step2ControllerTest extends TestCase
$sessionManager = new AccommodationSessionManager();
$sessionManager->save($request, $dto);
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form
->method('handleRequest')
->willReturnCallback(function () use ($dto, $form): FormInterface {
@@ -156,7 +156,7 @@ class Step3ControllerTest extends TestCase
private function createFormMock(bool $submitted, bool $valid): FormInterface
{
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form->method('handleRequest')->willReturnSelf();
$form->method('isSubmitted')->willReturn($submitted);
$form->method('isValid')->willReturn($valid);
@@ -50,7 +50,7 @@ class Step4ControllerTest extends TestCase
'ungroupedAdditionalServices' => [],
]);
$controller = new TestableStep4Controller($bookingService, $sessionManager, $this->createMock(FormInterface::class));
$controller = new TestableStep4Controller($bookingService, $sessionManager, $this->createStub(FormInterface::class));
$response = $controller->index($request);
@@ -73,9 +73,9 @@ class Step4ControllerTest extends TestCase
$sessionManager->save($request, $dto);
$controller = new TestableStep4Controller(
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingService::class),
$sessionManager,
$this->createMock(FormInterface::class),
$this->createStub(FormInterface::class),
);
$response = $controller->index($request);
@@ -115,7 +115,7 @@ class Step4ControllerTest extends TestCase
$bookingService->method('loadPrices')->willReturn([]);
$bookingService->expects(self::once())->method('finalizeBooking')->willReturn($booking);
$inquiryForm = $this->createMock(FormInterface::class);
$inquiryForm = $this->createStub(FormInterface::class);
$inquiryForm->method('handleRequest')->willReturnSelf();
$inquiryForm->method('isSubmitted')->willReturn(true);
$inquiryForm->method('isValid')->willReturn(true);
@@ -158,7 +158,7 @@ class Step4ControllerTest extends TestCase
]);
$bookingService->expects(self::never())->method('finalizeBooking');
$inquiryForm = $this->createMock(FormInterface::class);
$inquiryForm = $this->createStub(FormInterface::class);
$inquiryForm->method('handleRequest')->willReturnSelf();
$inquiryForm->method('isSubmitted')->willReturn(true);
$inquiryForm->method('isValid')->willReturn(false);
@@ -184,9 +184,9 @@ class Step4ControllerTest extends TestCase
$sessionManager->save($request, $dto);
$controller = new TestableStep4Controller(
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingService::class),
$sessionManager,
$this->createMock(FormInterface::class),
$this->createStub(FormInterface::class),
);
$response = $controller->confirmInquiry($request);
@@ -209,9 +209,9 @@ class Step4ControllerTest extends TestCase
$sessionManager->save($request, $dto);
$controller = new TestableStep4Controller(
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingService::class),
$sessionManager,
$this->createMock(FormInterface::class),
$this->createStub(FormInterface::class),
);
$response = $controller->confirmInquiry($request);
@@ -242,7 +242,7 @@ class Step4ControllerTest extends TestCase
$bookingService->method('loadAccommodation')->with(1)->willReturn($accommodation);
$bookingService->expects(self::never())->method('finalizeBooking');
$confirmationForm = $this->createMock(FormInterface::class);
$confirmationForm = $this->createStub(FormInterface::class);
$confirmationForm->method('handleRequest')->willReturnSelf();
$confirmationForm->method('isSubmitted')->willReturn(false);
@@ -288,7 +288,7 @@ class Step4ControllerTest extends TestCase
$bookingService->method('loadPrices')->willReturn([]);
$bookingService->expects(self::once())->method('finalizeBooking')->willReturn($booking);
$confirmationForm = $this->createMock(FormInterface::class);
$confirmationForm = $this->createStub(FormInterface::class);
$confirmationForm->method('handleRequest')->willReturnSelf();
$confirmationForm->method('isSubmitted')->willReturn(true);
$confirmationForm->method('isValid')->willReturn(true);
@@ -324,7 +324,7 @@ class Step4ControllerTest extends TestCase
$bookingService->method('loadAccommodation')->with(1)->willReturn($accommodation);
$bookingService->expects(self::never())->method('finalizeBooking');
$confirmationForm = $this->createMock(FormInterface::class);
$confirmationForm = $this->createStub(FormInterface::class);
$confirmationForm->method('handleRequest')->willReturnSelf();
$confirmationForm->method('isSubmitted')->willReturn(true);
$confirmationForm->method('isValid')->willReturn(false);
@@ -14,6 +14,7 @@ use App\Service\AccommodationBookingBreakdownCalculator;
use App\Service\AccommodationBookingLinkSigner;
use App\Service\AccommodationBookingService;
use App\Service\AccommodationTermsUrlProvider;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -39,8 +40,8 @@ class IndexControllerTest extends TestCase
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingService::class),
);
$response = $controller->access($booking->getUuid(), Request::create('/groups/booking/offer/'.$booking->getUuid()));
@@ -53,7 +54,7 @@ class IndexControllerTest extends TestCase
{
$booking = new AccommodationBooking();
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository = $this->createStub(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
@@ -63,8 +64,8 @@ class IndexControllerTest extends TestCase
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingService::class),
);
$response = $controller->access($booking->getUuid(), Request::create('/groups/booking/offer/'.$booking->getUuid()));
@@ -75,7 +76,7 @@ class IndexControllerTest extends TestCase
public function testAccessRendersUnavailableForUnknownUuid(): void
{
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository = $this->createStub(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn(null);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
@@ -84,8 +85,8 @@ class IndexControllerTest extends TestCase
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingService::class),
);
$response = $controller->access('unknown-uuid', Request::create('/groups/booking/offer/unknown-uuid'));
@@ -94,15 +95,13 @@ class IndexControllerTest extends TestCase
self::assertSame('groups/offer/unavailable.html.twig', $controller->renderedView);
}
/**
* @dataProvider statusesTheCustomerMustNotSee
*/
#[DataProvider('statusesTheCustomerMustNotSee')]
public function testAccessRendersUnavailableForABookingThatIsNotOfferedYet(AccommodationBookingStatus $status): void
{
$booking = new AccommodationBooking();
$booking->setStatus($status);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository = $this->createStub(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
@@ -112,8 +111,8 @@ class IndexControllerTest extends TestCase
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingService::class),
);
$response = $controller->access($booking->getUuid(), Request::create('/groups/booking/offer/'.$booking->getUuid()));
@@ -137,19 +136,18 @@ class IndexControllerTest extends TestCase
/**
* The status is re-read on every view, so an authorized session is no free pass: a
* booking pushed back into Entwurf stops showing the offer from that moment on.
*
* @dataProvider statusesTheCustomerMustNotSee
*/
#[DataProvider('statusesTheCustomerMustNotSee')]
public function testViewRendersUnavailableForABookingTheCustomerMustNotSee(AccommodationBookingStatus $status): void
{
$booking = new AccommodationBooking();
$booking->setStatus($status);
$booking->setAccommodation(new Accommodation());
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository = $this->createStub(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner = $this->createStub(AccommodationBookingLinkSigner::class);
$linkSigner->method('isSessionAuthorized')->willReturn(true);
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
@@ -159,7 +157,7 @@ class IndexControllerTest extends TestCase
$bookingRepository,
$linkSigner,
$breakdownCalculator,
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingService::class),
);
$request = Request::create('/groups/booking/offer/'.$booking->getUuid().'/view');
@@ -179,7 +177,7 @@ class IndexControllerTest extends TestCase
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->with(['uuid' => $booking->getUuid()])->willReturn($booking);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner = $this->createStub(AccommodationBookingLinkSigner::class);
$linkSigner->method('isSessionAuthorized')->willReturn(true);
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
@@ -207,17 +205,17 @@ class IndexControllerTest extends TestCase
{
$booking = new AccommodationBooking();
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository = $this->createStub(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner = $this->createStub(AccommodationBookingLinkSigner::class);
$linkSigner->method('isSessionAuthorized')->willReturn(false);
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingService::class),
);
$response = $controller->view($booking->getUuid(), Request::create('/groups/booking/offer/'.$booking->getUuid().'/view'));
@@ -235,18 +233,18 @@ class IndexControllerTest extends TestCase
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->with(['uuid' => $booking->getUuid()])->willReturn($booking);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner = $this->createStub(AccommodationBookingLinkSigner::class);
$linkSigner->method('isSessionAuthorized')->willReturn(true);
$confirmationForm = $this->createMock(FormInterface::class);
$confirmationForm = $this->createStub(FormInterface::class);
$confirmationForm->method('handleRequest')->willReturnSelf();
$confirmationForm->method('isSubmitted')->willReturn(false);
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingService::class),
$confirmationForm,
);
@@ -268,16 +266,16 @@ class IndexControllerTest extends TestCase
$booking->setStatus(AccommodationBookingStatus::Open);
$booking->setRemarks('Bitte Zimmer im EG');
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository = $this->createStub(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner = $this->createStub(AccommodationBookingLinkSigner::class);
$linkSigner->method('isSessionAuthorized')->willReturn(true);
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::once())->method('acceptBooking')->with($booking, 'Bitte Zimmer im EG');
$confirmationForm = $this->createMock(FormInterface::class);
$confirmationForm = $this->createStub(FormInterface::class);
$confirmationForm->method('handleRequest')->willReturnSelf();
$confirmationForm->method('isSubmitted')->willReturn(true);
$confirmationForm->method('isValid')->willReturn(true);
@@ -285,7 +283,7 @@ class IndexControllerTest extends TestCase
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$bookingService,
$confirmationForm,
);
@@ -303,17 +301,17 @@ class IndexControllerTest extends TestCase
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Open);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository = $this->createStub(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner = $this->createStub(AccommodationBookingLinkSigner::class);
$linkSigner->method('isSessionAuthorized')->willReturn(true);
$bookingService = $this->createMock(AccommodationBookingService::class);
// No remark on the booking and none submitted: the empty string clears rather than keeps.
$bookingService->expects(self::once())->method('acceptBooking')->with($booking, '');
$confirmationForm = $this->createMock(FormInterface::class);
$confirmationForm = $this->createStub(FormInterface::class);
$confirmationForm->method('handleRequest')->willReturnSelf();
$confirmationForm->method('isSubmitted')->willReturn(true);
$confirmationForm->method('isValid')->willReturn(true);
@@ -321,7 +319,7 @@ class IndexControllerTest extends TestCase
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$bookingService,
$confirmationForm,
);
@@ -339,16 +337,16 @@ class IndexControllerTest extends TestCase
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Open);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository = $this->createStub(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner = $this->createStub(AccommodationBookingLinkSigner::class);
$linkSigner->method('isSessionAuthorized')->willReturn(true);
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('acceptBooking');
$confirmationForm = $this->createMock(FormInterface::class);
$confirmationForm = $this->createStub(FormInterface::class);
$confirmationForm->method('handleRequest')->willReturnSelf();
$confirmationForm->method('isSubmitted')->willReturn(true);
$confirmationForm->method('isValid')->willReturn(false);
@@ -356,7 +354,7 @@ class IndexControllerTest extends TestCase
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$bookingService,
$confirmationForm,
);
@@ -373,17 +371,17 @@ class IndexControllerTest extends TestCase
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Received);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository = $this->createStub(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner = $this->createStub(AccommodationBookingLinkSigner::class);
$linkSigner->method('isSessionAuthorized')->willReturn(true);
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingService::class),
);
$response = $controller->confirm($booking->getUuid(), Request::create('/groups/booking/offer/'.$booking->getUuid().'/confirm'));
@@ -395,17 +393,17 @@ class IndexControllerTest extends TestCase
{
$booking = new AccommodationBooking();
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository = $this->createStub(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner = $this->createStub(AccommodationBookingLinkSigner::class);
$linkSigner->method('isSessionAuthorized')->willReturn(false);
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingService::class),
);
$response = $controller->confirm($booking->getUuid(), Request::create('/groups/booking/offer/'.$booking->getUuid().'/confirm'));
@@ -415,7 +413,7 @@ class IndexControllerTest extends TestCase
public function testConfirmRedirectsForUnknownUuid(): void
{
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository = $this->createStub(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn(null);
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
@@ -424,8 +422,8 @@ class IndexControllerTest extends TestCase
$controller = new TestableOfferController(
$bookingRepository,
$linkSigner,
$this->createMock(AccommodationBookingBreakdownCalculator::class),
$this->createMock(AccommodationBookingService::class),
$this->createStub(AccommodationBookingBreakdownCalculator::class),
$this->createStub(AccommodationBookingService::class),
);
$response = $controller->confirm('unknown-uuid', Request::create('/groups/booking/offer/unknown-uuid/confirm'));
@@ -80,7 +80,7 @@ class DashboardWidgetRegistryTest extends TestCase
private function provider(string $role, int $priority, ?DashboardWidget $widget): DashboardWidgetProviderInterface
{
$provider = $this->createMock(DashboardWidgetProviderInterface::class);
$provider = $this->createStub(DashboardWidgetProviderInterface::class);
$provider->method('getRequiredRole')->willReturn($role);
$provider->method('getPriority')->willReturn($priority);
$provider->method('build')->willReturn($widget);
@@ -93,7 +93,7 @@ class DashboardWidgetRegistryTest extends TestCase
*/
private function securityGranting(array $grantedRoles): Security
{
$security = $this->createMock(Security::class);
$security = $this->createStub(Security::class);
$security->method('isGranted')->willReturnCallback(
static fn (mixed $role): bool => \in_array($role, $grantedRoles, true),
);
@@ -64,10 +64,10 @@ class PendingRoleApprovalsWidgetProviderTest extends TestCase
*/
private function provider(array $pending): PendingRoleApprovalsWidgetProvider
{
$repository = $this->createMock(UserRepository::class);
$repository = $this->createStub(UserRepository::class);
$repository->method('findWithPendingRoles')->willReturn($pending);
$urlGenerator = $this->createMock(UrlGeneratorInterface::class);
$urlGenerator = $this->createStub(UrlGeneratorInterface::class);
$urlGenerator->method('generate')->willReturnCallback(
static function (string $route, array $parameters = []): string {
$path = '/'.str_replace('_', '/', substr($route, \strlen('app_')));
@@ -66,7 +66,7 @@ class RecentLogEntriesWidgetProviderTest extends TestCase
*/
private function provider(array $entries): RecentLogEntriesWidgetProvider
{
$repository = $this->createMock(LogEntryRepository::class);
$repository = $this->createStub(LogEntryRepository::class);
$repository->method('findLatest')->willReturn($entries);
return new RecentLogEntriesWidgetProvider($repository, $this->urlGenerator());
@@ -74,7 +74,7 @@ class RecentLogEntriesWidgetProviderTest extends TestCase
private function urlGenerator(): UrlGeneratorInterface
{
$urlGenerator = $this->createMock(UrlGeneratorInterface::class);
$urlGenerator = $this->createStub(UrlGeneratorInterface::class);
$urlGenerator->method('generate')->willReturnCallback(
static fn (string $route): string => '/'.str_replace('_', '/', substr($route, \strlen('app_'))),
);
@@ -7,6 +7,7 @@ namespace App\Tests\Entity\Groups;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingOrigin;
use App\Enum\Groups\AccommodationBookingStatus;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
class AccommodationBookingTest extends TestCase
@@ -14,9 +15,8 @@ class AccommodationBookingTest extends TestCase
/**
* The label is what the backoffice prints next to the status, so it must never
* contradict it — "Angebot · Bestätigt" is the shape of mistake this replaces.
*
* @dataProvider statusesBeforeTheCustomerCommits
*/
#[DataProvider('statusesBeforeTheCustomerCommits')]
public function testARecordIsCalledAnOfferUntilTheCustomerCommits(AccommodationBookingStatus $status): void
{
$booking = new AccommodationBooking();
@@ -36,9 +36,7 @@ class AccommodationBookingTest extends TestCase
yield 'open' => [AccommodationBookingStatus::Open];
}
/**
* @dataProvider statusesAfterTheCustomerCommits
*/
#[DataProvider('statusesAfterTheCustomerCommits')]
public function testARecordIsCalledABookingOnceTheCustomerHasCommitted(AccommodationBookingStatus $status): void
{
$booking = new AccommodationBooking();
@@ -104,20 +104,20 @@ class AccessDeniedListenerTest extends TestCase
private function dispatch(Request $request, ?UserInterface $user): ExceptionEvent
{
$security = $this->createMock(Security::class);
$security = $this->createStub(Security::class);
$security->method('getUser')->willReturn($user);
$resolver = $this->createMock(DefaultRouteResolver::class);
$resolver = $this->createStub(DefaultRouteResolver::class);
$resolver->method('resolveUrl')->willReturn('/admin/dashboard');
$listener = new AccessDeniedListener(
$security,
$this->createMock(LoggerInterface::class),
$this->createStub(LoggerInterface::class),
$resolver,
);
$event = new ExceptionEvent(
$this->createMock(HttpKernelInterface::class),
$this->createStub(HttpKernelInterface::class),
$request,
HttpKernelInterface::MAIN_REQUEST,
new AccessDeniedException(),
@@ -19,7 +19,7 @@ class DomainThemeListenerTest extends TestCase
protected function setUp(): void
{
$this->kernel = $this->createMock(HttpKernelInterface::class);
$this->kernel = $this->createStub(HttpKernelInterface::class);
}
public function testSetsThemeAttributeForMatchingDomain(): void
@@ -52,7 +52,7 @@ class AccommodationBookingChangeAccommodationTypeTest extends TestCase
{
$fields = [];
$builder = $this->createMock(FormBuilderInterface::class);
$builder = $this->createStub(FormBuilderInterface::class);
$builder->method('add')->willReturnCallback(
static function (string $name, ?string $type = null, array $fieldOptions = []) use (&$fields, $builder) {
$fields[$name] = $fieldOptions;
@@ -75,7 +75,7 @@ class AccommodationBookingCreateTypeTest extends TestCase
{
$names = [];
$builder = $this->createMock(FormBuilderInterface::class);
$builder = $this->createStub(FormBuilderInterface::class);
$builder->method('add')->willReturnCallback(static function (string $name) use (&$names, $builder) {
$names[] = $name;
@@ -7,6 +7,7 @@ namespace App\Tests\Form\Admin\Groups;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Form\Admin\Groups\AccommodationBookingType;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -17,17 +18,13 @@ use Symfony\Component\Validator\Validation;
class AccommodationBookingTypeTest extends TestCase
{
/**
* @dataProvider statusesWithoutMandatoryFields
*/
#[DataProvider('statusesWithoutMandatoryFields')]
public function testDraftAndDiscardedAreValidatedWithoutTheEditGroup(AccommodationBookingStatus $status): void
{
self::assertSame(['Default'], $this->resolveValidationGroups($status));
}
/**
* @dataProvider customerFacingStatuses
*/
#[DataProvider('customerFacingStatuses')]
public function testCustomerFacingStatusesAddTheEditGroup(AccommodationBookingStatus $status): void
{
self::assertSame(['Default', 'edit'], $this->resolveValidationGroups($status));
@@ -52,9 +49,7 @@ class AccommodationBookingTypeTest extends TestCase
yield 'confirmed' => [AccommodationBookingStatus::Confirmed];
}
/**
* @dataProvider statusesWithoutMandatoryFields
*/
#[DataProvider('statusesWithoutMandatoryFields')]
public function testEmptyContactDataPassesValidation(AccommodationBookingStatus $status): void
{
$booking = new AccommodationBooking();
@@ -89,7 +84,7 @@ class AccommodationBookingTypeTest extends TestCase
$booking = new AccommodationBooking();
$booking->setStatus($status);
$form = $this->createMock(FormInterface::class);
$form = $this->createStub(FormInterface::class);
$form->method('getData')->willReturn($booking);
return ($resolver->resolve()['validation_groups'])($form);
+7 -7
View File
@@ -5,13 +5,13 @@ declare(strict_types=1);
namespace App\Tests\Form\Model;
use App\BusProNet\Constants;
use App\BusProNet\Model\Booking;
use App\BusProNet\Model\Address;
use App\Form\Model\AddressDto;
use App\BusProNet\Model\Service;
use App\BusProNet\Model\Booking;
use App\BusProNet\Model\Insurance;
use App\BusProNet\Model\Service;
use App\BusProNet\Model\Travel;
use App\BusProNet\XmlLoader\AgencyLoader;
use App\Form\Model\AddressDto;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\Form\Model\ParticipantEditDto;
@@ -47,10 +47,10 @@ class ParticipantEditDtoTest extends TestCase
protected function setUp(): void
{
// Create mock services for validator dependencies
$mockVoucherService = $this->createMock(VoucherValidator::class);
$mockPriceCalculatorService = $this->createMock(BookingPriceCalculator::class);
$mockParticipantEligibilityChecker = $this->createMock(ParticipantEligibilityChecker::class);
$mockServiceAgeEvaluator = $this->createMock(ServiceAgeEvaluator::class);
$mockVoucherService = $this->createStub(VoucherValidator::class);
$mockPriceCalculatorService = $this->createStub(BookingPriceCalculator::class);
$mockParticipantEligibilityChecker = $this->createStub(ParticipantEligibilityChecker::class);
$mockServiceAgeEvaluator = $this->createStub(ServiceAgeEvaluator::class);
// Ski pass validation is exercised against the real gate, not a mock: which participant
// needs a pass is exactly the behaviour under test here.
+1 -1
View File
@@ -91,7 +91,7 @@ class PersonalDataTypeTest extends TestCase
*/
private function createForm(PersonalData $personalData, array $options = []): FormInterface
{
$countries = $this->createMock(CountryDataProvider::class);
$countries = $this->createStub(CountryDataProvider::class);
$countries->method('getAll')->willReturn([]);
return Forms::createFormFactoryBuilder()
@@ -8,8 +8,9 @@ use App\BusProNet\Constants;
use App\BusProNet\Model\Booking;
use App\BusProNet\Model\Service;
use App\BusProNet\Model\Travel;
use App\BusProNet\XmlParser\TravelParser;
use App\BusProNet\Utility\DirectionMapper;
use App\BusProNet\XmlCrawlerFactory;
use App\BusProNet\XmlParser\TravelParser;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\Form\Service\ParticipantFieldOptionsProvider;
@@ -18,7 +19,6 @@ use App\Service\InsuranceManager;
use App\Service\ServiceAvailabilityCalculator;
use App\Service\ServiceLabelFormatter;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Contracts\Translation\TranslatorInterface;
class ParticipantFieldOptionsProviderBabyTest extends TestCase
@@ -28,17 +28,17 @@ class ParticipantFieldOptionsProviderBabyTest extends TestCase
protected function setUp(): void
{
$this->serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
$this->serviceAvailabilityCalculator = $this->createStub(ServiceAvailabilityCalculator::class);
// These tests target age filtering, so availability filtering passes everything through
// unless a test stubs it explicitly
$this->serviceAvailabilityCalculator
->method('filterAvailableServices')
->willReturnArgument(0)
;
$insuranceService = $this->createMock(InsuranceManager::class);
$priceCalculatorService = $this->createMock(BookingPriceCalculator::class);
$insuranceService = $this->createStub(InsuranceManager::class);
$priceCalculatorService = $this->createStub(BookingPriceCalculator::class);
$serviceLabelFormatter = new ServiceLabelFormatter();
$translator = $this->createMock(TranslatorInterface::class);
$translator = $this->createStub(TranslatorInterface::class);
$translator->method('trans')->willReturnCallback(
function (string $message, array $parameters = []): string {
return match ($message) {
@@ -488,7 +488,7 @@ class ParticipantFieldOptionsProviderBabyTest extends TestCase
private function createTravelWithExportedSkiPasses(array $serviceIds): Travel
{
$parser = new TravelParser();
$crawler = new Crawler(file_get_contents('/var/www/html/var/xmlexport/Ziel_2456.xml'));
$crawler = XmlCrawlerFactory::create(file_get_contents('/var/www/html/var/xmlexport/Ziel_2456.xml'));
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $parser->parse($travelNode);
@@ -29,13 +29,13 @@ class ParticipantFieldOptionsProviderInsuranceTest extends TestCase
protected function setUp(): void
{
$serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
$serviceAvailabilityCalculator = $this->createStub(ServiceAvailabilityCalculator::class);
// InsuranceManager is stateless - use the real implementation so actual
// eligibility/price-tier filtering runs, not a stubbed-out mock.
$insuranceService = new InsuranceManager();
$this->priceCalculatorService = $this->createMock(BookingPriceCalculator::class);
$this->priceCalculatorService = $this->createStub(BookingPriceCalculator::class);
$serviceLabelFormatter = new ServiceLabelFormatter();
$translator = $this->createMock(TranslatorInterface::class);
$translator = $this->createStub(TranslatorInterface::class);
$translator->method('trans')->willReturnCallback(fn (string $message) => $message);
$this->provider = new ParticipantFieldOptionsProvider(
@@ -28,11 +28,11 @@ class ParticipantFieldOptionsProviderMandatoryServiceTest extends TestCase
protected function setUp(): void
{
$serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
$insuranceService = $this->createMock(InsuranceManager::class);
$priceCalculatorService = $this->createMock(BookingPriceCalculator::class);
$serviceAvailabilityCalculator = $this->createStub(ServiceAvailabilityCalculator::class);
$insuranceService = $this->createStub(InsuranceManager::class);
$priceCalculatorService = $this->createStub(BookingPriceCalculator::class);
$serviceLabelFormatter = new ServiceLabelFormatter();
$translator = $this->createMock(TranslatorInterface::class);
$translator = $this->createStub(TranslatorInterface::class);
$this->provider = new ParticipantFieldOptionsProvider(
$serviceAvailabilityCalculator,
@@ -159,10 +159,10 @@ class ParticipantFieldOptionsProviderMandatoryServiceTest extends TestCase
$provider = new ParticipantFieldOptionsProvider(
$serviceAvailabilityCalculator,
$this->createMock(InsuranceManager::class),
$this->createMock(BookingPriceCalculator::class),
$this->createStub(InsuranceManager::class),
$this->createStub(BookingPriceCalculator::class),
new ServiceLabelFormatter(),
$this->createMock(TranslatorInterface::class)
$this->createStub(TranslatorInterface::class)
);
$options = $provider->getFieldOptions('parking', $bookingDto, 0);
@@ -30,13 +30,13 @@ class ParticipantFieldOptionsProviderSkiPassAvailabilityTest extends TestCase
protected function setUp(): void
{
$translator = $this->createMock(TranslatorInterface::class);
$translator = $this->createStub(TranslatorInterface::class);
$translator->method('trans')->willReturnArgument(0);
$this->provider = new ParticipantFieldOptionsProvider(
new ServiceAvailabilityCalculator(),
$this->createMock(InsuranceManager::class),
$this->createMock(BookingPriceCalculator::class),
$this->createStub(InsuranceManager::class),
$this->createStub(BookingPriceCalculator::class),
new ServiceLabelFormatter(),
$translator
);
@@ -12,32 +12,46 @@ use App\Form\Service\ParticipantInsuranceFieldHandler;
use App\Service\BookingPriceCalculator;
use App\Service\FamilyInsuranceAvailabilityChecker;
use App\Service\InsuranceManager;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
class ParticipantInsuranceFieldHandlerTest extends TestCase
{
private ParticipantInsuranceFieldHandler $handler;
private ?ParticipantInsuranceFieldHandler $handler = null;
private InsuranceManager $insuranceService;
private BookingPriceCalculator $priceCalculatorService;
protected function setUp(): void
{
$this->insuranceService = $this->createMock(InsuranceManager::class);
$this->priceCalculatorService = $this->createMock(BookingPriceCalculator::class);
$this->useInsuranceService($this->createStub(InsuranceManager::class));
// Mock getSelectableInsurances to return input array
$this->insuranceService->method('getSelectableInsurances')
->willReturnCallback(fn (Travel $travel) => $travel->insurances ?? []);
$this->priceCalculatorService = $this->createStub(BookingPriceCalculator::class);
// Mock price calculator to return a default price
// Price calculator returns a default price
$this->priceCalculatorService->method('calculateIndividualParticipantPriceExcludingInsurance')
->willReturn(500.0);
$this->priceCalculatorService->method('resolveInsuranceTravelPrice')
->willReturn(500.0);
}
// Real checker over the mocked collaborators - the selection-time recording below is
/**
* Installs the insurance service every test runs against, applying the
* getSelectableInsurances() pass-through they all rely on. Tests that set
* expectations pass a mock in here instead of the setUp() stub.
*/
private function useInsuranceService(InsuranceManager&Stub $insuranceService): void
{
$insuranceService->method('getSelectableInsurances')
->willReturnCallback(fn (Travel $travel) => $travel->insurances ?? []);
$this->insuranceService = $insuranceService;
}
private function handler(): ParticipantInsuranceFieldHandler
{
// Real checker over the doubled collaborators - the selection-time recording below is
// only meaningful against the actual "is a family insurance available" definition
$this->handler = new ParticipantInsuranceFieldHandler(
return $this->handler ??= new ParticipantInsuranceFieldHandler(
$this->insuranceService,
$this->priceCalculatorService,
new FamilyInsuranceAvailabilityChecker($this->insuranceService, $this->priceCalculatorService),
@@ -46,12 +60,12 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
public function testGetFieldName(): void
{
$this->assertEquals('insurance', $this->handler->getFieldName());
$this->assertEquals('insurance', $this->handler()->getFieldName());
}
public function testGetDependencies(): void
{
$dependencies = $this->handler->getDependencies();
$dependencies = $this->handler()->getDependencies();
// Insurance handler depends on all price-affecting fields to ensure accurate reassignment
$expectedDependencies = [
@@ -72,14 +86,14 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
public function testShouldProcessReturnsTrueInCreateMode(): void
{
$result = $this->handler->shouldProcess([], BookingDto::MODE_CREATE, 0);
$result = $this->handler()->shouldProcess([], BookingDto::MODE_CREATE, 0);
$this->assertTrue($result);
}
public function testShouldProcessReturnsFalseInEditMode(): void
{
$result = $this->handler->shouldProcess([], BookingDto::MODE_EDIT, 0);
$result = $this->handler()->shouldProcess([], BookingDto::MODE_EDIT, 0);
$this->assertFalse($result, 'Insurance handler should not process in edit mode as API does not return insurance data');
}
@@ -89,7 +103,7 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
$bookingDto = $this->createMockBookingDto();
$bookingDto->method('getParticipant')->with(0)->willReturn(null);
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
$this->handler()->processField(['insurance' => '123'], $bookingDto, 0);
// No assertions needed - just ensure no exceptions are thrown
$this->addToAssertionCount(1);
@@ -107,7 +121,7 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField(['insurance' => null], $bookingDto, 0);
$this->handler()->processField(['insurance' => null], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
@@ -124,7 +138,7 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField(['insurance' => ''], $bookingDto, 0);
$this->handler()->processField(['insurance' => ''], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
@@ -141,7 +155,7 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField([], $bookingDto, 0);
$this->handler()->processField([], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
@@ -156,13 +170,15 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
$this->handler()->processField(['insurance' => '123'], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
public function testProcessFieldSetsInsuranceWhenEligible(): void
{
$this->useInsuranceService($this->createMock(InsuranceManager::class));
$insurance = $this->createInsurance('123');
$participant = new ParticipantDto();
$travel = new Travel();
@@ -178,13 +194,15 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
->with([$insurance], $participant, $bookingDto, 500.0)
->willReturn([$insurance]);
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
$this->handler()->processField(['insurance' => '123'], $bookingDto, 0);
$this->assertSame($insurance, $participant->insurance);
}
public function testProcessFieldClearsInsuranceWhenNotEligible(): void
{
$this->useInsuranceService($this->createMock(InsuranceManager::class));
$insurance = $this->createInsurance('123');
$participant = new ParticipantDto();
$travel = new Travel();
@@ -200,13 +218,15 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
->with([$insurance], $participant, $bookingDto, 500.0)
->willReturn([]); // Not eligible
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
$this->handler()->processField(['insurance' => '123'], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
public function testProcessFieldSwitchingToNewInsuranceIsNotOverwrittenByStaleResubmissionCheck(): void
{
$this->useInsuranceService($this->createMock(InsuranceManager::class));
// Regression: switching from one already-selected insurance to a different one must
// not be re-validated (and potentially overwritten) against the OLD, now-stale
// insurance by the "form resubmission" block afterward.
@@ -230,13 +250,15 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
->method('getEligibleInsurances')
->willReturn([$newInsurance]);
$this->handler->processField(['insurance' => '2'], $bookingDto, 0);
$this->handler()->processField(['insurance' => '2'], $bookingDto, 0);
$this->assertSame($newInsurance, $participant->insurance);
}
public function testProcessFieldWorksWithStringAndIntegerIds(): void
{
$this->useInsuranceService($this->createMock(InsuranceManager::class));
$insurance = $this->createInsurance(123); // Integer ID
$participant = new ParticipantDto();
$travel = new Travel();
@@ -251,7 +273,7 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
->method('getEligibleInsurances')
->willReturn([$insurance]);
$this->handler->processField(['insurance' => '123'], $bookingDto, 0); // String selection
$this->handler()->processField(['insurance' => '123'], $bookingDto, 0); // String selection
$this->assertSame($insurance, $participant->insurance);
}
@@ -266,7 +288,7 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
$this->handler()->processField(['insurance' => '123'], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
@@ -281,7 +303,7 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
$this->handler()->processField(['insurance' => '123'], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
@@ -306,7 +328,7 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
$this->insuranceService->method('getEligibleInsurances')->willReturn([$nonFamilyInsurance]);
$this->handler->processField(['insurance' => '1'], $bookingDto, 0);
$this->handler()->processField(['insurance' => '1'], $bookingDto, 0);
$this->assertTrue(
$bookingDto->applicantInsuranceChosenWhileFamilyIneligible,
@@ -346,7 +368,7 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
fn (array $insurances) => $insurances
);
$this->handler->processField(['insurance' => '1'], $bookingDto, 0);
$this->handler()->processField(['insurance' => '1'], $bookingDto, 0);
$this->assertFalse(
$bookingDto->applicantInsuranceChosenWhileFamilyIneligible,
@@ -389,7 +411,7 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
fn (array $insurances) => array_values(array_filter($insurances, fn ($i) => false === $i->familyInsurance))
);
$this->handler->processField(['insurance' => '1'], $bookingDto, 0);
$this->handler()->processField(['insurance' => '1'], $bookingDto, 0);
$this->assertTrue(
$bookingDto->applicantInsuranceChosenWhileFamilyIneligible,
@@ -399,9 +421,9 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
public function testGetFieldStateModificationsReturnsEmptyArray(): void
{
$bookingDto = $this->createMockBookingDto();
$bookingDto = $this->createStub(BookingDto::class);
$result = $this->handler->getFieldStateModifications([], $bookingDto, 0);
$result = $this->handler()->getFieldStateModifications([], $bookingDto, 0);
$this->assertIsArray($result);
$this->assertEmpty($result);
@@ -409,7 +431,7 @@ class ParticipantInsuranceFieldHandlerTest extends TestCase
public function testGetAffectedFieldNamesReturnsEmptyArray(): void
{
$result = $this->handler->getAffectedFieldNames();
$result = $this->handler()->getAffectedFieldNames();
$this->assertIsArray($result);
$this->assertEmpty($result);
@@ -4,14 +4,15 @@ declare(strict_types=1);
namespace App\Tests\Form\Service;
use App\BusProNet\Constants;
use App\BusProNet\Model\Service;
use App\BusProNet\Model\Travel;
use App\BusProNet\Utility\DirectionMapper;
use App\BusProNet\Constants;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\Form\Service\ParticipantParkingFieldHandler;
use App\Service\ServiceAvailabilityCalculator;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
class ParticipantParkingFieldHandlerTest extends TestCase
@@ -39,17 +40,13 @@ class ParticipantParkingFieldHandlerTest extends TestCase
$this->assertTrue($this->handler->shouldProcess(['some' => 'data'], BookingDto::MODE_EDIT, 5));
}
/**
* @dataProvider normalizeCheckboxValueCheckedProvider
*/
#[DataProvider('normalizeCheckboxValueCheckedProvider')]
public function testNormalizeCheckboxValueReturnsTrueWhenChecked(mixed $value): void
{
$this->assertTrue($this->invokeNormalizeCheckboxValue($value));
}
/**
* @dataProvider normalizeCheckboxValueUncheckedProvider
*/
#[DataProvider('normalizeCheckboxValueUncheckedProvider')]
public function testNormalizeCheckboxValueReturnsFalseWhenUnchecked(mixed $value): void
{
$this->assertFalse($this->invokeNormalizeCheckboxValue($value));
@@ -15,31 +15,35 @@ use PHPUnit\Framework\TestCase;
class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestCase
{
private ParticipantTransportationDiscountReplacementFieldHandler $handler;
private ?ParticipantTransportationDiscountReplacementFieldHandler $handler = null;
private ServiceAvailabilityCalculator $serviceAvailabilityCalculator;
protected function setUp(): void
{
$this->serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
$this->handler = new ParticipantTransportationDiscountReplacementFieldHandler(
$this->serviceAvailabilityCalculator = $this->createStub(ServiceAvailabilityCalculator::class);
}
private function handler(): ParticipantTransportationDiscountReplacementFieldHandler
{
return $this->handler ??= new ParticipantTransportationDiscountReplacementFieldHandler(
$this->serviceAvailabilityCalculator
);
}
public function testGetFieldName(): void
{
$this->assertSame('transportationDiscountReplacement', $this->handler->getFieldName());
$this->assertSame('transportationDiscountReplacement', $this->handler()->getFieldName());
}
public function testGetDependencies(): void
{
$this->assertSame(['transportationOutbound', 'transportationInbound'], $this->handler->getDependencies());
$this->assertSame(['transportationOutbound', 'transportationInbound'], $this->handler()->getDependencies());
}
public function testShouldProcessAlwaysReturnsTrue(): void
{
$this->assertTrue($this->handler->shouldProcess([], BookingDto::MODE_CREATE, 0));
$this->assertTrue($this->handler->shouldProcess(['some' => 'data'], BookingDto::MODE_EDIT, 5));
$this->assertTrue($this->handler()->shouldProcess([], BookingDto::MODE_CREATE, 0));
$this->assertTrue($this->handler()->shouldProcess(['some' => 'data'], BookingDto::MODE_EDIT, 5));
}
public function testProcessFieldReplacesDiscountedWithRegularWhenInboundIsBus(): void
@@ -62,7 +66,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Assert outbound was replaced with regular PKW
$this->assertSame($regularPkw->id, $participant->transportationOutbound->id);
@@ -79,6 +83,8 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
public function testProcessFieldRestoresDiscountedPkwWhenInboundChangesToPkw(): void
{
$this->serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
// Setup services
$discountedPkw = $this->createPkwService(100, 'Selbstorganisiert (-15€ Rabatt)', -15.0);
$regularPkw = $this->createPkwService(101, 'Selbstorganisiert', 0.0);
@@ -104,7 +110,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Assert outbound was replaced with discounted PKW
$this->assertSame($discountedPkw->id, $participant->transportationOutbound->id);
@@ -120,6 +126,8 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
public function testProcessFieldDoesNotRestoreDiscountWhenUnavailable(): void
{
$this->serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
// Setup services
$discountedPkw = $this->createPkwService(100, 'Selbstorganisiert (-15€ Rabatt)', -15.0);
$regularPkw = $this->createPkwService(101, 'Selbstorganisiert', 0.0);
@@ -145,7 +153,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Assert outbound remains regular PKW
$this->assertSame($regularPkw, $participant->transportationOutbound);
@@ -174,7 +182,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Assert outbound remains BUS (no replacement)
$this->assertSame($busOutbound, $participant->transportationOutbound);
@@ -203,7 +211,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Assert outbound remains regular PKW (already correct)
$this->assertSame($regularPkw, $participant->transportationOutbound);
@@ -232,7 +240,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Assert outbound remains discounted PKW (already optimal)
$this->assertSame($discountedPkw, $participant->transportationOutbound);
@@ -256,7 +264,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process - should handle gracefully
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Assert no error and no notification
$this->assertNull($participant->transportationOutbound);
@@ -265,6 +273,8 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
public function testProcessFieldHandlesNullInbound(): void
{
$this->serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
// Setup services
$discountedPkw = $this->createPkwService(100, 'Selbstorganisiert (-15€ Rabatt)', -15.0);
$regularPkw = $this->createPkwService(101, 'Selbstorganisiert', 0.0);
@@ -289,7 +299,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process - null inbound is treated as non-BUS, should attempt restoration
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Assert outbound was replaced with discounted PKW
$this->assertSame($discountedPkw->id, $participant->transportationOutbound->id);
@@ -306,7 +316,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process - should handle gracefully
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Should not throw error
$this->expectNotToPerformAssertions();
@@ -314,6 +324,8 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
public function testProcessFieldSkipsDiscountRestorationForBabyParticipant(): void
{
$this->serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
// Setup services
$discountedPkw = $this->createPkwService(100, 'Selbstorganisiert (-15€ Rabatt)', -15.0);
$regularPkw = $this->createPkwService(101, 'Selbstorganisiert', 0.0);
@@ -339,7 +351,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Assert outbound remains regular PKW (no discount restoration for babies)
$this->assertSame($regularPkw->id, $participant->transportationOutbound->id);
@@ -350,6 +362,8 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
public function testProcessFieldSkipsDiscountRestorationForTwoYearOldParticipant(): void
{
$this->serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
// Setup services
$discountedPkw = $this->createPkwService(100, 'Selbstorganisiert (-15€ Rabatt)', -15.0);
$regularPkw = $this->createPkwService(101, 'Selbstorganisiert', 0.0);
@@ -375,7 +389,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Assert outbound remains regular PKW
$this->assertSame($regularPkw->id, $participant->transportationOutbound->id);
@@ -386,6 +400,8 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
public function testProcessFieldRestoresDiscountForThreeYearOldParticipant(): void
{
$this->serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
// Setup services
$discountedPkw = $this->createPkwService(100, 'Selbstorganisiert (-15€ Rabatt)', -15.0);
$regularPkw = $this->createPkwService(101, 'Selbstorganisiert', 0.0);
@@ -414,7 +430,7 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
$submittedData = [];
// Process
$this->handler->processField($submittedData, $bookingDto, 0);
$this->handler()->processField($submittedData, $bookingDto, 0);
// Assert outbound was replaced with discounted PKW (3-year-old is eligible)
$this->assertSame($discountedPkw->id, $participant->transportationOutbound->id);
@@ -204,7 +204,7 @@ class ParticipantVegFieldHandlerTest extends TestCase
private function createMockBookingDto(?Travel $travel = null): BookingDto
{
$bookingDto = $this->createMock(BookingDto::class);
$bookingDto = $this->createStub(BookingDto::class);
if (null !== $travel) {
$bookingDto->travel = $travel;
+1 -1
View File
@@ -111,7 +111,7 @@ class DatabaseHandlerTest extends TestCase
*/
private function connection(?string &$table, ?array &$data, ?array &$types): Connection
{
$connection = $this->createMock(Connection::class);
$connection = $this->createStub(Connection::class);
$connection
->method('insert')
->willReturnCallback(
@@ -11,6 +11,7 @@ use App\Entity\Groups\AccommodationBooking;
use App\Message\CreateClickUpBookingTaskMessage;
use App\MessageHandler\CreateClickUpBookingTaskHandler;
use App\Repository\Groups\AccommodationBookingRepository;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
@@ -48,7 +49,7 @@ class CreateClickUpBookingTaskHandlerTest extends TestCase
public function testAVanishedBookingIsSkipped(): void
{
$repository = $this->createMock(AccommodationBookingRepository::class);
$repository = $this->createStub(AccommodationBookingRepository::class);
$repository->method('find')->willReturn(null);
$client = $this->createMock(ApiClient::class);
@@ -58,15 +59,13 @@ class CreateClickUpBookingTaskHandlerTest extends TestCase
$this->handler($repository, $client)(new CreateClickUpBookingTaskMessage(42));
}
/**
* @dataProvider incompleteBookings
*/
#[DataProvider('incompleteBookings')]
public function testABookingWithoutTheDataForATaskNameIsSkipped(callable $mutate): void
{
$booking = $this->booking();
$mutate($booking);
$repository = $this->createMock(AccommodationBookingRepository::class);
$repository = $this->createStub(AccommodationBookingRepository::class);
$repository->method('find')->willReturn($booking);
$client = $this->createMock(ApiClient::class);
@@ -94,10 +93,10 @@ class CreateClickUpBookingTaskHandlerTest extends TestCase
public function testAFailingStatusUpdateDoesNotRetryTheTaskCreation(): void
{
$repository = $this->createMock(AccommodationBookingRepository::class);
$repository = $this->createStub(AccommodationBookingRepository::class);
$repository->method('find')->willReturn($this->booking());
$client = $this->createMock(ApiClient::class);
$client = $this->createStub(ApiClient::class);
$client->method('isConfigured')->willReturn(true);
$client->method('createTaskFromTemplate')->willReturn('abc123');
$client->method('updateTaskStatus')->willThrowException(new ClickUpException('boom'));
@@ -81,7 +81,7 @@ class MailjetNewsletterEventHandlerTest extends TestCase
$consent = new NewsletterConsent('[email protected]', 123);
$consent->markRevoked(new \DateTimeImmutable('2026-04-29T11:00:00+00:00'));
$repository = $this->createMock(NewsletterConsentRepository::class);
$repository = $this->createStub(NewsletterConsentRepository::class);
$repository->method('findOneByEmailAndListId')->willReturn($consent);
$entityManager = $this->createMock(EntityManagerInterface::class);
@@ -103,7 +103,7 @@ class MailjetNewsletterEventHandlerTest extends TestCase
$consent = new NewsletterConsent('[email protected]', 123);
$consent->markConfirmed(new \DateTimeImmutable('2026-04-29T11:00:00+00:00'));
$repository = $this->createMock(NewsletterConsentRepository::class);
$repository = $this->createStub(NewsletterConsentRepository::class);
$repository->method('findOneByEmailAndListId')->willReturn($consent);
$entityManager = $this->createMock(EntityManagerInterface::class);
@@ -126,7 +126,7 @@ class MailjetNewsletterEventHandlerTest extends TestCase
$consent = new NewsletterConsent('[email protected]', 123);
$consent->markRevoked(new \DateTimeImmutable('2026-04-29T11:00:00+00:00'));
$repository = $this->createMock(NewsletterConsentRepository::class);
$repository = $this->createStub(NewsletterConsentRepository::class);
$repository->method('findOneByEmailAndListId')->willReturn($consent);
$entityManager = $this->createMock(EntityManagerInterface::class);
+3 -4
View File
@@ -6,6 +6,7 @@ namespace App\Tests\Model;
use App\Model\ContingentCalendarQuery;
use App\Model\ContingentPricesQuery;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Validation;
@@ -30,15 +31,13 @@ class ContingentQueryTest extends TestCase
self::assertNull($query->dateToDate());
}
/**
* @dataProvider invalidCalendarQueries
*/
#[DataProvider('invalidCalendarQueries')]
public function testCalendarQueryRejectsInvalidInput(ContingentCalendarQuery $query): void
{
self::assertGreaterThan(0, $this->validator()->validate($query)->count());
}
public function invalidCalendarQueries(): iterable
public static function invalidCalendarQueries(): iterable
{
yield 'normalized invalid date' => [new ContingentCalendarQuery('HOTEL', '2026-02-31', '2026-03-01')];
yield 'reversed range' => [new ContingentCalendarQuery('HOTEL', '2026-03-02', '2026-03-01')];
@@ -4,13 +4,14 @@ declare(strict_types=1);
namespace App\Tests\Model;
use PHPUnit\Framework\TestCase;
use App\Model\NewsletterSubscriptionRequest;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidatorFactory;
use Symfony\Component\Validator\ConstraintValidatorInterface;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\EmailValidator;
use Symfony\Component\Validator\ConstraintValidatorFactory;
use Symfony\Component\Validator\ConstraintValidatorInterface;
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Validator\ValidatorInterface;
@@ -43,10 +44,9 @@ class NewsletterSubscriptionRequestTest extends TestCase
}
/**
* @dataProvider invalidRequests
*
* @param list<mixed> $listIds
*/
#[DataProvider('invalidRequests')]
public function testInvalidRequestFailsValidation(?string $email, array $listIds): void
{
$request = new NewsletterSubscriptionRequest();
@@ -61,7 +61,7 @@ class NewsletterSubscriptionRequestTest extends TestCase
/**
* @return iterable<string, array{0: ?string, 1: list<mixed>}>
*/
public function invalidRequests(): iterable
public static function invalidRequests(): iterable
{
yield 'invalid email' => ['not-an-email', [10321569]];
yield 'empty list ids' => ['[email protected]', []];
@@ -8,6 +8,7 @@ use App\Repository\Filter\AppliesListFiltersTrait;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
class AppliesListFiltersTraitTest extends TestCase
@@ -25,9 +26,7 @@ class AppliesListFiltersTraitTest extends TestCase
self::assertSame('%bonn%', $qb->getParameter('searchTerm1')?->getValue());
}
/**
* @dataProvider emptyTerms
*/
#[DataProvider('emptyTerms')]
public function testAnEmptyTermNarrowsNothing(?string $term): void
{
$qb = $this->queryBuilder();
@@ -119,7 +118,7 @@ class AppliesListFiltersTraitTest extends TestCase
private function queryBuilder(): QueryBuilder
{
$em = $this->createMock(EntityManagerInterface::class);
$em = $this->createStub(EntityManagerInterface::class);
$em->method('getExpressionBuilder')->willReturn(new Expr());
return (new QueryBuilder($em))->select('b')->from('Booking', 'b');
+7 -7
View File
@@ -206,14 +206,14 @@ class BpnAuthenticatorTest extends TestCase
$personalData->personId = 42;
$personalData->addressId = 4711;
$apiClient = $this->createMock(ApiClient::class);
$apiClient = $this->createStub(ApiClient::class);
$apiClient->method('getPersonalData')->willReturn($personalData);
$apiClient->method('getCrmAttributes')->willReturn($crmAttributes);
$repository = $this->createMock(EntityRepository::class);
$repository = $this->createStub(EntityRepository::class);
$repository->method('findOneBy')->willReturn($existing);
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager = $this->createStub(EntityManagerInterface::class);
$entityManager->method('getRepository')->willReturn($repository);
$entityManager
->method('persist')
@@ -225,19 +225,19 @@ class BpnAuthenticatorTest extends TestCase
})
;
$crypt = $this->createMock(Crypt::class);
$crypt = $this->createStub(Crypt::class);
$crypt->method('encrypt')->willReturn('encrypted');
$completenessChecker = $this->createMock(ProfileCompletenessChecker::class);
$completenessChecker = $this->createStub(ProfileCompletenessChecker::class);
$completenessChecker->method('isComplete')->willReturn(true);
return new BpnAuthenticator(
$this->createMock(UrlGeneratorInterface::class),
$this->createStub(UrlGeneratorInterface::class),
$apiClient,
$entityManager,
$crypt,
$completenessChecker,
$this->createMock(LoggerInterface::class),
$this->createStub(LoggerInterface::class),
);
}
+1 -1
View File
@@ -36,7 +36,7 @@ class DefaultRouteResolverTest extends TestCase
->willReturn($hasAdministrativeAccess)
;
$urlGenerator = $this->createMock(UrlGeneratorInterface::class);
$urlGenerator = $this->createStub(UrlGeneratorInterface::class);
$urlGenerator
->method('generate')
->willReturnCallback(static fn (string $route): string => match ($route) {
@@ -141,7 +141,7 @@ class AccommodationBookingBreakdownCalculatorTest extends TestCase
'undersubscription40Eur' => 0,
'undersubscription40Chf' => 0,
]),
$priceRepository ?? $this->createMock(AccommodationPriceRepository::class),
$priceRepository ?? $this->createStub(AccommodationPriceRepository::class),
);
}
}
@@ -178,7 +178,7 @@ class AccommodationBookingLinkSignerTest extends TestCase
private function createSigner(): AccommodationBookingLinkSigner
{
$urlGenerator = $this->createMock(UrlGeneratorInterface::class);
$urlGenerator = $this->createStub(UrlGeneratorInterface::class);
$urlGenerator
->method('generate')
->willReturnCallback(static fn (string $name, array $parameters) => sprintf(
@@ -64,7 +64,7 @@ class AccommodationBookingPdfGeneratorTest extends TestCase
$twig = new Environment(new FilesystemLoader(__DIR__.'/../../templates'));
$twig->addExtension(new IntlExtension());
$calculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$calculator = $this->createStub(AccommodationBookingBreakdownCalculator::class);
$calculator->method('compute')->willReturn($breakdown);
return new AccommodationBookingPdfGenerator($twig, $calculator, \dirname(__DIR__, 2));
@@ -25,6 +25,7 @@ use App\Service\AccommodationBookingService;
use App\Service\CmsDataProvider;
use App\Service\PriceTimelineBuilder;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
@@ -153,10 +154,10 @@ class AccommodationBookingServiceTest extends TestCase
$booking->setStatus(AccommodationBookingStatus::Open);
$booking->setAccessLinkIssuedAt(new \DateTimeImmutable());
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner = $this->createStub(AccommodationBookingLinkSigner::class);
$linkSigner->method('sign')->willReturn('https://example.com/offer/signed-link');
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator = $this->createStub(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->method('compute')->willReturn(null);
$mailer = $this->createMock(Mailer::class);
@@ -183,7 +184,7 @@ class AccommodationBookingServiceTest extends TestCase
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner->method('sign')->with($booking)->willReturn('https://example.com/offer/signed-link');
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator = $this->createStub(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->method('compute')->willReturn(['total' => 1000, 'currency' => 'EUR']);
$mailer = $this->createMock(Mailer::class);
@@ -208,7 +209,7 @@ class AccommodationBookingServiceTest extends TestCase
$booking->setEmail('[email protected]');
$booking->setStatus(AccommodationBookingStatus::Open);
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator = $this->createStub(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->method('compute')->willReturn(null);
$mailer = $this->createMock(Mailer::class);
@@ -231,10 +232,10 @@ class AccommodationBookingServiceTest extends TestCase
$booking->setEmail('[email protected]');
$booking->setStatus(AccommodationBookingStatus::Open);
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator = $this->createStub(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->method('compute')->willReturn(null);
$mailer = $this->createMock(Mailer::class);
$mailer = $this->createStub(Mailer::class);
$mailer->method('createAndSendEmail')->willThrowException(new \RuntimeException('SMTP down'));
$logger = $this->createMock(LoggerInterface::class);
@@ -258,7 +259,7 @@ class AccommodationBookingServiceTest extends TestCase
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager->expects(self::once())->method('flush');
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator = $this->createStub(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->method('compute')->willReturn(null);
$mailer = $this->createMock(Mailer::class);
@@ -416,9 +417,7 @@ class AccommodationBookingServiceTest extends TestCase
self::assertSame($issuedAt, $booking->getAccessLinkIssuedAt());
}
/**
* @dataProvider statusesThatAreNotAwaitingAnOffer
*/
#[DataProvider('statusesThatAreNotAwaitingAnOffer')]
public function testSendOfferNoOpsOnceTheOfferIsOut(AccommodationBookingStatus $status): void
{
$entityManager = $this->createMock(EntityManagerInterface::class);
@@ -495,9 +494,7 @@ class AccommodationBookingServiceTest extends TestCase
self::assertSame($issuedAt, $booking->getAccessLinkIssuedAt());
}
/**
* @dataProvider statusesThatAreNotAwaitingAnOffer
*/
#[DataProvider('statusesThatAreNotAwaitingAnOffer')]
public function testGenerateAccessLinkNoOpsOnceTheOfferIsOut(AccommodationBookingStatus $status): void
{
$entityManager = $this->createMock(EntityManagerInterface::class);
@@ -533,9 +530,7 @@ class AccommodationBookingServiceTest extends TestCase
self::assertSame(AccommodationBookingStatus::Discarded, $booking->getStatus());
}
/**
* @dataProvider closedStatuses
*/
#[DataProvider('closedStatuses')]
public function testDiscardBookingNoOpsForAClosedBooking(AccommodationBookingStatus $status): void
{
$entityManager = $this->createMock(EntityManagerInterface::class);
@@ -643,7 +638,7 @@ class AccommodationBookingServiceTest extends TestCase
$booking->setEmail('[email protected]');
$booking->setRemarks('vom Telefonat');
$service = $this->createServiceWithAccommodation(mailer: $this->createMock(Mailer::class));
$service = $this->createServiceWithAccommodation(mailer: $this->createStub(Mailer::class));
$service->acceptBooking($booking, " Bitte Zimmer im EG\nund Frühstück um 8 \n");
@@ -657,7 +652,7 @@ class AccommodationBookingServiceTest extends TestCase
$booking->setEmail('[email protected]');
$booking->setRemarks('vom Telefonat');
$service = $this->createServiceWithAccommodation(mailer: $this->createMock(Mailer::class));
$service = $this->createServiceWithAccommodation(mailer: $this->createStub(Mailer::class));
$service->acceptBooking($booking, ' ');
@@ -671,7 +666,7 @@ class AccommodationBookingServiceTest extends TestCase
$booking->setEmail('[email protected]');
$booking->setRemarks('vom Telefonat');
$service = $this->createServiceWithAccommodation(mailer: $this->createMock(Mailer::class));
$service = $this->createServiceWithAccommodation(mailer: $this->createStub(Mailer::class));
$service->acceptBooking($booking);
@@ -684,7 +679,7 @@ class AccommodationBookingServiceTest extends TestCase
$booking->setStatus(AccommodationBookingStatus::Received);
$booking->setRemarks('vom Telefonat');
$service = $this->createServiceWithAccommodation(mailer: $this->createMock(Mailer::class));
$service = $this->createServiceWithAccommodation(mailer: $this->createStub(Mailer::class));
$service->acceptBooking($booking, 'zu spät');
@@ -693,7 +688,7 @@ class AccommodationBookingServiceTest extends TestCase
public function testConfirmBookingConfirmsReceivedBookingAndNotifiesTheCustomer(): void
{
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager = $this->createStub(EntityManagerInterface::class);
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Received);
@@ -835,7 +830,7 @@ class AccommodationBookingServiceTest extends TestCase
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Received);
$mailer = $this->createMock(Mailer::class);
$mailer = $this->createStub(Mailer::class);
$mailer->method('createAndSendEmail')->willThrowException(new \RuntimeException('SMTP down'));
$logger = $this->createMock(LoggerInterface::class);
@@ -852,7 +847,7 @@ class AccommodationBookingServiceTest extends TestCase
$booking->setEmail('[email protected]');
$booking->setStatus(AccommodationBookingStatus::Confirmed);
$mailer = $this->createMock(Mailer::class);
$mailer = $this->createStub(Mailer::class);
$mailer->method('createAndSendEmail')->willThrowException(new \RuntimeException('SMTP down'));
$logger = $this->createMock(LoggerInterface::class);
@@ -894,7 +889,7 @@ class AccommodationBookingServiceTest extends TestCase
$booking->setEmail('[email protected]');
$booking->setStatus(AccommodationBookingStatus::Confirmed);
$pdfGenerator = $this->createMock(AccommodationBookingPdfGenerator::class);
$pdfGenerator = $this->createStub(AccommodationBookingPdfGenerator::class);
$pdfGenerator->method('createAttachment')->willThrowException(new \RuntimeException('no prices'));
$mailer = $this->createMock(Mailer::class);
@@ -1038,7 +1033,7 @@ class AccommodationBookingServiceTest extends TestCase
->with(['calendarCode' => 'HOTEL'])
->willReturn($accommodation);
$priceRepo = $this->createMock(AccommodationPriceRepository::class);
$priceRepo = $this->createStub(AccommodationPriceRepository::class);
$priceRepo
->method('findByHotelCodeAndDateRange')
->willReturn($prices);
@@ -1046,16 +1041,16 @@ class AccommodationBookingServiceTest extends TestCase
return new AccommodationBookingService(
$accommodationRepo,
$priceRepo,
$this->createMock(AdditionalServiceRepository::class),
$this->createMock(BoardServiceRepository::class),
$this->createStub(AdditionalServiceRepository::class),
$this->createStub(BoardServiceRepository::class),
new PriceTimelineBuilder(),
$entityManager ?? $this->createMock(EntityManagerInterface::class),
$mailer ?? $this->createMock(Mailer::class),
$logger ?? $this->createMock(LoggerInterface::class),
$this->createMock(CmsDataProvider::class),
$linkSigner ?? $this->createMock(AccommodationBookingLinkSigner::class),
$breakdownCalculator ?? $this->createMock(AccommodationBookingBreakdownCalculator::class),
$pdfGenerator ?? $this->createMock(AccommodationBookingPdfGenerator::class),
$entityManager ?? $this->createStub(EntityManagerInterface::class),
$mailer ?? $this->createStub(Mailer::class),
$logger ?? $this->createStub(LoggerInterface::class),
$this->createStub(CmsDataProvider::class),
$linkSigner ?? $this->createStub(AccommodationBookingLinkSigner::class),
$breakdownCalculator ?? $this->createStub(AccommodationBookingBreakdownCalculator::class),
$pdfGenerator ?? $this->createStub(AccommodationBookingPdfGenerator::class),
'[email protected]',
);
}
@@ -13,7 +13,7 @@ class AccommodationPriceCoverageTest extends TestCase
{
public function testCoversOnlyDaysWithinPricePeriod(): void
{
$coverage = new AccommodationPriceCoverage($this->createMock(AccommodationPriceRepository::class));
$coverage = new AccommodationPriceCoverage($this->createStub(AccommodationPriceRepository::class));
$covered = $coverage->coveredDatesFor(
[$this->price('2026-06-01', '2026-06-09')],
@@ -30,7 +30,7 @@ class AccommodationPriceCoverageTest extends TestCase
public function testGapBetweenPricePeriodsStaysUncovered(): void
{
$coverage = new AccommodationPriceCoverage($this->createMock(AccommodationPriceRepository::class));
$coverage = new AccommodationPriceCoverage($this->createStub(AccommodationPriceRepository::class));
$covered = $coverage->coveredDatesFor(
[$this->price('2026-06-01', '2026-06-02'), $this->price('2026-06-05', '2026-06-06')],
@@ -46,7 +46,7 @@ class AccommodationPriceCoverageTest extends TestCase
public function testNoPricesMeansNoCoverage(): void
{
$coverage = new AccommodationPriceCoverage($this->createMock(AccommodationPriceRepository::class));
$coverage = new AccommodationPriceCoverage($this->createStub(AccommodationPriceRepository::class));
$covered = $coverage->coveredDatesFor(
[],
@@ -137,7 +137,7 @@ class ApplicantInsuranceCascadeTest extends TestCase
$cascade = new ApplicantInsuranceCascade(
$insuranceService,
$this->createMock(BookingPriceCalculator::class)
$this->createStub(BookingPriceCalculator::class)
);
$cascade->apply($bookingDto);
@@ -201,11 +201,11 @@ class ApplicantInsuranceCascadeTest extends TestCase
*/
private function createCascade(array $assignments, array $selectable): ApplicantInsuranceCascade
{
$insuranceService = $this->createMock(InsuranceManager::class);
$insuranceService = $this->createStub(InsuranceManager::class);
$insuranceService->method('getSelectableInsurances')->willReturn($selectable);
$insuranceService->method('batchAssignInsuranceToParticipants')->willReturn($assignments);
$priceCalculator = $this->createMock(BookingPriceCalculator::class);
$priceCalculator = $this->createStub(BookingPriceCalculator::class);
$priceCalculator->method('calculateIndividualParticipantPriceExcludingInsurance')->willReturn(0.0);
return new ApplicantInsuranceCascade($insuranceService, $priceCalculator);
+35 -31
View File
@@ -19,23 +19,25 @@ use PHPUnit\Framework\TestCase;
class BookingConfiguratorBabyTest extends TestCase
{
private BookingConfigurator $bookingService;
private ?BookingConfigurator $bookingService = null;
private ParticipantEligibilityChecker $participantEligibilityService;
protected function setUp(): void
{
$travelDataService = $this->createMock(TravelDataProvider::class);
$this->participantEligibilityService = $this->createMock(ParticipantEligibilityChecker::class);
$bookingStatusRuleRegistry = $this->createMock(BookingStatusRuleRegistry::class);
$bookingStatusRuleRegistry->method('evaluateStatus')->willReturn('F');
$agencyLoader = $this->createMock(AgencyLoader::class);
$this->participantEligibilityService = $this->createStub(ParticipantEligibilityChecker::class);
}
$this->bookingService = new BookingConfigurator(
$this->createMock(BookingSessionManager::class),
$travelDataService,
private function bookingService(): BookingConfigurator
{
$bookingStatusRuleRegistry = $this->createStub(BookingStatusRuleRegistry::class);
$bookingStatusRuleRegistry->method('evaluateStatus')->willReturn('F');
return $this->bookingService ??= new BookingConfigurator(
$this->createStub(BookingSessionManager::class),
$this->createStub(TravelDataProvider::class),
$this->participantEligibilityService,
$bookingStatusRuleRegistry,
$agencyLoader,
$this->createStub(AgencyLoader::class),
'F' // default booking status
);
}
@@ -52,7 +54,7 @@ class BookingConfiguratorBabyTest extends TestCase
$participant->additionalServices = [];
$bookingDto->participants[0] = $participant;
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertEmpty($participant->additionalServices, 'Mandatory services should not be preselected for baby participants');
}
@@ -69,7 +71,7 @@ class BookingConfiguratorBabyTest extends TestCase
$participant->additionalServices = [];
$bookingDto->participants[0] = $participant;
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertEmpty($participant->additionalServices, 'Mandatory services should not be preselected for participants at BABY_MAX_AGE');
}
@@ -91,7 +93,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertNotEmpty($participant->additionalServices, 'Mandatory services should be preselected for non-baby participants');
$this->assertCount(1, $participant->additionalServices);
@@ -115,7 +117,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertNotEmpty($participant->additionalServices, 'Mandatory services should be preselected for adult participants');
$this->assertCount(1, $participant->additionalServices);
@@ -123,6 +125,8 @@ class BookingConfiguratorBabyTest extends TestCase
public function testPreselectMandatoryServicesHandlesMixedParticipants(): void
{
$this->participantEligibilityService = $this->createMock(ParticipantEligibilityChecker::class);
$travel = $this->createTravelWithMandatoryServices();
$bookingDto = new BookingDto($travel, 1);
@@ -146,7 +150,7 @@ class BookingConfiguratorBabyTest extends TestCase
->with($bookingDto, 1) // Only called for adult
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertEmpty($babyParticipant->additionalServices, 'Baby should not have mandatory services preselected');
$this->assertNotEmpty($adultParticipant->additionalServices, 'Adult should have mandatory services preselected');
@@ -164,7 +168,7 @@ class BookingConfiguratorBabyTest extends TestCase
$participant->additionalServices = [];
$bookingDto->participants[0] = $participant;
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertEmpty($participant->additionalServices, 'Mandatory services should not be preselected for newborn babies');
}
@@ -186,7 +190,7 @@ class BookingConfiguratorBabyTest extends TestCase
$participant->additionalServices = [];
$bookingDto->participants[0] = $participant;
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
// At age 1, participant is a baby and should be skipped
$this->assertEmpty($participant->additionalServices, 'Age should be calculated at travel date, not current date');
@@ -207,7 +211,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertCount(1, $participant->additionalServices);
$this->assertSame('Auto Book Service', $participant->additionalServices[0]->label);
@@ -229,7 +233,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertEmpty($participant->additionalServices);
}
@@ -250,7 +254,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertCount(1, $participant->additionalServices);
$this->assertSame('Mandatory And Auto Book Service', $participant->additionalServices[0]->label);
@@ -270,7 +274,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertNotNull($participant->skiPass);
$this->assertSame('Auto Book Ski Pass', $participant->skiPass?->label);
@@ -291,7 +295,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertNull($participant->skiPass);
}
@@ -311,7 +315,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertNotNull($participant->skiPass);
$this->assertSame('Mandatory And Auto Book Ski Pass', $participant->skiPass?->label);
@@ -331,7 +335,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertCount(1, $participant->board);
$this->assertSame('Auto Book Board', $participant->board[0]->label);
@@ -352,7 +356,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertSame([], $participant->board);
}
@@ -372,7 +376,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertCount(1, $participant->board);
$this->assertSame('Mandatory And Auto Book Board', $participant->board[0]->label);
@@ -393,7 +397,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertCount(1, $participant->rentals);
$this->assertSame('Auto Book Rental', $participant->rentals[0]->label);
@@ -415,7 +419,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertSame([], $participant->rentals);
}
@@ -436,7 +440,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertCount(1, $participant->rentals);
$this->assertSame('Mandatory And Auto Book Rental', $participant->rentals[0]->label);
@@ -456,7 +460,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertSame([], $participant->rentals);
}
@@ -480,7 +484,7 @@ class BookingConfiguratorBabyTest extends TestCase
->method('isParticipantEligible')
->willReturn(true);
$this->bookingService->preselectDefaultServices($bookingDto);
$this->bookingService()->preselectDefaultServices($bookingDto);
$this->assertSame([], $participant->rentals);
}
+18 -18
View File
@@ -4,11 +4,9 @@ declare(strict_types=1);
namespace App\Tests\Service;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\BusProNet\Constants;
use App\BusProNet\Model\CrmSelection;
use App\BusProNet\Model\CrmSelectionGroup;
use App\BusProNet\Constants;
use App\BusProNet\Model\Room;
use App\BusProNet\Model\Service;
use App\BusProNet\Model\Travel;
@@ -16,6 +14,8 @@ use App\BusProNet\Service\BookingStatusRuleRegistry;
use App\BusProNet\Service\StatusRule\Selection1473StatusRule;
use App\BusProNet\XmlLoader\AgencyLoader;
use App\Exception\NoRoomsAvailableException;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\Service\BookingConfigurator;
use App\Service\BookingSessionManager;
use App\Service\ParticipantEligibilityChecker;
@@ -32,12 +32,12 @@ class BookingConfiguratorStatusTest extends TestCase
protected function setUp(): void
{
$bookingSessionService = $this->createMock(BookingSessionManager::class);
$this->travelDataService = $this->createMock(TravelDataProvider::class);
$participantEligibility = $this->createMock(ParticipantEligibilityChecker::class);
$bookingStatusRuleRegistry = $this->createMock(BookingStatusRuleRegistry::class);
$bookingSessionService = $this->createStub(BookingSessionManager::class);
$this->travelDataService = $this->createStub(TravelDataProvider::class);
$participantEligibility = $this->createStub(ParticipantEligibilityChecker::class);
$bookingStatusRuleRegistry = $this->createStub(BookingStatusRuleRegistry::class);
$bookingStatusRuleRegistry->method('evaluateStatus')->willReturn('F');
$agencyLoader = $this->createMock(AgencyLoader::class);
$agencyLoader = $this->createStub(AgencyLoader::class);
$this->bookingService = new BookingConfigurator(
$bookingSessionService,
@@ -180,13 +180,13 @@ class BookingConfiguratorStatusTest extends TestCase
public function testStartFreshBookingWithSelection1473UsesOptionStatus(): void
{
$bookingService = new BookingConfigurator(
$this->createMock(BookingSessionManager::class),
$this->createStub(BookingSessionManager::class),
$this->travelDataService,
$this->createMock(ParticipantEligibilityChecker::class),
$this->createStub(ParticipantEligibilityChecker::class),
new BookingStatusRuleRegistry([
new Selection1473StatusRule(),
]),
$this->createMock(AgencyLoader::class),
$this->createStub(AgencyLoader::class),
'F'
);
@@ -230,15 +230,15 @@ class BookingConfiguratorStatusTest extends TestCase
public function testApplyCreateBookingStatusRulesSetsOptionFromRegistry(): void
{
$bookingStatusRuleRegistry = $this->createMock(BookingStatusRuleRegistry::class);
$bookingStatusRuleRegistry = $this->createStub(BookingStatusRuleRegistry::class);
$bookingStatusRuleRegistry->method('evaluateStatus')->willReturn('O');
$bookingService = new BookingConfigurator(
$this->createMock(BookingSessionManager::class),
$this->createStub(BookingSessionManager::class),
$this->travelDataService,
$this->createMock(ParticipantEligibilityChecker::class),
$this->createStub(ParticipantEligibilityChecker::class),
$bookingStatusRuleRegistry,
$this->createMock(AgencyLoader::class),
$this->createStub(AgencyLoader::class),
'F'
);
@@ -265,11 +265,11 @@ class BookingConfiguratorStatusTest extends TestCase
$bookingStatusRuleRegistry->expects($this->never())->method('evaluateStatus');
$bookingService = new BookingConfigurator(
$this->createMock(BookingSessionManager::class),
$this->createStub(BookingSessionManager::class),
$this->travelDataService,
$this->createMock(ParticipantEligibilityChecker::class),
$this->createStub(ParticipantEligibilityChecker::class),
$bookingStatusRuleRegistry,
$this->createMock(AgencyLoader::class),
$this->createStub(AgencyLoader::class),
'F'
);
@@ -44,7 +44,7 @@ class BookingCreateContextFactoryTest extends TestCase
$travel->rooms = [$roomByRoom, $roomByPax];
$bookingDto = new BookingDto($travel, 157047);
$summaryData = $this->createMock(BookingSummaryDto::class);
$summaryData = $this->createStub(BookingSummaryDto::class);
$summaryDataService = $this->createMock(BookingSummaryAssembler::class);
$summaryDataService->expects($this->once())
@@ -63,7 +63,7 @@ class BookingCreateContextFactoryTest extends TestCase
$priceCalculator->expects($this->never())
->method('calculateAllParticipantIndividualPrices');
$familyInsuranceService = $this->createMock(FamilyInsuranceAvailabilityChecker::class);
$familyInsuranceService = $this->createStub(FamilyInsuranceAvailabilityChecker::class);
$familyInsuranceService->method('isFamilyInsuranceUpgradeAvailable')->willReturn(true);
$service = new BookingCreateContextFactory(
@@ -101,7 +101,7 @@ class BookingCreateContextFactoryTest extends TestCase
$travel->rooms = [$room];
$bookingDto = new BookingDto($travel, 157047);
$summaryData = $this->createMock(BookingSummaryDto::class);
$summaryData = $this->createStub(BookingSummaryDto::class);
$cardData = new ParticipantCardDataDto(
name: 'Max Mustermann',
email: '[email protected]',
@@ -126,7 +126,7 @@ class BookingCreateContextFactoryTest extends TestCase
$priceCalculator->expects($this->never())
->method('calculateAllParticipantIndividualPrices');
$familyInsuranceService = $this->createMock(FamilyInsuranceAvailabilityChecker::class);
$familyInsuranceService = $this->createStub(FamilyInsuranceAvailabilityChecker::class);
$familyInsuranceService->method('isFamilyInsuranceUpgradeAvailable')->willReturn(true);
$service = new BookingCreateContextFactory(
@@ -162,7 +162,7 @@ class BookingCreateContextFactoryTest extends TestCase
$travel->rooms = [$room];
$bookingDto = new BookingDto($travel, 157047);
$summaryData = $this->createMock(BookingSummaryDto::class);
$summaryData = $this->createStub(BookingSummaryDto::class);
$summaryDataService = $this->createMock(BookingSummaryAssembler::class);
$summaryDataService->expects($this->once())
@@ -180,7 +180,7 @@ class BookingCreateContextFactoryTest extends TestCase
->with($bookingDto)
->willReturn([123.45]);
$familyInsuranceService = $this->createMock(FamilyInsuranceAvailabilityChecker::class);
$familyInsuranceService = $this->createStub(FamilyInsuranceAvailabilityChecker::class);
$familyInsuranceService->method('isFamilyInsuranceUpgradeAvailable')->willReturn(true);
$service = new BookingCreateContextFactory(
@@ -32,7 +32,7 @@ class BookingEditContextFactoryTest extends TestCase
$bookingData = new Booking();
$bookingData->dateId = 123;
$summaryData = $this->createMock(BookingSummaryDto::class);
$summaryData = $this->createStub(BookingSummaryDto::class);
$participantCardAssembler = $this->createMock(ParticipantCardAssembler::class);
$participantCardAssembler->expects($this->once())
@@ -34,9 +34,9 @@ class BookingEditDraftManagerMutabilityTest extends TestCase
protected function setUp(): void
{
$this->service = new BookingEditDraftManager(
$this->createMock(BookingEditDraftRepository::class),
$this->createMock(EntityManagerInterface::class),
$this->createMock(BookingChangeTracker::class),
$this->createStub(BookingEditDraftRepository::class),
$this->createStub(EntityManagerInterface::class),
$this->createStub(BookingChangeTracker::class),
new BookingEditDraftMerger(),
new NullLogger(),
);
@@ -544,7 +544,7 @@ class BookingEditDraftManagerMutabilityTest extends TestCase
private function createDraft(array $formData): BookingEditDraft
{
$user = $this->createMock(User::class);
$user = $this->createStub(User::class);
return new BookingEditDraft($user, 123, new \DateTimeImmutable(), $formData);
}
@@ -4,20 +4,20 @@ declare(strict_types=1);
namespace App\Tests\Service;
use App\BusProNet\Model\CrmSelection;
use App\BusProNet\Model\CrmSelectionGroup;
use App\BusProNet\Model\Address;
use App\BusProNet\Model\Booking;
use App\BusProNet\Model\CrmSelection;
use App\BusProNet\Model\CrmSelectionGroup;
use App\BusProNet\Model\Service;
use App\BusProNet\Model\Travel;
use App\BusProNet\XmlLoader\AgencyLoader;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\Form\Service\ServiceAgeEvaluator;
use App\Service\BookingEditPreFlightChecker;
use App\Service\BookingPriceCalculator;
use App\Service\ParticipantEligibilityChecker;
use App\Service\VoucherValidator;
use App\Form\Service\ServiceAgeEvaluator;
use App\Validator\Constraints\MandatoryAdditionalServicesSelectedValidator;
use App\Validator\Constraints\PromoVoucherValidator;
use App\Validator\Constraints\PurchaseVoucherValidator;
@@ -248,19 +248,14 @@ class BookingEditPreFlightCheckerTest extends TestCase
private function createValidator(): ValidatorInterface
{
$voucherValidator = $this->createMock(VoucherValidator::class);
$bookingPriceCalculator = $this->createMock(BookingPriceCalculator::class);
$participantEligibilityChecker = $this->createMock(ParticipantEligibilityChecker::class);
$voucherValidator = $this->createStub(VoucherValidator::class);
$bookingPriceCalculator = $this->createStub(BookingPriceCalculator::class);
$participantEligibilityChecker = $this->createStub(ParticipantEligibilityChecker::class);
$participantEligibilityChecker
->method('isParticipantEligible')
->willReturn(false);
$validatorFactory = new class(
$voucherValidator,
$bookingPriceCalculator,
$participantEligibilityChecker,
new ServiceAgeEvaluator(),
) implements ConstraintValidatorFactoryInterface {
$validatorFactory = new class($voucherValidator, $bookingPriceCalculator, $participantEligibilityChecker, new ServiceAgeEvaluator()) implements ConstraintValidatorFactoryInterface {
public function __construct(
private readonly VoucherValidator $voucherValidator,
private readonly BookingPriceCalculator $bookingPriceCalculator,
+9 -11
View File
@@ -19,6 +19,7 @@ use App\Service\BookingEditSubmitGuard;
use App\Service\BookingEditSubmitter;
use App\Service\BookingSessionManager;
use App\Service\TravelDataProvider;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -53,9 +54,7 @@ class BookingEditSubmitterTest extends TestCase
$this->assertFalse($result->immutableChangesReverted);
}
/**
* @dataProvider updateFailureProvider
*/
#[DataProvider('updateFailureProvider')]
public function testHandleSubmissionReturnsRedirectWhenUpdateThrows(
\Throwable $exception,
string $expectedStatus,
@@ -437,13 +436,13 @@ class BookingEditSubmitterTest extends TestCase
?BookingSessionManager $bookingSessionService = null,
): BookingEditSubmitter {
return new BookingEditSubmitter(
$apiClient ?? $this->createMock(\App\BusProNet\ApiClient::class),
$dataLoader ?? $this->createMock(BookingEditDataLoader::class),
$draftService ?? $this->createMock(BookingEditDraftManager::class),
$travelDataService ?? $this->createMock(TravelDataProvider::class),
$submitGuard ?? $this->createMock(BookingEditSubmitGuard::class),
$bookingSessionService ?? $this->createMock(BookingSessionManager::class),
$this->createMock(LoggerInterface::class),
$apiClient ?? $this->createStub(\App\BusProNet\ApiClient::class),
$dataLoader ?? $this->createStub(BookingEditDataLoader::class),
$draftService ?? $this->createStub(BookingEditDraftManager::class),
$travelDataService ?? $this->createStub(TravelDataProvider::class),
$submitGuard ?? $this->createStub(BookingEditSubmitGuard::class),
$bookingSessionService ?? $this->createStub(BookingSessionManager::class),
$this->createStub(LoggerInterface::class),
);
}
@@ -475,5 +474,4 @@ class BookingEditSubmitterTest extends TestCase
return $request;
}
}
Loaded 100 of 118 files, more files were not shown because too many files have changed in this diff. Show more