fix invalid token
This commit is contained in:
@@ -11,7 +11,7 @@ class DeleteInactiveUsers extends BaseCommand
|
|||||||
{
|
{
|
||||||
protected $group = 'Maintenance';
|
protected $group = 'Maintenance';
|
||||||
protected $name = 'users:delete-inactive-users';
|
protected $name = 'users:delete-inactive-users';
|
||||||
protected $description = 'Delete users that are inactive and created more than 15 minutes ago, along with their entries in the parents table and user_roles table if applicable.';
|
protected $description = 'Delete unverified inactive registrations created more than 15 minutes ago, along with their entries in the parents table and user_roles table if applicable.';
|
||||||
|
|
||||||
public function run(array $params)
|
public function run(array $params)
|
||||||
{
|
{
|
||||||
@@ -24,11 +24,12 @@ class DeleteInactiveUsers extends BaseCommand
|
|||||||
log_message('debug', 'Cutoff time for deletion: ' . $cutoffTime);
|
log_message('debug', 'Cutoff time for deletion: ' . $cutoffTime);
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────
|
||||||
// 1 Fetch inactive users older than 15 min
|
// 1 Fetch unfinished registrations older than 15 min
|
||||||
// ─────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────
|
||||||
$users = $db->table('users')
|
$users = $db->table('users')
|
||||||
->select('id, firstname, lastname, email, created_at')
|
->select('id, firstname, lastname, email, created_at')
|
||||||
->where('status', 'Inactive')
|
->where('status', 'Inactive')
|
||||||
|
->where('is_verified', 0)
|
||||||
->where('created_at <', $cutoffTime)
|
->where('created_at <', $cutoffTime)
|
||||||
->get()
|
->get()
|
||||||
->getResultArray();
|
->getResultArray();
|
||||||
@@ -102,4 +103,4 @@ class DeleteInactiveUsers extends BaseCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -442,7 +442,7 @@ class ParentAttendanceReportController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Build formatted success message
|
// ✅ Build formatted success message
|
||||||
$msg = '✅ <strong>Submission received successfully for ' . count($successNames) . ' item' . (count($successNames) > 1 ? 's' : '') . '.</strong><br>';
|
$msg = '✅ <strong>Submission received successfully for ' . count($successNames) . ' student' . (count($successNames) > 1 ? 's' : '') . '.</strong><br>';
|
||||||
$msg .= '<ul style="margin-top:5px;">';
|
$msg .= '<ul style="margin-top:5px;">';
|
||||||
foreach ($successNames as $s) {
|
foreach ($successNames as $s) {
|
||||||
$dateLabel = $s['date_label'] ?? ($s['date'] ?? '');
|
$dateLabel = $s['date_label'] ?? ($s['date'] ?? '');
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ use App\Services\Parents\ParentAttendanceService;
|
|||||||
use App\Services\Parents\ParentEnrollmentService;
|
use App\Services\Parents\ParentEnrollmentService;
|
||||||
use App\Services\Parents\ParentEventParticipationService;
|
use App\Services\Parents\ParentEventParticipationService;
|
||||||
use App\Services\Parents\ParentPaymentService;
|
use App\Services\Parents\ParentPaymentService;
|
||||||
|
use App\Services\Parents\ParentRegistrationNotificationService;
|
||||||
use App\Services\Parents\ParentRegistrationService;
|
use App\Services\Parents\ParentRegistrationService;
|
||||||
use App\Support\Enrollment\DeliberationDecision;
|
use App\Support\Enrollment\DeliberationDecision;
|
||||||
use App\Support\Enrollment\EnrollmentEligibility;
|
use App\Support\Enrollment\EnrollmentEligibility;
|
||||||
@@ -71,6 +72,7 @@ class ParentController extends BaseController
|
|||||||
protected ?ParentEnrollmentService $parentEnrollmentService = null;
|
protected ?ParentEnrollmentService $parentEnrollmentService = null;
|
||||||
protected ParentEventParticipationService $parentEventParticipationService;
|
protected ParentEventParticipationService $parentEventParticipationService;
|
||||||
protected ParentPaymentService $parentPaymentService;
|
protected ParentPaymentService $parentPaymentService;
|
||||||
|
protected ParentRegistrationNotificationService $parentRegistrationNotificationService;
|
||||||
protected ?ParentRegistrationService $parentRegistrationService = null;
|
protected ?ParentRegistrationService $parentRegistrationService = null;
|
||||||
|
|
||||||
|
|
||||||
@@ -95,6 +97,11 @@ class ParentController extends BaseController
|
|||||||
$this->parentAccountService = new ParentAccountService($this->db, $this->userModel, $this->authorizedUsersModel);
|
$this->parentAccountService = new ParentAccountService($this->db, $this->userModel, $this->authorizedUsersModel);
|
||||||
$this->parentAttendanceService = new ParentAttendanceService($this->db);
|
$this->parentAttendanceService = new ParentAttendanceService($this->db);
|
||||||
$this->parentPaymentService = new ParentPaymentService($this->db);
|
$this->parentPaymentService = new ParentPaymentService($this->db);
|
||||||
|
$this->parentRegistrationNotificationService = new ParentRegistrationNotificationService(
|
||||||
|
$this->userModel,
|
||||||
|
$this->studentModel,
|
||||||
|
service('emailService')
|
||||||
|
);
|
||||||
$this->parentEnrollmentService = new ParentEnrollmentService(
|
$this->parentEnrollmentService = new ParentEnrollmentService(
|
||||||
$this->db,
|
$this->db,
|
||||||
$this->userModel,
|
$this->userModel,
|
||||||
@@ -180,10 +187,9 @@ class ParentController extends BaseController
|
|||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
// Retrieve all parents from the database where role is parent
|
return view('administrator/parent', [
|
||||||
$parents = $this->userModel->where('role', 'parent')->findAll();
|
'parents' => $this->parentAccountService->administratorParentList(),
|
||||||
// Pass the parents to the view
|
]);
|
||||||
return view('administrator/parent', ['parents' => $parents]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create()
|
public function create()
|
||||||
@@ -194,44 +200,29 @@ class ParentController extends BaseController
|
|||||||
|
|
||||||
public function store()
|
public function store()
|
||||||
{
|
{
|
||||||
// Handle the form submission to create a new parent
|
$this->parentAccountService->createAdministratorParent((array) $this->request->getPost());
|
||||||
$data = [
|
|
||||||
'firstname' => $this->request->getPost('firstname'),
|
|
||||||
'lastname' => $this->request->getPost('lastname'),
|
|
||||||
'email' => strtolower($this->request->getPost('email')),
|
|
||||||
'password' => password_hash($this->request->getPost('password'), PASSWORD_DEFAULT),
|
|
||||||
'role' => 'parent',
|
|
||||||
];
|
|
||||||
$this->userModel->insert($data);
|
|
||||||
return redirect()->to('/administrator/parent');
|
return redirect()->to('/administrator/parent');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit($id)
|
public function edit($id)
|
||||||
{
|
{
|
||||||
// Retrieve the parent details to edit
|
return view('administrator/edit_parent', [
|
||||||
$parent = $this->userModel->find($id);
|
'parent' => $this->parentAccountService->parentById((int) $id),
|
||||||
return view('administrator/edit_parent', ['parent' => $parent]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update($id)
|
public function update($id)
|
||||||
{
|
{
|
||||||
// Handle the form submission to update an existing parent
|
$this->parentAccountService->updateAdministratorParent((int) $id, (array) $this->request->getPost());
|
||||||
$data = [
|
|
||||||
'firstname' => $this->request->getPost('firstname'),
|
|
||||||
'lastname' => $this->request->getPost('lastname'),
|
|
||||||
'email' => strtolower($this->request->getPost('email')),
|
|
||||||
];
|
|
||||||
if ($this->request->getPost('password')) {
|
|
||||||
$data['password'] = password_hash($this->request->getPost('password'), PASSWORD_DEFAULT);
|
|
||||||
}
|
|
||||||
$this->userModel->update($id, $data);
|
|
||||||
return redirect()->to('/administrator/parent');
|
return redirect()->to('/administrator/parent');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy($id)
|
public function destroy($id)
|
||||||
{
|
{
|
||||||
// Delete the parent
|
$this->parentAccountService->deleteParent((int) $id);
|
||||||
$this->userModel->delete($id);
|
|
||||||
return redirect()->to('/administrator/parent');
|
return redirect()->to('/administrator/parent');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2192,7 +2183,7 @@ class ParentController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($registeredStudentIds !== []) {
|
if ($registeredStudentIds !== []) {
|
||||||
$this->notifyAdminsAboutRegisteredStudents($registeredStudentIds, (int) $parentId);
|
$this->parentRegistrationNotificationService->sendAdminNewStudentEmails($registeredStudentIds, (int) $parentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($studentAdded) {
|
if ($studentAdded) {
|
||||||
@@ -2208,55 +2199,6 @@ class ParentController extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Send admin registration emails after commit so only saved students are reported.
|
|
||||||
*
|
|
||||||
* @param list<int> $studentIds
|
|
||||||
*/
|
|
||||||
private function notifyAdminsAboutRegisteredStudents(array $studentIds, int $parentId): void
|
|
||||||
{
|
|
||||||
$parent = $this->userModel->find($parentId);
|
|
||||||
if (! is_array($parent)) {
|
|
||||||
log_message('warning', 'Unable to send admin student registration email: parent not found for ID ' . $parentId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (array_values(array_unique(array_filter(array_map('intval', $studentIds)))) as $studentId) {
|
|
||||||
$student = $this->studentModel->find($studentId);
|
|
||||||
if (! is_array($student)) {
|
|
||||||
log_message('warning', 'Unable to send admin student registration email: student not found for ID ' . $studentId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$payload = $student;
|
|
||||||
$payload['parents'] = [
|
|
||||||
'user_id' => $parentId,
|
|
||||||
'firstname' => (string) ($parent['firstname'] ?? ''),
|
|
||||||
'lastname' => (string) ($parent['lastname'] ?? ''),
|
|
||||||
'email' => (string) ($parent['email'] ?? ''),
|
|
||||||
];
|
|
||||||
|
|
||||||
$studentFullName = trim((string) ($student['firstname'] ?? '') . ' ' . (string) ($student['lastname'] ?? '')) ?: 'Student ID ' . $studentId;
|
|
||||||
$adminMessage = view('emails/admin_student_registered', ['student' => $payload], ['saveData' => true]);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$sent = service('emailService')->send(
|
|
||||||
'registration@alrahmaisgl.org',
|
|
||||||
'New Student Registered: ' . $studentFullName,
|
|
||||||
$adminMessage,
|
|
||||||
'notifications'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (! $sent) {
|
|
||||||
log_message('error', 'Admin student registration email failed for student ID ' . $studentId);
|
|
||||||
}
|
|
||||||
} catch (Throwable $e) {
|
|
||||||
log_message('error', 'Admin student registration email failed for student ID ' . $studentId . ': ' . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Function to check if the parent has registered kids and redirect accordingly
|
// Function to check if the parent has registered kids and redirect accordingly
|
||||||
public function registerKidCheck()
|
public function registerKidCheck()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ require_once APPPATH . 'Helpers/pbkdf2_helper.php';
|
|||||||
|
|
||||||
class UserController extends BaseController
|
class UserController extends BaseController
|
||||||
{
|
{
|
||||||
private const ACTIVATION_TTL_HOURS = 48;
|
private const ACTIVATION_TTL_MINUTES = 15;
|
||||||
protected $userModel;
|
protected $userModel;
|
||||||
protected $roleModel;
|
protected $roleModel;
|
||||||
protected $userRoleModel;
|
protected $userRoleModel;
|
||||||
@@ -654,30 +654,7 @@ class UserController extends BaseController
|
|||||||
|
|
||||||
public function confirm($token)
|
public function confirm($token)
|
||||||
{
|
{
|
||||||
log_message('info', 'Processing email confirmation.');
|
return $this->setPassword($token);
|
||||||
|
|
||||||
$tokenHash = $this->hashToken($token);
|
|
||||||
$user = $this->userModel
|
|
||||||
->groupStart()
|
|
||||||
->where('token', $tokenHash)
|
|
||||||
->orWhere('token', $token)
|
|
||||||
->groupEnd()
|
|
||||||
->where('created_at >=', Time::now()->subHours(self::ACTIVATION_TTL_HOURS)->toDateTimeString())
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (!$user || $user['is_verified'] == 1) {
|
|
||||||
return redirect()->to('/invalid_token');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Mark the user as verified and generate an account ID
|
|
||||||
$account_id = 'ACC' . str_pad($user['id'], 8, '0', STR_PAD_LEFT); // Example: ACC00000001
|
|
||||||
$this->userModel->update($user['id'], ['is_verified' => 1, 'token' => null, 'account_id' => $account_id]);
|
|
||||||
|
|
||||||
log_message('info', 'User verified and account ID generated: ' . $account_id);
|
|
||||||
|
|
||||||
// Redirect to the set password page
|
|
||||||
return redirect()->to('/set_password/' . $user['id']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPassword($token)
|
public function setPassword($token)
|
||||||
@@ -690,7 +667,7 @@ class UserController extends BaseController
|
|||||||
->where('token', $tokenHash)
|
->where('token', $tokenHash)
|
||||||
->orWhere('token', $token)
|
->orWhere('token', $token)
|
||||||
->groupEnd()
|
->groupEnd()
|
||||||
->where('created_at >=', Time::now()->subHours(self::ACTIVATION_TTL_HOURS)->toDateTimeString())
|
->where('created_at >=', Time::now()->subMinutes(self::ACTIVATION_TTL_MINUTES)->toDateTimeString())
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
if (!$user || $user['is_verified'] == 1) {
|
if (!$user || $user['is_verified'] == 1) {
|
||||||
@@ -747,7 +724,7 @@ class UserController extends BaseController
|
|||||||
->where('token', $tokenHash)
|
->where('token', $tokenHash)
|
||||||
->orWhere('token', $token)
|
->orWhere('token', $token)
|
||||||
->groupEnd()
|
->groupEnd()
|
||||||
->where('created_at >=', Time::now()->subHours(self::ACTIVATION_TTL_HOURS)->toDateTimeString())
|
->where('created_at >=', Time::now()->subMinutes(self::ACTIVATION_TTL_MINUTES)->toDateTimeString())
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
log_message('debug', "Attempting to set password for user $userId");
|
log_message('debug', "Attempting to set password for user $userId");
|
||||||
|
|||||||
@@ -31,6 +31,6 @@ class CleanupScheduler implements FilterInterface
|
|||||||
{
|
{
|
||||||
// Call the cleanup controller method
|
// Call the cleanup controller method
|
||||||
\CodeIgniter\CLI\CLI::init();
|
\CodeIgniter\CLI\CLI::init();
|
||||||
command('cleanup:unverified_users');
|
command('users:delete-inactive-users');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,12 +85,12 @@ class UserModel extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get unverified users created more than 2 minutes ago.
|
* Get unverified users created more than 15 minutes ago.
|
||||||
*/
|
*/
|
||||||
public function getUnverifiedUsers()
|
public function getUnverifiedUsers()
|
||||||
{
|
{
|
||||||
return $this->where('is_verified', 0)
|
return $this->where('is_verified', 0)
|
||||||
->where('created_at <', date('Y-m-d H:i:s', time() - 120))
|
->where('created_at <', date('Y-m-d H:i:s', time() - 15 * 60))
|
||||||
->findAll();
|
->findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,49 @@ class ParentAccountService
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function administratorParentList(): array
|
||||||
|
{
|
||||||
|
return $this->userModel->where('role', 'parent')->findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parentById(int $id): ?array
|
||||||
|
{
|
||||||
|
$parent = $this->userModel->find($id);
|
||||||
|
|
||||||
|
return is_array($parent) ? $parent : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createAdministratorParent(array $post): bool|int|string
|
||||||
|
{
|
||||||
|
return $this->userModel->insert([
|
||||||
|
'firstname' => $post['firstname'] ?? null,
|
||||||
|
'lastname' => $post['lastname'] ?? null,
|
||||||
|
'email' => strtolower((string) ($post['email'] ?? '')),
|
||||||
|
'password' => password_hash((string) ($post['password'] ?? ''), PASSWORD_DEFAULT),
|
||||||
|
'role' => 'parent',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateAdministratorParent(int $id, array $post): bool
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'firstname' => $post['firstname'] ?? null,
|
||||||
|
'lastname' => $post['lastname'] ?? null,
|
||||||
|
'email' => strtolower((string) ($post['email'] ?? '')),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (! empty($post['password'])) {
|
||||||
|
$data['password'] = password_hash((string) $post['password'], PASSWORD_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (bool) $this->userModel->update($id, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteParent(int $id): bool
|
||||||
|
{
|
||||||
|
return (bool) $this->userModel->delete($id);
|
||||||
|
}
|
||||||
|
|
||||||
public function createRelatedUser(array $userData, string $relationToStudent, string $semester, string $schoolYear): int|false
|
public function createRelatedUser(array $userData, string $relationToStudent, string $semester, string $schoolYear): int|false
|
||||||
{
|
{
|
||||||
$schoolIdService = new SchoolIdService();
|
$schoolIdService = new SchoolIdService();
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Parents;
|
||||||
|
|
||||||
|
use App\Models\StudentModel;
|
||||||
|
use App\Models\UserModel;
|
||||||
|
use App\Services\EmailService;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class ParentRegistrationNotificationService
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly UserModel $userModel,
|
||||||
|
private readonly StudentModel $studentModel,
|
||||||
|
private readonly EmailService $emailService,
|
||||||
|
private readonly string $adminEmail = 'registration@alrahmaisgl.org',
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param list<int> $studentIds
|
||||||
|
*/
|
||||||
|
public function sendAdminNewStudentEmails(array $studentIds, int $parentId): void
|
||||||
|
{
|
||||||
|
$parent = $this->userModel->find($parentId);
|
||||||
|
if (! is_array($parent)) {
|
||||||
|
log_message('warning', 'Unable to send admin student registration email: parent not found for ID ' . $parentId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (array_values(array_unique(array_filter(array_map('intval', $studentIds)))) as $studentId) {
|
||||||
|
$student = $this->studentModel->find($studentId);
|
||||||
|
if (! is_array($student)) {
|
||||||
|
log_message('warning', 'Unable to send admin student registration email: student not found for ID ' . $studentId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sendAdminNewStudentEmail($student, $parent, $parentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $student
|
||||||
|
* @param array<string, mixed> $parent
|
||||||
|
*/
|
||||||
|
private function sendAdminNewStudentEmail(array $student, array $parent, int $parentId): void
|
||||||
|
{
|
||||||
|
$studentId = (int) ($student['id'] ?? 0);
|
||||||
|
$studentFullName = trim((string) ($student['firstname'] ?? '') . ' ' . (string) ($student['lastname'] ?? ''))
|
||||||
|
?: 'Student ID ' . $studentId;
|
||||||
|
|
||||||
|
$payload = $student;
|
||||||
|
$payload['parents'] = [
|
||||||
|
'user_id' => $parentId,
|
||||||
|
'firstname' => (string) ($parent['firstname'] ?? ''),
|
||||||
|
'lastname' => (string) ($parent['lastname'] ?? ''),
|
||||||
|
'email' => (string) ($parent['email'] ?? ''),
|
||||||
|
];
|
||||||
|
|
||||||
|
$adminMessage = view('emails/admin_student_registered', ['student' => $payload], ['saveData' => true]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$sent = $this->emailService->send(
|
||||||
|
$this->adminEmail,
|
||||||
|
'New Student Registered: ' . $studentFullName,
|
||||||
|
$adminMessage,
|
||||||
|
'notifications'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (! $sent) {
|
||||||
|
log_message('error', 'Admin student registration email failed for student ID ' . $studentId);
|
||||||
|
}
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
log_message('error', 'Admin student registration email failed for student ID ' . $studentId . ': ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
if (! function_exists('view')) {
|
||||||
|
function view($name, array $data = [], $options = [])
|
||||||
|
{
|
||||||
|
return $name . ':' . ($data['student']['firstname'] ?? '') . ' ' . ($data['student']['lastname'] ?? '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Tests\App\Services {
|
||||||
|
|
||||||
|
use App\Models\StudentModel;
|
||||||
|
use App\Models\UserModel;
|
||||||
|
use App\Services\EmailService;
|
||||||
|
use App\Services\Parents\ParentRegistrationNotificationService;
|
||||||
|
use CodeIgniter\Test\CIUnitTestCase;
|
||||||
|
|
||||||
|
final class ParentRegistrationNotificationServiceTest extends CIUnitTestCase
|
||||||
|
{
|
||||||
|
public function testSendsAdminTemplateEmailForRegisteredStudent(): void
|
||||||
|
{
|
||||||
|
$userModel = $this->createMock(UserModel::class);
|
||||||
|
$userModel->expects($this->once())
|
||||||
|
->method('find')
|
||||||
|
->with(12)
|
||||||
|
->willReturn([
|
||||||
|
'firstname' => 'Parent',
|
||||||
|
'lastname' => 'One',
|
||||||
|
'email' => 'parent@example.test',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$studentModel = $this->createMock(StudentModel::class);
|
||||||
|
$studentModel->expects($this->once())
|
||||||
|
->method('find')
|
||||||
|
->with(34)
|
||||||
|
->willReturn([
|
||||||
|
'id' => 34,
|
||||||
|
'firstname' => 'Student',
|
||||||
|
'lastname' => 'One',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$emailService = $this->createMock(EmailService::class);
|
||||||
|
$emailService->expects($this->once())
|
||||||
|
->method('send')
|
||||||
|
->with(
|
||||||
|
'registration@example.test',
|
||||||
|
'New Student Registered: Student One',
|
||||||
|
$this->stringContains('emails/admin_student_registered'),
|
||||||
|
'notifications'
|
||||||
|
)
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$service = new ParentRegistrationNotificationService(
|
||||||
|
$userModel,
|
||||||
|
$studentModel,
|
||||||
|
$emailService,
|
||||||
|
'registration@example.test'
|
||||||
|
);
|
||||||
|
|
||||||
|
$service->sendAdminNewStudentEmails([34], 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user