fix: false draft-restored message

This commit is contained in:
Björn Fromme
2026-08-31 09:31:00 +02:00
parent bfad61f1dd
commit 81b724c11a
4 changed files with 244 additions and 5 deletions
@@ -52,6 +52,7 @@ class ParticipantControllerTest extends TestCase
$bookingDto = $this->createBookingDto();
$bookingData = $this->createBooking();
$participant = $bookingDto->participants[0];
$bookingDto->originalFingerprint = (new BookingChangeTracker())->generateFingerprint($bookingDto);
$participant->lastName = ParticipantDataPrefiller::TOKEN;
$form = $this->createMock(FormInterface::class);
@@ -254,6 +255,96 @@ class ParticipantControllerTest extends TestCase
$this->assertSame(['participant_form', 'booking_summary'], $controller->renderedBlocks);
}
/**
* Regression: saving the participant form without touching anything used to write a
* draft identical to the API state. The overview then reloaded from the API, found
* that draft, applied it and told the user their draft had been restored — for edits
* they never made.
*/
public function testSubmitWithoutChangesDeletesDraftInsteadOfSavingIt(): void
{
$draftService = $this->createMock(BookingEditDraftManager::class);
$draftService->expects($this->never())->method('saveDraft');
$draftService->expects($this->once())->method('deleteDraft')->with($this->isInstanceOf(User::class), 42);
$this->runValidSubmit($draftService, dirty: false);
}
public function testSubmitWithChangesPersistsDraft(): void
{
$draftService = $this->createMock(BookingEditDraftManager::class);
$draftService->expects($this->once())->method('saveDraft');
$draftService->expects($this->never())->method('deleteDraft');
$this->runValidSubmit($draftService, dirty: true);
}
/**
* Drives editParticipant() through a valid, non-dummy submit.
*/
private function runValidSubmit(BookingEditDraftManager $draftService, bool $dirty): void
{
$request = Request::create('/bookings/42/edit/participants/0', 'POST');
$user = $this->createUser();
$bookingDto = $this->createBookingDto();
$bookingData = $this->createBooking();
$participant = $bookingDto->participants[0];
$participant->firstName = 'Anna';
$bookingDto->originalFingerprint = (new BookingChangeTracker())->generateFingerprint($bookingDto);
if (true === $dirty) {
$participant->firstName = 'Berta';
}
$form = $this->createStub(FormInterface::class);
$form->method('handleRequest')->willReturnSelf();
$form->method('isSubmitted')->willReturn(true);
$form->method('isValid')->willReturn(true);
$dataLoader = $this->createStub(BookingEditDataLoader::class);
$dataLoader->method('fetchBookingData')->willReturn($bookingData);
$bookingSessionService = $this->createMock(BookingSessionManager::class);
$bookingSessionService->method('getBookingDto')->willReturn($bookingDto);
$bookingSessionService->expects($this->once())
->method('saveBookingDto')
->with($request, $bookingDto, BookingDto::MODE_EDIT);
$participantFormSupportService = $this->createStub(ParticipantFormSupport::class);
$participantFormSupportService->method('ensureParticipantExists')->willReturn($participant);
$participantFormSupportService->method('createParticipantEditDto')
->willReturn(new ParticipantEditDto($participant, $bookingDto));
$participantFormSupportService->method('getParticipantFormOptions')
->willReturn(['booking_context' => $bookingDto]);
$participantFormSupportService->method('collectAndClearNotifications')->willReturn([]);
$contextFactory = $this->createStub(BookingEditContextFactory::class);
$contextFactory->method('createParticipantContext')->willReturn(
new BookingEditContext($bookingDto, $bookingData, null, $this->createStub(BookingSummaryDto::class))
);
$controller = new TestableParticipantController(
$dataLoader,
$draftService,
$contextFactory,
$this->createStub(BookingConfigurator::class),
$bookingSessionService,
new ParticipantDataPrefiller(
$this->createStub(ApiClient::class),
$this->createStub(Crypt::class),
$this->createStub(LoggerInterface::class),
),
$participantFormSupportService,
$user,
$form,
);
$response = $controller->editParticipant(42, 0, $request);
$this->assertInstanceOf(RedirectResponse::class, $response);
}
private function createUser(): User
{
return new User('[email protected]');
@@ -445,6 +536,7 @@ final class TestableParticipantController extends ParticipantController
$draftService,
$editContextFactory,
$bookingService,
new BookingChangeTracker(),
$bookingSessionService,
$prepopulationService,
$participantFormSupportService,