trip-planner/backend/tests/Unit/CalendarSlotServiceTest.php
myrmidex 6d738ac66a 7-display-daily-timeline (#34)
Reviewed-on: https://codeberg.org/lvl0/trip-planner/pulls/34
Co-authored-by: myrmidex <myrmidex@myrmidex.net>
Co-committed-by: myrmidex <myrmidex@myrmidex.net>
2025-10-07 22:55:00 +02:00

235 lines
7.2 KiB
PHP

<?php
namespace Tests\Unit;
use App\Domain\Trip\Services\CalendarSlotService;
use App\Models\Trip;
use App\Models\CalendarSlot;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use Carbon\Carbon;
class CalendarSlotServiceTest extends TestCase
{
use RefreshDatabase;
private CalendarSlotService $service;
private Trip $trip;
protected function setUp(): void
{
parent::setUp();
$this->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);
}
}