trip-planner/backend/tests/Feature/CalendarSlotTest.php

230 lines
7.2 KiB
PHP
Raw Normal View History

<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\User;
use App\Models\Trip;
use App\Models\CalendarSlot;
use Illuminate\Foundation\Testing\RefreshDatabase;
class CalendarSlotTest extends TestCase
{
use RefreshDatabase;
private $user;
private $token;
protected function setUp(): void
{
parent::setUp();
$this->user = User::factory()->create();
$this->token = $this->user->createToken('test-token')->plainTextToken;
}
public function test_calendar_slots_are_auto_created_when_trip_is_created()
{
$tripData = [
'name' => 'Test Trip',
'description' => 'Test Description',
'start_date' => '2024-01-01',
'end_date' => '2024-01-03'
];
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->token,
'Accept' => 'application/json'
])->postJson('/api/trips', $tripData);
$response->assertStatus(201);
$tripId = $response->json('data.id');
// Check that 3 calendar slots were created (Jan 1, 2, 3)
$this->assertDatabaseCount('calendar_slots', 3);
$slots = CalendarSlot::where('trip_id', $tripId)
->orderBy('slot_order')
->get();
$this->assertEquals('Day 1', $slots[0]->name);
$this->assertEquals('2024-01-01', $slots[0]->slot_date->format('Y-m-d'));
$this->assertEquals(1, $slots[0]->slot_order);
$this->assertEquals('Day 2', $slots[1]->name);
$this->assertEquals('2024-01-02', $slots[1]->slot_date->format('Y-m-d'));
$this->assertEquals(2, $slots[1]->slot_order);
$this->assertEquals('Day 3', $slots[2]->name);
$this->assertEquals('2024-01-03', $slots[2]->slot_date->format('Y-m-d'));
$this->assertEquals(3, $slots[2]->slot_order);
}
public function test_calendar_slots_are_updated_when_trip_dates_change()
{
$trip = Trip::factory()->create([
'created_by_user_id' => $this->user->id,
'start_date' => '2024-01-01',
'end_date' => '2024-01-02'
]);
// Initially should have 2 slots
$this->assertCount(2, $trip->calendarSlots);
// Update trip dates
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->token,
'Accept' => 'application/json'
])->putJson("/api/trips/{$trip->id}", [
'name' => $trip->name,
'start_date' => '2024-02-01',
'end_date' => '2024-02-04'
]);
$response->assertStatus(200);
// Should now have 4 slots with new dates
$trip->refresh();
$slots = $trip->calendarSlots()->orderBy('slot_order')->get();
$this->assertCount(4, $slots);
$this->assertEquals('2024-02-01', $slots[0]->slot_date->format('Y-m-d'));
$this->assertEquals('2024-02-02', $slots[1]->slot_date->format('Y-m-d'));
$this->assertEquals('2024-02-03', $slots[2]->slot_date->format('Y-m-d'));
$this->assertEquals('2024-02-04', $slots[3]->slot_date->format('Y-m-d'));
}
public function test_can_list_calendar_slots_for_trip()
{
$trip = Trip::factory()->create([
'created_by_user_id' => $this->user->id,
'start_date' => '2024-01-01',
'end_date' => '2024-01-03'
]);
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->token,
'Accept' => 'application/json'
])->getJson("/api/trips/{$trip->id}/calendar-slots");
$response->assertStatus(200)
->assertJsonCount(3, 'data')
->assertJsonPath('data.0.name', 'Day 1')
->assertJsonPath('data.1.name', 'Day 2')
->assertJsonPath('data.2.name', 'Day 3');
}
public function test_can_update_calendar_slot_name()
{
$trip = Trip::factory()->create([
'created_by_user_id' => $this->user->id,
'start_date' => '2024-01-01',
'end_date' => '2024-01-01'
]);
$slot = $trip->calendarSlots()->first();
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->token,
'Accept' => 'application/json'
])->putJson("/api/calendar-slots/{$slot->id}", [
'name' => 'Arrival Day'
]);
$response->assertStatus(200)
->assertJsonPath('data.name', 'Arrival Day');
$this->assertDatabaseHas('calendar_slots', [
'id' => $slot->id,
'name' => 'Arrival Day'
]);
}
public function test_cannot_access_calendar_slots_of_other_users_trip()
{
$otherUser = User::factory()->create();
$otherTrip = Trip::factory()->create([
'created_by_user_id' => $otherUser->id,
'start_date' => '2024-01-01',
'end_date' => '2024-01-02'
]);
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->token,
'Accept' => 'application/json'
])->getJson("/api/trips/{$otherTrip->id}/calendar-slots");
$response->assertStatus(403);
}
public function test_cannot_update_calendar_slot_of_other_users_trip()
{
$otherUser = User::factory()->create();
$otherTrip = Trip::factory()->create([
'created_by_user_id' => $otherUser->id,
'start_date' => '2024-01-01',
'end_date' => '2024-01-01'
]);
$slot = $otherTrip->calendarSlots()->first();
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->token,
'Accept' => 'application/json'
])->putJson("/api/calendar-slots/{$slot->id}", [
'name' => 'Hacked Name'
]);
$response->assertStatus(403);
}
public function test_no_slots_created_for_trip_without_dates()
{
$tripData = [
'name' => 'Trip without dates',
'description' => 'No dates set'
];
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->token,
'Accept' => 'application/json'
])->postJson('/api/trips', $tripData);
$response->assertStatus(201);
$tripId = $response->json('data.id');
// No slots should be created
$this->assertDatabaseCount('calendar_slots', 0);
$slots = CalendarSlot::where('trip_id', $tripId)->get();
$this->assertCount(0, $slots);
}
public function test_slots_created_when_dates_added_to_trip()
{
$trip = Trip::factory()->create([
'created_by_user_id' => $this->user->id,
'start_date' => null,
'end_date' => null
]);
// Initially no slots
$this->assertCount(0, $trip->calendarSlots);
// Add dates to trip
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->token,
'Accept' => 'application/json'
])->putJson("/api/trips/{$trip->id}", [
'name' => $trip->name,
'start_date' => '2024-03-01',
'end_date' => '2024-03-02'
]);
$response->assertStatus(200);
// Now should have 2 slots
$trip->refresh();
$this->assertCount(2, $trip->calendarSlots);
}
}