Files
myep/tests/Form/Service/ParticipantInsuranceFieldHandlerTest.php
T

282 lines
9.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Form\Service;
use App\BusProNet\Model\Insurance;
use App\BusProNet\Model\Travel;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\Form\Service\ParticipantInsuranceFieldHandler;
use App\Service\BookingPriceCalculator;
use App\Service\InsuranceManager;
use PHPUnit\Framework\TestCase;
class ParticipantInsuranceFieldHandlerTest extends TestCase
{
private ParticipantInsuranceFieldHandler $handler;
private InsuranceManager $insuranceService;
private BookingPriceCalculator $priceCalculatorService;
protected function setUp(): void
{
$this->insuranceService = $this->createMock(InsuranceManager::class);
$this->priceCalculatorService = $this->createMock(BookingPriceCalculator::class);
// Mock getSelectableInsurances to return input array
$this->insuranceService->method('getSelectableInsurances')
->willReturnCallback(fn (Travel $travel) => $travel->insurances ?? []);
// Mock price calculator to return a default price
$this->priceCalculatorService->method('calculateIndividualParticipantPriceExcludingInsurance')
->willReturn(500.0);
$this->handler = new ParticipantInsuranceFieldHandler($this->insuranceService, $this->priceCalculatorService);
}
public function testGetFieldName(): void
{
$this->assertEquals('insurance', $this->handler->getFieldName());
}
public function testGetDependencies(): void
{
$dependencies = $this->handler->getDependencies();
// Insurance handler depends on all price-affecting fields to ensure accurate reassignment
$expectedDependencies = [
'dateOfBirth',
'skiPass',
'rentals',
'courses',
'additionalServices',
'board',
'transportationOutbound',
'transportationInbound',
'pickup',
'parking',
];
$this->assertEquals($expectedDependencies, $dependencies);
}
public function testShouldProcessReturnsTrueInCreateMode(): void
{
$result = $this->handler->shouldProcess([], BookingDto::MODE_CREATE, 0);
$this->assertTrue($result);
}
public function testShouldProcessReturnsFalseInEditMode(): void
{
$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');
}
public function testProcessFieldSetsInsuranceToNullWhenNoParticipant(): void
{
$bookingDto = $this->createMockBookingDto();
$bookingDto->method('getParticipant')->with(0)->willReturn(null);
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
// No assertions needed - just ensure no exceptions are thrown
$this->addToAssertionCount(1);
}
public function testProcessFieldClearsInsuranceWhenNullSelection(): void
{
$participant = new ParticipantDto();
$participant->insurance = $this->createInsurance('123');
$travel = new Travel();
$travel->insurances = [];
$bookingDto = $this->createMockBookingDto();
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField(['insurance' => null], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
public function testProcessFieldClearsInsuranceWhenEmptyStringSelection(): void
{
$participant = new ParticipantDto();
$participant->insurance = $this->createInsurance('123');
$travel = new Travel();
$travel->insurances = [];
$bookingDto = $this->createMockBookingDto();
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField(['insurance' => ''], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
public function testProcessFieldClearsInsuranceWhenMissingFromData(): void
{
$participant = new ParticipantDto();
$participant->insurance = $this->createInsurance('123');
$travel = new Travel();
$travel->insurances = [];
$bookingDto = $this->createMockBookingDto();
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField([], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
public function testProcessFieldClearsInsuranceWhenNotFoundInAvailableInsurances(): void
{
$participant = new ParticipantDto();
$travel = new Travel();
$travel->insurances = [$this->createInsurance('456')]; // Different ID
$bookingDto = $this->createMockBookingDto();
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
public function testProcessFieldSetsInsuranceWhenEligible(): void
{
$insurance = $this->createInsurance('123');
$participant = new ParticipantDto();
$travel = new Travel();
$travel->insurances = [$insurance];
$bookingDto = $this->createMockBookingDto();
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->insuranceService
->expects($this->once())
->method('getEligibleInsurances')
->with([$insurance], $participant, $bookingDto, 500.0)
->willReturn([$insurance]);
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
$this->assertSame($insurance, $participant->insurance);
}
public function testProcessFieldClearsInsuranceWhenNotEligible(): void
{
$insurance = $this->createInsurance('123');
$participant = new ParticipantDto();
$travel = new Travel();
$travel->insurances = [$insurance];
$bookingDto = $this->createMockBookingDto();
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->insuranceService
->expects($this->once())
->method('getEligibleInsurances')
->with([$insurance], $participant, $bookingDto, 500.0)
->willReturn([]); // Not eligible
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
public function testProcessFieldWorksWithStringAndIntegerIds(): void
{
$insurance = $this->createInsurance(123); // Integer ID
$participant = new ParticipantDto();
$travel = new Travel();
$travel->insurances = [$insurance];
$bookingDto = $this->createMockBookingDto();
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->insuranceService
->expects($this->once())
->method('getEligibleInsurances')
->willReturn([$insurance]);
$this->handler->processField(['insurance' => '123'], $bookingDto, 0); // String selection
$this->assertSame($insurance, $participant->insurance);
}
public function testProcessFieldHandlesEmptyInsurancesArray(): void
{
$participant = new ParticipantDto();
$travel = new Travel();
$travel->insurances = []; // No insurances available
$bookingDto = $this->createMockBookingDto();
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
public function testProcessFieldHandlesNullInsurancesProperty(): void
{
$participant = new ParticipantDto();
$travel = new Travel();
// $travel->insurances not set, defaults to []
$bookingDto = $this->createMockBookingDto();
$bookingDto->method('getParticipant')->with(0)->willReturn($participant);
$bookingDto->travel = $travel;
$this->handler->processField(['insurance' => '123'], $bookingDto, 0);
$this->assertNull($participant->insurance);
}
public function testGetFieldStateModificationsReturnsEmptyArray(): void
{
$bookingDto = $this->createMockBookingDto();
$result = $this->handler->getFieldStateModifications([], $bookingDto, 0);
$this->assertIsArray($result);
$this->assertEmpty($result);
}
public function testGetAffectedFieldNamesReturnsEmptyArray(): void
{
$result = $this->handler->getAffectedFieldNames();
$this->assertIsArray($result);
$this->assertEmpty($result);
}
private function createInsurance(string|int $id, string $label = 'Test Insurance'): Insurance
{
$insurance = new Insurance();
$insurance->id = (string) $id;
$insurance->label = $label;
return $insurance;
}
private function createMockBookingDto(): BookingDto
{
return $this->createMock(BookingDto::class);
}
}