ACL\Login test class add
- db create shell script for ACL\Login to reset full database to known good stated - basic tests written to check core login class
This commit is contained in:
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
|
||||
/**
|
||||
* Test class for ACL\Login
|
||||
@@ -15,6 +16,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
{
|
||||
private static $db;
|
||||
private static $log;
|
||||
/** @var \CoreLibs\Create\Session&MockObject */
|
||||
private static $session;
|
||||
|
||||
/**
|
||||
@@ -26,29 +28,55 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
{
|
||||
if (!extension_loaded('pgsql')) {
|
||||
self::markTestSkipped(
|
||||
'The PgSQL extension is not available.'
|
||||
'The PgSQL extension is not available for ACL\Login test.'
|
||||
);
|
||||
}
|
||||
// init session
|
||||
self::$session = new \CoreLibs\Create\Session('ACLLoginTest');
|
||||
// database/CoreLibsACLLogin_database_create_data.sql
|
||||
$load_sql_file = __DIR__
|
||||
. DIRECTORY_SEPARATOR
|
||||
. 'database/CoreLibsACLLogin_database_create_data.sql';
|
||||
if (!is_file($load_sql_file)) {
|
||||
self::markTestIncomplete(
|
||||
'Missing ACL\Login database load SQL file'
|
||||
);
|
||||
}
|
||||
// ASSUME that DB is on Port 5432 and use DEFAULT in path postgresql
|
||||
$db_user = "corelibs_acl_login_test";
|
||||
$db_password = "corelibs_acl_login_test";
|
||||
$db_name = "corelibs_acl_login_test";
|
||||
$db_host = "localhost";
|
||||
// run the drop restore script before connecting to the database
|
||||
// check exit, if not null then abort
|
||||
$command = __DIR__ . DIRECTORY_SEPARATOR
|
||||
. "CoreLibsACLLogin_database_prepare.sh "
|
||||
. "$load_sql_file "
|
||||
. "$db_user "
|
||||
. "$db_name "
|
||||
. "$db_host ";
|
||||
exec($command, $ouput, $result);
|
||||
if ($result != 0 || !empty($output[0])) {
|
||||
self::markTestIncomplete(
|
||||
'Drop/Create ACL\Login database failed with: ' . $result
|
||||
);
|
||||
}
|
||||
|
||||
// logger is always needed
|
||||
// define basic connection set valid and one invalid
|
||||
self::$log = new \CoreLibs\Debug\Logging([
|
||||
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
|
||||
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
|
||||
'file_id' => 'CoreLibs-ACL-Login-Test',
|
||||
'debug_all' => false,
|
||||
'debug_all' => true,
|
||||
'echo_all' => false,
|
||||
'print_all' => false,
|
||||
'print_all' => true,
|
||||
]);
|
||||
// if we do have pgsql, we need to create a test DB or check that one
|
||||
// exists and clean the table to zero state
|
||||
// test database we need to connect do, if not possible this test is skipped
|
||||
self::$db = new \CoreLibs\DB\IO(
|
||||
[
|
||||
'db_name' => 'corelibs_acl_login_test',
|
||||
'db_user' => 'corelibs_acl_login_test',
|
||||
'db_pass' => 'corelibs_acl_login_test',
|
||||
'db_host' => 'localhost',
|
||||
'db_name' => $db_name,
|
||||
'db_user' => $db_user,
|
||||
'db_pass' => $db_password,
|
||||
'db_host' => $db_host,
|
||||
'db_port' => 5432,
|
||||
'db_schema' => 'public',
|
||||
'db_type' => 'pgsql',
|
||||
@@ -58,19 +86,45 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
],
|
||||
self::$log
|
||||
);
|
||||
// ALWAYS drop DB and RECREATE DB
|
||||
// dropdb -U corelibs_acl_login_test -h localhost corelibs_acl_login_test
|
||||
// createdb -U corelibs_acl_login_test -O corelibs_acl_login_test -E utf8 corelibs_acl_login_test;
|
||||
if (!self::$db->dbGetConnectionStatus()) {
|
||||
self::markTestSkipped(
|
||||
'Cannot connect to valid Test DB for ACL\Login test.'
|
||||
);
|
||||
}
|
||||
/*
|
||||
// check if they already exist, drop them
|
||||
if ($db->dbShowTableMetaData('table_with_primary_key') !== false) {
|
||||
$db->dbExec("DROP TABLE table_with_primary_key");
|
||||
$db->dbExec("DROP TABLE table_without_primary_key");
|
||||
$db->dbExec("DROP TABLE test_meta");
|
||||
// check that edit_user table exist, I assume if this one does,
|
||||
// the rest does too
|
||||
if (!self::$db->dbShowTableMetaData('edit_user') !== false) {
|
||||
self::markTestIncomplete(
|
||||
'Cannot find edit_user table in ACL\Login database for testing'
|
||||
);
|
||||
}
|
||||
*/
|
||||
// define mandatory constant
|
||||
// must set
|
||||
// TARGET
|
||||
define('TARGET', 'test');
|
||||
// LOGIN DB SCHEMA
|
||||
// define('LOGIN_DB_SCHEMA', '');
|
||||
|
||||
// SHOULD SET
|
||||
// PASSWORD_MIN_LENGTH (d9)
|
||||
// PASSWORD_MAX_LENGTH (d255)
|
||||
// DEFAULT_ACL_LEVEL (d80)
|
||||
|
||||
// OPT:
|
||||
// LOGOUT_TARGET
|
||||
// PASSWORD_CHANGE
|
||||
// PASSWORD_FORGOT
|
||||
|
||||
// LANG:
|
||||
// SITE_LOCALE
|
||||
// DEFAULT_LOCALE
|
||||
// CONTENT_PATH (domain)
|
||||
|
||||
$_SESSION = [];
|
||||
global $_SESSION;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,19 +142,370 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @testdox ACL\Login Class tests
|
||||
* @return array
|
||||
*/
|
||||
public function loginProvider(): array
|
||||
{
|
||||
// 0: mock settings
|
||||
// 1: post array IN
|
||||
// login_login, login_username, login_password, login_logout
|
||||
// change_password, pw_username, pw_old_password, pw_new_password,
|
||||
// pw_new_password_confirm
|
||||
// 2: override session set
|
||||
// 3: expected error code, 0 for all ok, 3 for login page view
|
||||
// note that 1 (no db), 2 (no session) must be tested too
|
||||
// 4: expected return on ok (error: 0)
|
||||
return [
|
||||
'load, no login' => [
|
||||
// error code, only for exceptions
|
||||
[
|
||||
'page_name' => 'edit_users.php',
|
||||
],
|
||||
[],
|
||||
[],
|
||||
3000,
|
||||
[
|
||||
'login_error' => 0
|
||||
],
|
||||
],
|
||||
'load, session euid set only, php error' => [
|
||||
[
|
||||
'page_name' => 'edit_users.php',
|
||||
],
|
||||
[],
|
||||
[
|
||||
'EUID' => 1,
|
||||
],
|
||||
2,
|
||||
[],
|
||||
],
|
||||
'load, session euid set, all set' => [
|
||||
[
|
||||
'page_name' => 'edit_users.php',
|
||||
'edit_access_id' => 1,
|
||||
'base_access' => 'list',
|
||||
'page_access' => 'list',
|
||||
],
|
||||
[],
|
||||
[
|
||||
'EUID' => 1,
|
||||
'USER_NAME' => '',
|
||||
'GROUP_NAME' => '',
|
||||
'ADMIN' => 1,
|
||||
'GROUP_ACL_LEVEL' => -1,
|
||||
'PAGES_ACL_LEVEL' => [],
|
||||
'USER_ACL_LEVEL' => -1,
|
||||
'UNIT' => [
|
||||
1 => [
|
||||
'acl_level' => 80,
|
||||
'name' => 'Admin Access',
|
||||
'uid' => '',
|
||||
'level' => -1,
|
||||
'default' => 0,
|
||||
'data' => []
|
||||
],
|
||||
],
|
||||
// 'UNIT_DEFAULT' => '',
|
||||
// 'DEFAULT_ACL_LIST' => [],
|
||||
],
|
||||
0,
|
||||
[
|
||||
'login_error' => 0,
|
||||
'admin_flag' => true,
|
||||
'check_access' => true,
|
||||
'check_access_id' => 1,
|
||||
'base_access' => true,
|
||||
'page_access' => true,
|
||||
],
|
||||
],
|
||||
// login: all missing
|
||||
'login: all missing' => [
|
||||
[
|
||||
'page_name' => 'edit_users.php',
|
||||
],
|
||||
[
|
||||
'login_login' => 'Login',
|
||||
'login_username' => '',
|
||||
'login_password' => '',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
[
|
||||
'login_error' => 102
|
||||
]
|
||||
],
|
||||
// login: missing username
|
||||
'login: missing username' => [
|
||||
[
|
||||
'page_name' => 'edit_users.php',
|
||||
],
|
||||
[
|
||||
'login_login' => 'Login',
|
||||
'login_username' => '',
|
||||
'login_password' => 'abc',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
[
|
||||
'login_error' => 102
|
||||
]
|
||||
],
|
||||
// login: missing password
|
||||
'login: missing password' => [
|
||||
[
|
||||
'page_name' => 'edit_users.php',
|
||||
],
|
||||
[
|
||||
'login_login' => 'Login',
|
||||
'login_username' => 'abc',
|
||||
'login_password' => '',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
[
|
||||
'login_error' => 102
|
||||
]
|
||||
],
|
||||
// login: user not found
|
||||
'login: user not found' => [
|
||||
[
|
||||
'page_name' => 'edit_users.php',
|
||||
],
|
||||
[
|
||||
'login_login' => 'Login',
|
||||
'login_username' => 'abc',
|
||||
'login_password' => 'abc',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
[
|
||||
'login_error' => 1010
|
||||
]
|
||||
],
|
||||
// login: invalid password
|
||||
// 9999: not valid password encoding
|
||||
// 1013: normal password failed
|
||||
// 1012: plain password check failed
|
||||
'login: invalid password' => [
|
||||
[
|
||||
'page_name' => 'edit_users.php',
|
||||
],
|
||||
[
|
||||
'login_login' => 'Login',
|
||||
'login_username' => 'admin',
|
||||
'login_password' => 'abc',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
[
|
||||
// default password is plain text
|
||||
'login_error' => 1012
|
||||
]
|
||||
],
|
||||
// login: ok (but not enabled)
|
||||
// login: ok (but locked)
|
||||
// login: ok
|
||||
'login: ok' => [
|
||||
[
|
||||
'page_name' => 'edit_users.php',
|
||||
'edit_access_id' => 1,
|
||||
'base_access' => 'list',
|
||||
'page_access' => 'list',
|
||||
],
|
||||
[
|
||||
'login_login' => 'Login',
|
||||
'login_username' => 'admin',
|
||||
'login_password' => 'admin',
|
||||
],
|
||||
[],
|
||||
0,
|
||||
[
|
||||
'login_error' => 0,
|
||||
'admin_flag' => true,
|
||||
'check_access' => true,
|
||||
'check_access_id' => 1,
|
||||
'base_access' => true,
|
||||
'page_access' => true,
|
||||
]
|
||||
],
|
||||
//
|
||||
// other:
|
||||
// login check edit access id of ID not null and not in array
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* main test for acl login
|
||||
*
|
||||
* @dataProvider loginProvider
|
||||
* @testdox ACL\Login Class tests [$_dataName]
|
||||
*
|
||||
* @param array<string,string> $mock_settings
|
||||
* @param array<string,string> $post
|
||||
* @param array<string,mixed> $session
|
||||
* @param int $error
|
||||
* @param array<string,mixed> $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testACLLogin(
|
||||
array $mock_settings,
|
||||
array $post,
|
||||
array $session,
|
||||
int $error,
|
||||
array $expected
|
||||
): void {
|
||||
// echo "ACL LOGIN TEST\n";
|
||||
$_SESSION = [];
|
||||
|
||||
// init session (as MOCK)
|
||||
/** @var \CoreLibs\Create\Session&MockObject */
|
||||
$session_mock = $this->createPartialMock(
|
||||
\CoreLibs\Create\Session::class,
|
||||
['startSession', 'checkActiveSession', 'sessionDestroy']
|
||||
);
|
||||
$session_mock->method('startSession')->willReturn('ACLLOGINTEST12');
|
||||
$session_mock->method('checkActiveSession')->willReturn(true);
|
||||
$session_mock->method('sessionDestroy')->will(
|
||||
$this->returnCallback(function () {
|
||||
global $_SESSION;
|
||||
$_SESSION = [];
|
||||
return true;
|
||||
})
|
||||
);
|
||||
|
||||
// set _POST data
|
||||
foreach ($post as $post_var => $post_value) {
|
||||
$_POST[$post_var] = $post_value;
|
||||
}
|
||||
|
||||
// set _SESSION data
|
||||
foreach ($session as $session_var => $session_value) {
|
||||
$_SESSION[$session_var] = $session_value;
|
||||
}
|
||||
|
||||
/** @var \CoreLibs\ACL\Login&MockObject */
|
||||
$login_mock = $this->getMockBuilder(\CoreLibs\ACL\Login::class)
|
||||
->setConstructorArgs([self::$db, self::$log, $session_mock, false])
|
||||
->onlyMethods(['loginTerminate', 'loginReadPageName', 'loginPrintLogin'])
|
||||
->getMock();
|
||||
$login_mock->expects($this->any())
|
||||
->method('loginTerminate')
|
||||
->will(
|
||||
$this->returnCallback(function ($code) {
|
||||
throw new \Exception('', $code);
|
||||
})
|
||||
);
|
||||
$login_mock->expects($this->any())
|
||||
->method('loginReadPageName')
|
||||
// set from mock settings, or empty if not set at all
|
||||
->willReturn($mock_settings['page_name'] ?? '');
|
||||
// do not echo out any string here
|
||||
$login_mock->expects($this->any())
|
||||
->method('loginPrintLogin')
|
||||
->willReturnCallback(function () {
|
||||
});
|
||||
// run test
|
||||
try {
|
||||
$login_mock->loginMainCall();
|
||||
// on ok, do post login check based on expected return
|
||||
// - loginGetLastErrorCode
|
||||
$this->assertEquals(
|
||||
$expected['login_error'],
|
||||
$login_mock->loginGetLastErrorCode(),
|
||||
'Assert login error code'
|
||||
);
|
||||
// - loginGetPageName
|
||||
$this->assertEquals(
|
||||
$mock_settings['page_name'],
|
||||
$login_mock->loginGetPageName(),
|
||||
'Assert page name'
|
||||
);
|
||||
// - loginCheckPermissions [duplicated from loginrun]
|
||||
// - loginCheckAccess [use Base, Page below]
|
||||
// - loginCheckAccessBase
|
||||
$this->assertEquals(
|
||||
$expected['base_access'],
|
||||
$login_mock->loginCheckAccessBase($mock_settings['base_access']),
|
||||
'Assert base access'
|
||||
);
|
||||
// - loginCheckAccessPage
|
||||
$this->assertEquals(
|
||||
$expected['page_access'],
|
||||
$login_mock->loginCheckAccessPage($mock_settings['page_access']),
|
||||
'Assert page access'
|
||||
);
|
||||
// - loginCheckEditAccess
|
||||
$this->assertEquals(
|
||||
$expected['check_access'],
|
||||
$login_mock->loginCheckEditAccess($mock_settings['edit_access_id']),
|
||||
'Assert check access'
|
||||
);
|
||||
// - loginCheckEditAccessId
|
||||
$this->assertEquals(
|
||||
$expected['check_access_id'],
|
||||
$login_mock->loginCheckEditAccessId((int)$mock_settings['edit_access_id']),
|
||||
'Assert check access id valid'
|
||||
);
|
||||
// - loginGetEditAccessData [test extra]
|
||||
// - loginIsAdmin
|
||||
$this->assertEquals(
|
||||
$expected['admin_flag'],
|
||||
$login_mock->loginIsAdmin(),
|
||||
'Assert admin flag set'
|
||||
);
|
||||
// .. end with: loginLogoutUser
|
||||
} catch (\Exception $e) {
|
||||
// print "[E]: " . $e->getCode() . ", ERROR: " . $login_mock->loginGetLastErrorCode() . "/"
|
||||
// . ($expected['login_error'] ?? 0) . "\n";
|
||||
// if this is 3000, then we do further error checks
|
||||
if ($e->getCode() == 3000) {
|
||||
$this->assertEquals(
|
||||
$expected['login_error'],
|
||||
$login_mock->loginGetLastErrorCode(),
|
||||
'Assert login error code, exit'
|
||||
);
|
||||
}
|
||||
// print "EXCEPTION: " . print_r($e, true) . "\n";
|
||||
$this->assertEquals(
|
||||
$e->getCode(),
|
||||
$error,
|
||||
'Expected error code: ' . $e->getCode()
|
||||
. ', ' . $e->getMessage()
|
||||
. ', ' . $e->getLine()
|
||||
);
|
||||
}
|
||||
// print "PAGENAME: " . $login_mock->loginGetPageName() . "\n";
|
||||
// $echo_string = $this->getActualOutput();
|
||||
|
||||
// $this->setOutputCallback(
|
||||
// function ($echo) {
|
||||
// // echo "A";
|
||||
// echo "--" . $echo . "--\n";
|
||||
// }
|
||||
// );
|
||||
|
||||
// $echo_string = $this->getActualOutput();
|
||||
// echo "~~~~~~~~~~~~~~~~\n";
|
||||
// print "ECHO: " . $echo_string . "\n";
|
||||
|
||||
// compare result to expected
|
||||
}
|
||||
|
||||
// other tests
|
||||
// - loginSetPasswordMinLength
|
||||
//
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @testdox ACL\Login Class empty void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testACLLogin()
|
||||
{
|
||||
$this->assertTrue(true, 'ACL Login Tests not implemented');
|
||||
$this->markTestIncomplete(
|
||||
'ACL\Login Tests have not yet been implemented'
|
||||
);
|
||||
|
||||
$login = new \CoreLibs\ACL\Login(self::$db, self::$log, self::$session);
|
||||
}
|
||||
// public function testOther(): void
|
||||
// {
|
||||
// echo "HERE EMPTY 1\n";
|
||||
// }
|
||||
}
|
||||
|
||||
// __END__
|
||||
|
||||
Reference in New Issue
Block a user