createStub(TranslatorInterface::class); $translator->method('trans')->willReturnArgument(0); $this->provider = new ParticipantFieldOptionsProvider( new ServiceAvailabilityCalculator(), $this->createStub(InsuranceManager::class), $this->createStub(BookingPriceCalculator::class), new ServiceLabelFormatter(), $translator ); } public function testOnRequestCourseIsReadonlyInEditMode(): void { $course = $this->createCourse(id: 1, status: Constants::STATUS_ON_REQUEST); $bookingDto = $this->createEditBookingDto([$course]); $attributes = $this->getChoiceAttributes($bookingDto, $course); $this->assertArrayHasKey('readonly', $attributes); $this->assertSame( 'Diese Leistung ist derzeit nur auf Anfrage buchbar. Bitte kontaktiere uns.', $attributes['data-tooltip'] ); } public function testSoldOutCourseIsReadonlyInEditMode(): void { $course = $this->createCourse(id: 1, available: 0); $bookingDto = $this->createEditBookingDto([$course]); $attributes = $this->getChoiceAttributes($bookingDto, $course); $this->assertArrayHasKey('readonly', $attributes); $this->assertSame('ausgebucht', $attributes['data-tooltip']); } public function testOnRequestCourseStaysSelectableWhenAlreadyBooked(): void { $course = $this->createCourse(id: 1, status: Constants::STATUS_ON_REQUEST); $bookingDto = $this->createEditBookingDto([$course], heldServiceIds: [1]); $attributes = $this->getChoiceAttributes($bookingDto, $course); $this->assertArrayNotHasKey('readonly', $attributes); $this->assertArrayNotHasKey('data-tooltip', $attributes); } public function testUnlimitedCourseIsNotReadonlyInEditMode(): void { // A null contingent means unlimited. The previous edit branch inverted this and made // such a service read-only for anyone who did not already hold it. $course = $this->createCourse(id: 1, available: null); $bookingDto = $this->createEditBookingDto([$course]); $attributes = $this->getChoiceAttributes($bookingDto, $course); $this->assertArrayNotHasKey('readonly', $attributes); } public function testOnRequestCourseStaysSelectableInCreateMode(): void { $course = $this->createCourse(id: 1, status: Constants::STATUS_ON_REQUEST); $bookingDto = $this->createBookingDto([$course]); $this->assertSame(BookingDto::MODE_CREATE, $bookingDto->getMode()); $attributes = $this->getChoiceAttributes($bookingDto, $course); $this->assertArrayNotHasKey('readonly', $attributes); } /** @return array */ private function getChoiceAttributes(BookingDto $bookingDto, Service $service): array { $options = $this->provider->getFieldOptions('courses', $bookingDto, 0); return $options['choice_attr']($service); } /** @param Service[] $courses */ private function createBookingDto(array $courses): BookingDto { $travel = new Travel(); $travel->dateFrom = new \DateTimeImmutable('2027-01-09'); $travel->dateTo = new \DateTimeImmutable('2027-01-16'); foreach ($courses as $course) { $travel->additionalServices[$course->id] = $course; } $bookingDto = new BookingDto($travel, 1); $participant = new ParticipantDto(); $participant->index = 0; $participant->dateOfBirth = new \DateTimeImmutable('1990-01-01'); $bookingDto->participants[0] = $participant; return $bookingDto; } /** * @param Service[] $courses * @param list $heldServiceIds IDs participant 0 already holds in the booking */ private function createEditBookingDto(array $courses, array $heldServiceIds = []): BookingDto { $bookingDto = $this->createBookingDto($courses); $heldServices = []; foreach ($heldServiceIds as $serviceId) { $held = clone $bookingDto->travel->additionalServices[$serviceId]; $held->mapping = [0]; $heldServices[$serviceId] = $held; } // A non-null booking is what puts the DTO into edit mode $booking = new Booking(); $booking->additionalServices = $heldServices; $bookingDto->booking = $booking; return $bookingDto; } private function createCourse(int $id, ?int $available = 10, string $status = Constants::STATUS_AVAILABLE): Service { $service = new Service(); $service->id = $id; $service->label = sprintf('Kurs %d', $id); $service->subType = Constants::TOKEN_COURSES; $service->category = Constants::CATEGORY_ADDITIONAL; $service->price = (float) $id; $service->available = $available; $service->status = $status; return $service; } }