Deploy Ladill Care / deploy (push) Successful in 1m11s
Nurses without consult rights see unit placement, MAR, nursing assessments, and meds/labs instead of the GP consult/pathways toolkit. Co-authored-by: Cursor <cursoragent@cursor.com>
361 lines
12 KiB
PHP
361 lines
12 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Http\Middleware\EnsurePlatformSession;
|
|
use App\Models\Branch;
|
|
use App\Models\CareUnit;
|
|
use App\Models\Department;
|
|
use App\Models\Member;
|
|
use App\Models\Organization;
|
|
use App\Models\User;
|
|
use App\Services\Care\CarePermissions;
|
|
use App\Services\Care\RosterService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class CareMyShiftsAndNavPermissionsTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected User $owner;
|
|
|
|
protected Organization $organization;
|
|
|
|
protected Branch $branch;
|
|
|
|
protected CareUnit $unit;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->withoutMiddleware(EnsurePlatformSession::class);
|
|
|
|
$this->owner = User::create([
|
|
'public_id' => 'my-shifts-owner',
|
|
'name' => 'Owner',
|
|
'email' => 'my-shifts-owner@example.com',
|
|
]);
|
|
|
|
$this->organization = Organization::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'name' => 'Shifts Clinic',
|
|
'slug' => 'shifts-clinic',
|
|
'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',
|
|
]);
|
|
|
|
$this->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' => $this->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,
|
|
]);
|
|
}
|
|
|
|
public function test_ambulance_staff_cannot_access_care_units_or_nursing_services_hub(): void
|
|
{
|
|
$user = User::create([
|
|
'public_id' => 'amb-staff',
|
|
'name' => 'Ambulance',
|
|
'email' => 'amb@example.com',
|
|
]);
|
|
$member = Member::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'user_ref' => $user->public_id,
|
|
'role' => 'ambulance_staff',
|
|
'branch_id' => $this->branch->id,
|
|
]);
|
|
|
|
$permissions = app(CarePermissions::class);
|
|
$this->assertFalse($permissions->can($member, 'nursing.services.view'));
|
|
$this->assertFalse($permissions->can($member, 'inpatient.placement.view'));
|
|
$this->assertFalse($permissions->can($member, 'admin.departments.view'));
|
|
$this->assertTrue($permissions->can($member, 'nursing.my_shifts.view'));
|
|
$this->assertFalse($permissions->can($member, 'nursing.station.view'));
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.care-units.index'))
|
|
->assertForbidden();
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.nursing.services'))
|
|
->assertForbidden();
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.nursing.station'))
|
|
->assertForbidden();
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.dashboard'))
|
|
->assertOk()
|
|
->assertDontSee('>Care units<', false)
|
|
->assertDontSee('>Nursing Services<', false)
|
|
->assertDontSee('>My care unit<', false)
|
|
->assertSee('My shifts', false);
|
|
}
|
|
|
|
public function test_staff_see_their_assigned_shifts(): void
|
|
{
|
|
$user = User::create([
|
|
'public_id' => 'nurse-shifts',
|
|
'name' => 'Nurse Ama',
|
|
'email' => 'nurse-shifts@example.com',
|
|
]);
|
|
$member = Member::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'user_ref' => $user->public_id,
|
|
'role' => 'nurse',
|
|
'branch_id' => $this->branch->id,
|
|
]);
|
|
|
|
$roster = app(RosterService::class);
|
|
$shifts = $roster->ensureDefaultShifts($this->organization, $this->owner->public_id);
|
|
$day = $shifts->firstWhere('code', 'day');
|
|
|
|
$roster->assign(
|
|
$this->unit,
|
|
$day,
|
|
$member,
|
|
now()->toDateString(),
|
|
$this->owner->public_id,
|
|
$this->owner->public_id,
|
|
);
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.my-shifts'))
|
|
->assertOk()
|
|
->assertSee('My shifts')
|
|
->assertSee('Medical Ward')
|
|
->assertSee('Day shift');
|
|
}
|
|
|
|
public function test_regular_nurse_cannot_access_nursing_services_hub(): void
|
|
{
|
|
$user = User::create([
|
|
'public_id' => 'nurse-hub',
|
|
'name' => 'Ward Nurse',
|
|
'email' => 'nurse-hub@example.com',
|
|
]);
|
|
$member = Member::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'user_ref' => $user->public_id,
|
|
'role' => 'nurse',
|
|
'branch_id' => $this->branch->id,
|
|
]);
|
|
|
|
$permissions = app(CarePermissions::class);
|
|
$this->assertFalse($permissions->can($member, 'nursing.services.view'));
|
|
$this->assertFalse($permissions->can($member, 'inpatient.placement.view'));
|
|
$this->assertFalse($permissions->can($member, 'nursing.roster.manage'));
|
|
$this->assertTrue($permissions->can($member, 'nursing.my_shifts.view'));
|
|
$this->assertTrue($permissions->can($member, 'nursing.station.view'));
|
|
$this->assertTrue($permissions->can($member, 'mar.view'));
|
|
$this->assertTrue($permissions->can($member, 'nursing.notes.manage'));
|
|
$this->assertFalse($permissions->can($member, 'admin.departments.view'));
|
|
$this->assertFalse($permissions->can($member, 'admin.departments.manage'));
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.care-units.index'))
|
|
->assertForbidden();
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.care-units.create'))
|
|
->assertForbidden();
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.departments.index'))
|
|
->assertForbidden();
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.departments.create'))
|
|
->assertForbidden();
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.nursing.services'))
|
|
->assertForbidden();
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.specialty.show', 'nursing_services'))
|
|
->assertForbidden();
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.nursing.station'))
|
|
->assertOk()
|
|
->assertSee('My care unit')
|
|
->assertSee('No unit assigned for today');
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.dashboard'))
|
|
->assertOk()
|
|
->assertDontSee('>Care units<', false)
|
|
->assertDontSee('>Departments<', false)
|
|
->assertDontSee('>Nursing Services<', false)
|
|
->assertDontSee('>Nursing<', false)
|
|
->assertDontSee('>Clinical forms<', false)
|
|
->assertSee('>My care unit<', false)
|
|
->assertSee('My shifts', false);
|
|
}
|
|
|
|
public function test_regular_nurse_station_shows_rostered_unit_patients_and_clinical_boards(): void
|
|
{
|
|
$user = User::create([
|
|
'public_id' => 'nurse-station',
|
|
'name' => 'Nurse Kojo',
|
|
'email' => 'nurse-station@example.com',
|
|
]);
|
|
$member = Member::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'user_ref' => $user->public_id,
|
|
'role' => 'nurse',
|
|
'branch_id' => $this->branch->id,
|
|
]);
|
|
|
|
$roster = app(RosterService::class);
|
|
$day = $roster->ensureDefaultShifts($this->organization, $this->owner->public_id)->firstWhere('code', 'day');
|
|
$roster->assign(
|
|
$this->unit,
|
|
$day,
|
|
$member,
|
|
now()->toDateString(),
|
|
$this->owner->public_id,
|
|
$this->owner->public_id,
|
|
);
|
|
|
|
$patient = \App\Models\Patient::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'branch_id' => $this->branch->id,
|
|
'patient_number' => 'P-WARD-1',
|
|
'first_name' => 'Ama',
|
|
'last_name' => 'Mensah',
|
|
]);
|
|
\App\Models\Visit::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'branch_id' => $this->branch->id,
|
|
'patient_id' => $patient->id,
|
|
'care_unit_id' => $this->unit->id,
|
|
'status' => \App\Models\Visit::STATUS_OPEN,
|
|
'checked_in_at' => now(),
|
|
'placed_at' => now(),
|
|
]);
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.nursing.station'))
|
|
->assertOk()
|
|
->assertSee('Medical Ward')
|
|
->assertSee('Ama Mensah')
|
|
->assertSee('MAR round')
|
|
->assertSee('Vitals & assess', false)
|
|
->assertSee('Notes')
|
|
->assertSee('Handover');
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.care-units.mar', $this->unit))
|
|
->assertOk()
|
|
->assertSee('MAR board');
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.care-units.notes', $this->unit))
|
|
->assertOk()
|
|
->assertSee('Nursing notes');
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.care-units.assessments', $this->unit))
|
|
->assertOk()
|
|
->assertSee('Ward assessment board');
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.care-units.show', $this->unit))
|
|
->assertOk()
|
|
->assertSee('Ama Mensah');
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.my-shifts'))
|
|
->assertOk()
|
|
->assertSee('Open care unit');
|
|
}
|
|
|
|
public function test_nurse_patient_chart_shows_nursing_care_not_gp_clinical_toolkit(): void
|
|
{
|
|
$user = User::create([
|
|
'public_id' => 'nurse-chart',
|
|
'name' => 'Nurse Chart',
|
|
'email' => 'nurse-chart@example.com',
|
|
]);
|
|
Member::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'user_ref' => $user->public_id,
|
|
'role' => 'nurse',
|
|
'branch_id' => $this->branch->id,
|
|
]);
|
|
|
|
$patient = \App\Models\Patient::create([
|
|
'uuid' => (string) \Illuminate\Support\Str::uuid(),
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'branch_id' => $this->branch->id,
|
|
'patient_number' => 'P-CHART-1',
|
|
'first_name' => 'Efua',
|
|
'last_name' => 'Owusu',
|
|
]);
|
|
|
|
\App\Models\Visit::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'branch_id' => $this->branch->id,
|
|
'patient_id' => $patient->id,
|
|
'care_unit_id' => $this->unit->id,
|
|
'status' => \App\Models\Visit::STATUS_OPEN,
|
|
'checked_in_at' => now(),
|
|
'placed_at' => now(),
|
|
]);
|
|
|
|
$this->actingAs($user)
|
|
->get(route('care.patients.show', $patient))
|
|
->assertOk()
|
|
->assertSee('Visit & nursing care', false)
|
|
->assertSee('On unit now')
|
|
->assertSee('Nursing assessments')
|
|
->assertSee('My care unit')
|
|
->assertDontSee('Visit & clinical history', false)
|
|
->assertDontSee('Condition pathways')
|
|
->assertDontSee('Follow-up scores')
|
|
->assertDontSee('Start assessment');
|
|
}
|
|
}
|