143 lines
5.3 KiB
PHP
143 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace Tests\App\Services;
|
|
|
|
use App\Services\EmailService;
|
|
use App\Services\EnrollmentRegistrationEmailService;
|
|
use App\Services\EnrollmentTransitionService;
|
|
use App\Support\Enrollment\DeliberationDecision;
|
|
use CodeIgniter\Database\BaseBuilder;
|
|
use CodeIgniter\Database\BaseConnection;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class EnrollmentRegistrationEmailServiceTest extends TestCase
|
|
{
|
|
public function testPassedStudentMessageStaysConcise(): void
|
|
{
|
|
$service = $this->service();
|
|
|
|
$evaluation = [
|
|
'deliberation_decision' => DeliberationDecision::PASSED,
|
|
'placement_status' => 'exit_required',
|
|
'source_grade_name' => '8',
|
|
'adult_student' => false,
|
|
'blockers' => [
|
|
'The student has passed the highest available grade and must follow the school completion or exit process.',
|
|
'Registration for the new school year has not opened yet.',
|
|
],
|
|
];
|
|
|
|
$status = $this->invoke($service, 'registrationStatus', [$evaluation]);
|
|
$message = $this->invoke($service, 'decisionMessage', ['Student Name', $evaluation, 'August 1, 2026', 'August 31, 2026']);
|
|
$action = $this->invoke($service, 'requiredAction', [$evaluation, 'August 31, 2026']);
|
|
|
|
$this->assertSame('Eligible', $status);
|
|
$this->assertStringContainsString('Student Name has successfully passed Grade 8.', $message);
|
|
$this->assertStringNotContainsString('Re-enrollment for the new school year will open on August 1, 2026.', $message);
|
|
$this->assertStringNotContainsString('Please make sure to re-enroll your child before August 31, 2026', $message);
|
|
$this->assertStringNotContainsString('sign in to the parent portal', $message);
|
|
$this->assertStringContainsString('Complete re-enrollment before August 31, 2026.', $action);
|
|
$this->assertStringNotContainsString('Not Eligible', $status);
|
|
$this->assertStringNotContainsString('Registration for the new school year has not opened yet', $message);
|
|
$this->assertStringNotContainsString('Contact the school administration.', $action);
|
|
}
|
|
|
|
public function testFinancialSectionIsHiddenWhenNothingIsDue(): void
|
|
{
|
|
$service = $this->service();
|
|
|
|
$html = $this->invoke($service, 'financialSection', [10, [
|
|
'registration_fee' => 0,
|
|
'tuition_due_at_registration' => 0,
|
|
'mandatory_fees' => 0,
|
|
], null]);
|
|
|
|
$this->assertSame('', $html);
|
|
}
|
|
|
|
public function testFinancialSectionShowsWhenAnyAmountIsDue(): void
|
|
{
|
|
$service = $this->service();
|
|
|
|
$html = $this->invoke($service, 'financialSection', [10, [
|
|
'registration_fee' => 25,
|
|
'tuition_due_at_registration' => 0,
|
|
'mandatory_fees' => 0,
|
|
], null]);
|
|
|
|
$this->assertStringContainsString('Family Account Information', $html);
|
|
$this->assertStringContainsString('Total currently due:</strong> $25.00', $html);
|
|
}
|
|
|
|
public function testAutomaticDistributionPlacementShowsOnlyGrade(): void
|
|
{
|
|
$service = $this->service();
|
|
|
|
$placement = $this->invoke($service, 'placementText', [[
|
|
'placement_status' => 'automatic_distribution_pending',
|
|
'assigned_grade_name' => '9',
|
|
]]);
|
|
|
|
$this->assertSame('Grade 9', $placement);
|
|
}
|
|
|
|
public function testForceCannotSendWithoutAdminLaunchApproval(): void
|
|
{
|
|
$emailService = $this->createMock(EmailService::class);
|
|
$emailService->expects($this->never())->method('send');
|
|
$service = $this->service($this->dbWithNoRecipientFamilies(), $emailService);
|
|
|
|
$summary = $service->sendForSchoolYear([
|
|
'name' => '2026-2027',
|
|
'registration_launch_approved_at' => null,
|
|
], null, false, true);
|
|
|
|
$this->assertSame(0, $summary['sent']);
|
|
$this->assertSame(1, $summary['skipped']);
|
|
$this->assertStringContainsString('not approved', implode(' ', $summary['messages']));
|
|
}
|
|
|
|
/**
|
|
* @param list<mixed> $args
|
|
*/
|
|
private function invoke(EnrollmentRegistrationEmailService $service, string $method, array $args): mixed
|
|
{
|
|
$reflection = new \ReflectionMethod($service, $method);
|
|
$reflection->setAccessible(true);
|
|
|
|
return $reflection->invokeArgs($service, $args);
|
|
}
|
|
|
|
private function service(?BaseConnection $db = null, ?EmailService $emailService = null): EnrollmentRegistrationEmailService
|
|
{
|
|
$db ??= $this->createMock(BaseConnection::class);
|
|
|
|
return new EnrollmentRegistrationEmailService(
|
|
$db,
|
|
new EnrollmentTransitionService($db),
|
|
$emailService ?? $this->createMock(EmailService::class),
|
|
);
|
|
}
|
|
|
|
private function dbWithNoRecipientFamilies(): BaseConnection
|
|
{
|
|
$query = new class {
|
|
public function getResultArray(): array
|
|
{
|
|
return [];
|
|
}
|
|
};
|
|
|
|
$builder = $this->createMock(BaseBuilder::class);
|
|
$builder->method('select')->willReturnSelf();
|
|
$builder->method('where')->willReturnSelf();
|
|
$builder->method('get')->willReturn($query);
|
|
|
|
$db = $this->createMock(BaseConnection::class);
|
|
$db->method('table')->willReturn($builder);
|
|
$db->method('fieldExists')->with('user_type', 'users')->willReturn(false);
|
|
|
|
return $db;
|
|
}
|
|
}
|