@@ -629,12 +629,27 @@ def test_gap_time_blocks_slot_immediately_after_appointment(self):
629629 def test_gap_time_slot_after_gap_window_is_available (self ):
630630 """A slot starting after appointment_end + gap_time is available."""
631631 appt = self ._make_appointment (datetime .time (9 , 0 ), datetime .time (10 , 0 ), service = self .service1 )
632- # 30-min gap → effective blocked range is [9:00, 10:30)
633- # slot 10:30 is at the boundary: slot < (10:00 + 30min) is False → available
632+ # 30-min gap applied on both sides:
633+ # gap-after: slot 10:00-10:30 is blocked (10:00 < 10:00+30min)
634+ # slot 10:30: slot(10:30) < 10:30 is False → available
634635 result = exclude_booked_slots ([appt ], self .slots , self .slot_duration , gap_time = 30 )
635636 slot_10_30 = datetime .datetime .combine (self .today , datetime .time (10 , 30 ))
636637 self .assertIn (slot_10_30 , result )
637638
639+ def test_gap_time_blocks_slot_ending_within_gap_before_appointment (self ):
640+ """A slot whose end falls within the gap window before an appointment starts is blocked.
641+ Covers the pre-appointment side of the gap (reviewer comment).
642+ """
643+ # Appointment starts at 10:30. slot_duration=30min, so slot 10:00→10:30 ends exactly at 10:30.
644+ # With a 30-min gap: slot_end(10:30) + gap(30min) = 11:00 > appointment_start(10:30) → blocked.
645+ appt = self ._make_appointment (datetime .time (10 , 30 ), datetime .time (11 , 30 ), service = self .service1 )
646+ result = exclude_booked_slots ([appt ], self .slots , self .slot_duration , gap_time = 30 )
647+ slot_10_00 = datetime .datetime .combine (self .today , datetime .time (10 , 0 ))
648+ self .assertNotIn (slot_10_00 , result )
649+ # slot 9:30 → slot_end 10:00 + gap 30min = 10:30; 10:30 < 10:30 is False → available
650+ slot_9_30 = datetime .datetime .combine (self .today , datetime .time (9 , 30 ))
651+ self .assertIn (slot_9_30 , result )
652+
638653 def test_gap_time_zero_no_effect (self ):
639654 """gap_time=0 has no effect compared to gap_time=None."""
640655 appt = self ._make_appointment (datetime .time (9 , 0 ), datetime .time (10 , 0 ), service = self .service1 )
@@ -644,21 +659,23 @@ def test_gap_time_zero_no_effect(self):
644659
645660 def test_combined_service_duration_and_gap_time (self ):
646661 """service_duration and gap_time can be used together."""
647- # 1-hr appointment at 10:00-11:00, 1-hr service_duration, 30-min gap
662+ # 1-hr appointment at 10:00-11:00, 1-hr service_duration, 30-min gap (both sides)
648663 appt = self ._make_appointment (datetime .time (10 , 0 ), datetime .time (11 , 0 ), service = self .service1 )
649664 service_duration = datetime .timedelta (hours = 1 )
650- # Effective: check_duration=1hr, gap= 30min, so slot < 11:30 is blocked if slot+ 1hr > 10:00
651- # slot 9:30 → [9:30, 10:30] > 10:00 → blocked
652- # slot 10:00 → blocked (inside appointment )
653- # slot 10 :30 → slot( 10:30) < 11:30 and [10 :30,11:30] > 10:00 → blocked
654- # slot 11 :00 → slot( 11:00) < 11:30 → blocked
655- # slot 11:30 → slot(11:30) not < 11:30 → available
665+ # check_duration = max( 30min, 1hr) = 1hr; gap = 30min
666+ # blocked if: appointment_start( 10:00) < slot_end+gap AND slot < appointment_end(11:00)+gap(11:30)
667+ # slot 9:00 → slot_end= 10:00; 10:00 < 10:30=True; 9:00 < 11:30=True → blocked (pre-gap )
668+ # slot 9 :30 → slot_end= 10:30; 10:00 < 11:00=True; 9 :30 < 11:30=True → blocked
669+ # slot 10 :00, 10:30, 11:00 → blocked (inside/near appointment)
670+ # slot 11:30 → slot(11:30) < 11:30 is False → available
656671 result = exclude_booked_slots ([appt ], self .slots , self .slot_duration ,
657672 service_duration = service_duration , gap_time = 30 )
658673 slot_11_30 = datetime .datetime .combine (self .today , datetime .time (11 , 30 ))
659674 self .assertIn (slot_11_30 , result )
660675 slot_10_30 = datetime .datetime .combine (self .today , datetime .time (10 , 30 ))
661676 self .assertNotIn (slot_10_30 , result )
677+ slot_9_00 = datetime .datetime .combine (self .today , datetime .time (9 , 0 ))
678+ self .assertNotIn (slot_9_00 , result )
662679
663680
664681class TestDayOffExistsForDateRange (BaseTest ):
0 commit comments