391 lines
13 KiB
PHP
391 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']
|
|
);
|
|
}
|
|
}
|