Files
2026-02-10 22:11:06 -05:00

258 lines
6.6 KiB
PHP

<?php
namespace Tests\App\Controllers\Api;
use App\Controllers\Api\MessagesController;
use App\Models\MessageModel as BaseMessageModel;
use App\Models\StudentClassModel as BaseStudentClassModel;
use App\Models\StudentModel as BaseStudentModel;
use App\Models\TeacherClassModel as BaseTeacherClassModel;
use App\Models\UserModel as BaseUserModel;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\HTTP\URI;
use CodeIgniter\HTTP\UserAgent;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\Mock\MockIncomingRequest;
use Config\App;
class FakeMessagesRequest extends MockIncomingRequest
{
public function __construct(private readonly ?array $json = null)
{
parent::__construct(config(App::class), new URI('http://example.com'), 'php://input', new UserAgent());
}
public function getJSON(bool $assoc = false, int $depth = 512, int $options = 0): ?array
{
return $this->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']);
}
}