fix: ensure mandatory services are preselected in edit mode
This commit is contained in:
@@ -12,6 +12,7 @@ use App\Form\Model\BookingDto;
|
|||||||
use App\Htmx\HxTrait;
|
use App\Htmx\HxTrait;
|
||||||
use App\Model\BookingEditSubmissionResult;
|
use App\Model\BookingEditSubmissionResult;
|
||||||
use App\Service\BookingChangeTracker;
|
use App\Service\BookingChangeTracker;
|
||||||
|
use App\Service\BookingConfigurator;
|
||||||
use App\Service\BookingEditContextFactory;
|
use App\Service\BookingEditContextFactory;
|
||||||
use App\Service\BookingEditDataLoader;
|
use App\Service\BookingEditDataLoader;
|
||||||
use App\Service\BookingEditDraftManager;
|
use App\Service\BookingEditDraftManager;
|
||||||
@@ -42,6 +43,7 @@ class IndexController extends AbstractController
|
|||||||
private readonly BookingEditDraftManager $draftService,
|
private readonly BookingEditDraftManager $draftService,
|
||||||
private readonly BookingSessionManager $bookingSessionService,
|
private readonly BookingSessionManager $bookingSessionService,
|
||||||
private readonly BookingChangeTracker $fingerprintService,
|
private readonly BookingChangeTracker $fingerprintService,
|
||||||
|
private readonly BookingConfigurator $bookingConfigurator,
|
||||||
private readonly BookingEditContextFactory $editContextFactory,
|
private readonly BookingEditContextFactory $editContextFactory,
|
||||||
private readonly BookingEditPreFlightChecker $preFlightChecker,
|
private readonly BookingEditPreFlightChecker $preFlightChecker,
|
||||||
private readonly BookingEditSubmitter $formSubmitter,
|
private readonly BookingEditSubmitter $formSubmitter,
|
||||||
@@ -92,6 +94,9 @@ class IndexController extends AbstractController
|
|||||||
return $this->redirectToRoute('app_bookings');
|
return $this->redirectToRoute('app_bookings');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->bookingConfigurator->preselectDefaultServices($bookingDto);
|
||||||
|
$this->bookingSessionService->saveBookingDto($request, $bookingDto, BookingDto::MODE_EDIT);
|
||||||
|
|
||||||
// Show flash message if draft was restored
|
// Show flash message if draft was restored
|
||||||
if (true === $this->dataLoader->isDraftRestored()) {
|
if (true === $this->dataLoader->isDraftRestored()) {
|
||||||
$this->addFlash('info', 'Dein zuvor gespeicherter Entwurf wurde wiederhergestellt.');
|
$this->addFlash('info', 'Dein zuvor gespeicherter Entwurf wurde wiederhergestellt.');
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use App\Htmx\HxTrait;
|
|||||||
use App\Service\BookingEditContextFactory;
|
use App\Service\BookingEditContextFactory;
|
||||||
use App\Service\BookingEditDataLoader;
|
use App\Service\BookingEditDataLoader;
|
||||||
use App\Service\BookingEditDraftManager;
|
use App\Service\BookingEditDraftManager;
|
||||||
|
use App\Service\BookingConfigurator;
|
||||||
use App\Service\ParticipantDataPrefiller;
|
use App\Service\ParticipantDataPrefiller;
|
||||||
use App\Service\BookingSessionManager;
|
use App\Service\BookingSessionManager;
|
||||||
use App\Service\ParticipantFormSupport;
|
use App\Service\ParticipantFormSupport;
|
||||||
@@ -34,6 +35,7 @@ class ParticipantController extends AbstractController
|
|||||||
private readonly BookingEditDataLoader $dataLoader,
|
private readonly BookingEditDataLoader $dataLoader,
|
||||||
private readonly BookingEditDraftManager $draftService,
|
private readonly BookingEditDraftManager $draftService,
|
||||||
private readonly BookingEditContextFactory $editContextFactory,
|
private readonly BookingEditContextFactory $editContextFactory,
|
||||||
|
private readonly BookingConfigurator $bookingConfigurator,
|
||||||
private readonly BookingSessionManager $bookingSessionService,
|
private readonly BookingSessionManager $bookingSessionService,
|
||||||
private readonly ParticipantDataPrefiller $prepopulationService,
|
private readonly ParticipantDataPrefiller $prepopulationService,
|
||||||
private readonly ParticipantFormSupport $participantFormSupportService,
|
private readonly ParticipantFormSupport $participantFormSupportService,
|
||||||
@@ -148,6 +150,15 @@ class ParticipantController extends AbstractController
|
|||||||
|
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
$this->bookingConfigurator->preselectDefaultServices($bookingDto);
|
||||||
|
$this->bookingSessionService->saveBookingDto($request, $bookingDto, BookingDto::MODE_EDIT);
|
||||||
|
|
||||||
|
$form = $this->createForm(
|
||||||
|
BookingParticipantType::class,
|
||||||
|
$this->participantFormSupportService->createParticipantEditDto($bookingDto, $index),
|
||||||
|
$this->participantFormSupportService->getParticipantFormOptions($bookingDto, true)
|
||||||
|
);
|
||||||
|
|
||||||
$notifications = $this->participantFormSupportService->collectAndClearNotifications($bookingDto);
|
$notifications = $this->participantFormSupportService->collectAndClearNotifications($bookingDto);
|
||||||
$context = $this->editContextFactory->createParticipantContext(
|
$context = $this->editContextFactory->createParticipantContext(
|
||||||
$bookingDto,
|
$bookingDto,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use App\Form\Model\ParticipantCardDataDto;
|
|||||||
use App\Form\Model\ParticipantCardPriceDto;
|
use App\Form\Model\ParticipantCardPriceDto;
|
||||||
use App\Model\BookingEditSubmissionResult;
|
use App\Model\BookingEditSubmissionResult;
|
||||||
use App\Service\BookingChangeTracker;
|
use App\Service\BookingChangeTracker;
|
||||||
|
use App\Service\BookingConfigurator;
|
||||||
use App\Service\BookingEditContextFactory;
|
use App\Service\BookingEditContextFactory;
|
||||||
use App\Service\BookingEditDataLoader;
|
use App\Service\BookingEditDataLoader;
|
||||||
use App\Service\BookingEditDraftManager;
|
use App\Service\BookingEditDraftManager;
|
||||||
@@ -81,6 +82,16 @@ class IndexControllerTest extends TestCase
|
|||||||
->method('isDraftRestored')
|
->method('isDraftRestored')
|
||||||
->willReturn(false);
|
->willReturn(false);
|
||||||
|
|
||||||
|
$bookingSessionService = $this->createMock(BookingSessionManager::class);
|
||||||
|
$bookingSessionService->expects($this->once())
|
||||||
|
->method('saveBookingDto')
|
||||||
|
->with($request, $bookingDto, BookingDto::MODE_EDIT);
|
||||||
|
|
||||||
|
$bookingConfigurator = $this->createMock(BookingConfigurator::class);
|
||||||
|
$bookingConfigurator->expects($this->once())
|
||||||
|
->method('preselectDefaultServices')
|
||||||
|
->with($bookingDto);
|
||||||
|
|
||||||
$preflightChecker = $this->createMock(BookingEditPreFlightChecker::class);
|
$preflightChecker = $this->createMock(BookingEditPreFlightChecker::class);
|
||||||
$preflightChecker->expects($this->once())
|
$preflightChecker->expects($this->once())
|
||||||
->method('findMissingValueLabelsByParticipantIndex')
|
->method('findMissingValueLabelsByParticipantIndex')
|
||||||
@@ -96,8 +107,9 @@ class IndexControllerTest extends TestCase
|
|||||||
$controller = new TestableIndexController(
|
$controller = new TestableIndexController(
|
||||||
$dataLoader,
|
$dataLoader,
|
||||||
$this->createMock(BookingEditDraftManager::class),
|
$this->createMock(BookingEditDraftManager::class),
|
||||||
$this->createMock(BookingSessionManager::class),
|
$bookingSessionService,
|
||||||
$fingerprintService,
|
$fingerprintService,
|
||||||
|
$bookingConfigurator,
|
||||||
$contextFactory,
|
$contextFactory,
|
||||||
$preflightChecker,
|
$preflightChecker,
|
||||||
$this->createMock(BookingEditSubmitter::class),
|
$this->createMock(BookingEditSubmitter::class),
|
||||||
@@ -170,6 +182,7 @@ class IndexControllerTest extends TestCase
|
|||||||
$this->createMock(BookingEditDraftManager::class),
|
$this->createMock(BookingEditDraftManager::class),
|
||||||
$this->createMock(BookingSessionManager::class),
|
$this->createMock(BookingSessionManager::class),
|
||||||
$fingerprintService,
|
$fingerprintService,
|
||||||
|
$this->createMock(BookingConfigurator::class),
|
||||||
$contextFactory,
|
$contextFactory,
|
||||||
$preflightChecker,
|
$preflightChecker,
|
||||||
$this->createMock(BookingEditSubmitter::class),
|
$this->createMock(BookingEditSubmitter::class),
|
||||||
@@ -253,6 +266,7 @@ class IndexControllerTest extends TestCase
|
|||||||
$this->createMock(BookingEditDraftManager::class),
|
$this->createMock(BookingEditDraftManager::class),
|
||||||
$this->createMock(BookingSessionManager::class),
|
$this->createMock(BookingSessionManager::class),
|
||||||
$fingerprintService,
|
$fingerprintService,
|
||||||
|
$this->createMock(BookingConfigurator::class),
|
||||||
$contextFactory,
|
$contextFactory,
|
||||||
$preflightChecker,
|
$preflightChecker,
|
||||||
$submitter,
|
$submitter,
|
||||||
@@ -335,6 +349,7 @@ class IndexControllerTest extends TestCase
|
|||||||
$this->createMock(BookingEditDraftManager::class),
|
$this->createMock(BookingEditDraftManager::class),
|
||||||
$this->createMock(BookingSessionManager::class),
|
$this->createMock(BookingSessionManager::class),
|
||||||
$fingerprintService,
|
$fingerprintService,
|
||||||
|
$this->createMock(BookingConfigurator::class),
|
||||||
$contextFactory,
|
$contextFactory,
|
||||||
$preflightChecker,
|
$preflightChecker,
|
||||||
$submitter,
|
$submitter,
|
||||||
@@ -526,6 +541,7 @@ class IndexControllerTest extends TestCase
|
|||||||
$this->createMock(BookingEditDraftManager::class),
|
$this->createMock(BookingEditDraftManager::class),
|
||||||
$this->createMock(BookingSessionManager::class),
|
$this->createMock(BookingSessionManager::class),
|
||||||
$fingerprintService,
|
$fingerprintService,
|
||||||
|
$this->createMock(BookingConfigurator::class),
|
||||||
$this->createMock(BookingEditContextFactory::class),
|
$this->createMock(BookingEditContextFactory::class),
|
||||||
$preflightChecker,
|
$preflightChecker,
|
||||||
$submitter,
|
$submitter,
|
||||||
@@ -566,6 +582,7 @@ final class TestableIndexController extends IndexController
|
|||||||
BookingEditDraftManager $draftService,
|
BookingEditDraftManager $draftService,
|
||||||
BookingSessionManager $bookingSessionService,
|
BookingSessionManager $bookingSessionService,
|
||||||
BookingChangeTracker $fingerprintService,
|
BookingChangeTracker $fingerprintService,
|
||||||
|
BookingConfigurator $bookingService,
|
||||||
BookingEditContextFactory $editContextFactory,
|
BookingEditContextFactory $editContextFactory,
|
||||||
BookingEditPreFlightChecker $preFlightChecker,
|
BookingEditPreFlightChecker $preFlightChecker,
|
||||||
BookingEditSubmitter $formSubmitter,
|
BookingEditSubmitter $formSubmitter,
|
||||||
@@ -579,6 +596,7 @@ final class TestableIndexController extends IndexController
|
|||||||
$draftService,
|
$draftService,
|
||||||
$bookingSessionService,
|
$bookingSessionService,
|
||||||
$fingerprintService,
|
$fingerprintService,
|
||||||
|
$bookingService,
|
||||||
$editContextFactory,
|
$editContextFactory,
|
||||||
$preFlightChecker,
|
$preFlightChecker,
|
||||||
$formSubmitter,
|
$formSubmitter,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use App\Form\Model\BookingEditContext;
|
|||||||
use App\Form\Model\BookingSummaryDto;
|
use App\Form\Model\BookingSummaryDto;
|
||||||
use App\Form\Model\ParticipantDto;
|
use App\Form\Model\ParticipantDto;
|
||||||
use App\Form\Model\ParticipantEditDto;
|
use App\Form\Model\ParticipantEditDto;
|
||||||
|
use App\Service\BookingConfigurator;
|
||||||
use App\Service\BookingEditContextFactory;
|
use App\Service\BookingEditContextFactory;
|
||||||
use App\Service\BookingEditDataLoader;
|
use App\Service\BookingEditDataLoader;
|
||||||
use App\Service\BookingEditDraftManager;
|
use App\Service\BookingEditDraftManager;
|
||||||
@@ -26,6 +27,7 @@ use Carbon\CarbonImmutable;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\Form\FormView;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
@@ -126,6 +128,7 @@ class ParticipantControllerTest extends TestCase
|
|||||||
$dataLoader,
|
$dataLoader,
|
||||||
$draftService,
|
$draftService,
|
||||||
$contextFactory,
|
$contextFactory,
|
||||||
|
$this->createMock(BookingConfigurator::class),
|
||||||
$bookingSessionService,
|
$bookingSessionService,
|
||||||
$prepopulationService,
|
$prepopulationService,
|
||||||
$participantFormSupportService,
|
$participantFormSupportService,
|
||||||
@@ -145,6 +148,109 @@ class ParticipantControllerTest extends TestCase
|
|||||||
$this->assertSame(BookingParticipantType::class, $controller->createdFormTypes[1]);
|
$this->assertSame(BookingParticipantType::class, $controller->createdFormTypes[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRefreshPreselectsDefaultServicesAndRerendersParticipantForm(): void
|
||||||
|
{
|
||||||
|
$request = Request::create('/bookings/42/edit/participants/0/refresh', 'POST');
|
||||||
|
$user = $this->createUser();
|
||||||
|
$bookingDto = $this->createBookingDto();
|
||||||
|
$bookingData = $this->createBooking();
|
||||||
|
$participant = $bookingDto->participants[0];
|
||||||
|
|
||||||
|
$form = $this->createMock(FormInterface::class);
|
||||||
|
$form->expects($this->once())
|
||||||
|
->method('handleRequest')
|
||||||
|
->with($request)
|
||||||
|
->willReturnSelf();
|
||||||
|
$form->expects($this->once())
|
||||||
|
->method('createView')
|
||||||
|
->willReturn(new FormView());
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$bookingConfigurator = $this->createMock(BookingConfigurator::class);
|
||||||
|
$bookingConfigurator->expects($this->once())
|
||||||
|
->method('preselectDefaultServices')
|
||||||
|
->with($bookingDto);
|
||||||
|
|
||||||
|
$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, true)
|
||||||
|
->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,
|
||||||
|
],
|
||||||
|
'validation_groups' => false,
|
||||||
|
]);
|
||||||
|
$participantFormSupportService->expects($this->once())
|
||||||
|
->method('collectAndClearNotifications')
|
||||||
|
->with($bookingDto)
|
||||||
|
->willReturn([]);
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$prepopulationService = new ParticipantDataPrefiller(
|
||||||
|
$this->createMock(ApiClient::class),
|
||||||
|
$this->createMock(Crypt::class),
|
||||||
|
$this->createMock(LoggerInterface::class),
|
||||||
|
);
|
||||||
|
|
||||||
|
$controller = new TestableParticipantController(
|
||||||
|
$dataLoader,
|
||||||
|
$this->createMock(BookingEditDraftManager::class),
|
||||||
|
$contextFactory,
|
||||||
|
$bookingConfigurator,
|
||||||
|
$bookingSessionService,
|
||||||
|
$prepopulationService,
|
||||||
|
$participantFormSupportService,
|
||||||
|
$user,
|
||||||
|
$form,
|
||||||
|
);
|
||||||
|
|
||||||
|
$response = $controller->refreshParticipantForm(42, 0, $request);
|
||||||
|
|
||||||
|
$this->assertSame(200, $response->getStatusCode());
|
||||||
|
$this->assertSame([BookingParticipantType::class, BookingParticipantType::class], $controller->createdFormTypes);
|
||||||
|
$this->assertSame(['participant_form', 'booking_summary'], $controller->renderedBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
private function createUser(): User
|
private function createUser(): User
|
||||||
{
|
{
|
||||||
return new User('[email protected]');
|
return new User('[email protected]');
|
||||||
@@ -184,6 +290,11 @@ final class TestableParticipantController extends ParticipantController
|
|||||||
|
|
||||||
public ?string $renderTemplate = null;
|
public ?string $renderTemplate = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var list<string>
|
||||||
|
*/
|
||||||
|
public array $renderedBlocks = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<string, mixed>
|
* @var array<string, mixed>
|
||||||
*/
|
*/
|
||||||
@@ -201,6 +312,7 @@ final class TestableParticipantController extends ParticipantController
|
|||||||
BookingEditDataLoader $dataLoader,
|
BookingEditDataLoader $dataLoader,
|
||||||
BookingEditDraftManager $draftService,
|
BookingEditDraftManager $draftService,
|
||||||
BookingEditContextFactory $editContextFactory,
|
BookingEditContextFactory $editContextFactory,
|
||||||
|
BookingConfigurator $bookingService,
|
||||||
BookingSessionManager $bookingSessionService,
|
BookingSessionManager $bookingSessionService,
|
||||||
ParticipantDataPrefiller $prepopulationService,
|
ParticipantDataPrefiller $prepopulationService,
|
||||||
ParticipantFormSupport $participantFormSupportService,
|
ParticipantFormSupport $participantFormSupportService,
|
||||||
@@ -213,6 +325,7 @@ final class TestableParticipantController extends ParticipantController
|
|||||||
$dataLoader,
|
$dataLoader,
|
||||||
$draftService,
|
$draftService,
|
||||||
$editContextFactory,
|
$editContextFactory,
|
||||||
|
$bookingService,
|
||||||
$bookingSessionService,
|
$bookingSessionService,
|
||||||
$prepopulationService,
|
$prepopulationService,
|
||||||
$participantFormSupportService,
|
$participantFormSupportService,
|
||||||
@@ -256,4 +369,14 @@ final class TestableParticipantController extends ParticipantController
|
|||||||
|
|
||||||
return new Response('');
|
return new Response('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $parameters
|
||||||
|
*/
|
||||||
|
protected function renderBlockView(string $view, string $block, array $parameters = []): string
|
||||||
|
{
|
||||||
|
$this->renderedBlocks[] = $block;
|
||||||
|
|
||||||
|
return '<div></div>';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user