withoutMiddleware(EnsurePlatformSession::class); $this->owner = User::create([ 'public_id' => 'roster-owner', 'name' => 'Owner', 'email' => 'roster-owner@example.com', ]); $this->organization = Organization::create([ 'owner_ref' => $this->owner->public_id, 'name' => 'Roster Hospital', 'slug' => 'roster-hospital', 'settings' => [ 'onboarded' => true, 'facility_type' => 'hospital', 'plan' => 'pro', 'plan_expires_at' => now()->addMonth()->toIso8601String(), ], ]); Member::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'user_ref' => $this->owner->public_id, 'role' => 'hospital_admin', ]); $branch = Branch::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'name' => 'Main', 'is_active' => true, ]); $department = Department::create([ 'owner_ref' => $this->owner->public_id, 'branch_id' => $branch->id, 'name' => 'Medicine', 'type' => 'general', 'is_active' => true, ]); $this->unit = CareUnit::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'department_id' => $department->id, 'name' => 'Medical Ward', 'kind' => 'inpatient', 'is_active' => true, ]); $nurseUser = User::create([ 'public_id' => 'roster-nurse', 'name' => 'Nurse Ama', 'email' => 'roster-nurse@example.com', ]); $this->nurseMember = Member::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'user_ref' => $nurseUser->public_id, 'role' => 'nurse', 'branch_id' => $branch->id, ]); } public function test_default_shifts_are_seeded_on_index(): void { $this->actingAs($this->owner) ->get(route('care.shifts.index')) ->assertOk() ->assertSee('Day shift') ->assertSee('Evening shift') ->assertSee('Night shift'); $this->assertSame(3, Shift::query()->where('organization_id', $this->organization->id)->count()); } public function test_roster_assign_does_not_create_unit_assignment(): void { $roster = app(RosterService::class); $shifts = $roster->ensureDefaultShifts($this->organization, $this->owner->public_id); $day = $shifts->firstWhere('code', 'day'); $this->actingAs($this->owner) ->post(route('care.care-units.roster.store', $this->unit), [ 'shift_id' => $day->id, 'member_id' => $this->nurseMember->id, 'duty_date' => now()->toDateString(), 'notes' => 'Cover', ]) ->assertRedirect(); $entry = RosterEntry::query()->first(); $this->assertNotNull($entry); $this->assertSame(RosterEntry::STATUS_SCHEDULED, $entry->status); $this->assertNull($entry->staff_assignment_id); $this->assertSame(0, StaffAssignment::query()->count()); } public function test_roster_cancel_allows_reassign(): void { $roster = app(RosterService::class); $shifts = $roster->ensureDefaultShifts($this->organization, $this->owner->public_id); $day = $shifts->firstWhere('code', 'day'); $date = now()->toDateString(); $entry = $roster->assign( $this->unit, $day, $this->nurseMember, $date, $this->owner->public_id, $this->owner->public_id, ); $this->actingAs($this->owner) ->delete(route('care.care-units.roster.destroy', [$this->unit, $entry])) ->assertRedirect(); $this->assertSoftDeleted('care_roster_entries', ['id' => $entry->id]); $this->assertSame(0, StaffAssignment::query()->count()); $this->actingAs($this->owner) ->post(route('care.care-units.roster.store', $this->unit), [ 'shift_id' => $day->id, 'member_id' => $this->nurseMember->id, 'duty_date' => $date, ]) ->assertRedirect(); $this->assertSame(1, RosterEntry::query()->where('care_unit_id', $this->unit->id)->count()); } public function test_nursing_services_hub_and_specialty_redirect(): void { $this->assertTrue(app(SpecialtyModuleService::class)->isEnabled($this->organization, 'nursing_services')); $this->actingAs($this->owner) ->get(route('care.nursing.services')) ->assertOk() ->assertSee('Nursing Services') ->assertSee('Nurse Ama') ->assertSee('Medical Ward'); $this->actingAs($this->owner) ->get(route('care.specialty.show', 'nursing_services')) ->assertRedirect(route('care.nursing.services')); } public function test_unit_roster_grid_renders(): void { $this->actingAs($this->owner) ->get(route('care.care-units.roster', $this->unit)) ->assertOk() ->assertSee('Shift assignments') ->assertSee('Day shift'); } }