json; } public function getPost($key = null, $filter = null, $default = null) { if ($key === null) { return $this->json ?? []; } return $this->json[$key] ?? $default; } } class StubMessageModel extends BaseMessageModel { public array $inbox = []; public array $sent = []; public array $drafts = []; public array $trashed = []; public array $inserted = []; public array $marked = []; public function __construct() { // avoid parent initialization } public function getInboxMessages($userId) { return $this->inbox; } public function getSentMessages($userId) { return $this->sent; } public function getDraftMessages($userId) { return $this->drafts; } public function getTrashedMessages($userId) { return $this->trashed; } public function insert($row = null, bool $returnID = true) { $this->inserted = is_array($row) ? $row : []; return 123; } public function find($id = null) { return ['id' => $id ?? 0] + $this->inserted; } public function markAsRead($messageId) { $this->marked[] = $messageId; } } class StubTeacherClassModel extends BaseTeacherClassModel { public array $data = []; public function findAll($limit = 0, $offset = 0) { return $this->data; } } class StubStudentClassModel extends BaseStudentClassModel { public array $perClass = []; private $lastClass = null; public function where($column, $value) { if ($column === 'class_section_id') { $this->lastClass = $value; } return $this; } public function findAll($limit = 0, $offset = 0) { return $this->perClass[$this->lastClass] ?? []; } } class StubStudentModel extends BaseStudentModel { public array $students = []; public function find($id = null) { return $this->students[$id] ?? null; } } class StubUserModel extends BaseUserModel { public array $users = []; public function find($id = null) { return $this->users[$id] ?? null; } } class TestableMessagesController extends MessagesController { public StubMessageModel $stubMessageModel; public StubTeacherClassModel $stubTeacherClassModel; public StubStudentClassModel $stubStudentClassModel; public StubStudentModel $stubStudentModel; public StubUserModel $stubUserModel; public array $receivedMessages = []; public array $read = []; public function __construct() { // intentionally skip parent constructor } protected function success($data = null, string $message = 'Success', int $code = ResponseInterface::HTTP_OK) { return ['data' => $data, 'message' => $message, 'code' => $code]; } protected function error(string $message = 'An error occurred', int $code = ResponseInterface::HTTP_BAD_REQUEST, ?array $errors = null) { return ['message' => $message, 'code' => $code, 'errors' => $errors]; } protected function getCurrentUser(): ?object { return (object)[ 'id' => 42, 'roles' => ['administrator'], ]; } protected function getReceivedMessages(int $userId): array { return $this->receivedMessages; } protected function markAsRead(int $messageId): void { $this->read[] = $messageId; } protected function generateMessageNumber(): string { return 'MSG-TEST'; } protected function getRecipientId(array $role): ?int { return 99; } public function setModels() { $this->messageModel = new StubMessageModel(); $this->teacherClassModel = new StubTeacherClassModel(); $this->studentClassModel = new StubStudentClassModel(); $this->studentModel = new StubStudentModel(); $this->userModel = new StubUserModel(); } } class MessagesControllerTest extends CIUnitTestCase { private TestableMessagesController $controller; protected function setUp(): void { parent::setUp(); $this->controller = new TestableMessagesController(); $this->controller->setModels(); } public function testInboxUsesMessageModel() { $this->controller->messageModel->inbox = [['id' => 1]]; $response = $this->controller->inbox(); $this->assertSame(ResponseInterface::HTTP_OK, $response['code']); $this->assertSame([['id' => 1]], $response['data']); } public function testSendCreatesMessageWhenRecipientProvided() { $request = new FakeMessagesRequest([ 'recipient_id' => 5, 'subject' => 'Hi', 'message' => 'Hello', ]); $this->controller->setRequest($request); $response = $this->controller->send(); $this->assertSame(ResponseInterface::HTTP_OK, $response['code']); $this->assertSame('Message sent successfully', $response['message']); $this->assertSame('MSG-TEST', $response['data']['message_number']); $this->assertNotEmpty($this->controller->messageModel->inserted); } public function testGetRecipientsReturnsTeachers() { $this->controller->teacherClassModel->data = [ ['teacher_id' => 12, 'class_section_id' => 1], ]; $this->controller->userModel->users = [ 12 => ['firstname' => 'Jane', 'lastname' => 'Doe'], ]; $response = $this->controller->getRecipients('teacher'); $this->assertSame(ResponseInterface::HTTP_OK, $response['code']); $this->assertCount(1, $response['data']); $this->assertSame('Jane Doe', $response['data'][0]['name']); } }