createUser(); $bookingDto = $this->createBookingDto(); $bookingData = $this->createBooking(); $participant = $bookingDto->participants[0]; $participant->lastName = ParticipantDataPrefiller::TOKEN; $form = $this->createMock(FormInterface::class); $form->expects($this->once()) ->method('handleRequest') ->with($request) ->willReturnSelf(); $form->expects($this->once()) ->method('isSubmitted') ->willReturn(true); $form->expects($this->never()) ->method('isValid'); $dataLoader = $this->createMock(BookingEditDataLoader::class); $dataLoader->expects($this->once()) ->method('fetchBookingData') ->with(42, $user) ->willReturn($bookingData); $bookingSessionService = $this->createMock(BookingSessionManager::class); $bookingSessionService->expects($this->once()) ->method('getBookingDto') ->with($request, BookingDto::MODE_EDIT) ->willReturn($bookingDto); $bookingSessionService->expects($this->once()) ->method('saveBookingDto') ->with($request, $bookingDto, BookingDto::MODE_EDIT); $draftService = $this->createMock(BookingEditDraftManager::class); $draftService->expects($this->once()) ->method('saveDraft') ->with($user, 42, $bookingDto); $prepopulationService = new ParticipantDataPrefiller( $this->createMock(ApiClient::class), $this->createMock(Crypt::class), $this->createMock(LoggerInterface::class), ); $participantFormSupportService = $this->createMock(ParticipantFormSupport::class); $participantFormSupportService->expects($this->once()) ->method('ensureParticipantExists') ->with($bookingDto, 0) ->willReturn($participant); $participantFormSupportService->expects($this->exactly(2)) ->method('createParticipantEditDto') ->with($bookingDto, 0) ->willReturn(new ParticipantEditDto($participant, $bookingDto)); $participantFormSupportService->expects($this->exactly(2)) ->method('getParticipantFormOptions') ->with($bookingDto) ->willReturn([ 'booking_context' => $bookingDto, 'body_dimension_ranges' => [ 'height_min' => 100, 'height_max' => 250, 'weight_min' => 20, 'weight_max' => 200, 'shoe_size_min' => 20, 'shoe_size_max' => 55, ], ]); $summaryData = $this->createMock(BookingSummaryDto::class); $context = new BookingEditContext($bookingDto, $bookingData, null, $summaryData); $contextFactory = $this->createMock(BookingEditContextFactory::class); $contextFactory->expects($this->once()) ->method('prepareBookingDto') ->with($bookingDto); $contextFactory->expects($this->once()) ->method('createParticipantContext') ->with($bookingDto, $bookingData) ->willReturn($context); $controller = new TestableParticipantController( $dataLoader, $draftService, $contextFactory, $bookingSessionService, $prepopulationService, $participantFormSupportService, $user, $form, ); $response = $controller->editParticipant(42, 0, $request); $this->assertInstanceOf(Response::class, $response); $this->assertSame('booking/edit/participant.html.twig', $controller->renderTemplate); $this->assertSame('Vorname 1', $participant->firstName); $this->assertSame('Muster 1 14:30', $participant->lastName); $this->assertSame('teilnehmer.in1@example.com', $participant->email); $this->assertSame('2006-01-15', $participant->dateOfBirth?->format('Y-m-d')); $this->assertSame(BookingParticipantType::class, $controller->createdFormTypes[0]); $this->assertSame(BookingParticipantType::class, $controller->createdFormTypes[1]); } private function createUser(): User { return new User('tester@example.com'); } private function createBookingDto(): BookingDto { $travel = new Travel(); $travel->id = 1234; $bookingDto = new BookingDto($travel, 77); $bookingDto->booking = new Booking(); $bookingDto->booking->id = 42; $bookingDto->participants = [new ParticipantDto()]; $bookingDto->participants[0]->index = 0; return $bookingDto; } private function createBooking(): Booking { $booking = new Booking(); $booking->id = 42; $booking->dateId = 1234; $booking->participantsStatus = ['F']; return $booking; } } final class TestableParticipantController extends ParticipantController { /** * @var array */ public array $createdFormTypes = []; public ?string $renderTemplate = null; /** * @var array */ public array $renderParameters = []; /** * @var FormInterface */ private readonly FormInterface $form; /** * @param FormInterface $form */ public function __construct( BookingEditDataLoader $dataLoader, BookingEditDraftManager $draftService, BookingEditContextFactory $editContextFactory, BookingSessionManager $bookingSessionService, ParticipantDataPrefiller $prepopulationService, ParticipantFormSupport $participantFormSupportService, private readonly User $user, FormInterface $form, ) { $this->form = $form; parent::__construct( $dataLoader, $draftService, $editContextFactory, $bookingSessionService, $prepopulationService, $participantFormSupportService, ); } protected function getUser(): UserInterface { return $this->user; } /** * @return FormInterface */ protected function createForm(string $type, mixed $data = null, array $options = []): FormInterface { $this->createdFormTypes[] = $type; return $this->form; } protected function addFlash(string $type, mixed $message): void { } /** * @param array $parameters */ protected function redirectToRoute(string $route, array $parameters = [], int $status = 302): RedirectResponse { return new RedirectResponse('/'.$route, $status); } /** * @param array $parameters */ protected function render(string $view, array $parameters = [], ?Response $response = null): Response { $this->renderTemplate = $view; $this->renderParameters = $parameters; return new Response(''); } }