%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; } }