198 lines
5.5 KiB
PHP
198 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace Tests\App\Controllers\Api;
|
|
|
|
use App\Controllers\Api\NotificationController;
|
|
use CodeIgniter\HTTP\URI;
|
|
use CodeIgniter\HTTP\UserAgent;
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
|
use CodeIgniter\Test\Mock\MockIncomingRequest;
|
|
use Config\App;
|
|
|
|
class StubUserNotificationModel
|
|
{
|
|
public array $whereHistory = [];
|
|
private ?array $firstResult = null;
|
|
public ?array $lastUpdate = null;
|
|
|
|
public function select(string $columns): self
|
|
{
|
|
return $this;
|
|
}
|
|
|
|
public function join(string $table, string $cond): self
|
|
{
|
|
return $this;
|
|
}
|
|
|
|
public function where(string $column, $value = null): self
|
|
{
|
|
$this->whereHistory[] = ['column' => $column, 'value' => $value];
|
|
return $this;
|
|
}
|
|
|
|
public function first(): ?array
|
|
{
|
|
return $this->firstResult;
|
|
}
|
|
|
|
public function update(int $id, array $data): bool
|
|
{
|
|
$this->lastUpdate = ['id' => $id, 'data' => $data];
|
|
return true;
|
|
}
|
|
|
|
public function setFirstResult(?array $result): void
|
|
{
|
|
$this->firstResult = $result;
|
|
}
|
|
}
|
|
|
|
class FakeNotificationRequest extends MockIncomingRequest
|
|
{
|
|
public function __construct(private readonly array $params = [])
|
|
{
|
|
parent::__construct(config(App::class), new URI('https://test.alrahmaisgl.org'), null, new UserAgent());
|
|
}
|
|
|
|
public function getGet($key = null, $filter = null, $default = null)
|
|
{
|
|
if ($key === null) {
|
|
return $this->params;
|
|
}
|
|
|
|
return $this->params[$key] ?? $default;
|
|
}
|
|
}
|
|
|
|
class TestableNotificationController extends NotificationController
|
|
{
|
|
private array $overridePagination = [];
|
|
private ?object $currentUser = null;
|
|
|
|
public function __construct()
|
|
{
|
|
// Skip normal boot to keep dependencies under test control.
|
|
}
|
|
|
|
public function setModels(StubUserNotificationModel $model): void
|
|
{
|
|
$this->userNotificationModel = $model;
|
|
}
|
|
|
|
public function setCurrentUser(object $user): void
|
|
{
|
|
$this->currentUser = $user;
|
|
}
|
|
|
|
public function setPaginatedResult(array $result): void
|
|
{
|
|
$this->overridePagination = $result;
|
|
}
|
|
|
|
protected function paginate($source, int $page = 1, int $perPage = 20): array
|
|
{
|
|
if (!empty($this->overridePagination)) {
|
|
return $this->overridePagination;
|
|
}
|
|
|
|
return parent::paginate($source, $page, $perPage);
|
|
}
|
|
|
|
protected function getCurrentUser(): ?object
|
|
{
|
|
return $this->currentUser;
|
|
}
|
|
}
|
|
|
|
class NotificationControllerTest extends CIUnitTestCase
|
|
{
|
|
private TestableNotificationController $controller;
|
|
private StubUserNotificationModel $model;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->controller = new TestableNotificationController();
|
|
$this->model = new StubUserNotificationModel();
|
|
$this->controller->setModels($this->model);
|
|
$this->controller->setCurrentUser((object) ['id' => 42]);
|
|
}
|
|
|
|
public function testIndexReturnsPaginatedNotifications()
|
|
{
|
|
$payload = ['data' => [['id' => 1]], 'pagination' => ['total' => 1]];
|
|
$this->controller->setPaginatedResult($payload);
|
|
$request = new FakeNotificationRequest();
|
|
$this->controller->setRequest($request);
|
|
|
|
$response = $this->controller->index();
|
|
|
|
$this->assertTrue($response['status']);
|
|
$this->assertSame($payload, $response['data']);
|
|
$this->assertSame('Notifications retrieved successfully', $response['message']);
|
|
}
|
|
|
|
public function testIndexRespectsReadFilter()
|
|
{
|
|
$payload = ['data' => [], 'pagination' => ['total' => 0]];
|
|
$this->controller->setPaginatedResult($payload);
|
|
$request = new FakeNotificationRequest(['read' => 'false']);
|
|
$this->controller->setRequest($request);
|
|
|
|
$this->controller->index();
|
|
|
|
$readWhere = array_filter(
|
|
$this->model->whereHistory,
|
|
static fn ($entry) => $entry['column'] === 'user_notifications.is_read'
|
|
);
|
|
|
|
$this->assertNotEmpty($readWhere);
|
|
$this->assertSame(0, $readWhere[array_key_last($readWhere)]['value']);
|
|
}
|
|
|
|
public function testShowReturnsNotification()
|
|
{
|
|
$this->model->setFirstResult(['id' => 99, 'notification_id' => 99]);
|
|
|
|
$response = $this->controller->show(99);
|
|
|
|
$this->assertTrue($response['status']);
|
|
$this->assertSame('Notification retrieved successfully', $response['message']);
|
|
}
|
|
|
|
public function testShowReturns404WhenMissing()
|
|
{
|
|
$this->model->setFirstResult(null);
|
|
|
|
$response = $this->controller->show(9);
|
|
|
|
$this->assertFalse($response['status']);
|
|
$this->assertSame(404, $response['code']);
|
|
}
|
|
|
|
public function testMarkReadUpdatesNotification()
|
|
{
|
|
$this->model->setFirstResult(['id' => 50, 'notification_id' => 500]);
|
|
|
|
$response = $this->controller->markRead(500);
|
|
|
|
$this->assertTrue($response['status']);
|
|
$this->assertSame('Notification marked as read', $response['message']);
|
|
$this->assertSame(50, $this->model->lastUpdate['id']);
|
|
$this->assertSame(1, $this->model->lastUpdate['data']['is_read']);
|
|
$this->assertNotEmpty($this->model->lastUpdate['data']['read_at']);
|
|
}
|
|
|
|
public function testMarkReadReturns404WhenNotFound()
|
|
{
|
|
$this->model->setFirstResult(null);
|
|
|
|
$response = $this->controller->markRead(77);
|
|
|
|
$this->assertFalse($response['status']);
|
|
$this->assertSame(404, $response['code']);
|
|
}
|
|
}
|