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'); } }