100 lines
3.8 KiB
PHP
100 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Http\Client\Doctor;
|
|
|
|
use App\Enums\ShiftDayEnum;
|
|
use App\Enums\UserEnum;
|
|
use App\Models\Shift;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Carbon;
|
|
use Inertia\Testing\AssertableInertia as Assert;
|
|
use Tests\TestCase;
|
|
|
|
class ShiftControllerTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function doctor(): User
|
|
{
|
|
return User::factory()->create(['level' => UserEnum::Doctor->value]);
|
|
}
|
|
|
|
public function test_routes_require_authentication(): void
|
|
{
|
|
$shift = Shift::factory()->create();
|
|
|
|
$this->get(route('dashboard.shifts.index'))->assertRedirect(route('login'));
|
|
$this->put(route('dashboard.shifts.update', $shift))->assertRedirect(route('login'));
|
|
$this->delete(route('dashboard.shifts.destroy', $shift))->assertRedirect(route('login'));
|
|
}
|
|
|
|
public function test_routes_are_forbidden_for_non_doctors(): void
|
|
{
|
|
$vet = User::factory()->create(['level' => UserEnum::Vet->value]);
|
|
$shift = Shift::factory()->create();
|
|
|
|
$this->actingAs($vet)->get(route('dashboard.shifts.index'))->assertForbidden();
|
|
$this->actingAs($vet)->put(route('dashboard.shifts.update', $shift))->assertForbidden();
|
|
$this->actingAs($vet)->delete(route('dashboard.shifts.destroy', $shift))->assertForbidden();
|
|
}
|
|
|
|
public function test_index_lists_my_shifts_and_open_upcoming_shifts_sorted(): void
|
|
{
|
|
Carbon::setTestNow('2026-09-21 10:00:00');
|
|
$doctor = $this->doctor();
|
|
$mine = Shift::factory()->weekly(ShiftDayEnum::Monday)->forDoctor($doctor)->create();
|
|
Shift::factory()->weekly(ShiftDayEnum::Monday)->forDoctor()->create();
|
|
$openLater = Shift::factory()->onDate('2026-09-25')->create();
|
|
$openWeekly = Shift::factory()->weekly(ShiftDayEnum::Saturday)->create();
|
|
Shift::factory()->onDate('2026-09-20')->create();
|
|
Shift::factory()->weekly(ShiftDayEnum::Sunday)->inactive()->create();
|
|
|
|
$this->actingAs($doctor)->get(route('dashboard.shifts.index'))
|
|
->assertOk()
|
|
->assertInertia(fn (Assert $page) => $page
|
|
->component('Dashboard/Shifts/Index')
|
|
->has('myShifts.data', 1)
|
|
->where('myShifts.data.0.id', $mine->id)
|
|
->has('openShifts.data', 2)
|
|
->where('openShifts.data.0.id', $openWeekly->id)
|
|
->where('openShifts.data.1.id', $openLater->id));
|
|
}
|
|
|
|
public function test_update_claims_open_shift(): void
|
|
{
|
|
$doctor = $this->doctor();
|
|
$shift = Shift::factory()->onDate('2026-09-21')->create();
|
|
|
|
$this->actingAs($doctor)->put(route('dashboard.shifts.update', $shift))->assertOk();
|
|
|
|
$this->assertDatabaseHas('shifts', ['id' => $shift->id, 'user_id' => $doctor->id]);
|
|
}
|
|
|
|
public function test_update_rejects_taken_shift(): void
|
|
{
|
|
$shift = Shift::factory()->onDate('2026-09-21')->forDoctor()->create();
|
|
|
|
$this->actingAs($this->doctor())->putJson(route('dashboard.shifts.update', $shift))->assertUnprocessable()->assertJsonValidationErrors('shift');
|
|
}
|
|
|
|
public function test_destroy_releases_own_shift(): void
|
|
{
|
|
$doctor = $this->doctor();
|
|
$shift = Shift::factory()->onDate('2026-09-21')->forDoctor($doctor)->create();
|
|
|
|
$this->actingAs($doctor)->delete(route('dashboard.shifts.destroy', $shift))->assertOk();
|
|
|
|
$this->assertDatabaseHas('shifts', ['id' => $shift->id, 'user_id' => null]);
|
|
}
|
|
|
|
public function test_destroy_rejects_another_doctors_shift(): void
|
|
{
|
|
$shift = Shift::factory()->onDate('2026-09-21')->forDoctor()->create();
|
|
|
|
$this->actingAs($this->doctor())->deleteJson(route('dashboard.shifts.destroy', $shift))->assertUnprocessable();
|
|
|
|
$this->assertNotNull($shift->fresh()->user_id);
|
|
}
|
|
}
|