handler = new ParticipantVegFieldHandler(); } public function testGetFieldName(): void { $this->assertEquals('veg', $this->handler->getFieldName()); } public function testGetDependencies(): void { $dependencies = $this->handler->getDependencies(); $this->assertEquals(['dateOfBirth'], $dependencies); } public function testShouldProcessAlwaysReturnsTrue(): void { // Should always process to handle deselection cases $this->assertTrue($this->handler->shouldProcess([], BookingDto::MODE_CREATE, 0)); $this->assertTrue($this->handler->shouldProcess([], BookingDto::MODE_EDIT, 0)); $this->assertTrue($this->handler->shouldProcess(['veg' => '123'], BookingDto::MODE_CREATE, 0)); } public function testProcessFieldDoesNothingWhenNoParticipant(): void { $bookingDto = $this->createMockBookingDto(); $bookingDto->method('getParticipants')->willReturn([]); $this->handler->processField(['veg' => '123'], $bookingDto, 0); // No assertions needed - just ensure no exceptions are thrown $this->addToAssertionCount(1); } public function testProcessFieldClearsVegWhenNullSelection(): void { $participant = new ParticipantDto(); $participant->veg = $this->createService(123); $travel = $this->createMockTravel([]); $bookingDto = $this->createMockBookingDto($travel); $bookingDto->method('getParticipants')->willReturn([$participant]); $this->handler->processField(['veg' => null], $bookingDto, 0); $this->assertNull($participant->veg); } public function testProcessFieldClearsVegWhenEmptyStringSelection(): void { $participant = new ParticipantDto(); $participant->veg = $this->createService(123); $travel = $this->createMockTravel([]); $bookingDto = $this->createMockBookingDto($travel); $bookingDto->method('getParticipants')->willReturn([$participant]); $this->handler->processField(['veg' => ''], $bookingDto, 0); $this->assertNull($participant->veg); } public function testProcessFieldClearsVegWhenMissingFromData(): void { $participant = new ParticipantDto(); $participant->veg = $this->createService(123); $travel = $this->createMockTravel([]); $bookingDto = $this->createMockBookingDto($travel); $bookingDto->method('getParticipants')->willReturn([$participant]); $this->handler->processField([], $bookingDto, 0); $this->assertNull($participant->veg); } public function testProcessFieldClearsVegWhenNotFoundInAvailableServices(): void { $participant = new ParticipantDto(); $otherService = $this->createService(456); $travel = $this->createMockTravel([$otherService]); $bookingDto = $this->createMockBookingDto($travel); $bookingDto->method('getParticipants')->willReturn([$participant]); $this->handler->processField(['veg' => '123'], $bookingDto, 0); $this->assertNull($participant->veg); } public function testProcessFieldSetsVegWhenAvailable(): void { $vegService = $this->createService(123); $participant = new ParticipantDto(); $travel = $this->createMockTravel([$vegService]); $bookingDto = $this->createMockBookingDto($travel); $bookingDto->method('getParticipants')->willReturn([$participant]); $this->handler->processField(['veg' => '123'], $bookingDto, 0); $this->assertSame($vegService, $participant->veg); } public function testProcessFieldWorksWithStringAndIntegerIds(): void { $vegService = $this->createService(123); // Integer ID $participant = new ParticipantDto(); $travel = $this->createMockTravel([$vegService]); $bookingDto = $this->createMockBookingDto($travel); $bookingDto->method('getParticipants')->willReturn([$participant]); $this->handler->processField(['veg' => '123'], $bookingDto, 0); // String selection $this->assertSame($vegService, $participant->veg); } public function testProcessFieldHandlesEmptyServicesArray(): void { $participant = new ParticipantDto(); $travel = $this->createMockTravel([]); $bookingDto = $this->createMockBookingDto($travel); $bookingDto->method('getParticipants')->willReturn([$participant]); $this->handler->processField(['veg' => '123'], $bookingDto, 0); $this->assertNull($participant->veg); } public function testProcessFieldSelectsFromMultipleVegOptions(): void { $vegetarian = $this->createService(1, 'Vegetarisch'); $vegan = $this->createService(2, 'Vegan'); $participant = new ParticipantDto(); $travel = $this->createMockTravel([$vegetarian, $vegan]); $bookingDto = $this->createMockBookingDto($travel); $bookingDto->method('getParticipants')->willReturn([$participant]); $this->handler->processField(['veg' => '2'], $bookingDto, 0); $this->assertSame($vegan, $participant->veg); } 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 createService(int $id, string $label = 'Test Service'): Service { $service = new Service(); $service->id = $id; $service->label = $label; $service->subType = Constants::TOKEN_VEG; return $service; } private function createMockTravel(array $vegServices): Travel { $travel = $this->createMock(Travel::class); $travel->method('getAdditionalServicesBySubTypes') ->with(Constants::TOKEN_VEG, true) ->willReturn($vegServices); return $travel; } private function createMockBookingDto(?Travel $travel = null): BookingDto { $bookingDto = $this->createStub(BookingDto::class); if (null !== $travel) { $bookingDto->travel = $travel; } return $bookingDto; } }