createValidParticipant(); $participant->rentals = []; // No rentals, so body measurements not required $participant->height = null; $participant->weight = null; $participant->shoeSize = null; $this->validator->validate($participant, new Participant()); $this->assertNoViolation(); } public function testParticipantWithRentalsButNoBodyMeasurementsFailsValidation(): void { $participant = $this->createValidParticipant(); $participant->rentals = [$this->createMockService()]; $participant->height = null; $participant->weight = null; $participant->shoeSize = null; $this->validator->validate($participant, new Participant()); $this->buildViolation('Bitte angeben wegen Leihmaterial') ->atPath('property.path.height') ->buildNextViolation('Bitte angeben wegen Leihmaterial') ->atPath('property.path.shoeSize') ->buildNextViolation('Bitte angeben wegen Leihmaterial') ->atPath('property.path.weight') ->assertRaised(); } public function testParticipantWithRentalsAndPartialBodyMeasurementsFailsValidation(): void { $participant = $this->createValidParticipant(); $participant->rentals = [$this->createMockService()]; $participant->height = '175'; $participant->weight = null; // Missing $participant->shoeSize = '42'; $this->validator->validate($participant, new Participant()); $this->buildViolation('Bitte angeben wegen Leihmaterial') ->atPath('property.path.weight') ->assertRaised(); } public function testParticipantWithRentalsAndCompleteBodyMeasurementsPassesValidation(): void { $participant = $this->createValidParticipant(); $participant->rentals = [$this->createMockService()]; $participant->height = '175'; $participant->weight = '70'; $participant->shoeSize = '42'; $this->validator->validate($participant, new Participant()); $this->assertNoViolation(); } public function testCanceledParticipantSkipsValidation(): void { $participant = $this->createValidParticipant(); $participant->status = 'S'; // Canceled $participant->transportationOutbound = null; $participant->transportationInbound = null; $this->validator->validate($participant, new Participant()); $this->assertNoViolation(); } public function testParticipantWithBusTransportationButNoPickupFailsValidation(): void { $participant = $this->createValidParticipant(); $busService = new Service(); $busService->subType = 'BUS'; $participant->transportationOutbound = $busService; $participant->pickup = null; $this->validator->validate($participant, new Participant()); $this->buildViolation('Bitte auswählen') ->atPath('property.path.pickup') ->assertRaised(); } public function testParticipantWithNonBusTransportationPassesPickupValidation(): void { $participant = $this->createValidParticipant(); $trainService = new Service(); $trainService->subType = 'TRAIN'; $participant->transportationOutbound = $trainService; $participant->pickup = null; // Not required for non-bus $this->validator->validate($participant, new Participant()); $this->assertNoViolation(); } private function createValidParticipant(): ParticipantDto { $participant = new ParticipantDto(); // Set valid transportation to avoid transportation validation errors $participant->transportationOutbound = $this->createMockService(); $participant->transportationInbound = $this->createMockService(); // Set status to active $participant->status = 'F'; return $participant; } private function createMockService(): Service { $service = new Service(); $service->id = 123; $service->label = 'Test Service'; $service->subType = 'TRAIN'; // Non-bus to avoid pickup validation return $service; } }