condition = new InsuranceMutabilityCondition(); // Set a fixed "now" for time-dependent tests Carbon::setTestNow('2025-01-15 12:00:00'); } protected function tearDown(): void { // Reset Carbon's test time after each test Carbon::setTestNow(); } public function testAlwaysEditableInCreateFlow(): void { $travel = new Travel(); $travel->dateFrom = new \DateTimeImmutable('+10 days'); $bookingDto = new BookingDto($travel, 123); $result = $this->condition->evaluate($bookingDto, 0, []); $this->assertFalse($result, 'Insurance should always be editable in create flow'); } public function testReadonlyWhen40DaysBeforeTravel(): void { // Now is 2025-01-15, travel is 40 days later: 2025-02-24 $travelDate = new \DateTimeImmutable('2025-02-24 12:00:00'); $bookingDate = new \DateTimeImmutable('2025-01-05 12:00:00'); $bookingDto = $this->createEditDto($travelDate, $bookingDate); $result = $this->condition->evaluate($bookingDto, 0, []); $this->assertTrue($result, 'Insurance should be readonly in edit mode (API limitation)'); } public function testReadonlyWhenExactly30DaysBeforeTravel(): void { // Now is fixed at 2025-01-15 12:00:00 // Travel date exactly 30 days later: 2025-02-14 12:00:00 $travelDate = new \DateTimeImmutable('2025-02-14 12:00:00'); $bookingDate = new \DateTimeImmutable('2024-12-20 12:00:00'); $bookingDto = $this->createEditDto($travelDate, $bookingDate); $result = $this->condition->evaluate($bookingDto, 0, []); $this->assertTrue($result, 'Insurance should be readonly in edit mode (API limitation)'); } public function testReadonlyWhen20DaysBeforeTravel(): void { // Now is 2025-01-15, travel is 20 days later: 2025-02-04 $travelDate = new \DateTimeImmutable('2025-02-04 12:00:00'); $bookingDate = new \DateTimeImmutable('2025-01-05 12:00:00'); $bookingDto = $this->createEditDto($travelDate, $bookingDate); $result = $this->condition->evaluate($bookingDto, 0, []); $this->assertTrue($result, 'Insurance should be readonly when 20 days before travel (standard case)'); } public function testReadonlyWhen2DaysAfterLateBooking(): void { // Now is 2025-01-15, booking was 2 days ago: 2025-01-13 // Travel is 15 days after booking: 2025-01-28 (late booking) $bookingDate = new \DateTimeImmutable('2025-01-13 12:00:00'); $travelDate = new \DateTimeImmutable('2025-01-28 12:00:00'); $bookingDto = $this->createEditDto($travelDate, $bookingDate); $result = $this->condition->evaluate($bookingDto, 0, []); $this->assertTrue($result, 'Insurance should be readonly in edit mode (API limitation)'); } public function testReadonlyWhenExactly3DaysAfterLateBooking(): void { // Now is 2025-01-15, booking was exactly 3 days ago: 2025-01-12 // Travel is 15 days after booking: 2025-01-27 (late booking) $bookingDate = new \DateTimeImmutable('2025-01-12 12:00:00'); $travelDate = new \DateTimeImmutable('2025-01-27 12:00:00'); $bookingDto = $this->createEditDto($travelDate, $bookingDate); $result = $this->condition->evaluate($bookingDto, 0, []); $this->assertTrue($result, 'Insurance should be readonly in edit mode (API limitation)'); } public function testReadonlyWhen5DaysAfterLateBooking(): void { // Now is 2025-01-15, booking was 5 days ago: 2025-01-10 // Travel is 15 days after booking: 2025-01-25 (late booking) $bookingDate = new \DateTimeImmutable('2025-01-10 12:00:00'); $travelDate = new \DateTimeImmutable('2025-01-25 12:00:00'); $bookingDto = $this->createEditDto($travelDate, $bookingDate); $result = $this->condition->evaluate($bookingDto, 0, []); $this->assertTrue($result, 'Insurance should be readonly 5 days after late booking'); } public function testReadonlyWhenTravelDatePassed(): void { // Now is 2025-01-15, travel was 5 days ago: 2025-01-10 $travelDate = new \DateTimeImmutable('2025-01-10 12:00:00'); $bookingDate = new \DateTimeImmutable('2024-12-01 12:00:00'); $bookingDto = $this->createEditDto($travelDate, $bookingDate); $result = $this->condition->evaluate($bookingDto, 0, []); $this->assertTrue($result, 'Insurance should be readonly when travel date has passed'); } public function testGetDependentFieldsReturnsEmptyArray(): void { $result = $this->condition->getDependentFields(); $this->assertIsArray($result); $this->assertEmpty($result, 'Insurance mutability has no field dependencies'); } public function testGetDescriptionReturnsString(): void { $result = $this->condition->getDescription(); $this->assertIsString($result); $this->assertStringContainsString('not editable', $result); $this->assertStringContainsString('edit mode', $result); } private function createEditDto(\DateTimeImmutable $travelDate, \DateTimeImmutable $bookingDate): BookingDto { $booking = new Booking(); $booking->bookingDate = $bookingDate; $travel = new Travel(); $travel->dateFrom = $travelDate; $bookingDto = new BookingDto($travel, 1); $bookingDto->booking = $booking; return $bookingDto; } }