fix is_new issue with enrollment fixes
Deploy to Shared Hosting / Shared hosting deploy (push) Failing after 48s
Tests / PHPUnit (push) Failing after 1m22s

This commit is contained in:
root
2026-08-20 19:57:25 -04:00
parent 127098b87c
commit 889c037660
29 changed files with 77306 additions and 293 deletions
@@ -0,0 +1,117 @@
<?php
namespace Tests\App\Services;
use App\Services\AdministratorDashboardService;
use App\Services\AdminNotificationSettingsService;
use App\Services\StudentDecisionService;
use App\Support\Enrollment\DeliberationDecision;
use CodeIgniter\Database\BaseConnection;
use PHPUnit\Framework\TestCase;
final class ExtractedAdminAndGradingServiceTest extends TestCase
{
public function testAdminNotificationSubjectOptionsAreStable(): void
{
$service = new AdminNotificationSettingsService(
$this->createMock(BaseConnection::class),
$this->createMock(\App\Models\AdminNotificationSubjectModel::class)
);
$this->assertSame([
'academics' => 'Academics',
'attendance' => 'Attendance',
'events' => 'Events',
'finance' => 'Finance',
'general' => 'General',
'print_requests' => 'Print Requests',
], $service->subjectOptions());
}
public function testAdminNotificationExcludedRolesIncludeParentAndTeacher(): void
{
$service = new AdminNotificationSettingsService(
$this->createMock(BaseConnection::class),
$this->createMock(\App\Models\AdminNotificationSubjectModel::class)
);
$excluded = $service->excludedRoles();
$this->assertContains('parent', $excluded);
$this->assertContains('teacher', $excluded);
$this->assertContains('teacher_assistant', $excluded);
}
public function testDashboardCountUniqueEntitiesDedupesIds(): void
{
$service = new AdministratorDashboardService(
$this->createMock(BaseConnection::class),
$this->createMock(\App\Models\UserModel::class),
$this->createMock(\App\Models\LoginActivityModel::class)
);
$count = $this->invoke($service, 'countUniqueEntities', [[
['id' => 1],
['id' => 1],
['user_id' => 2],
['user_id' => 2],
['name' => 'ignored'],
]]);
$this->assertSame(2, $count);
}
public function testStudentDecisionClassLabelHelpers(): void
{
$service = new StudentDecisionService(
$this->createMock(BaseConnection::class),
$this->createMock(\App\Models\ConfigurationModel::class),
$this->createMock(\App\Models\StudentModel::class),
$this->createMock(\App\Models\StudentClassModel::class),
$this->createMock(\App\Models\UserModel::class)
);
$this->assertSame('Class 8A', $this->invoke($service, 'classOnlyLabel', ['Class 8A']));
$this->assertSame('Class 8', $this->invoke($service, 'classOnlyLabel', ['Class 8-A']));
$this->assertTrue($this->invoke($service, 'isKgClass', ['KG']));
$this->assertTrue($this->invoke($service, 'isKgClass', ['Kindergarten']));
$this->assertFalse($this->invoke($service, 'isKgClass', ['Class 1']));
}
public function testNextYearPlacementLabelUsesDeliberationDecision(): void
{
$service = new StudentDecisionService(
$this->createMock(BaseConnection::class),
$this->createMock(\App\Models\ConfigurationModel::class),
$this->createMock(\App\Models\StudentModel::class),
$this->createMock(\App\Models\StudentClassModel::class),
$this->createMock(\App\Models\UserModel::class)
);
$repeat = $this->invoke($service, 'nextYearPlacementLabel', [
DeliberationDecision::REPEAT_CLASS,
'Class 5',
'5A',
'2015-01-01',
'2024-2025',
]);
$this->assertSame('Class 5', $repeat);
$passed = $this->invoke($service, 'nextYearPlacementLabel', [
DeliberationDecision::PASSED,
'Class 5',
'5A',
'2015-01-01',
'2024-2025',
]);
$this->assertSame('', $passed);
}
private function invoke(object $service, string $method, array $args = []): mixed
{
$ref = new \ReflectionMethod($service, $method);
$ref->setAccessible(true);
return $ref->invokeArgs($service, $args);
}
}
@@ -0,0 +1,112 @@
<?php
namespace Tests\App\Services;
use App\Models\StudentYearStatusModel;
use App\Services\StudentYearStatusService;
use App\Support\SchoolYear\SchoolYearTableRegistry;
use CodeIgniter\Database\BaseConnection;
use PHPUnit\Framework\TestCase;
final class StudentYearStatusServiceTest extends TestCase
{
public function testIsNewDefaultsTrueWhenNoRowExists(): void
{
$db = $this->createMock(BaseConnection::class);
$db->method('tableExists')->willReturn(true);
$yearStatusModel = $this->getMockBuilder(StudentYearStatusModel::class)
->disableOriginalConstructor()
->onlyMethods(['first'])
->addMethods(['where'])
->getMock();
$yearStatusModel->method('where')->willReturnSelf();
$yearStatusModel->method('first')->willReturn(null);
$service = new StudentYearStatusService($db, $yearStatusModel);
$this->assertTrue($service->isNew(42, '2025-2026'));
}
public function testIsNewReadsYearScopedFlag(): void
{
$db = $this->createMock(BaseConnection::class);
$db->method('tableExists')->willReturn(true);
$yearStatusModel = $this->getMockBuilder(StudentYearStatusModel::class)
->disableOriginalConstructor()
->onlyMethods(['first'])
->addMethods(['where'])
->getMock();
$yearStatusModel->method('where')->willReturnSelf();
$yearStatusModel->method('first')->willReturn([
'student_id' => 7,
'school_year' => '2025-2026',
'is_new' => 0,
]);
$service = new StudentYearStatusService($db, $yearStatusModel);
$this->assertFalse($service->isNew(7, '2025-2026'));
}
public function testAttachToStudentsAppliesYearFlags(): void
{
$db = $this->createMock(BaseConnection::class);
$db->method('tableExists')->willReturn(true);
$yearStatusModel = $this->getMockBuilder(StudentYearStatusModel::class)
->disableOriginalConstructor()
->onlyMethods(['findAll'])
->addMethods(['select', 'whereIn', 'where'])
->getMock();
$yearStatusModel->method('select')->willReturnSelf();
$yearStatusModel->method('whereIn')->willReturnSelf();
$yearStatusModel->method('where')->willReturnSelf();
$yearStatusModel->method('findAll')->willReturn([
['student_id' => 1, 'is_new' => 1],
['student_id' => 2, 'is_new' => 0],
]);
$service = new StudentYearStatusService($db, $yearStatusModel);
$students = [
['id' => 1, 'is_new' => 0],
['student_id' => 2, 'is_new' => 1],
['id' => 3, 'is_new' => 0],
];
$service->attachToStudents($students, '2025-2026');
$this->assertSame(1, $students[0]['is_new']);
$this->assertSame(0, $students[1]['is_new']);
$this->assertSame(1, $students[2]['is_new']);
}
public function testUpsertInsertsYearRowOnly(): void
{
$db = $this->createMock(BaseConnection::class);
$db->method('tableExists')->willReturn(true);
$yearStatusModel = $this->getMockBuilder(StudentYearStatusModel::class)
->disableOriginalConstructor()
->onlyMethods(['insert', 'update', 'first'])
->addMethods(['where'])
->getMock();
$yearStatusModel->method('where')->willReturnSelf();
$yearStatusModel->method('first')->willReturn(null);
$yearStatusModel->expects($this->once())->method('insert')->with([
'student_id' => 9,
'school_year' => '2025-2026',
'is_new' => 0,
]);
$service = new StudentYearStatusService($db, $yearStatusModel);
$service->upsert(9, '2025-2026', false);
}
public function testRegistryIncludesStudentYearStatus(): void
{
$this->assertTrue(SchoolYearTableRegistry::isYearScoped('student_year_status'));
}
}