Files
alrahma_sunday_school_api/tests/Unit/Services/Attendance/StudentAttendanceWriterServiceTest.php
T
2026-03-08 16:33:24 -04:00

322 lines
10 KiB
PHP

<?php
namespace Tests\Unit\Services\Attendance;
use App\Models\AttendanceData;
use App\Models\AttendanceRecord;
use App\Models\Student;
use App\Services\Attendance\AttendanceRecordSyncService;
use App\Services\Attendance\StudentAttendanceWriterService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use RuntimeException;
use Tests\TestCase;
class StudentAttendanceWriterServiceTest extends TestCase
{
use RefreshDatabase;
protected StudentAttendanceWriterService $service;
protected function setUp(): void
{
parent::setUp();
$this->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);
}
}