fix all issues before deploy
Deploy to Shared Hosting / Shared hosting deploy (push) Failing after 47s
Tests / PHPUnit (push) Failing after 1m18s

This commit is contained in:
root
2026-08-25 03:10:44 -04:00
parent 5f5afe97ad
commit 9899af7b37
11 changed files with 515 additions and 37 deletions
@@ -3,6 +3,7 @@
namespace Tests\App\Services;
use App\Services\EnrollmentTransitionService;
use App\Support\Enrollment\DeliberationDecision;
use CodeIgniter\Database\BaseBuilder;
use CodeIgniter\Database\BaseConnection;
use PHPUnit\Framework\TestCase;
@@ -27,6 +28,71 @@ final class EnrollmentTransitionServiceTest extends TestCase
$this->assertSame(10, (int) $result['id']);
}
public function testKgMissingDecisionUsesAgePlacementDecision(): void
{
$service = new EnrollmentTransitionService($this->createMock(BaseConnection::class));
$this->assertSame(
DeliberationDecision::PASSED,
$this->invoke($service, 'decisionForKgWithoutFinalDecision', [['class_name' => 'KG'], 6, ''])
);
$this->assertSame(
DeliberationDecision::REPEAT_CLASS,
$this->invoke($service, 'decisionForKgWithoutFinalDecision', [['class_name' => 'Kindergarten'], 5, ''])
);
$this->assertNull($this->invoke($service, 'decisionForKgWithoutFinalDecision', [['class_name' => 'KG'], 6, 'Needs review']));
$this->assertNull($this->invoke($service, 'decisionForKgWithoutFinalDecision', [['class_name' => '1'], 6, '']));
}
public function testExplicitNewStudentStatusMarksFirstEnrollmentCandidate(): void
{
$statusBuilder = $this->builderReturning(['is_new' => 1]);
$statusBuilder->method('where')->willReturnSelf();
$db = $this->createMock(BaseConnection::class);
$db->method('tableExists')->with('student_year_status')->willReturn(true);
$db->method('table')->with('student_year_status')->willReturn($statusBuilder);
$service = new EnrollmentTransitionService($db);
$this->assertTrue($this->invoke($service, 'isFirstEnrollmentStudent', [
42,
['school_year' => '2026-2027'],
'2026-2027',
]));
}
public function testFirstEnrollmentPlacementUsesRegistrationGradeBaseSection(): void
{
$classBuilder = $this->builderReturning(['id' => 3, 'class_name' => '3']);
$classBuilder->method('where')->willReturnSelf();
$sectionBuilder = $this->builderReturning([
'class_section_id' => 30,
'class_id' => 3,
'class_section_name' => '3',
]);
$sectionBuilder->method('where')->willReturnSelf();
$db = $this->createMock(BaseConnection::class);
$db->method('tableExists')->willReturnCallback(static fn (string $table): bool => $table === 'classSection');
$db->method('fieldExists')->willReturn(false);
$db->method('table')->willReturnCallback(static function (string $table) use ($classBuilder, $sectionBuilder) {
return $table === 'classes' ? $classBuilder : $sectionBuilder;
});
$service = new EnrollmentTransitionService($db);
$placement = $this->invoke($service, 'firstEnrollmentPlacement', [
['registration_grade' => 'Grade 3'],
'2026-2027',
]);
$this->assertSame(3, (int) $placement['assigned_grade_id']);
$this->assertSame(30, (int) $placement['assigned_class_section_id']);
$this->assertSame('same_class_assigned', $placement['placement_status']);
}
public function testClassLookupFallsBackToGlobalRowsWhenSchoolYearSpecificRowIsMissing(): void
{
$firstBuilder = $this->builderReturning(null);
@@ -145,6 +211,66 @@ final class EnrollmentTransitionServiceTest extends TestCase
$this->assertContains('SIBLING_LAST_NAME_MISMATCH', $evaluation['blocking_rule_codes']);
}
public function testNewStudentDoesNotMakeReturningSiblingsFailLastNameRule(): void
{
$studentBuilder = $this->createMock(BaseBuilder::class);
$studentBuilder->method('select')->willReturnSelf();
$studentBuilder->method('where')->willReturnSelf();
$studentBuilder->method('orderBy')->willReturnSelf();
$studentBuilder->method('get')->willReturn(new class {
public function getResultArray(): array
{
return [
['id' => 1, 'firstname' => 'Ibrahim', 'lastname' => 'Khalid', 'parent_id' => 9],
['id' => 2, 'firstname' => 'Eesa', 'lastname' => 'Khalid', 'parent_id' => 9],
['id' => 3, 'firstname' => 'Lamia', 'lastname' => 'Khalid', 'parent_id' => 9],
['id' => 4, 'firstname' => 'New', 'lastname' => 'Khalid', 'parent_id' => 9],
];
}
});
$assignmentBuilder = $this->createMock(BaseBuilder::class);
$assignmentBuilder->method('select')->willReturnSelf();
$assignmentBuilder->method('join')->willReturnSelf();
$assignmentBuilder->method('where')->willReturnSelf();
$assignmentBuilder->method('orderBy')->willReturnSelf();
$assignmentBuilder->method('limit')->willReturnSelf();
$assignmentBuilder->method('get')->willReturnCallback(new class {
private int $calls = 0;
public function __invoke(): object
{
$this->calls++;
$hasSourceAssignment = $this->calls <= 3;
return new class($hasSourceAssignment) {
public function __construct(private readonly bool $hasSourceAssignment)
{
}
public function getRowArray(): ?array
{
return $this->hasSourceAssignment ? ['class_section_id' => 10] : null;
}
};
}
});
$db = $this->createMock(BaseConnection::class);
$db->method('tableExists')->willReturnCallback(static fn (string $table): bool => in_array($table, ['students', 'student_class'], true));
$db->method('table')->willReturnCallback(static function (string $table) use ($studentBuilder, $assignmentBuilder) {
return $table === 'students' ? $studentBuilder : $assignmentBuilder;
});
$service = new EnrollmentTransitionService($db);
$evaluation = [];
$this->invoke($service, 'applyHouseholdLastNameRule', [&$evaluation, 9, '2025-2026']);
$this->assertTrue($evaluation['family_name_check_ok']);
$this->assertArrayNotHasKey('blocking_rule_codes', $evaluation);
}
public function testPreviousYearBalanceBlocksEnrollment(): void
{
$service = $this->serviceWithFinance(125.50, 'submission_blocked_until_payment');
@@ -343,6 +469,29 @@ final class EnrollmentTransitionServiceTest extends TestCase
$this->assertArrayNotHasKey('parent_enrollment_allowed', $evaluation);
}
public function testClassReassignmentFlagIsIgnored(): void
{
$db = $this->createMock(BaseConnection::class);
$db->method('tableExists')->with('enrollment_flags')->willReturn(true);
$db->expects($this->never())->method('table');
$service = new EnrollmentTransitionService($db);
$written = $this->invoke($service, 'upsertOpenFlag', [
123,
'2026-2027',
'2025-2026',
[
'flag_type' => 'CLASS_REASSIGNMENT_REQUIRED',
'priority' => 'normal',
'details' => ['reason' => 'repeat class'],
],
null,
]);
$this->assertFalse($written);
}
public function testPreviousLastNameExceptionDoesNotCarryForwardWhenNewStudentIsAdded(): void
{
$service = $this->serviceWithLastNameCarryForward(