feat: refactor participant card DTOs and labels

This commit is contained in:
Björn Fromme
2026-04-11 18:28:32 +02:00
parent f22ceae41c
commit 1b0e479e49
10 changed files with 299 additions and 139 deletions
@@ -13,6 +13,7 @@ use App\Form\Model\ParticipantDto;
use App\Form\Service\ParticipantFieldOptionsProvider;
use App\Service\BookingPriceCalculatorService;
use App\Service\InsuranceService;
use App\Service\ServiceLabelFormatter;
use App\Service\ServiceAvailabilityCalculator;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -27,12 +28,14 @@ class ParticipantFieldOptionsProviderBabyTest extends TestCase
$this->serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
$insuranceService = $this->createMock(InsuranceService::class);
$priceCalculatorService = $this->createMock(BookingPriceCalculatorService::class);
$serviceLabelFormatter = new ServiceLabelFormatter();
$translator = $this->createMock(TranslatorInterface::class);
$this->provider = new ParticipantFieldOptionsProvider(
$this->serviceAvailabilityCalculator,
$insuranceService,
$priceCalculatorService,
$serviceLabelFormatter,
$translator
);
}
@@ -12,6 +12,7 @@ use App\Form\Model\ParticipantDto;
use App\Form\Service\ParticipantFieldOptionsProvider;
use App\Service\BookingPriceCalculatorService;
use App\Service\InsuranceService;
use App\Service\ServiceLabelFormatter;
use App\Service\ServiceAvailabilityCalculator;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -30,12 +31,14 @@ class ParticipantFieldOptionsProviderMandatoryServiceTest extends TestCase
$serviceAvailabilityCalculator = $this->createMock(ServiceAvailabilityCalculator::class);
$insuranceService = $this->createMock(InsuranceService::class);
$priceCalculatorService = $this->createMock(BookingPriceCalculatorService::class);
$serviceLabelFormatter = new ServiceLabelFormatter();
$translator = $this->createMock(TranslatorInterface::class);
$this->provider = new ParticipantFieldOptionsProvider(
$serviceAvailabilityCalculator,
$insuranceService,
$priceCalculatorService,
$serviceLabelFormatter,
$translator
);
}
@@ -110,6 +113,28 @@ class ParticipantFieldOptionsProviderMandatoryServiceTest extends TestCase
$this->assertArrayNotHasKey('checked', $attributes);
}
public function testParkingLabelIncludesPrice(): void
{
$parkingService = new Service();
$parkingService->id = 3;
$parkingService->label = 'Parkplatz';
$parkingService->subType = Constants::TOKEN_PARKING;
$parkingService->available = 10;
$parkingService->price = 12.5;
$travel = $this->createTravelWithAdditionalServices([$parkingService]);
$bookingDto = new BookingDto($travel, 1);
$participant = new ParticipantDto();
$participant->index = 0;
$participant->dateOfBirth = $travel->dateFrom->modify('-25 years');
$bookingDto->participants[0] = $participant;
$options = $this->provider->getFieldOptions('parking', $bookingDto, 0);
$this->assertSame('Parkplatz (€12,50)', $options['label']);
}
public function testNullParticipantReturnsEmptyOptions(): void
{
$mandatoryService = $this->createMandatoryService(1, 'Ortstaxe');
@@ -23,7 +23,10 @@ class ParticipantCardDataServiceTest extends TestCase
{
$this->priceCalculator = $this->createMock(BookingPriceCalculatorService::class);
$this->validator = $this->createMock(ValidatorInterface::class);
$this->service = new ParticipantCardDataService($this->priceCalculator, $this->validator);
$this->service = new ParticipantCardDataService(
$this->priceCalculator,
$this->validator
);
}
public function testGetCardDataWithFullParticipantData(): void
@@ -55,9 +58,10 @@ class ParticipantCardDataServiceTest extends TestCase
$result = $this->service->getCardData($bookingDto, 0);
$this->assertEquals('Max Mustermann', $result['name']);
$this->assertEquals('Doppelzimmer', $result['roomName']);
$this->assertEquals('450,50 €', $result['price']);
$this->assertSame('Max Mustermann', $result->name);
$this->assertSame('Doppelzimmer', $result->roomName);
$this->assertSame(450.50, $result->price->amount);
$this->assertFalse($result->price->showDash);
}
public function testGetCardDataWithPartialName(): void
@@ -79,7 +83,7 @@ class ParticipantCardDataServiceTest extends TestCase
$result = $this->service->getCardData($bookingDto, 0);
$this->assertEquals('Max', $result['name']);
$this->assertSame('Max', $result->name);
}
public function testGetCardDataWithNoName(): void
@@ -101,7 +105,7 @@ class ParticipantCardDataServiceTest extends TestCase
$result = $this->service->getCardData($bookingDto, 0);
$this->assertEquals('Anmelder:in', $result['name']);
$this->assertSame('Anmelder:in', $result->name);
}
public function testGetCardDataWithEmptyName(): void
@@ -123,7 +127,7 @@ class ParticipantCardDataServiceTest extends TestCase
$result = $this->service->getCardData($bookingDto, 0);
$this->assertEquals('Anmelder:in', $result['name']);
$this->assertSame('Anmelder:in', $result->name);
}
public function testGetCardDataWithNoRoomAssignment(): void
@@ -145,7 +149,7 @@ class ParticipantCardDataServiceTest extends TestCase
$result = $this->service->getCardData($bookingDto, 0);
$this->assertEquals('Kein Zimmer zugewiesen', $result['roomName']);
$this->assertSame('Kein Zimmer zugewiesen', $result->roomName);
}
public function testGetCardDataWithUnknownRoom(): void
@@ -167,7 +171,7 @@ class ParticipantCardDataServiceTest extends TestCase
$result = $this->service->getCardData($bookingDto, 0);
$this->assertEquals('Unbekanntes Zimmer', $result['roomName']);
$this->assertSame('Unbekanntes Zimmer', $result->roomName);
}
public function testGetCardDataWithZeroPriceAndNoRoom(): void
@@ -190,7 +194,8 @@ class ParticipantCardDataServiceTest extends TestCase
$result = $this->service->getCardData($bookingDto, 0);
// When no room assigned and price is zero, display dash (incomplete configuration)
$this->assertEquals('-', $result['price']);
$this->assertNull($result->price->amount);
$this->assertTrue($result->price->showDash);
}
public function testGetCardDataWithZeroPriceButRoomAssigned(): void
@@ -219,7 +224,8 @@ class ParticipantCardDataServiceTest extends TestCase
$result = $this->service->getCardData($bookingDto, 0);
// When room is assigned but price is zero, display formatted zero price
$this->assertEquals('0,00 €', $result['price']);
$this->assertSame(0.0, $result->price->amount);
$this->assertFalse($result->price->showDash);
}
public function testGetCardDataWithInvalidIndex(): void
@@ -279,19 +285,22 @@ class ParticipantCardDataServiceTest extends TestCase
$this->assertCount(3, $result);
// First participant
$this->assertEquals('Max Mustermann', $result[0]['name']);
$this->assertEquals('Einzelzimmer', $result[0]['roomName']);
$this->assertEquals('450,00 €', $result[0]['price']);
$this->assertSame('Max Mustermann', $result[0]->name);
$this->assertSame('Einzelzimmer', $result[0]->roomName);
$this->assertSame(450.0, $result[0]->price->amount);
$this->assertFalse($result[0]->price->showDash);
// Second participant
$this->assertEquals('Anna Schmidt', $result[1]['name']);
$this->assertEquals('Doppelzimmer', $result[1]['roomName']);
$this->assertEquals('500,00 €', $result[1]['price']);
$this->assertSame('Anna Schmidt', $result[1]->name);
$this->assertSame('Doppelzimmer', $result[1]->roomName);
$this->assertSame(500.0, $result[1]->price->amount);
$this->assertFalse($result[1]->price->showDash);
// Third participant (no name)
$this->assertEquals('Teilnehmer:in', $result[2]['name']);
$this->assertEquals('Doppelzimmer', $result[2]['roomName']);
$this->assertEquals('480,00 €', $result[2]['price']);
$this->assertSame('Teilnehmer:in', $result[2]->name);
$this->assertSame('Doppelzimmer', $result[2]->roomName);
$this->assertSame(480.0, $result[2]->price->amount);
$this->assertFalse($result[2]->price->showDash);
}
public function testGetAllCardsDataWithEmptyParticipants(): void
@@ -323,7 +332,8 @@ class ParticipantCardDataServiceTest extends TestCase
$result = $this->service->getCardData($bookingDto, 0);
$this->assertEquals('1.234,56 €', $result['price']);
$this->assertSame(1234.56, $result->price->amount);
$this->assertFalse($result->price->showDash);
}
public function testFallbackNameIndexingIsOneBasedNotZeroBased(): void
@@ -346,9 +356,9 @@ class ParticipantCardDataServiceTest extends TestCase
$result2 = $this->service->getCardData($bookingDto, 1);
$result3 = $this->service->getCardData($bookingDto, 2);
$this->assertEquals('Anmelder:in', $result1['name']);
$this->assertEquals('Teilnehmer:in', $result2['name']);
$this->assertEquals('Teilnehmer:in', $result3['name']);
$this->assertSame('Anmelder:in', $result1->name);
$this->assertSame('Teilnehmer:in', $result2->name);
$this->assertSame('Teilnehmer:in', $result3->name);
}
public function testGetCardDataWithValidationReturnsValidCard(): void
@@ -384,13 +394,14 @@ class ParticipantCardDataServiceTest extends TestCase
->method('validate')
->willReturn($violations);
$result = $this->service->getCardDataWithValidation($bookingDto, 0, ['booking_create']);
$result = $this->service->getCardDataWithValidation($bookingDto, 0);
$this->assertEquals('Max Mustermann', $result['name']);
$this->assertEquals('Doppelzimmer', $result['roomName']);
$this->assertEquals('450,50 €', $result['price']);
$this->assertTrue($result['isValid']);
$this->assertEmpty($result['errorMessages']);
$this->assertSame('Max Mustermann', $result->name);
$this->assertSame('Doppelzimmer', $result->roomName);
$this->assertSame(450.50, $result->price->amount);
$this->assertFalse($result->price->showDash);
$this->assertTrue($result->isValid);
$this->assertEmpty($result->errorMessages);
}
public function testGetCardDataWithValidationReturnsInvalidCard(): void
@@ -424,12 +435,12 @@ class ParticipantCardDataServiceTest extends TestCase
->method('validate')
->willReturn($violations);
$result = $this->service->getCardDataWithValidation($bookingDto, 0, ['booking_create']);
$result = $this->service->getCardDataWithValidation($bookingDto, 0);
$this->assertEquals('Max Mustermann', $result['name']);
$this->assertFalse($result['isValid']);
$this->assertCount(1, $result['errorMessages']);
$this->assertEquals('Diese E-Mail Adresse wird bereits von einem anderen Teilnehmer verwendet', $result['errorMessages'][0]);
$this->assertSame('Max Mustermann', $result->name);
$this->assertFalse($result->isValid);
$this->assertCount(1, $result->errorMessages);
$this->assertSame('Diese E-Mail Adresse wird bereits von einem anderen Teilnehmer verwendet', $result->errorMessages[0]);
}
public function testGetAllCardsDataWithValidationReturnsAllCards(): void
@@ -472,12 +483,12 @@ class ParticipantCardDataServiceTest extends TestCase
->method('validate')
->willReturn($violations);
$result = $this->service->getAllCardsDataWithValidation($bookingDto, ['booking_create']);
$result = $this->service->getAllCardsDataWithValidation($bookingDto);
$this->assertCount(2, $result);
$this->assertTrue($result[0]['isValid']);
$this->assertTrue($result[1]['isValid']);
$this->assertEquals('Max Mustermann', $result[0]['name']);
$this->assertEquals('Anna Schmidt', $result[1]['name']);
$this->assertTrue($result[0]->isValid);
$this->assertTrue($result[1]->isValid);
$this->assertSame('Max Mustermann', $result[0]->name);
$this->assertSame('Anna Schmidt', $result[1]->name);
}
}
@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace App\Tests\Service;
use App\BusProNet\Model\Service;
use App\Service\ServiceLabelFormatter;
use PHPUnit\Framework\TestCase;
class ServiceLabelFormatterTest extends TestCase
{
private ServiceLabelFormatter $formatter;
protected function setUp(): void
{
$this->formatter = new ServiceLabelFormatter();
}
public function testFormatServiceLabelReturnsLabelWithoutPrice(): void
{
$service = new Service();
$service->label = 'Skipass';
$service->price = null;
$this->assertSame('Skipass', $this->formatter->formatServiceLabel($service));
}
public function testFormatServiceLabelFormatsIncludedService(): void
{
$service = new Service();
$service->label = 'Ortstaxe';
$service->price = 0.0;
$this->assertSame('Ortstaxe (inkl.)', $this->formatter->formatServiceLabel($service));
}
public function testFormatServiceLabelFormatsPositivePrice(): void
{
$service = new Service();
$service->label = 'Parkplatz';
$service->price = 12.5;
$this->assertSame('Parkplatz (€12,50)', $this->formatter->formatServiceLabel($service));
}
public function testFormatServiceLabelFormatsNegativePrice(): void
{
$service = new Service();
$service->label = 'Rabatt';
$service->price = -8.0;
$this->assertSame('Rabatt (-8,00€ Rabatt)', $this->formatter->formatServiceLabel($service));
}
public function testFormatServiceLabelForServicesFallsBackWhenEmpty(): void
{
$this->assertSame(
'Verpflegung',
$this->formatter->formatServiceLabelForServices('Verpflegung', [])
);
}
}