insuranceMatchingService = $this->createMock(InsuranceMatchingService::class); $insuranceTypeFilterService = $this->createMock(InsuranceTypeFilterService::class); $insuranceTypeFilterService->method('filterNonComplementary') ->willReturnArgument(0); $this->handler = new ParticipantInsuranceFieldHandler($this->insuranceMatchingService, $insuranceTypeFilterService); } 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'); $bookingDto = $this->createMockBookingDto(); $bookingDto->method('getParticipant')->with(0)->willReturn($participant); $this->handler->processField(['insurance' => null], $bookingDto, 0); $this->assertNull($participant->insurance); } public function testProcessFieldClearsInsuranceWhenEmptyStringSelection(): void { $participant = new ParticipantDto(); $participant->insurance = $this->createInsurance('123'); $bookingDto = $this->createMockBookingDto(); $bookingDto->method('getParticipant')->with(0)->willReturn($participant); $this->handler->processField(['insurance' => ''], $bookingDto, 0); $this->assertNull($participant->insurance); } public function testProcessFieldClearsInsuranceWhenMissingFromData(): void { $participant = new ParticipantDto(); $participant->insurance = $this->createInsurance('123'); $bookingDto = $this->createMockBookingDto(); $bookingDto->method('getParticipant')->with(0)->willReturn($participant); $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->insuranceMatchingService ->expects($this->once()) ->method('getEligibleInsurances') ->with([$insurance], $participant, $bookingDto) ->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->insuranceMatchingService ->expects($this->once()) ->method('getEligibleInsurances') ->with([$insurance], $participant, $bookingDto) ->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->insuranceMatchingService ->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); } }