add new ststs feature
Deploy to Shared Hosting / Shared hosting deploy (push) Failing after 51s
Tests / PHPUnit (push) Successful in 1m25s

This commit is contained in:
root
2026-09-13 02:20:14 -04:00
parent 1787144f27
commit c3a30989b2
16 changed files with 1395 additions and 84 deletions
@@ -135,6 +135,9 @@ final class ExamDraftControllerGroupingTest extends CIUnitTestCase
public function testGeneratedPdfBesideDocxIsRejectedAsLossy(): void
{
$directory = WRITEPATH . 'uploads/exams/finals';
if (!is_dir($directory)) {
$this->assertTrue(mkdir($directory, 0755, true) || is_dir($directory));
}
$base = 'conversion-safety-' . uniqid('', true);
$pdf = $directory . '/' . $base . '.pdf';
$docx = $directory . '/' . $base . '.docx';
@@ -0,0 +1,81 @@
<?php
namespace Tests\App\Services;
use App\Services\AcademicStatisticsService;
use CodeIgniter\Test\CIUnitTestCase;
class AcademicStatisticsServiceTest extends CIUnitTestCase
{
public function testSummarizesUniqueStudentsScoresAndClasses(): void
{
$stats = AcademicStatisticsService::summarize([
['student_id' => 1, 'class_section_id' => 10, 'class_section_name' => '1-A', 'gender' => 'Male', 'fall_score' => 80, 'spring_score' => 100],
['student_id' => 2, 'class_section_id' => 10, 'class_section_name' => '1-A', 'gender' => 'female', 'fall_score' => 55, 'spring_score' => null],
['student_id' => 3, 'class_section_id' => 20, 'class_section_name' => '2-A', 'gender' => 'girl', 'fall_score' => null, 'spring_score' => null],
], '2025-2026');
$this->assertSame(3, $stats['totalStudents']);
$this->assertSame(2, $stats['totalClasses']);
$this->assertSame(2, $stats['scoredStudents']);
$this->assertSame(72.5, $stats['averageScore']);
$this->assertSame(50.0, $stats['passRate']);
$this->assertSame(1, $stats['topPerformers']);
$this->assertSame(['Pass' => 1, 'Fail' => 1, 'Awaiting results' => 1], $stats['results']);
$this->assertSame(['Male' => 1, 'Female' => 2], $stats['gender']);
$this->assertSame([
'labels' => ['1-A', '2-A'],
'values' => [2, 1],
'male' => [1, 0],
'female' => [1, 1],
], $stats['classSizes']);
$this->assertSame([
'Passed' => ['Male' => 1, 'Female' => 0],
'Failed' => ['Male' => 0, 'Female' => 1],
'Top performers' => ['Male' => 1, 'Female' => 0],
'Trophy winners' => ['Male' => 1, 'Female' => 1],
], $stats['genderByStat']);
$this->assertSame(2, $stats['trophyWinners']);
$this->assertSame(['Male' => 1, 'Female' => 1], $stats['trophyGender']);
}
public function testAveragesMultipleClassScoresOncePerStudent(): void
{
$stats = AcademicStatisticsService::summarize([
['student_id' => 9, 'class_section_id' => 1, 'class_section_name' => 'Quran', 'gender' => 'M', 'fall_score' => 100, 'spring_score' => 100],
['student_id' => 9, 'class_section_id' => 2, 'class_section_name' => 'Arabic', 'gender' => 'M', 'fall_score' => 80, 'spring_score' => 80],
]);
$this->assertSame(1, $stats['totalStudents']);
$this->assertSame(2, $stats['totalClasses']);
$this->assertSame(90.0, $stats['averageScore']);
$this->assertSame(1, $stats['topPerformers']);
}
public function testKgStudentsPassWithoutSemesterScores(): void
{
$stats = AcademicStatisticsService::summarize([
['student_id' => 21, 'class_section_id' => 3, 'class_section_name' => 'KG-A', 'gender' => 'Male', 'fall_score' => null, 'spring_score' => null],
['student_id' => 22, 'class_section_id' => 4, 'class_section_name' => '1-A', 'gender' => 'Female', 'fall_score' => null, 'spring_score' => null],
]);
$this->assertSame(['Pass' => 1, 'Fail' => 0, 'Awaiting results' => 1], $stats['results']);
$this->assertSame(100.0, $stats['passRate']);
$this->assertSame(1, $stats['scoreBands']['KG Passed']);
$this->assertSame(['Male' => 1, 'Female' => 0], $stats['genderByStat']['Passed']);
}
public function testTrophyWinnersUseClassThresholdAndAreDistributedByGender(): void
{
$stats = AcademicStatisticsService::summarize([
['student_id' => 31, 'class_section_id' => 8, 'class_section_name' => '4-A', 'gender' => 'Male', 'fall_score' => 100, 'spring_score' => 100],
['student_id' => 32, 'class_section_id' => 8, 'class_section_name' => '4-A', 'gender' => 'Female', 'fall_score' => 90, 'spring_score' => 90],
['student_id' => 33, 'class_section_id' => 8, 'class_section_name' => '4-A', 'gender' => 'boy', 'fall_score' => 80, 'spring_score' => 80],
['student_id' => 34, 'class_section_id' => 8, 'class_section_name' => '4-A', 'gender' => 'girl', 'fall_score' => 70, 'spring_score' => 70],
]);
$this->assertSame(3, $stats['trophyWinners']);
$this->assertSame(['Male' => 2, 'Female' => 1], $stats['trophyGender']);
$this->assertSame(['Male' => 2, 'Female' => 1], $stats['genderByStat']['Trophy winners']);
}
}
@@ -0,0 +1,24 @@
<?php
namespace Tests\App\Services;
use App\Services\FinancialCategorySummaryService;
use CodeIgniter\Test\CIUnitTestCase;
class FinancialCategorySummaryServiceTest extends CIUnitTestCase
{
public function testDonationsAreIncomeAndExcludedFromExpenses(): void
{
$summary = FinancialCategorySummaryService::summarize([
['category' => 'Books', 'amount' => 125.50],
['category' => 'Donation', 'amount' => 500],
['category' => 'Office Supplies', 'amount' => 75],
['category' => 'donation', 'amount' => 25],
]);
$this->assertSame(200.50, $summary['totalExpenses']);
$this->assertSame(525.0, $summary['donationIncome']);
$this->assertSame(['Books' => 125.50, 'Office Supplies' => 75.0], $summary['expenseCategories']);
$this->assertArrayNotHasKey('Donation', $summary['expenseCategories']);
}
}