Files
alrahma_sunday_school_api/tests/Unit/Services/AssignmentServiceTest.php
T
2026-06-09 01:25:14 -04:00

398 lines
13 KiB
PHP

<?php
namespace Tests\Unit\Services;
use App\Models\ClassSection;
use App\Models\Configuration;
use App\Models\Student;
use App\Models\StudentClass;
use App\Models\TeacherClass;
use App\Models\User;
use App\Services\AssignmentService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AssignmentServiceTest extends TestCase
{
use RefreshDatabase;
protected AssignmentService $service;
protected User $teacherMain;
protected User $teacherAssistant;
protected User $updatedByUser;
protected ClassSection $sectionA;
protected ClassSection $sectionB;
protected Student $studentOne;
protected Student $studentTwo;
protected function setUp(): void
{
parent::setUp();
$this->service = app(AssignmentService::class);
Configuration::query()->create([
'config_key' => 'semester',
'config_value' => 'Fall',
]);
Configuration::query()->create([
'config_key' => 'school_year',
'config_value' => '2025-2026',
]);
$this->updatedByUser = User::factory()->create();
$this->teacherMain = User::factory()->create([
'firstname' => 'John',
'lastname' => 'Doe',
]);
$this->teacherAssistant = User::factory()->create([
'firstname' => 'Jane',
'lastname' => 'Smith',
]);
$this->sectionA = ClassSection::factory()->create([
'section_name' => 'Alpha Section',
]);
$this->sectionB = ClassSection::factory()->create([
'section_name' => 'Beta Section',
]);
$this->studentOne = Student::factory()->create([
'firstname' => 'Ali',
'lastname' => 'One',
'age' => 10,
'gender' => 'Male',
'registration_grade' => 'Grade 4',
'photo_consent' => 1,
'tuition_paid' => 0,
'school_id' => 'S-100',
'is_active' => 1,
]);
$this->studentTwo = Student::factory()->create([
'firstname' => 'Maya',
'lastname' => 'Two',
'age' => 11,
'gender' => 'Female',
'registration_grade' => 'Grade 5',
'photo_consent' => 0,
'tuition_paid' => 1,
'school_id' => 'S-101',
'is_active' => 1,
]);
}
public function test_get_current_semester_returns_config_value(): void
{
$this->assertSame('Fall', $this->service->getCurrentSemester());
}
public function test_get_current_school_year_returns_config_value(): void
{
$this->assertSame('2025-2026', $this->service->getCurrentSchoolYear());
}
public function test_get_assignments_overview_returns_grouped_sections(): void
{
TeacherClass::query()->create([
'teacher_id' => $this->teacherMain->id,
'class_section_id' => $this->sectionA->id,
'position' => 'main',
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Alpha description',
]);
TeacherClass::query()->create([
'teacher_id' => $this->teacherAssistant->id,
'class_section_id' => $this->sectionA->id,
'position' => 'ta',
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Alpha description',
]);
StudentClass::query()->create([
'student_id' => $this->studentOne->id,
'class_section_id' => $this->sectionA->id,
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Alpha description',
'updated_by' => $this->updatedByUser->id,
]);
$result = $this->service->getAssignmentsOverview('2025-2026', 'Fall');
$this->assertSame('2025-2026', $result['schoolYear']);
$this->assertSame('2025-2026', $result['selectedYear']);
$this->assertSame('Fall', $result['selectedSemester']);
$this->assertSame('Fall', $result['semester']);
$this->assertSame('2025-2026', $result['current_school_year']);
$this->assertCount(1, $result['classSections']);
$section = $result['classSections'][0];
$this->assertSame($this->sectionA->id, $section['class_section_id']);
$this->assertSame('Alpha Section', $section['class_section_name']);
$this->assertSame(['John Doe'], $section['main_teachers']);
$this->assertSame(['Jane Smith'], $section['teacher_assistants']);
$this->assertSame('Fall', $section['semester']);
$this->assertSame('2025-2026', $section['school_year']);
$this->assertSame('Alpha description', $section['description']);
$this->assertCount(1, $section['students']);
$this->assertSame('Ali', $section['students'][0]['firstname']);
}
public function test_get_assignments_overview_uses_fallback_config_values_when_metadata_missing(): void
{
TeacherClass::query()->create([
'teacher_id' => $this->teacherMain->id,
'class_section_id' => $this->sectionA->id,
'position' => 'main',
'semester' => '',
'school_year' => null,
'description' => null,
]);
$result = $this->service->getAssignmentsOverview();
$section = $result['classSections'][0];
$this->assertSame('Fall', $section['semester']);
$this->assertSame('2025-2026', $section['school_year']);
$this->assertSame('', $section['description']);
}
public function test_get_assignments_overview_excludes_inactive_students(): void
{
$inactiveStudent = Student::factory()->create([
'firstname' => 'Inactive',
'lastname' => 'Student',
'is_active' => 0,
]);
TeacherClass::query()->create([
'teacher_id' => $this->teacherMain->id,
'class_section_id' => $this->sectionA->id,
'position' => 'main',
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Alpha description',
]);
StudentClass::query()->create([
'student_id' => $inactiveStudent->id,
'class_section_id' => $this->sectionA->id,
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Should not appear',
'updated_by' => $this->updatedByUser->id,
]);
$result = $this->service->getAssignmentsOverview();
$section = $result['classSections'][0];
$this->assertSame([], $section['students']);
}
public function test_get_assignments_overview_sorts_sections_by_name(): void
{
TeacherClass::query()->create([
'teacher_id' => $this->teacherMain->id,
'class_section_id' => $this->sectionB->id,
'position' => 'main',
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Beta description',
]);
TeacherClass::query()->create([
'teacher_id' => $this->teacherAssistant->id,
'class_section_id' => $this->sectionA->id,
'position' => 'main',
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Alpha description',
]);
$result = $this->service->getAssignmentsOverview();
$this->assertCount(2, $result['classSections']);
$this->assertSame('Alpha Section', $result['classSections'][0]['class_section_name']);
$this->assertSame('Beta Section', $result['classSections'][1]['class_section_name']);
}
public function test_get_assignments_overview_collects_school_years_descending(): void
{
TeacherClass::query()->create([
'teacher_id' => $this->teacherMain->id,
'class_section_id' => $this->sectionA->id,
'position' => 'main',
'semester' => 'Fall',
'school_year' => '2024-2025',
'description' => 'Old year',
]);
TeacherClass::query()->create([
'teacher_id' => $this->teacherAssistant->id,
'class_section_id' => $this->sectionB->id,
'position' => 'main',
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'New year',
]);
$result = $this->service->getAssignmentsOverview();
$this->assertSame(['2025-2026', '2024-2025'], array_values($result['schoolYears']));
}
public function test_store_assignment_creates_new_row(): void
{
$assignment = $this->service->storeAssignment([
'student_id' => $this->studentOne->id,
'class_section_id' => $this->sectionA->id,
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Created by service',
], $this->updatedByUser->id);
$this->assertInstanceOf(StudentClass::class, $assignment);
$this->assertDatabaseHas('student_class', [
'student_id' => $this->studentOne->id,
'class_section_id' => $this->sectionA->id,
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Created by service',
'updated_by' => $this->updatedByUser->id,
]);
}
public function test_store_assignment_updates_existing_row(): void
{
StudentClass::query()->create([
'student_id' => $this->studentOne->id,
'class_section_id' => $this->sectionA->id,
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Old',
'updated_by' => $this->updatedByUser->id,
]);
$assignment = $this->service->storeAssignment([
'student_id' => $this->studentOne->id,
'class_section_id' => $this->sectionA->id,
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'New',
], $this->updatedByUser->id);
$this->assertSame('New', $assignment->description);
$this->assertSame(
1,
StudentClass::query()
->where('student_id', $this->studentOne->id)
->where('class_section_id', $this->sectionA->id)
->where('semester', 'Fall')
->where('school_year', '2025-2026')
->count()
);
$this->assertDatabaseHas('student_class', [
'student_id' => $this->studentOne->id,
'class_section_id' => $this->sectionA->id,
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'New',
]);
}
public function test_get_class_assignment_data_returns_all_sections(): void
{
TeacherClass::query()->create([
'teacher_id' => $this->teacherMain->id,
'class_section_id' => $this->sectionA->id,
'position' => 'main',
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Alpha description',
]);
TeacherClass::query()->create([
'teacher_id' => $this->teacherAssistant->id,
'class_section_id' => $this->sectionB->id,
'position' => 'ta',
'semester' => 'Spring',
'school_year' => '2025-2026',
'description' => 'Beta description',
]);
StudentClass::query()->create([
'student_id' => $this->studentOne->id,
'class_section_id' => $this->sectionA->id,
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Alpha description',
'updated_by' => $this->updatedByUser->id,
]);
StudentClass::query()->create([
'student_id' => $this->studentTwo->id,
'class_section_id' => $this->sectionB->id,
'semester' => 'Spring',
'school_year' => '2025-2026',
'description' => 'Beta description',
'updated_by' => $this->updatedByUser->id,
]);
$result = $this->service->getClassAssignmentData();
$this->assertSame('Fall', $result['semester']);
$this->assertSame('2025-2026', $result['school_year']);
$this->assertCount(2, $result['classSections']);
$this->assertSame('Alpha Section', $result['classSections'][0]['class_section_name']);
$this->assertSame('Beta Section', $result['classSections'][1]['class_section_name']);
}
public function test_get_class_assignment_data_deduplicates_teacher_names(): void
{
TeacherClass::query()->create([
'teacher_id' => $this->teacherMain->id,
'class_section_id' => $this->sectionA->id,
'position' => 'main',
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Alpha description',
]);
TeacherClass::query()->create([
'teacher_id' => $this->teacherMain->id,
'class_section_id' => $this->sectionA->id,
'position' => 'main',
'semester' => 'Fall',
'school_year' => '2025-2026',
'description' => 'Alpha description',
]);
$result = $this->service->getClassAssignmentData();
$this->assertSame(
['John Doe'],
$result['classSections'][0]['main_teachers']
);
}
}