322 lines
10 KiB
PHP
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);
|
|
}
|
|
} |