withoutMiddleware(EnsurePlatformSession::class); $this->owner = User::create([ 'public_id' => 'clinical-owner', 'name' => 'Owner', 'email' => 'clinical@example.com', ]); $this->organization = Organization::create([ 'owner_ref' => $this->owner->public_id, 'name' => 'Clinical Clinic', 'slug' => 'clinical-clinic', 'settings' => [ 'onboarded' => true, 'facility_type' => 'clinic', 'plan' => 'pro', 'plan_expires_at' => now()->addMonth()->toIso8601String(), 'queue_integration_enabled' => true, ], ]); 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, ]); } /** * @return array{0: Visit, 1: Department} */ protected function activateWithVisit(string $module, string $departmentType): array { app(SpecialtyModuleService::class)->activate( $this->organization, $this->owner->public_id, $module, ); $department = Department::query() ->where('branch_id', $this->branch->id) ->where('type', $departmentType) ->firstOrFail(); $patient = Patient::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'patient_number' => 'P-CL-1', 'first_name' => 'Kofi', 'last_name' => 'Asante', 'gender' => 'male', 'date_of_birth' => '1985-03-01', ]); $visit = Visit::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'patient_id' => $patient->id, 'status' => Visit::STATUS_OPEN, 'checked_in_at' => now(), ]); Appointment::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'patient_id' => $patient->id, 'department_id' => $department->id, 'visit_id' => $visit->id, 'type' => Appointment::TYPE_WALK_IN, 'status' => Appointment::STATUS_WAITING, 'scheduled_at' => now(), 'waiting_at' => now(), ]); return [$visit, $department]; } public function test_emergency_triage_form_saves_structured_record_and_alerts(): void { [$visit] = $this->activateWithVisit('emergency', 'emergency'); $this->actingAs($this->owner) ->get(route('care.specialty.workspace', ['module' => 'emergency', 'visit' => $visit, 'tab' => 'triage'])) ->assertOk() ->assertSee('Triage acuity') ->assertSee('Chief complaint'); $this->actingAs($this->owner) ->post(route('care.specialty.clinical.save', ['module' => 'emergency', 'visit' => $visit]), [ 'tab' => 'triage', 'stage_code' => 'arrival', 'status' => 'active', 'payload' => [ 'acuity' => '1 - Resuscitation', 'chief_complaint' => 'Chest pain', 'airway_ok' => '0', 'breathing_ok' => '1', 'circulation_ok' => '1', 'pain_score' => '9', 'mode_of_arrival' => 'Ambulance', 'disposition_intent' => 'Resus', 'notes' => 'Immediate attention', ], ]) ->assertRedirect(); $record = SpecialtyClinicalRecord::query() ->where('visit_id', $visit->id) ->where('record_type', 'triage') ->first(); $this->assertNotNull($record); $this->assertSame('Chest pain', $record->payload['chief_complaint'] ?? null); $this->assertFalse((bool) ($record->payload['airway_ok'] ?? true)); $this->assertNotEmpty($record->alerts); $this->assertTrue(collect($record->alerts)->contains(fn ($a) => ($a['code'] ?? '') === 'er.high_acuity')); $this->assertTrue(collect($record->alerts)->contains(fn ($a) => ($a['code'] ?? '') === 'er.abc_compromise')); $this->actingAs($this->owner) ->get(route('care.specialty.workspace', ['module' => 'emergency', 'visit' => $visit, 'tab' => 'triage'])) ->assertOk() ->assertSee('High-acuity triage') ->assertSee('ABC compromise'); } public function test_blood_bank_request_save(): void { [$bbVisit] = $this->activateWithVisit('blood_bank', 'blood_bank'); $this->actingAs($this->owner) ->post(route('care.specialty.clinical.save', ['module' => 'blood_bank', 'visit' => $bbVisit]), [ 'tab' => 'requests', 'payload' => [ 'product' => 'Packed RBC', 'units' => '2', 'urgency' => 'Emergency / massive', 'patient_blood_group' => 'O+', 'indication' => 'Trauma bleed', 'crossmatch_status' => 'Not started', ], ]) ->assertRedirect(); $this->assertDatabaseHas('care_specialty_clinical_records', [ 'visit_id' => $bbVisit->id, 'module_key' => 'blood_bank', 'record_type' => 'blood_request', ]); } public function test_ophthalmology_uses_eye_exam_form_not_generic_notes(): void { app(SpecialtyModuleService::class)->activate( $this->organization, $this->owner->public_id, 'ophthalmology', ); $fields = app(\App\Services\Care\SpecialtyClinicalRecordService::class) ->fieldsFor('ophthalmology', 'eye_exam'); $names = collect($fields)->pluck('name')->all(); $this->assertContains('iop_od', $names); $this->assertContains('iop_os', $names); $this->assertContains('findings', $names); $this->assertContains('chief_complaint', $names); $this->assertNotContains('working_diagnosis', $names); [$visit] = $this->activateWithVisit('ophthalmology', 'ophthalmology'); $this->actingAs($this->owner) ->get(route('care.specialty.workspace', [ 'module' => 'ophthalmology', 'visit' => $visit, 'tab' => 'exam', ])) ->assertOk() ->assertSee('Chief complaint') ->assertSee('IOP OS'); } }