recreate project
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\App\Controllers\Api;
|
||||
|
||||
use App\Controllers\Api\PreferencesController;
|
||||
use CodeIgniter\HTTP\URI;
|
||||
use CodeIgniter\HTTP\UserAgent;
|
||||
use CodeIgniter\Test\CIUnitTestCase;
|
||||
use CodeIgniter\Test\Mock\MockIncomingRequest;
|
||||
use Config\App;
|
||||
use Config\Services;
|
||||
|
||||
class StubPreferencesModel
|
||||
{
|
||||
private ?array $firstResult = null;
|
||||
private array $findResults = [];
|
||||
private int $nextInsertId = 200;
|
||||
public ?array $lastUpdate = null;
|
||||
public ?array $lastInsertData = null;
|
||||
|
||||
public function where(string $column, $value): self
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function first(): ?array
|
||||
{
|
||||
return $this->firstResult;
|
||||
}
|
||||
|
||||
public function setFirstResult(?array $result): void
|
||||
{
|
||||
$this->firstResult = $result;
|
||||
}
|
||||
|
||||
public function update(int $id, array $data): bool
|
||||
{
|
||||
$this->lastUpdate = ['id' => $id, 'data' => $data];
|
||||
$this->findResults[$id] = ['id' => $id] + $data;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function insert(array $data): int
|
||||
{
|
||||
$id = $this->nextInsertId++;
|
||||
$this->lastInsertData = $data;
|
||||
$this->findResults[$id] = ['id' => $id] + $data;
|
||||
return $id;
|
||||
}
|
||||
|
||||
public function find(int $id): ?array
|
||||
{
|
||||
return $this->findResults[$id] ?? null;
|
||||
}
|
||||
|
||||
public function setFindResult(int $id, array $result): void
|
||||
{
|
||||
$this->findResults[$id] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
class FakeJsonRequest extends MockIncomingRequest
|
||||
{
|
||||
public function __construct(private readonly ?array $payload)
|
||||
{
|
||||
parent::__construct(config(App::class), new URI('https://test.alrahmaisgl.org'), null, new UserAgent());
|
||||
}
|
||||
|
||||
public function getJSON(bool $assoc = false, int $depth = 512, int $options = 0): ?array
|
||||
{
|
||||
return $this->payload;
|
||||
}
|
||||
}
|
||||
|
||||
class TestablePreferencesController extends PreferencesController
|
||||
{
|
||||
private ?object $currentUser = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// Skip the real constructor to avoid bootstrapping models.
|
||||
}
|
||||
|
||||
public function setPreferencesModel(StubPreferencesModel $model): void
|
||||
{
|
||||
$this->preferencesModel = $model;
|
||||
}
|
||||
|
||||
public function setCurrentUser(?object $user): void
|
||||
{
|
||||
$this->currentUser = $user;
|
||||
}
|
||||
|
||||
protected function getCurrentUser(): ?object
|
||||
{
|
||||
return $this->currentUser;
|
||||
}
|
||||
}
|
||||
|
||||
class PreferencesControllerTest extends CIUnitTestCase
|
||||
{
|
||||
private TestablePreferencesController $controller;
|
||||
private StubPreferencesModel $preferencesModel;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
Services::resetSingle('validation');
|
||||
Services::resetSingle('session');
|
||||
|
||||
$this->preferencesModel = new StubPreferencesModel();
|
||||
|
||||
$this->controller = new TestablePreferencesController();
|
||||
$this->controller->setPreferencesModel($this->preferencesModel);
|
||||
}
|
||||
|
||||
public function testIndexRequiresAuthentication()
|
||||
{
|
||||
$this->controller->setCurrentUser(null);
|
||||
|
||||
$response = $this->controller->index();
|
||||
|
||||
$this->assertFalse($response['status']);
|
||||
$this->assertSame(401, $response['code']);
|
||||
$this->assertSame('Authentication required', $response['message']);
|
||||
}
|
||||
|
||||
public function testIndexReturnsDefaultsIfNoPreferences()
|
||||
{
|
||||
$this->controller->setCurrentUser((object) ['id' => 7]);
|
||||
$this->preferencesModel->setFirstResult(null);
|
||||
|
||||
$response = $this->controller->index();
|
||||
|
||||
$this->assertTrue($response['status']);
|
||||
$this->assertSame('Preferences retrieved successfully', $response['message']);
|
||||
$this->assertSame(1, $response['data']['notification_email']);
|
||||
$this->assertSame('light', $response['data']['theme']);
|
||||
$this->assertSame('blue', $response['data']['style_color']);
|
||||
$this->assertSame('white', $response['data']['menu_color']);
|
||||
}
|
||||
|
||||
public function testIndexPropagatesStoredPreferencesAndSessionStyles()
|
||||
{
|
||||
$this->controller->setCurrentUser((object) ['id' => 9]);
|
||||
$this->preferencesModel->setFirstResult([
|
||||
'id' => 11,
|
||||
'user_id' => 9,
|
||||
'notification_email' => 0,
|
||||
'notification_sms' => 0,
|
||||
'theme' => 'dark',
|
||||
'language' => 'fr',
|
||||
]);
|
||||
|
||||
session()->set('style_color', 'rose');
|
||||
session()->set('menu_color', 'navy');
|
||||
|
||||
$response = $this->controller->index();
|
||||
|
||||
$this->assertTrue($response['status']);
|
||||
$this->assertSame(0, $response['data']['notification_email']);
|
||||
$this->assertSame('rose', $response['data']['style_color']);
|
||||
$this->assertSame('navy', $response['data']['menu_color']);
|
||||
}
|
||||
|
||||
public function testUpdateReturnsValidationErrors()
|
||||
{
|
||||
$this->controller->setCurrentUser((object) ['id' => 3]);
|
||||
$this->setRequestPayload(['notification_email' => '2']);
|
||||
|
||||
$response = $this->controller->update();
|
||||
|
||||
$this->assertFalse($response['status']);
|
||||
$this->assertSame(422, $response['code']);
|
||||
$this->assertSame('Validation failed', $response['message']);
|
||||
$this->assertArrayHasKey('errors', $response);
|
||||
}
|
||||
|
||||
public function testUpdateInsertsWhenPreferencesAbsent()
|
||||
{
|
||||
$this->controller->setCurrentUser((object) ['id' => 12]);
|
||||
$this->preferencesModel->setFirstResult(null);
|
||||
|
||||
$payload = [
|
||||
'notification_email' => 0,
|
||||
'notification_sms' => 1,
|
||||
'theme' => 'dark',
|
||||
'language' => 'es',
|
||||
'style_color' => 'green',
|
||||
'menu_color' => 'brand',
|
||||
];
|
||||
|
||||
$this->setRequestPayload($payload);
|
||||
|
||||
$response = $this->controller->update();
|
||||
|
||||
$this->assertTrue($response['status']);
|
||||
$this->assertSame('Preferences updated successfully', $response['message']);
|
||||
$this->assertSame(0, $response['data']['notification_email']);
|
||||
$this->assertSame('green', session()->get('style_color'));
|
||||
$this->assertSame('brand', session()->get('menu_color'));
|
||||
$this->assertSame($this->preferencesModel->lastInsertData, [
|
||||
'user_id' => 12,
|
||||
'notification_email' => 0,
|
||||
'notification_sms' => 1,
|
||||
'theme' => 'dark',
|
||||
'language' => 'es',
|
||||
]);
|
||||
}
|
||||
|
||||
public function testUpdateModifiesExistingPreferences()
|
||||
{
|
||||
$this->controller->setCurrentUser((object) ['id' => 21]);
|
||||
$this->preferencesModel->setFirstResult([
|
||||
'id' => 18,
|
||||
'user_id' => 21,
|
||||
'notification_email' => 1,
|
||||
'notification_sms' => 1,
|
||||
'theme' => 'light',
|
||||
'language' => 'en',
|
||||
]);
|
||||
$this->preferencesModel->setFindResult(18, [
|
||||
'id' => 18,
|
||||
'user_id' => 21,
|
||||
'notification_email' => 1,
|
||||
'notification_sms' => 1,
|
||||
'theme' => 'light',
|
||||
'language' => 'en',
|
||||
]);
|
||||
|
||||
$payload = ['notification_email' => 1, 'notification_sms' => 0, 'language' => 'fr'];
|
||||
$this->setRequestPayload($payload);
|
||||
|
||||
$response = $this->controller->update();
|
||||
|
||||
$this->assertTrue($response['status']);
|
||||
$this->assertSame('Preferences updated successfully', $response['message']);
|
||||
$this->assertSame(1, $this->preferencesModel->lastUpdate['data']['notification_email']);
|
||||
$this->assertSame(0, $this->preferencesModel->lastUpdate['data']['notification_sms']);
|
||||
$this->assertSame(18, $this->preferencesModel->lastUpdate['id']);
|
||||
$this->assertSame('fr', $response['data']['language']);
|
||||
}
|
||||
|
||||
private function setRequestPayload(?array $payload): void
|
||||
{
|
||||
$request = new FakeJsonRequest($payload);
|
||||
$this->controller->setRequest($request);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user