feat: fold purchase and promo voucher fields into one code field

This commit is contained in:
fromme committed 2026-10-06 10:41:30 +02:00
1 parent 93512b8345
commit 21d756a2e3
21 files changed
+801 -432

No files matched your search

+37 -17
View File
@@ -16,13 +16,9 @@ use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\Form\Model\ParticipantEditDto;
use App\Form\Service\ServiceAgeEvaluator;
use App\Service\BookingPriceCalculator;
use App\Service\ParticipantEligibilityChecker;
use App\Service\ServiceAvailabilityCalculator;
use App\Service\VoucherValidator;
use App\Validator\Constraints\MandatoryAdditionalServicesSelectedValidator;
use App\Validator\Constraints\PromoVoucherValidator;
use App\Validator\Constraints\PurchaseVoucherValidator;
use App\Validator\Constraints\SkiPassSelectionValidator;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Constraint;
@@ -48,8 +44,6 @@ class ParticipantEditDtoTest extends TestCase
protected function setUp(): void
{
// Create mock services for validator dependencies
$mockVoucherService = $this->createStub(VoucherValidator::class);
$mockPriceCalculatorService = $this->createStub(BookingPriceCalculator::class);
$mockParticipantEligibilityChecker = $this->createStub(ParticipantEligibilityChecker::class);
$mockServiceAgeEvaluator = $this->createStub(ServiceAgeEvaluator::class);
@@ -61,10 +55,8 @@ class ParticipantEditDtoTest extends TestCase
);
// Create custom validator factory that can inject dependencies
$validatorFactory = new class($mockVoucherService, $mockPriceCalculatorService, $mockParticipantEligibilityChecker, $mockServiceAgeEvaluator, $participantEligibilityChecker) implements ConstraintValidatorFactoryInterface {
$validatorFactory = new class($mockParticipantEligibilityChecker, $mockServiceAgeEvaluator, $participantEligibilityChecker) implements ConstraintValidatorFactoryInterface {
public function __construct(
private readonly VoucherValidator $voucherService,
private readonly BookingPriceCalculator $priceCalculatorService,
private readonly ParticipantEligibilityChecker $participantEligibilityService,
private readonly ServiceAgeEvaluator $serviceAgeEvaluator,
private readonly ParticipantEligibilityChecker $realEligibilityChecker,
@@ -75,14 +67,6 @@ class ParticipantEditDtoTest extends TestCase
{
$className = $constraint->validatedBy();
if (PurchaseVoucherValidator::class === $className) {
return new PurchaseVoucherValidator($this->voucherService);
}
if (PromoVoucherValidator::class === $className) {
return new PromoVoucherValidator($this->voucherService, $this->priceCalculatorService);
}
if (EmailValidator::class === $className) {
return new EmailValidator(Email::VALIDATION_MODE_HTML5);
}
@@ -125,6 +109,42 @@ class ParticipantEditDtoTest extends TestCase
$this->assertCount(0, $violations);
}
public function testRejectedVoucherCodeFailsValidation(): void
{
$bookingDto = $this->createBookingDtoWithParticipants([
$this->createValidAdultParticipant('[email protected]'),
]);
$bookingDto->participants[0]->voucherCodeError = 'Gutschein ungültig: Gutschein nicht gefunden';
$violations = $this->validator->validate(
new ParticipantEditDto(participant: $bookingDto->participants[0], bookingContext: $bookingDto),
null,
['booking_create']
);
$this->assertCount(1, $violations);
$this->assertSame('participant.voucherCode', $violations->get(0)->getPropertyPath());
$this->assertSame('Gutschein ungültig: Gutschein nicht gefunden', $violations->get(0)->getMessage());
}
public function testAppliedPromoCodeRejectedOnRecheckFailsValidation(): void
{
$bookingDto = $this->createBookingDtoWithParticipants([
$this->createValidAdultParticipant('[email protected]'),
]);
$bookingDto->participants[0]->promoVoucherCode = 'R-SOMMER26';
$bookingDto->participants[0]->promoVoucherError = 'Aktionscode ungültig: Mindestpreis nicht erreicht';
$violations = $this->validator->validate(
new ParticipantEditDto(participant: $bookingDto->participants[0], bookingContext: $bookingDto),
null,
['booking_create']
);
$this->assertCount(1, $violations);
$this->assertSame('participant.voucherCode', $violations->get(0)->getPropertyPath());
}
public function testAdultWithDuplicateEmailFailsValidation(): void
{
$bookingDto = $this->createBookingDtoWithParticipants([