Files

127 lines
6.1 KiB
PHP

<?php
namespace Tests\Feature\Http\Admin;
use App\Enums\ShiftDayEnum;
use App\Enums\UserEnum;
use App\Models\Shift;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Inertia\Testing\AssertableInertia as Assert;
use Tests\Concerns\InteractsWithAdmin;
use Tests\TestCase;
class ShiftControllerTest extends TestCase
{
use InteractsWithAdmin, RefreshDatabase;
protected function payload(array $overrides = []): array
{
return array_merge([
'day_of_week' => ShiftDayEnum::Monday->value,
'start_time' => '08:00',
'end_time' => '16:00',
'is_active' => true,
], $overrides);
}
public function test_guest_is_redirected(): void
{
$this->get(route('admin.shifts.index'))->assertRedirect(route('login'));
}
public function test_admin_without_permission_is_forbidden(): void
{
$admin = $this->adminWithoutPermissions();
$shift = Shift::factory()->create();
$this->actingAs($admin)->get(route('admin.shifts.index'))->assertForbidden();
$this->actingAs($admin)->get(route('admin.shifts.create'))->assertForbidden();
$this->actingAs($admin)->post(route('admin.shifts.store'), $this->payload())->assertForbidden();
$this->actingAs($admin)->get(route('admin.shifts.edit', $shift))->assertForbidden();
$this->actingAs($admin)->put(route('admin.shifts.update', $shift), $this->payload())->assertForbidden();
$this->actingAs($admin)->delete(route('admin.shifts.destroy', $shift))->assertForbidden();
$this->actingAs($admin)->post('/admin/shifts-bulk-delete', ['ids' => [$shift->id]])->assertForbidden();
$this->actingAs($admin)->get('/admin/shifts-calendar-data')->assertForbidden();
}
public function test_index_renders_with_filters(): void
{
$admin = $this->adminWithAllPermissions();
$doctor = User::factory()->create(['level' => UserEnum::Doctor->value, 'fullname' => 'دکتر الف']);
Shift::factory()->weekly(ShiftDayEnum::Monday)->forDoctor($doctor)->create();
Shift::factory()->weekly(ShiftDayEnum::Tuesday)->create();
Shift::factory()->weekly(ShiftDayEnum::Tuesday)->inactive()->create();
$this->actingAs($admin)->get(route('admin.shifts.index'))
->assertOk()
->assertInertia(fn (Assert $page) => $page->component('Shifts/index')->has('shifts.data', 3)->where('permissions_edit', false)->where('permissions_delete', false));
$this->actingAs($admin)->get(route('admin.shifts.index', ['day_of_week' => ShiftDayEnum::Tuesday->value]))->assertInertia(fn (Assert $page) => $page->has('shifts.data', 2));
$this->actingAs($admin)->get(route('admin.shifts.index', ['status' => 'فعال']))->assertInertia(fn (Assert $page) => $page->has('shifts.data', 2));
$this->actingAs($admin)->get(route('admin.shifts.index', ['occupancy' => 'آزاد']))->assertInertia(fn (Assert $page) => $page->has('shifts.data', 2));
$this->actingAs($admin)->get(route('admin.shifts.index', ['search' => 'الف']))->assertInertia(fn (Assert $page) => $page->has('shifts.data', 1));
}
public function test_create_and_edit_pages_render(): void
{
$admin = $this->adminWithAllPermissions();
$shift = Shift::factory()->create();
$this->actingAs($admin)->get(route('admin.shifts.create'))->assertInertia(fn (Assert $page) => $page->component('Shifts/create_and_edit')->missing('is_edit'));
$this->actingAs($admin)->get(route('admin.shifts.edit', $shift))->assertInertia(fn (Assert $page) => $page->component('Shifts/create_and_edit')->where('is_edit', true)->where('shift.id', $shift->id));
}
public function test_store_creates_shift_with_creator(): void
{
$admin = $this->adminWithAllPermissions();
$doctor = User::factory()->create(['level' => UserEnum::Doctor->value]);
$this->actingAs($admin)->post(route('admin.shifts.store'), $this->payload(['user_id' => $doctor->id]))->assertOk()->assertSessionHas('success');
$this->assertDatabaseHas('shifts', ['day_of_week' => ShiftDayEnum::Monday->value, 'start_time' => '08:00', 'end_time' => '16:00', 'user_id' => $doctor->id, 'created_by' => $admin->id, 'is_active' => 1]);
}
public function test_store_rejects_conflicting_shift(): void
{
$admin = $this->adminWithAllPermissions();
$doctor = User::factory()->create(['level' => UserEnum::Doctor->value]);
Shift::factory()->weekly(ShiftDayEnum::Monday)->between('08:00', '12:00')->forDoctor($doctor)->create();
$this->actingAs($admin)->postJson(route('admin.shifts.store'), $this->payload(['user_id' => $doctor->id, 'start_time' => '10:00', 'end_time' => '14:00']))
->assertUnprocessable()
->assertJsonValidationErrors('start_time');
}
public function test_update_changes_shift(): void
{
$admin = $this->adminWithAllPermissions();
$shift = Shift::factory()->weekly(ShiftDayEnum::Monday)->create();
$this->actingAs($admin)->put(route('admin.shifts.update', $shift), $this->payload(['day_of_week' => null, 'date' => '2026-09-21', 'is_active' => false]))->assertOk();
$shift->refresh();
$this->assertNull($shift->day_of_week);
$this->assertSame('2026-09-21', $shift->date->toDateString());
$this->assertFalse($shift->is_active);
}
public function test_destroy_and_bulk_delete_remove_shifts(): void
{
$admin = $this->adminWithAllPermissions();
$shifts = Shift::factory()->count(3)->create();
$this->actingAs($admin)->delete(route('admin.shifts.destroy', $shifts[0]))->assertOk();
$this->actingAs($admin)->post('/admin/shifts-bulk-delete', ['ids' => [$shifts[1]->id, $shifts[2]->id]])->assertOk();
$this->assertDatabaseCount('shifts', 0);
}
public function test_calendar_data_returns_all_shifts(): void
{
Shift::factory()->count(2)->create();
$this->actingAs($this->adminWithAllPermissions())->getJson('/admin/shifts-calendar-data')->assertOk()->assertJsonPath('success', true)->assertJsonCount(2, 'data');
}
}