service = new CalendarSlotService(); $this->trip = Trip::factory()->create([ 'start_date' => '2024-01-01', 'end_date' => '2024-01-03', ]); } /** @test */ public function it_calculates_slot_order_for_first_slot_on_date() { $order = $this->service->calculateSlotOrder( $this->trip->id, '2024-01-01', Carbon::parse('2024-01-01 10:00:00') ); $this->assertEquals(0, $order); } /** @test */ public function it_calculates_slot_order_based_on_chronological_position() { // Create existing slots CalendarSlot::create([ 'trip_id' => $this->trip->id, 'name' => 'Morning', 'datetime_start' => '2024-01-01 08:00:00', 'datetime_end' => '2024-01-01 09:00:00', 'slot_date' => '2024-01-01', 'slot_order' => 0, ]); CalendarSlot::create([ 'trip_id' => $this->trip->id, 'name' => 'Afternoon', 'datetime_start' => '2024-01-01 14:00:00', 'datetime_end' => '2024-01-01 15:00:00', 'slot_date' => '2024-01-01', 'slot_order' => 1, ]); // Calculate order for noon slot (should be between morning and afternoon) $order = $this->service->calculateSlotOrder( $this->trip->id, '2024-01-01', Carbon::parse('2024-01-01 12:00:00') ); $this->assertEquals(1, $order); } /** @test */ public function it_calculates_slot_order_for_earliest_time() { // Create existing slot CalendarSlot::create([ 'trip_id' => $this->trip->id, 'name' => 'Late Morning', 'datetime_start' => '2024-01-01 10:00:00', 'datetime_end' => '2024-01-01 11:00:00', 'slot_date' => '2024-01-01', 'slot_order' => 0, ]); // Calculate order for earlier time $order = $this->service->calculateSlotOrder( $this->trip->id, '2024-01-01', Carbon::parse('2024-01-01 08:00:00') ); $this->assertEquals(0, $order); } /** @test */ public function it_calculates_slot_order_for_latest_time() { // Create existing slots CalendarSlot::create([ 'trip_id' => $this->trip->id, 'name' => 'Morning', 'datetime_start' => '2024-01-01 08:00:00', 'datetime_end' => '2024-01-01 09:00:00', 'slot_date' => '2024-01-01', 'slot_order' => 0, ]); CalendarSlot::create([ 'trip_id' => $this->trip->id, 'name' => 'Noon', 'datetime_start' => '2024-01-01 12:00:00', 'datetime_end' => '2024-01-01 13:00:00', 'slot_date' => '2024-01-01', 'slot_order' => 1, ]); // Calculate order for later time $order = $this->service->calculateSlotOrder( $this->trip->id, '2024-01-01', Carbon::parse('2024-01-01 20:00:00') ); $this->assertEquals(2, $order); } /** @test */ public function it_only_considers_slots_from_same_date() { // Create slot on different date CalendarSlot::create([ 'trip_id' => $this->trip->id, 'name' => 'Other Day', 'datetime_start' => '2024-01-02 08:00:00', 'datetime_end' => '2024-01-02 09:00:00', 'slot_date' => '2024-01-02', 'slot_order' => 0, ]); // Calculate order for Jan 1 (should start at 0, not affected by Jan 2) $order = $this->service->calculateSlotOrder( $this->trip->id, '2024-01-01', Carbon::parse('2024-01-01 10:00:00') ); $this->assertEquals(0, $order); } /** @test */ public function it_recalculates_slot_orders_for_date() { // Create slots in non-chronological slot_order CalendarSlot::create([ 'trip_id' => $this->trip->id, 'name' => 'Evening', 'datetime_start' => '2024-01-01 20:00:00', 'datetime_end' => '2024-01-01 21:00:00', 'slot_date' => '2024-01-01', 'slot_order' => 5, // Wrong order ]); CalendarSlot::create([ 'trip_id' => $this->trip->id, 'name' => 'Morning', 'datetime_start' => '2024-01-01 08:00:00', 'datetime_end' => '2024-01-01 09:00:00', 'slot_date' => '2024-01-01', 'slot_order' => 3, // Wrong order ]); CalendarSlot::create([ 'trip_id' => $this->trip->id, 'name' => 'Afternoon', 'datetime_start' => '2024-01-01 14:00:00', 'datetime_end' => '2024-01-01 15:00:00', 'slot_date' => '2024-01-01', 'slot_order' => 1, // Wrong order ]); // Recalculate $this->service->recalculateSlotOrdersForDate($this->trip->id, '2024-01-01'); // Verify correct chronological order $slots = CalendarSlot::where('trip_id', $this->trip->id) ->where('slot_date', '2024-01-01') ->orderBy('slot_order') ->get(); $this->assertEquals('Morning', $slots[0]->name); $this->assertEquals(0, $slots[0]->slot_order); $this->assertEquals('Afternoon', $slots[1]->name); $this->assertEquals(1, $slots[1]->slot_order); $this->assertEquals('Evening', $slots[2]->name); $this->assertEquals(2, $slots[2]->slot_order); } /** @test */ public function it_only_recalculates_slots_for_specified_date() { // Create slots on Jan 1 CalendarSlot::create([ 'trip_id' => $this->trip->id, 'name' => 'Jan 1 Slot', 'datetime_start' => '2024-01-01 10:00:00', 'datetime_end' => '2024-01-01 11:00:00', 'slot_date' => '2024-01-01', 'slot_order' => 5, ]); // Create slots on Jan 2 CalendarSlot::create([ 'trip_id' => $this->trip->id, 'name' => 'Jan 2 Slot', 'datetime_start' => '2024-01-02 10:00:00', 'datetime_end' => '2024-01-02 11:00:00', 'slot_date' => '2024-01-02', 'slot_order' => 7, ]); // Recalculate only Jan 1 $this->service->recalculateSlotOrdersForDate($this->trip->id, '2024-01-01'); // Jan 1 should be recalculated to 0 $jan1Slot = CalendarSlot::where('slot_date', '2024-01-01')->first(); $this->assertEquals(0, $jan1Slot->slot_order); // Jan 2 should remain unchanged $jan2Slot = CalendarSlot::where('slot_date', '2024-01-02')->first(); $this->assertEquals(7, $jan2Slot->slot_order); } }