service = app(StudentAttendanceWriterService::class); } public function test_resolve_student_school_id_returns_passed_value_when_present(): void { $result = $this->service->resolveStudentSchoolId(100, 'SCH-100'); $this->assertSame('SCH-100', $result); } public function test_resolve_student_school_id_fetches_from_database_when_missing(): void { Student::query()->create([ 'id' => 101, 'firstname' => 'John', 'lastname' => 'Doe', 'school_id' => 'SCH-101', 'is_active' => 1, 'created_at' => now(), 'updated_at' => now(), ]); $result = $this->service->resolveStudentSchoolId(101, null); $this->assertSame('SCH-101', $result); } public function test_resolve_student_school_id_throws_when_student_missing(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Student school ID not found.'); $this->service->resolveStudentSchoolId(9999, null); } public function test_insert_attendance_data_creates_new_row(): void { $this->service->insertAttendanceData( classSectionId: 10, studentId: 200, studentSchoolId: 'SCH-200', status: 'Absent', reason: 'Sick', reported: 'yes', semester: 'Fall', schoolYear: '2025-2026', date: '2025-10-05', classId: 5, userId: 22 ); $this->assertDatabaseHas('attendance_data', [ 'class_id' => 5, 'class_section_id' => 10, 'student_id' => 200, 'school_id' => 'SCH-200', 'status' => 'absent', 'reason' => 'Sick', 'is_reported' => 'yes', 'is_notified' => 'no', 'semester' => 'Fall', 'school_year' => '2025-2026', 'date' => '2025-10-05', 'modified_by' => 22, ]); } public function test_update_attendance_data_updates_existing_row(): void { $row = AttendanceData::query()->create([ 'class_id' => 6, 'class_section_id' => 12, 'student_id' => 201, 'school_id' => 'SCH-201', 'status' => 'present', 'reason' => null, 'is_reported' => 'no', 'is_notified' => 'no', 'semester' => 'Fall', 'school_year' => '2025-2026', 'date' => '2025-10-12', 'modified_by' => 1, 'created_at' => now(), 'updated_at' => now(), ]); $this->service->updateAttendanceData( attendanceId: $row->id, newStatus: 'late', newReason: 'Traffic', reported: 'yes', userId: 99 ); $row->refresh(); $this->assertSame('late', $row->status); $this->assertSame('Traffic', $row->reason); $this->assertSame('yes', $row->is_reported); $this->assertSame(99, (int)$row->modified_by); } public function test_save_or_update_student_attendance_creates_new_attendance_and_record(): void { Student::query()->create([ 'id' => 300, 'firstname' => 'Sara', 'lastname' => 'Smith', 'school_id' => 'SCH-300', 'is_active' => 1, 'created_at' => now(), 'updated_at' => now(), ]); $result = $this->service->saveOrUpdateStudentAttendance([ 'class_section_id' => 15, 'student_id' => 300, 'school_id' => null, 'status' => 'present', 'reason' => 'On time', 'is_reported' => 'no', 'semester' => 'Fall', 'school_year' => '2025-2026', 'date' => '2025-10-19', 'class_id' => 9, 'user_id' => 88, ]); $this->assertSame('created', $result['mode']); $this->assertSame('present', $result['new_status']); $this->assertSame('SCH-300', $result['school_id']); $this->assertDatabaseHas('attendance_data', [ 'student_id' => 300, 'school_id' => 'SCH-300', 'status' => 'present', 'semester' => 'Fall', 'school_year' => '2025-2026', 'date' => '2025-10-19', ]); $this->assertDatabaseHas('attendance_record', [ 'student_id' => 300, 'school_id' => 'SCH-300', 'semester' => 'Fall', 'school_year' => '2025-2026', 'total_presence' => 1, 'total_absence' => 0, 'total_late' => 0, 'total_attendance' => 1, 'modified_by' => 88, ]); } public function test_save_or_update_student_attendance_updates_existing_attendance_and_record(): void { Student::query()->create([ 'id' => 301, 'firstname' => 'Ali', 'lastname' => 'Khan', 'school_id' => 'SCH-301', 'is_active' => 1, 'created_at' => now(), 'updated_at' => now(), ]); AttendanceRecord::query()->create([ 'class_section_id' => 16, 'student_id' => 301, 'school_id' => 'SCH-301', 'semester' => 'Fall', 'school_year' => '2025-2026', 'total_presence' => 2, 'total_absence' => 0, 'total_late' => 0, 'total_attendance' => 2, 'modified_by' => 1, 'created_at' => now(), 'updated_at' => now(), ]); $attendance = AttendanceData::query()->create([ 'class_id' => 10, 'class_section_id' => 16, 'student_id' => 301, 'school_id' => 'SCH-301', 'status' => 'present', 'reason' => null, 'is_reported' => 'no', 'is_notified' => 'no', 'semester' => 'Fall', 'school_year' => '2025-2026', 'date' => '2025-10-26', 'modified_by' => 1, 'created_at' => now(), 'updated_at' => now(), ]); $result = $this->service->saveOrUpdateStudentAttendance([ 'class_section_id' => 16, 'student_id' => 301, 'school_id' => 'SCH-301', 'status' => 'absent', 'reason' => 'Family trip', 'is_reported' => 'yes', 'semester' => 'Fall', 'school_year' => '2025-2026', 'date' => '2025-10-26', 'class_id' => 10, 'user_id' => 77, ]); $this->assertSame('updated', $result['mode']); $this->assertSame('present', $result['old_status']); $this->assertSame('absent', $result['new_status']); $attendance->refresh(); $this->assertSame('absent', $attendance->status); $this->assertSame('Family trip', $attendance->reason); $this->assertSame('yes', $attendance->is_reported); $this->assertSame(77, (int)$attendance->modified_by); $this->assertDatabaseHas('attendance_record', [ 'student_id' => 301, 'semester' => 'Fall', 'school_year' => '2025-2026', 'total_presence' => 1, 'total_absence' => 1, 'total_late' => 0, ]); } public function test_save_or_update_student_attendance_updates_existing_without_counter_change_when_status_same(): void { Student::query()->create([ 'id' => 302, 'firstname' => 'Mona', 'lastname' => 'Lee', 'school_id' => 'SCH-302', 'is_active' => 1, 'created_at' => now(), 'updated_at' => now(), ]); $record = AttendanceRecord::query()->create([ 'class_section_id' => 17, 'student_id' => 302, 'school_id' => 'SCH-302', 'semester' => 'Fall', 'school_year' => '2025-2026', 'total_presence' => 4, 'total_absence' => 1, 'total_late' => 0, 'total_attendance' => 5, 'modified_by' => 1, 'created_at' => now(), 'updated_at' => now(), ]); AttendanceData::query()->create([ 'class_id' => 11, 'class_section_id' => 17, 'student_id' => 302, 'school_id' => 'SCH-302', 'status' => 'present', 'reason' => null, 'is_reported' => 'no', 'is_notified' => 'no', 'semester' => 'Fall', 'school_year' => '2025-2026', 'date' => '2025-11-02', 'modified_by' => 1, 'created_at' => now(), 'updated_at' => now(), ]); $this->service->saveOrUpdateStudentAttendance([ 'class_section_id' => 17, 'student_id' => 302, 'school_id' => 'SCH-302', 'status' => 'present', 'reason' => 'Still present', 'is_reported' => 'no', 'semester' => 'Fall', 'school_year' => '2025-2026', 'date' => '2025-11-02', 'class_id' => 11, 'user_id' => 66, ]); $record->refresh(); $this->assertSame(4, (int)$record->total_presence); $this->assertSame(1, (int)$record->total_absence); $this->assertSame(0, (int)$record->total_late); $this->assertSame(5, (int)$record->total_attendance); } }