fix: enforce submit-time immutability, scope booking cache per user
This commit is contained in:
@@ -84,7 +84,6 @@ class BookingEditDraftServiceMutabilityTest extends TestCase
|
||||
$this->assertSame([], $participant->rentals);
|
||||
$this->assertNull($participant->skiPass);
|
||||
$this->assertNull($participant->rentalInsurance);
|
||||
$this->assertTrue($this->service->hadImmutableSkips());
|
||||
}
|
||||
|
||||
public function testDraftAppliesAdditionalServicesWhenMutable(): void
|
||||
@@ -127,7 +126,6 @@ class BookingEditDraftServiceMutabilityTest extends TestCase
|
||||
$skiPass = $participant->skiPass;
|
||||
$this->assertNotNull($skiPass);
|
||||
$this->assertSame(99, $skiPass?->id);
|
||||
$this->assertFalse($this->service->hadImmutableSkips());
|
||||
}
|
||||
|
||||
// --- Transportation Mutability ---
|
||||
@@ -171,7 +169,6 @@ class BookingEditDraftServiceMutabilityTest extends TestCase
|
||||
$this->assertSame($originalOutbound, $participant->transportationOutbound);
|
||||
$this->assertSame($originalInbound, $participant->transportationInbound);
|
||||
$this->assertFalse($participant->parking);
|
||||
$this->assertTrue($this->service->hadImmutableSkips());
|
||||
}
|
||||
|
||||
public function testDraftAppliesTransportationWhenMutable(): void
|
||||
@@ -242,7 +239,6 @@ class BookingEditDraftServiceMutabilityTest extends TestCase
|
||||
$this->assertSame($originalPickup, $participant->pickup);
|
||||
$this->assertNull($participant->dropOff);
|
||||
$this->assertFalse($participant->differentDropOff);
|
||||
$this->assertTrue($this->service->hadImmutableSkips());
|
||||
}
|
||||
|
||||
public function testDraftAppliesPickupsWhenMutable(): void
|
||||
@@ -353,7 +349,6 @@ class BookingEditDraftServiceMutabilityTest extends TestCase
|
||||
|
||||
// Pickups: mutable → draft applied
|
||||
$this->assertSame($draftPickup, $participant->pickup);
|
||||
$this->assertTrue($this->service->hadImmutableSkips());
|
||||
}
|
||||
|
||||
// --- Personal data draft restore respects edit mutability rules ---
|
||||
@@ -384,7 +379,6 @@ class BookingEditDraftServiceMutabilityTest extends TestCase
|
||||
$this->service->applyDraftToDto($draft, $dto, $travel);
|
||||
|
||||
$this->assertSame('Original', $participant->firstName);
|
||||
$this->assertTrue($this->service->hadImmutableSkips());
|
||||
}
|
||||
|
||||
public function testDraftAppliesPersonalDataForMutableNonFirstParticipant(): void
|
||||
@@ -412,45 +406,6 @@ class BookingEditDraftServiceMutabilityTest extends TestCase
|
||||
$this->service->applyDraftToDto($draft, $dto, $travel);
|
||||
|
||||
$this->assertSame('Updated', $mutableParticipant->firstName);
|
||||
$this->assertFalse($this->service->hadImmutableSkips());
|
||||
}
|
||||
|
||||
public function testDraftDoesNotFlagImmutableSkipWhenImmutableServiceStateMatchesDraft(): void
|
||||
{
|
||||
$originalService = $this->createService(10, 'Original');
|
||||
$participant = new ParticipantDto();
|
||||
$participant->additionalServices = [$originalService];
|
||||
$participant->courses = [];
|
||||
$participant->board = [];
|
||||
$participant->rentals = [];
|
||||
$participant->skiPass = null;
|
||||
$participant->rentalInsurance = null;
|
||||
|
||||
$travel = $this->createTravel(
|
||||
additionalServicesMutable: false,
|
||||
additionalServices: [10 => $originalService],
|
||||
);
|
||||
|
||||
$dto = $this->createBookingDto($travel, [$participant]);
|
||||
|
||||
$draft = $this->createDraft([
|
||||
'participants' => [
|
||||
0 => [
|
||||
'services' => [
|
||||
'additionalServices' => [10],
|
||||
'courses' => [],
|
||||
'board' => [],
|
||||
'rentals' => [],
|
||||
'skiPass' => null,
|
||||
'rentalInsurance' => null,
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->service->applyDraftToDto($draft, $dto, $travel);
|
||||
|
||||
$this->assertFalse($this->service->hadImmutableSkips());
|
||||
}
|
||||
|
||||
// --- Helpers ---
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Service;
|
||||
|
||||
use App\BusProNet\DataProcessor\BookingDataProcessor;
|
||||
use App\BusProNet\Model\Booking;
|
||||
use App\BusProNet\Model\Pickup;
|
||||
use App\BusProNet\Model\Service;
|
||||
use App\BusProNet\Model\Travel;
|
||||
use App\Form\Model\BookingDto;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
use App\Service\BookingEditSubmitGuardService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class BookingEditSubmitGuardServiceTest extends TestCase
|
||||
{
|
||||
public function testReconcileImmutableCategoriesRestoresLockedServiceData(): void
|
||||
{
|
||||
$travel = new Travel();
|
||||
$travel->additionalServicesMutable = false;
|
||||
$travel->transportationServicesMutable = false;
|
||||
$travel->pickupsMutable = false;
|
||||
|
||||
$workingParticipant = new ParticipantDto();
|
||||
$workingParticipant->index = 0;
|
||||
$workingParticipant->additionalServices = [$this->createService(99)];
|
||||
$workingParticipant->transportationOutbound = $this->createService(88);
|
||||
$workingParticipant->pickup = $this->createPickup(77);
|
||||
|
||||
$workingDto = new BookingDto($travel, 1);
|
||||
$workingDto->participants = [$workingParticipant];
|
||||
|
||||
$baselineParticipant = new ParticipantDto();
|
||||
$baselineParticipant->index = 0;
|
||||
$baselineParticipant->additionalServices = [$this->createService(10)];
|
||||
$baselineParticipant->transportationOutbound = $this->createService(20);
|
||||
$baselineParticipant->pickup = $this->createPickup(30);
|
||||
|
||||
$baselineDto = new BookingDto($travel, 1);
|
||||
$baselineDto->participants = [$baselineParticipant];
|
||||
|
||||
$processor = $this->createMock(BookingDataProcessor::class);
|
||||
$processor->expects($this->once())
|
||||
->method('createBookingDtoFromBooking')
|
||||
->willReturn($baselineDto);
|
||||
|
||||
$service = new BookingEditSubmitGuardService($processor);
|
||||
|
||||
$changed = $service->reconcileImmutableCategories($workingDto, new Booking());
|
||||
|
||||
$this->assertTrue($changed);
|
||||
$this->assertSame([10], array_map(static fn (Service $s) => $s->id, $workingParticipant->additionalServices));
|
||||
$this->assertSame(20, $workingParticipant->transportationOutbound?->id);
|
||||
$this->assertSame(30, $workingParticipant->pickup?->id);
|
||||
}
|
||||
|
||||
public function testReconcileImmutableCategoriesDoesNotChangeMutableCategories(): void
|
||||
{
|
||||
$travel = new Travel();
|
||||
$travel->additionalServicesMutable = true;
|
||||
$travel->transportationServicesMutable = true;
|
||||
$travel->pickupsMutable = true;
|
||||
|
||||
$workingParticipant = new ParticipantDto();
|
||||
$workingParticipant->index = 0;
|
||||
$workingParticipant->additionalServices = [$this->createService(99)];
|
||||
|
||||
$workingDto = new BookingDto($travel, 1);
|
||||
$workingDto->participants = [$workingParticipant];
|
||||
|
||||
$baselineParticipant = new ParticipantDto();
|
||||
$baselineParticipant->index = 0;
|
||||
$baselineParticipant->additionalServices = [$this->createService(10)];
|
||||
|
||||
$baselineDto = new BookingDto($travel, 1);
|
||||
$baselineDto->participants = [$baselineParticipant];
|
||||
|
||||
$processor = $this->createMock(BookingDataProcessor::class);
|
||||
$processor->expects($this->once())
|
||||
->method('createBookingDtoFromBooking')
|
||||
->willReturn($baselineDto);
|
||||
|
||||
$service = new BookingEditSubmitGuardService($processor);
|
||||
|
||||
$changed = $service->reconcileImmutableCategories($workingDto, new Booking());
|
||||
|
||||
$this->assertFalse($changed);
|
||||
$this->assertSame([99], array_map(static fn (Service $s) => $s->id, $workingParticipant->additionalServices));
|
||||
}
|
||||
|
||||
private function createService(int $id): Service
|
||||
{
|
||||
$service = new Service();
|
||||
$service->id = $id;
|
||||
|
||||
return $service;
|
||||
}
|
||||
|
||||
private function createPickup(int $id): Pickup
|
||||
{
|
||||
$pickup = new Pickup();
|
||||
$pickup->id = $id;
|
||||
|
||||
return $pickup;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user