createUser('teacher')); $this->getJson('/api/v1/parent-profiles?school_year=2025-2026') ->assertForbidden(); } public function test_parent_profiles_rejects_school_year_id_context(): void { Sanctum::actingAs($this->createUser('admin')); $this->getJson('/api/v1/parent-profiles?school_year_id=1') ->assertStatus(422); } public function test_parent_profiles_index_lists_only_selected_year_relevant_parents(): void { Sanctum::actingAs($this->createUser('admin')); $selectedParent = $this->createUser('parent', 'selected@example.com'); $otherParent = $this->createUser('parent', 'other@example.com'); $this->createStudentFamily($selectedParent->id, 'Amina', 'Selected', '2025-2026'); $this->createStudentFamily($otherParent->id, 'Omar', 'Other', '2024-2025'); $response = $this->getJson('/api/v1/parent-profiles?school_year=2025-2026'); $response->assertOk(); $this->assertSame(['selected@example.com'], array_column($response->json('data.parents'), 'email')); } public function test_parent_profile_show_returns_selected_year_siblings_and_finance_only(): void { Sanctum::actingAs($this->createUser('admin')); $parent = $this->createUser('parent', 'parent@example.com'); $this->createStudentFamily($parent->id, 'Amina', 'Sibling', '2025-2026'); $this->createStudentFamily($parent->id, 'Yusuf', 'Sibling', '2025-2026'); $this->createStudentFamily($parent->id, 'Old', 'Student', '2024-2025'); $selectedInvoice = DB::table('invoices')->insertGetId([ 'parent_id' => $parent->id, 'invoice_number' => 'INV-2025', 'status' => 'open', 'total_amount' => 100, 'paid_amount' => 25, 'balance' => 75, 'school_year' => '2025-2026', 'issue_date' => now()->toDateString(), 'due_date' => now()->addDays(5)->toDateString(), 'created_at' => now(), 'updated_at' => now(), ]); DB::table('invoices')->insert([ 'parent_id' => $parent->id, 'invoice_number' => 'INV-2024', 'status' => 'open', 'total_amount' => 80, 'paid_amount' => 0, 'balance' => 80, 'school_year' => '2024-2025', 'issue_date' => now()->subYear()->toDateString(), 'due_date' => now()->subYear()->addDays(5)->toDateString(), 'created_at' => now(), 'updated_at' => now(), ]); DB::table('payments')->insert([ 'parent_id' => $parent->id, 'invoice_id' => $selectedInvoice, 'total_amount' => 100, 'paid_amount' => 25, 'balance' => 75, 'number_of_installments' => 1, 'payment_method' => 'cash', 'payment_date' => now()->toDateString(), 'status' => 'completed', 'school_year' => '2024-2025', 'created_at' => now(), 'updated_at' => now(), ]); DB::table('emergency_contacts')->insert([ 'parent_id' => $parent->id, 'emergency_contact_name' => 'Emergency One', 'relation' => 'uncle', 'cellphone' => '5555555555', 'semester' => 'Fall', 'school_year' => '2025-2026', 'created_at' => now(), 'updated_at' => now(), ]); $response = $this->getJson('/api/v1/parent-profiles/'.$parent->id.'?school_year=2025-2026'); $response->assertOk(); $this->assertSame(['Amina', 'Yusuf'], array_column($response->json('data.students'), 'firstname')); $this->assertSame(['INV-2025'], array_column($response->json('data.invoices'), 'invoice_number')); $this->assertEquals(75.0, $response->json('data.finance_summary.positive_unpaid_balance')); $this->assertCount(1, $response->json('data.payments')); $this->assertCount(1, $response->json('data.emergency_contacts')); } private function createUser(string $roleName, ?string $email = null): User { DB::table('school_years')->updateOrInsert( ['name' => '2025-2026'], [ 'start_date' => '2025-09-01', 'end_date' => '2026-06-30', 'status' => 'active', 'is_current' => 1, 'updated_at' => now(), 'created_at' => now(), ], ); $roleId = DB::table('roles')->insertGetId([ 'name' => $roleName, 'priority' => 1, 'is_active' => 1, ]); $user = User::query()->create([ 'firstname' => ucfirst($roleName), 'lastname' => 'User', 'email' => $email ?? ($roleName.uniqid().'@example.com'), 'cellphone' => '5555555555', 'address_street' => '123 Main', 'city' => 'City', 'state' => 'ST', 'zip' => '12345', 'accept_school_policy' => 1, 'status' => 'Active', 'is_verified' => 1, 'is_suspended' => 0, 'password' => bcrypt('secret'), 'semester' => 'Fall', 'school_year' => '2025-2026', ]); DB::table('user_roles')->insert([ 'user_id' => $user->id, 'role_id' => $roleId, ]); return $user; } private function createStudentFamily(int $parentId, string $firstname, string $lastname, string $schoolYear): void { $familyId = DB::table('families')->insertGetId([ 'family_code' => uniqid('fam_', true), 'household_name' => $lastname.' Household', 'is_active' => 1, 'created_at' => now(), 'updated_at' => now(), ]); $studentId = DB::table('students')->insertGetId([ 'firstname' => $firstname, 'lastname' => $lastname, 'is_active' => 1, 'parent_id' => $parentId, 'school_year' => $schoolYear, 'created_at' => now(), 'updated_at' => now(), ]); DB::table('family_guardians')->insert([ 'family_id' => $familyId, 'user_id' => $parentId, 'relation' => 'parent', 'is_primary' => 1, 'receive_emails' => 1, 'receive_sms' => 0, 'created_at' => now(), 'updated_at' => now(), ]); DB::table('family_students')->insert([ 'family_id' => $familyId, 'student_id' => $studentId, 'is_primary_home' => 1, 'created_at' => now(), 'updated_at' => now(), ]); } }