withoutMiddleware(EnsurePlatformSession::class); $this->user = User::create([ 'public_id' => 'universal-intake-user', 'name' => 'Intake User', 'email' => 'intake@example.com', ]); $this->organization = Organization::create([ 'owner_ref' => $this->user->public_id, 'name' => 'Intake Clinic', 'slug' => 'intake-clinic', 'timezone' => 'UTC', 'settings' => [ 'onboarded' => true, 'rollout' => [CareFeatures::ASSESSMENTS_ENGINE => true], ], ]); $this->member = Member::create([ 'owner_ref' => $this->user->public_id, 'organization_id' => $this->organization->id, 'user_ref' => $this->user->public_id, 'role' => 'nurse', ]); $this->branch = Branch::create([ 'owner_ref' => $this->user->public_id, 'organization_id' => $this->organization->id, 'name' => 'Main', 'is_active' => true, ]); $this->patient = Patient::create([ 'uuid' => (string) Str::uuid(), 'owner_ref' => $this->user->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'patient_number' => 'LC-INTAKE-001', 'first_name' => 'Kwame', 'last_name' => 'Boateng', ]); } public function test_assessment_template_seeder_loads_universal_intake_pack(): void { $this->seed(AssessmentTemplateSeeder::class); $template = AssessmentTemplate::currentSystemByCode('universal_intake'); $this->assertNotNull($template); $this->assertSame(1, $template->version); $this->assertSame(AssessmentTemplate::CATEGORY_UNIVERSAL, $template->category); $this->assertNull($template->organization_id); $this->assertSame(['doctor', 'nurse'], $template->meta['capture_roles'] ?? null); $codes = $template->questions()->pluck('code')->all(); $this->assertContains('chief_complaint', $codes); $this->assertContains('hpi', $codes); $this->assertContains('pain_score', $codes); $this->assertContains('smoking_status', $codes); $this->assertContains('mobility', $codes); $this->assertContains('baseline_labs_summary', $codes); $chief = $template->questions()->where('code', 'chief_complaint')->first(); $this->assertTrue($chief->is_required); $this->assertSame(AssessmentQuestion::TYPE_TEXTAREA, $chief->answer_type); } public function test_seeder_is_idempotent_and_replaces_questions(): void { $this->seed(AssessmentTemplateSeeder::class); $firstId = AssessmentTemplate::currentSystemByCode('universal_intake')->id; $questionCount = AssessmentQuestion::where('template_id', $firstId)->count(); $this->seed(AssessmentTemplateSeeder::class); $this->assertSame(1, AssessmentTemplate::where('code', 'universal_intake')->count()); $this->assertSame($firstId, AssessmentTemplate::currentSystemByCode('universal_intake')->id); $this->assertSame($questionCount, AssessmentQuestion::where('template_id', $firstId)->count()); } public function test_nurse_can_complete_seeded_universal_intake_on_consultation(): void { $this->seed(AssessmentTemplateSeeder::class); $visit = Visit::create([ 'owner_ref' => $this->user->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'patient_id' => $this->patient->id, 'status' => Visit::STATUS_OPEN, 'checked_in_at' => now(), ]); $consultation = Consultation::create([ 'owner_ref' => $this->user->public_id, 'visit_id' => $visit->id, 'patient_id' => $this->patient->id, 'status' => Consultation::STATUS_DRAFT, 'started_at' => now(), 'symptoms' => 'Free-text headache narrative', ]); // Nurse has vitals + assessments.capture; free-text symptoms fields require consultations.manage. $this->actingAs($this->user) ->get(route('care.consultations.show', $consultation)) ->assertOk() ->assertSee('Patient history form') ->assertSee('do not overwrite each other', false) ->assertSee('Start patient history form'); $this->actingAs($this->user) ->post(route('care.consultations.assessments.store', $consultation), [ 'template_code' => 'universal_intake', ]) ->assertRedirect(); $assessment = Assessment::first(); $this->assertNotNull($assessment); $this->assertSame($consultation->id, $assessment->consultation_id); $this->assertSame('universal_intake', $assessment->template->code); $this->actingAs($this->user) ->put(route('care.assessments.update', $assessment), [ 'answers' => [ 'chief_complaint' => 'Severe headache for 2 days', 'pain_score' => 7, 'smoking_status' => 'never', 'mobility' => 'independent', ], ]) ->assertRedirect(); $this->actingAs($this->user) ->post(route('care.assessments.complete', $assessment)) ->assertRedirect(); $assessment->refresh(); $this->assertTrue($assessment->isCompleted()); // Dual narrative: free-text symptoms unchanged by structured intake. $this->assertSame('Free-text headache narrative', $consultation->fresh()->symptoms); $this->actingAs($this->user) ->get(route('care.patients.show', $this->patient)) ->assertOk() ->assertSee('Patient history form') ->assertSee('Severe headache for 2 days'); } public function test_create_form_lists_seeded_universal_for_nurse(): void { $this->seed(AssessmentTemplateSeeder::class); $this->actingAs($this->user) ->get(route('care.assessments.create', $this->patient)) ->assertOk() ->assertSee('Universal Intake') ->assertSee('universal_intake'); } }