AMS_Backend/tests/unit/UserTest.php
2025-11-06 13:41:06 +08:00

288 lines
11 KiB
PHP

<?php
namespace App\Tests\Controllers\Backend;
use App\Controllers\Backend\UserController;
use App\Models\User;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\HTTP\IncomingRequest;
class UserTest extends CIUnitTestCase
{
protected $mockUser;
protected $controller;
protected function setProtectedOrPrivateProperty($object, $property, $value)
{
$reflection = new \ReflectionObject($object);
while (!$reflection->hasProperty($property)) {
$reflection = $reflection->getParentClass();
if (!$reflection) {
throw new \Exception("Property {$property} does not exist");
}
}
$prop = $reflection->getProperty($property);
$prop->setAccessible(true);
$prop->setValue($object, $value);
}
protected function setUp(): void
{
parent::setUp();
$this->mockUser = $this->createMock(User::class);
$this->controller = new UserController();
$this->setProtectedOrPrivateProperty($this->controller, 'user', $this->mockUser);
$this->setProtectedOrPrivateProperty($this->controller, 'request', $this->createMock(IncomingRequest::class));
$this->setProtectedOrPrivateProperty($this->controller, 'response', service('response'));
}
public function testIndexReturnsUsers()
{
$users = [
['id' => 1, 'username' => 'john', 'name' => 'John Doe'],
['id' => 2, 'username' => 'jane', 'name' => 'Jane Doe'],
];
$this->mockUser->method('findAll')->willReturn($users);
$result = $this->controller->index();
$this->assertEquals(200, $result->getStatusCode());
$data = json_decode($result->getBody(), true);
$this->assertIsArray($data);
$this->assertArrayHasKey('status', $data);
$this->assertArrayHasKey('message', $data);
$this->assertArrayHasKey('data', $data);
$this->assertEquals('success', $data['status']);
$this->assertEquals('User data retrieved successfully.', $data['message']);
$this->assertEquals($users, $data['data']);
}
public function testIndexReturnsNoUsers()
{
$this->mockUser->method('findAll')->willReturn([]);
$result = $this->controller->index();
$this->assertEquals(200, $result->getStatusCode());
$data = json_decode($result->getBody(), true);
$this->assertIsArray($data);
$this->assertArrayHasKey('status', $data);
$this->assertArrayHasKey('message', $data);
$this->assertArrayHasKey('data', $data);
$this->assertEquals('error', $data['status']);
$this->assertEquals('No user data found.', $data['message']);
$this->assertEquals(null, $data['data']);
}
public function testShowReturnsUser()
{
$user = ['id' => 1, 'username' => 'john', 'name' => 'John Doe'];
$this->mockUser->method('find')->with(1)->willReturn($user);
$result = $this->controller->show(1);
$this->assertEquals(200, $result->getStatusCode());
$data = json_decode($result->getBody(), true);
$this->assertIsArray($data);
$this->assertArrayHasKey('status', $data);
$this->assertArrayHasKey('message', $data);
$this->assertArrayHasKey('data', $data);
$this->assertEquals('success', $data['status']);
$this->assertEquals('User retrieved successfully.', $data['message']);
$this->assertEquals($user, $data['data']);
}
public function testShowReturnsNotFound()
{
$this->mockUser->method('find')->with(99)->willReturn(null);
$result = $this->controller->show(99);
$this->assertEquals(404, $result->getStatusCode());
$data = json_decode($result->getBody(), true);
$this->assertIsArray($data);
$this->assertArrayHasKey('status', $data);
$this->assertArrayHasKey('message', $data);
$this->assertEquals('error', $data['status']);
$this->assertEquals('User not found.', $data['message']);
}
public function testCreateValidationFails()
{
$controller = $this->getMockBuilder(UserController::class)
->onlyMethods(['validate'])
->enableOriginalConstructor()
->getMock();
$controller->method('validate')->willReturn(false);
$validator = $this->getMockBuilder(\CodeIgniter\Validation\Validation::class)
->disableOriginalConstructor()
->getMock();
$validator->method('getErrors')->willReturn(['username' => 'Required']);
$this->setProtectedOrPrivateProperty($controller, 'validator', $validator);
$this->setProtectedOrPrivateProperty($controller, 'user', $this->mockUser);
$this->setProtectedOrPrivateProperty($controller, 'request', $this->createMock(\CodeIgniter\HTTP\IncomingRequest::class));
$this->setProtectedOrPrivateProperty($controller, 'response', service('response'));
$result = $controller->create();
$this->assertEquals(422, $result->getStatusCode());
$data = json_decode($result->getBody(), true);
$this->assertIsArray($data);
$this->assertArrayHasKey('status', $data);
$this->assertArrayHasKey('message', $data);
$this->assertArrayHasKey('error', $data);
$this->assertEquals('errors', $data['status']);
$this->assertEquals('Validation failed', $data['message']);
$this->assertArrayHasKey('username', $data['errors']);
}
public function testCreateSuccess()
{
$this->mockUser->method('insert')->willReturn(1);
$this->mockUser->method('find')->with(1)->willReturn([
'id' => 1, 'username' => 'john', 'name' => 'John Doe'
]);
$request = $this->createMock(IncomingRequest::class);
$request->method('getVar')->willReturnMap([
['username', 'john'],
['name', 'John Doe'],
['password_hash', 'password'],
['role', 'admin'],
['status', 'active'],
]);
$controller = $this->getMockBuilder(UserController::class)
->onlyMethods(['validate'])
->enableOriginalConstructor()
->getMock();
$controller->method('validate')->willReturn(true);
$this->setProtectedOrPrivateProperty($controller, 'request', $request);
$this->setProtectedOrPrivateProperty($controller, 'user', $this->mockUser);
$this->setProtectedOrPrivateProperty($controller, 'response', service('response'));
$result = $controller->create();
$this->assertEquals(201, $result->getStatusCode());
$data = json_decode($result->getBody(), true);
$this->assertIsArray($data);
$this->assertArrayHasKey('status', $data);
$this->assertArrayHasKey('message', $data);
$this->assertArrayHasKey('data', $data);
$this->assertEquals('success', $data['status']);
$this->assertEquals('User created successfully.', $data['message']);
$this->assertEquals([
'id' => 1, 'username' => 'john', 'name' => 'John Doe'
], $data['data']);
}
public function testUpdateUserNotFound()
{
$this->mockUser->method('find')->with(99)->willReturn(null);
$result = $this->controller->update(99);
$this->assertEquals(404, $result->getStatusCode());
$data = json_decode($result->getBody(), true);
$this->assertIsArray($data);
$this->assertArrayHasKey('status', $data);
$this->assertArrayHasKey('message', $data);
$this->assertEquals('error', $data['status']);
$this->assertEquals('User not found.', $data['message']);
}
public function testUpdateNoDataProvided()
{
$this->mockUser->method('find')->with(1)->willReturn(['id' => 1]);
$request = $this->createMock(IncomingRequest::class);
$request->method('getRawInput')->willReturn([]);
$request->method('getPost')->willReturn([]);
$this->setProtectedOrPrivateProperty($this->controller, 'request', $request);
$result = $this->controller->update(1);
$this->assertEquals(400, $result->getStatusCode());
$data = json_decode($result->getBody(), true);
$this->assertIsArray($data);
$this->assertArrayHasKey('status', $data);
$this->assertArrayHasKey('message', $data);
$this->assertEquals('error', $data['status']);
$this->assertEquals('No data provided to update.', $data['message']);
}
public function testUpdateSuccess()
{
$this->mockUser->method('find')->with(1)->willReturn(['id' => 1]);
$this->mockUser->expects($this->once())->method('update')->with(1, ['username' => 'john']);
$this->mockUser->method('find')->with(1)->willReturn(['id' => 1, 'username' => 'john']);
$request = $this->createMock(IncomingRequest::class);
$request->method('getRawInput')->willReturn(['username' => 'john']);
$request->method('getPost')->willReturn([]);
$this->setProtectedOrPrivateProperty($this->controller, 'request', $request);
$result = $this->controller->update(1);
$this->assertEquals(200, $result->getStatusCode());
$data = json_decode($result->getBody(), true);
$this->assertIsArray($data);
$this->assertArrayHasKey('status', $data);
$this->assertArrayHasKey('message', $data);
$this->assertArrayHasKey('data', $data);
$this->assertEquals('success', $data['status']);
$this->assertEquals('User updated successfully.', $data['message']);
$this->assertEquals(['id' => 1, 'username' => 'john'], $data['data']);
}
public function testDeleteUserNotFound()
{
$this->mockUser->method('find')->with(99)->willReturn(null);
$result = $this->controller->delete(99);
$this->assertEquals(404, $result->getStatusCode());
$data = json_decode($result->getBody(), true);
$this->assertIsArray($data);
$this->assertArrayHasKey('status', $data);
$this->assertArrayHasKey('message', $data);
$this->assertEquals('error', $data['status']);
$this->assertEquals('User not found.', $data['message']);
}
public function testDeleteSuccess()
{
$this->mockUser->method('find')->with(1)->willReturn(['id' => 1]);
$this->mockUser->expects($this->once())->method('delete')->with(1);
$result = $this->controller->delete(1);
$this->assertEquals(200, $result->getStatusCode());
$data = json_decode($result->getBody(), true);
$this->assertIsArray($data);
$this->assertArrayHasKey('status', $data);
$this->assertArrayHasKey('message', $data);
$this->assertEquals('success', $data['status']);
$this->assertEquals('User deleted successfully.', $data['message']);
}
}