%PDF- %PDF-
| Direktori : /www/varak.net/dmarc.varak.net/tests/classes/ |
| Current File : /www/varak.net/dmarc.varak.net/tests/classes/CoreTest.php |
<?php
namespace Liuch\DmarcSrg;
use Liuch\DmarcSrg\Users\User;
use Liuch\DmarcSrg\Users\DbUser;
use Liuch\DmarcSrg\Users\AdminUser;
use Liuch\DmarcSrg\Exception\SoftException;
use Liuch\DmarcSrg\Exception\ForbiddenException;
use Liuch\DmarcSrg\Exception\DatabaseNotFoundException;
use Liuch\DmarcSrg\Database\DatabaseController;
use Liuch\DmarcSrg\Database\UserMapperInterface;
use PHPUnit\Framework\Attributes\RunInSeparateProcess;
class CoreTest extends \PHPUnit\Framework\TestCase
{
/** @var Core */
private $core = null;
public function setUp(): void
{
$this->core = Core::instance();
$_SERVER['REQUEST_URI'] = '/';
}
public function testSelfInstance(): void
{
$this->assertSame($this->core, Core::instance());
}
public function testRequestMethod(): void
{
$_SERVER['REQUEST_METHOD'] = 'some_method';
$this->assertSame('some_method', $this->core->requestMethod());
unset($_SERVER['REQUEST_METHOD']);
}
public function testGetCurrentUserWhenAuthIsDisabled(): void
{
$auth = $this->getAuthDisabledMock();
$sess = $this->getSessionMock([ 'getData', 'destroy' ]);
$sess->expects($this->never())->method('destroy');
$sess->expects($this->never())->method('getData');
$core = new Core([ 'auth' => $auth, 'session' => $sess ]);
$usr = $core->getCurrentUser();
$this->assertInstanceOf(AdminUser::class, $usr);
}
public function testGetCurrentUserWhenNobodyLogin(): void
{
$auth = $this->getAuthEnabledMock();
$sess = $this->getSessionMock([ 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([]);
$core = new Core([ 'auth' => $auth, 'session' => $sess ]);
$this->assertNull($core->getCurrentUser());
}
public function testGetCurrentUserWhenAdminSessionHasWrongId(): void
{
$auth = $this->getAuthEnabledMock();
$sess = $this->getSessionMock([ 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([
'user' => [ 'id' => 1, 'name' => 'admin', 'level' => User::LEVEL_ADMIN ]
]);
$core = new Core([ 'auth' => $auth, 'session' => $sess ]);
$this->expectException(ForbiddenException::class);
$this->expectExceptionMessage('The user session has been broken!');
$core->getCurrentUser();
}
public function testGetCurrentUserWhenAdminSessionHasWrongLevel(): void
{
$auth = $this->getAuthEnabledMock();
$sess = $this->getSessionMock([ 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([
'user' => [ 'id' => 0, 'name' => 'admin', 'level' => User::LEVEL_USER ]
]);
$core = new Core([ 'auth' => $auth, 'session' => $sess ]);
$this->expectException(ForbiddenException::class);
$this->expectExceptionMessage('The user session has been broken!');
$core->getCurrentUser();
}
public function testGetCurrentUserWhenAdminSessionIsOk(): void
{
$auth = $this->getAuthEnabledMock();
$sess = $this->getSessionMock([ 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([
'user' => [ 'id' => 0, 'name' => 'admin', 'level' => User::LEVEL_ADMIN ]
]);
$core = new Core([ 'auth' => $auth, 'session' => $sess ]);
$this->assertInstanceOf(AdminUser::class, $core->getCurrentUser());
}
public function testGetCurrentNotAdminUserWhenUserManagerIsDisabled(): void
{
$sess = $this->getSessionMock([ 'destroy', 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([
'user' => [ 'id' => 1, 'name' => 'user', 'level' => User::LEVEL_USER ]
]);
$sess->expects($this->once())->method('destroy');
$core = new Core([
'auth' => $this->getAuthEnabledMock(),
'config' => $this->getConfig('users/user_management', false, false),
'session' => $sess
]);
$this->assertNull($core->getCurrentUser());
}
public function testGetCurrentNotAdminUserWhenUserManagerIsEnabledAndUserDoesNotExist(): void
{
$sess = $this->getSessionMock([ 'destroy', 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([
'user' => [ 'id' => 1, 'name' => 'user', 'level' => User::LEVEL_USER ],
's_id' => 1, 's_time' => (new DateTime())->getTimestamp() - 999999
]);
$sess->expects($this->once())->method('destroy');
$core = new Core([
'auth' => $this->getAuthEnabledMock(),
'config' => $this->getConfig('users/user_management', false, true),
'database' => $this->getDbMapperUserNotFound(),
'session' => $sess
]);
$this->expectException(SoftException::class);
$core->getCurrentUser();
}
public function testGetCurrentNotAdminUserWhenUserManagerIsEnabledAndUserIsDisabled(): void
{
$sess = $this->getSessionMock([ 'destroy', 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([
'user' => [ 'id' => 1, 'name' => 'user', 'level' => User::LEVEL_USER ],
's_id' => 1, 's_time' => (new DateTime())->getTimestamp() - 999999
]);
$sess->expects($this->once())->method('destroy');
$core = new Core([
'auth' => $this->getAuthEnabledMock(),
'config' => $this->getConfig('users/user_management', false, true),
'database' => $this->getDbMapperUserDisabled(),
'session' => $sess
]);
$this->assertNull($core->getCurrentUser());
}
public function testGetCurrentNotAdminUserWhenUserManagerIsEnabledAndUserExists(): void
{
$sess = $this->getSessionMock([ 'destroy', 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([
'user' => [ 'id' => 1, 'name' => 'user', 'level' => User::LEVEL_USER ],
's_id' => 1, 's_time' => (new DateTime())->getTimestamp() - 999999
]);
$sess->expects($this->never())->method('destroy');
$core = new Core([
'auth' => $this->getAuthEnabledMock(),
'config' => $this->getConfig('users/user_management', false, true),
'database' => $this->getDbMapperUserEnabled(),
'session' => $sess
]);
$usr = $core->getCurrentUser();
$this->assertInstanceOf(DbUser::class, $usr);
$this->assertSame(User::LEVEL_MANAGER, $usr->level());
}
public function testGetCurrentNotAdminUserWhenUserManagerIsEnabledAndUserGotNewStatus(): void
{
$sess = $this->getSessionMock([ 'destroy', 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([
'user' => [ 'id' => 1, 'name' => 'user', 'level' => User::LEVEL_USER ],
's_id' => 1, 's_time' => (new DateTime())->getTimestamp() - 999999
]);
$sess->expects($this->once())->method('destroy');
$core = new Core([
'auth' => $this->getAuthEnabledMock(),
'config' => $this->getConfig('users/user_management', false, true),
'database' => $this->getDbMapperUserChangedStatus(),
'session' => $sess
]);
$this->assertNull($core->getCurrentUser());
}
public function testSetAdminUserWithName(): void
{
$sess = $this->getSessionMock([ 'destroy', 'getData' ]);
$sess->expects($this->never())->method('destroy');
$sess->expects($this->never())->method('getData');
$core = new Core([
'auth' => $this->getAuthEnabledMock(),
'session' => $sess
]);
$core->setCurrentUser('admin');
$this->assertInstanceOf(AdminUser::class, $core->getCurrentUser());
}
public function testSetAdminUserWithInstance(): void
{
$sess = $this->getSessionMock([ 'destroy', 'getData' ]);
$sess->expects($this->never())->method('destroy');
$sess->expects($this->never())->method('getData');
$core = new Core([
'auth' => $this->getAuthEnabledMock(),
'session' => $sess
]);
$admin = new AdminUser();
$core->setCurrentUser($admin);
$this->assertSame($admin, $core->getCurrentUser());
}
public function testUnsetUserWithNullValueWithWeb(): void
{
$_SERVER['REQUEST_METHOD'] = 'GET'; // self::isWEB() -> true
$sess = $this->getSessionMock([ 'destroy', 'getData', 'setData' ]);
$sess->expects($this->once())->method('destroy');
$sess->expects($this->never())->method('getData');
$sess->expects($this->never())->method('setData');
$core = new Core([
'session' => $sess
]);
$core->setCurrentUser(null);
unset($_SERVER['REQUEST_METHOD']);
}
public function testSetDbUserWithWeb(): void
{
$_SERVER['REQUEST_METHOD'] = 'GET'; // self::isWEB() -> true
$sess = $this->getSessionMock([ 'destroy', 'getData', 'setData' ]);
$sess->expects($this->once())->method('destroy');
$sess->expects($this->never())->method('getData');
$sess->expects($this->once())->method('setData');
$db = $this->getDbMapperUserEnabled();
$core = new Core([
'session' => $sess,
'database' => $db
]);
$core->setCurrentUser(new DbUser([ 'id' => 1, 'name' => 'User' ], $db));
unset($_SERVER['REQUEST_METHOD']);
}
public function testSetDbUserWithNoWeb(): void
{
$sess = $this->getSessionMock([ 'destroy', 'getData', 'setData' ]);
$sess->expects($this->never())->method('destroy');
$sess->expects($this->never())->method('getData');
$sess->expects($this->never())->method('setData');
$core = new Core([
'session' => $sess
]);
$core->setCurrentUser(new DbUser([ 'id' => 1, 'name' => 'User' ]));
}
public function testSendHtml(): void
{
foreach ([
[ '', false, 'Empty custom CSS' ],
[ 'custom.css', true, 'Correct custom CSS' ],
[ 'custom.csss', false, 'Incorrect custom CSS' ]
] as $it) {
$core = new Core([
'config' => $this->getConfig('custom_css', '', $it[0]),
'template' => realpath(__DIR__ . '/../..') . '/template.html'
]);
ob_start();
$core->sendHtml();
$output = ob_get_contents();
ob_end_clean();
$this->assertIsString($output);
$this->assertStringNotContainsString('<!-- Custom CSS -->', $output, $it[2]);
if ($it[1]) {
$this->assertStringContainsString($it[0], $output, $it[2]);
} elseif (!empty($it[0])) {
$this->assertStringNotContainsString($it[0], $output, $it[2]);
}
}
}
public function testSendJson(): void
{
$data = [ 'key1' => 'value1', [ 'key2' => 'value2' ] ];
ob_start();
$this->core->sendJson($data);
$output = ob_get_contents();
ob_end_clean();
$this->assertJsonStringEqualsJsonString(json_encode($data), $output);
}
public function testAuthInstance(): void
{
$this->assertSame($this->core->auth(), $this->core->auth());
}
public function testStatusInstance(): void
{
$this->assertSame($this->core->status(), $this->core->status());
}
public function testAdminIntance(): void
{
$this->assertSame($this->core->admin(), $this->core->admin());
}
public function testErrorHandlerInstance(): void
{
$this->assertSame($this->core->errorHandler(), $this->core->errorHandler());
}
public function testLoggerInstance(): void
{
$this->assertSame($this->core->logger(), $this->core->logger());
}
public function testCheckingOneDependencyWithNoCurrentUser(): void
{
$sess = $this->getSessionMock([ 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([]);
$core = new Core([
'auth' => $this->getAuthEnabledMock(),
'session' => $sess
]);
$this->expectException(SoftException::class);
$this->expectExceptionMessage('Required dependency is missing. Contact the administrator.');
$core->checkDependencies('fake');
}
public function testCheckingOneDependencyWithNotAdminCurrentUser(): void
{
$sess = $this->getSessionMock([ 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([
'user' => [ 'id' => 1, 'name' => 'user', 'level' => User::LEVEL_USER ]
]);
$db = $this->getMockBuilder(DatabaseController::class)
->disableOriginalConstructor()
->getMock();
$core = new Core([
'auth' => $this->getAuthEnabledMock(),
'config' => $this->getConfig('users/user_management', false, true),
'database' => $db,
'session' => $sess
]);
$this->expectException(SoftException::class);
$this->expectExceptionMessage('Required dependency is missing. Contact the administrator.');
$core->checkDependencies('fake');
}
public function testCheckingOneDependencyWithAdminCurrentUser(): void
{
$sess = $this->getSessionMock([ 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([
'user' => [ 'id' => 0, 'name' => 'admin', 'level' => User::LEVEL_ADMIN ]
]);
$core = new Core([
'auth' => $this->getAuthEnabledMock(),
'session' => $sess
]);
$this->expectException(SoftException::class);
$this->expectExceptionMessage('Required dependency is missing: ext-fake.');
$core->checkDependencies('fake');
}
public function testCheckingSeveralDependencies(): void
{
$sess = $this->getSessionMock([ 'getData' ]);
$sess->expects($this->once())->method('getData')->willReturn([
'user' => [ 'id' => 0, 'name' => 'admin', 'level' => User::LEVEL_ADMIN ]
]);
$core = new Core([
'auth' => $this->getAuthEnabledMock(),
'session' => $sess
]);
$this->expectException(SoftException::class);
$this->expectExceptionMessage('Required dependencies are missing: ext-fake1, ext-fake2.');
$core->checkDependencies('fake1,fake2');
}
public function testConfigExistingParameters(): void
{
$core = new Core([ 'config' => $this->getConfig('some/param', 'default', 'some_value') ]);
$this->assertSame('some_value', $core->config('some/param', 'default'));
}
public function testConfigNonexistentParameters(): void
{
$core = new Core([ 'config' => [ 'Liuch\DmarcSrg\Config', [ 'tests/conf_test_file.php' ] ] ]);
$config = new Config('tests/conf_test_file.php');
$this->assertNull($core->config('some_unknown_parameter'));
$this->assertIsString($core->config('some_unknown_parameter', ''));
}
private function getAuthEnabledMock()
{
$auth = $this->getMockBuilder(Auth::class)
->disableOriginalConstructor()
->onlyMethods([ 'isEnabled' ])
->getMock();
$auth->expects($this->once())->method('isEnabled')->willReturn(true);
return $auth;
}
private function getAuthDisabledMock()
{
$auth = $this->getMockBuilder(Auth::class)
->disableOriginalConstructor()
->onlyMethods([ 'isEnabled' ])
->getMock();
$auth->expects($this->once())->method('isEnabled')->willReturn(false);
return $auth;
}
private function getSessionMock(array $methods)
{
return $this->getMockBuilder(Session::class)->onlyMethods($methods)->getMock();
}
private function getConfig(string $param, $defval, $value)
{
$config = $this->getMockBuilder(Config::class)
->disableOriginalConstructor()
->onlyMethods([ 'get' ])
->getMock();
$config->expects($this->once())
->method('get')
->with($this->equalTo($param), $this->equalTo($defval))
->willReturn($value);
return $config;
}
private function getDbMapperUserNotFound(): object
{
$mapper = $this->getMockBuilder(UserMapperInterface::class)->disableOriginalConstructor()->getMock();
$mapper->expects($this->once())->method('fetch')->willThrowException(new DatabaseNotFoundException());
$db = $this->getMockBuilder(DatabaseController::class)
->disableOriginalConstructor()
->onlyMethods([ 'getMapper' ])
->getMock();
$db->expects($this->once())->method('getMapper')->with('user')->willReturn($mapper);
return $db;
}
private function getDbMapperUserDisabled(): object
{
return $this->getDbMapperUserOnce('fetch', [ 'enabled', 'session' ], [ false, 1 ]);
}
private function getDbMapperUserEnabled(): object
{
return $this->getDbMapperUserOnce('fetch', [ 'enabled', 'session', 'level' ], [ true, 1, User::LEVEL_MANAGER ]);
}
private function getDbMapperUserChangedStatus(): object
{
return $this->getDbMapperUserOnce('fetch', [ 'enabled', 'session', 'level' ], [ true, 2, User::LEVEL_MANAGER ]);
}
private function getDbMapperUserOnce(string $method, array $keys, array $values): object
{
$mapper = $this->getMockBuilder(UserMapperInterface::class)
->disableOriginalConstructor()
->onlyMethods([
'exists', 'save', 'delete', 'fetch', 'list', 'getPasswordHash',
'savePasswordHash', 'setUserKey'
])
->getMock();
$mapper->expects($this->once())->method($method)->willReturnCallback(function (&$data) use ($keys, $values) {
for ($i = 0; $i < count($keys); ++$i) {
$data[$keys[$i]] = $values[$i];
}
});
$db = $this->getMockBuilder(DatabaseController::class)
->disableOriginalConstructor()
->onlyMethods([ 'getMapper' ])
->getMock();
$db->expects($this->once())->method('getMapper')->with('user')->willReturn($mapper);
return $db;
}
}