diff --git a/4dev/tests/CoreLibsCreateSessionTest.php b/4dev/tests/CoreLibsCreateSessionTest.php index be419e82..2eeaefe3 100644 --- a/4dev/tests/CoreLibsCreateSessionTest.php +++ b/4dev/tests/CoreLibsCreateSessionTest.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace tests; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\MockObject\MockObject; /** * Test class for Create\Session @@ -20,85 +21,246 @@ final class CoreLibsCreateSessionTest extends TestCase */ public function sessionProvider(): array { - // 0: session name as parameter - // 1: type p (param), g: global, c: constant - // 2: exepcted name (session) - // 3: regex check + // 0: session name as parameter or for GLOBAL value + // 1: type p: parameter, g: global, d: php.ini default + // 2: mock data as array + // checkCliStatus: true/false, + // getSessionStatus: PHP_SESSION_DISABLED for abort, + // PHP_SESSION_NONE/ACTIVE for ok + // setSessionName: true/false, + // checkActiveSession: true/false, [1st call, 2nd call] + // getSessionId: string or false + // 3: exepcted name (session) + // 4: expected error string return [ 'session parameter' => [ 'sessionNameParameter', 'p', + [ + 'checkCliStatus' => false, + 'getSessionStatus' => PHP_SESSION_NONE, + 'setSessionName' => true, + 'checkActiveSession' => [false, true], + 'getSessionId' => '1234abcd4567' + ], 'sessionNameParameter', - '/^\w+$/' + '' ], 'session globals' => [ 'sessionNameGlobals', 'g', + [ + 'checkCliStatus' => false, + 'getSessionStatus' => PHP_SESSION_NONE, + 'setSessionName' => true, + 'checkActiveSession' => [false, true], + 'getSessionId' => '1234abcd4567' + ], 'sessionNameGlobals', - '/^\w+$/' + '' ], 'session name default' => [ '', 'd', + [ + 'checkCliStatus' => false, + 'getSessionStatus' => PHP_SESSION_NONE, + 'setSessionName' => true, + 'checkActiveSession' => [false, true], + 'getSessionId' => '1234abcd4567' + ], '', - '/^\w+$/' + '' + ], + // error checks + // 1: we are in cli + 'on cli error' => [ + '', + 'd', + [ + 'checkCliStatus' => true, + 'getSessionStatus' => PHP_SESSION_NONE, + 'setSessionName' => true, + 'checkActiveSession' => [false, true], + 'getSessionId' => '1234abcd4567' + ], + '', + '[SESSION] No sessions in php cli' + ], + // 2: session disabled + 'session disabled error' => [ + '', + 'd', + [ + 'checkCliStatus' => false, + 'getSessionStatus' => PHP_SESSION_DISABLED, + 'setSessionName' => true, + 'checkActiveSession' => [false, true], + 'getSessionId' => '1234abcd4567' + ], + '', + '[SESSION] Sessions are disabled' + ], + // 3: invalid session name: string + 'invalid name chars error' => [ + '1invalid$session#;', + 'p', + [ + 'checkCliStatus' => false, + 'getSessionStatus' => PHP_SESSION_NONE, + 'setSessionName' => false, + 'checkActiveSession' => [false, true], + 'getSessionId' => '1234abcd4567' + ], + '', + '[SESSION] Invalid session name: 1invalid$session#;' + ], + // 3: invalid session name: only numbers + 'invalid name numbers only error' => [ + '123', + 'p', + [ + 'checkCliStatus' => false, + 'getSessionStatus' => PHP_SESSION_NONE, + 'setSessionName' => false, + 'checkActiveSession' => [false, true], + 'getSessionId' => '1234abcd4567' + ], + '', + '[SESSION] Invalid session name: 123' + ], + // 3: invalid session name: invalid name short + // 3: invalid session name: too long (128) + // 4: failed to start session (2nd false on check active session) + 'invalid name numbers only error' => [ + '', + 'd', + [ + 'checkCliStatus' => false, + 'getSessionStatus' => PHP_SESSION_NONE, + 'setSessionName' => true, + 'checkActiveSession' => [false, false], + 'getSessionId' => '1234abcd4567' + ], + '', + '[SESSION] Failed to activate session' + ], + // 5: get session id return false + 'invalid name numbers only error' => [ + '', + 'd', + [ + 'checkCliStatus' => false, + 'getSessionStatus' => PHP_SESSION_NONE, + 'setSessionName' => true, + 'checkActiveSession' => [false, true], + 'getSessionId' => false + ], + '', + '[SESSION] getSessionId did not return a session id' ], ]; } /** - * Undocumented function + * Test session start * + * @covers ::startSession * @dataProvider sessionProvider - * @testdox startSession $input name for $type will be $expected_n with $expected_i [$_dataName] + * @testdox startSession $input name for $type will be $expected (error: $expected_error) [$_dataName] * * @param string $input * @param string $type - * @param string|bool $expected_n - * @param string|bool $expected_i + * @param array $mock_data + * @param string $expected + * @param string $expected_error * @return void */ public function testStartSession( string $input, string $type, - $expected_n, - $expected_i + array $mock_data, + string $expected, + string $expected_error, ): void { - /* - // MOCK class for dummy call - $session = new \CoreLibs\Create\Session(); - $session_id = ''; + // override expected + if ($type == 'd') { + $expected = ini_get('session.name'); + } + /** @var \CoreLibs\Create\Session&MockObject $session_mock */ + $session_mock = $this->createPartialMock( + \CoreLibs\Create\Session::class, + [ + 'checkCliStatus', 'getSessionStatus', 'checkActiveSession', + 'setSessionName', 'startSessionCall', 'getSessionId', + 'getSessionName' + ] + ); + // set return values based requested input values + // OK: true + // error: false + $session_mock->method('checkCliStatus')->willReturn($mock_data['checkCliStatus']); + // OK: PHP_SESSION_ACTIVE, PHP_SESSION_NONE + // error: PHP_SESSION_DISABLED + $session_mock->method('getSessionStatus')->willReturn($mock_data['getSessionStatus']); + // false: try start + // true: skip start + // note that on second call if false -> error + $session_mock->method('checkActiveSession') + ->willReturnOnConsecutiveCalls( + $mock_data['checkActiveSession'][0], + $mock_data['checkActiveSession'][1], + ); + // dummy set for session name + $session_mock->method('setSessionName')->with($input)->willReturn($mock_data['setSessionName']); + // set session name & return bsed on request data + $session_mock->method('getSessionName')->willReturn($expected); + // will not return anything + $session_mock->method('startSessionCall'); + // in test case only return string + // false: will return false + $session_mock->method('getSessionId')->willReturn($mock_data['getSessionId']); + + // regex for session id + $ression_id_regex = "/^\w+$/"; + unset($GLOBALS['SET_SESSION_NAME']); + $session_id = ''; switch ($type) { case 'p': - $session_id = $session->startSession($input); + $session_id = $session_mock->startSession($input); break; case 'g': $GLOBALS['SET_SESSION_NAME'] = $input; - $session_id = $session->startSession(); + $session_id = $session_mock->startSession(); break; case 'd': - $expected_n = ini_get('session.name'); - $session_id = \$session->startSession(); + $session_id = $session_mock->startSession(); break; } - $this->assertMatchesRegularExpression( - $expected_i, - (string)$session_id - ); - $this->assertMatchesRegularExpression( - $expected_i, - (string)$session->getSessionId() - ); - $this->assertEquals( - $expected_n, - $session->getSessionName() - ); - if ($type == 'g') { - unset($GLOBALS['SET_SESSION_NAME']); - } */ - $this->markTestSkipped('[CoreLibsCreateSessionTest] No implementation ' - . 'for Create\Session. Cannot run session_start in CLI'); + // asert checks + if (!empty($session_id)) { + $this->assertMatchesRegularExpression( + $ression_id_regex, + (string)$session_id, + 'session id regex from retrun' + ); + $this->assertMatchesRegularExpression( + $ression_id_regex, + (string)$session_mock->getSessionId() + ); + $this->assertEquals( + $expected, + $session_mock->getSessionName() + ); + } else { + // false checks + $this->assertEquals( + $expected_error, + $session_mock->getErrorStr(), + 'error assert' + ); + } } /** @@ -109,7 +271,7 @@ final class CoreLibsCreateSessionTest extends TestCase public function sessionNameProvider(): array { // 0: string for session - // 1: expected return + // 1: expected return as bool return [ 'valid name' => [ 'abc', @@ -141,7 +303,7 @@ final class CoreLibsCreateSessionTest extends TestCase } /** - * Undocumented function + * test valid session name * * @covers ::checkValidSessionName * @dataProvider sessionNameProvider @@ -158,6 +320,153 @@ final class CoreLibsCreateSessionTest extends TestCase \CoreLibs\Create\Session::checkValidSessionName($input) ); } + + /** + * provider for set/get tests + * + * @return array + */ + public function sessionDataProvider(): array + { + return [ + 'test' => [ + 'foo', + 'bar', + 'bar', + ], + 'int key test' => [ + 123, + 'bar', + 'bar', + ], + // more complex value tests + 'array values' => [ + 'array', + [1, 2, 3], + [1, 2, 3], + ] + ]; + } + + /** + * method call test + * + * @covers ::setS + * @covers ::getS + * @covers ::issetS + * @covers ::unsetS + * @dataProvider sessionDataProvider + * @testdox setS/getS/issetS/unsetS $name with $input is $expected [$_dataName] + * + * @param string|int $name + * @param mixed $input + * @param mixed $expected + * @return void + */ + public function testMethodSetGet($name, $input, $expected): void + { + $session = new \CoreLibs\Create\Session(); + $session->setS($name, $input); + $this->assertEquals( + $expected, + $session->getS($name), + 'method set assert' + ); + // isset true + $this->assertTrue( + $session->issetS($name), + 'method isset assert ok' + ); + $session->unsetS($name); + $this->assertEquals( + '', + $session->getS($name), + 'method unset assert' + ); + // iset false + $this->assertFalse( + $session->issetS($name), + 'method isset assert false' + ); + } + + /** + * magic call test + * + * @covers ::__set + * @covers ::__get + * @covers ::__isset + * @covers ::__unset + * @dataProvider sessionDataProvider + * @testdox __set/__get/__iseet/__unset $name with $input is $expected [$_dataName] + * + * @param string|int $name + * @param mixed $input + * @param mixed $expected + * @return void + */ + public function testMagicSetGet($name, $input, $expected): void + { + $session = new \CoreLibs\Create\Session(); + $session->$name = $input; + $this->assertEquals( + $expected, + $session->$name, + 'magic set assert' + ); + // isset true + $this->assertTrue( + isset($session->$name), + 'magic isset assert ok' + ); + unset($session->$name); + $this->assertEquals( + '', + $session->$name, + 'magic unset assert' + ); + // isset true + $this->assertFalse( + isset($session->$name), + 'magic isset assert false' + ); + } + + /** + * unset all test + * + * @covers ::unsetAllS + * @testdox unsetAllS test + * + * @return void + */ + public function testUnsetAll(): void + { + $test_values = [ + 'foo' => 'abc', + 'bar' => '123' + ]; + $session = new \CoreLibs\Create\Session(); + foreach ($test_values as $name => $value) { + $session->setS($name, $value); + // confirm set + $this->assertEquals( + $value, + $session->getS($name), + 'set assert: ' . $name + ); + } + // unset all + $session->unsetAllS(); + // check unset + foreach (array_keys($test_values) as $name) { + $this->assertEquals( + '', + $session->getS($name), + 'unsert assert: ' . $name + ); + } + } } // __END__ diff --git a/4dev/tests/CoreLibsDBIOTest.php b/4dev/tests/CoreLibsDBIOTest.php index 165133b0..2fd95db0 100644 --- a/4dev/tests/CoreLibsDBIOTest.php +++ b/4dev/tests/CoreLibsDBIOTest.php @@ -36,6 +36,7 @@ declare(strict_types=1); namespace tests; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\MockObject\MockObject; /** * Test class for DB\IO + DB\SQL\PgSQL @@ -387,28 +388,24 @@ final class CoreLibsDBIOTest extends TestCase public function testDbVerson(string $input, bool $expected): void { // connect to valid DB - $db = new \CoreLibs\DB\IO( - self::$db_config['valid'], - self::$log - ); + // $db = new \CoreLibs\DB\IO( + // self::$db_config['valid'], + // self::$log + // ); + + /** @var \CoreLibs\DB\IO&MockObject $db_io_mock */ + $db_io_mock = $this->createPartialMock(\CoreLibs\DB\IO::class, ['dbVersion']); + $db_io_mock->method('dbVersion')->willReturn('13.6.0'); // print "DB VERSION: " . $db->dbVersion() . "\n"; - - // TODO: Mock \CoreLibs\DB\SQL\PgSQL somehow or Mock \CoreLibsDB\IO::dbVersion - // Create a stub for the SomeClass class. - // $stub = $this->createMock(\CoreLibs\DB\IO::class); - // $stub->method('dbVersion') - // ->willReturn('13.1.0'); - // print "DB: " . $stub->dbVersion() . "\n"; + // print "DB Mock: " . $stub->dbVersion() . "\n"; // print "TEST: " . ($stub->dbCompareVersion('=13.1.0') ? 'YES' : 'NO') . "\n"; // print "TEST: " . ($stub->dbCompareVersion('=13.6.0') ? 'YES' : 'NO') . "\n"; - // $mock = $this->getMockBuilder(CoreLibs\DB\IO::class) - // ->addMethods(['dbVersion']) - // ->ge‌​tMock(); $this->assertEquals( $expected, - $db->dbCompareVersion($input) + // $db->dbCompareVersion($input) + $db_io_mock->dbCompareVersion($input) ); // print "IT HAS TO BE 13.1.0: " . $stub->dbVersion() . "\n"; diff --git a/www/admin/class_test.session.php b/www/admin/class_test.session.php index b65dc10c..95a16cf2 100644 --- a/www/admin/class_test.session.php +++ b/www/admin/class_test.session.php @@ -120,6 +120,21 @@ print "[READ] B " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "
"; print "[READ] Confirm " . $var . " is " . $value . ": " . (($_SESSION[$var] ?? '') == $value ? 'Matching' : 'Not matching') . "
"; +// test set wrappers methods +$session->setS('setwrap', 'YES, method set _SESSION var'); +print "[READ WRAP] A setwrap: " . $session->getS('setwrap') . "
"; +print "[READ WRAP] Isset: " . ($session->issetS('setwrap') ? 'Yes' : 'No') . "
"; +$session->unsetS('setwrap'); +print "[READ WRAP] unset setwrap: " . $session->getS('setwrap') . "
"; +print "[READ WRAP] unset Isset: " . ($session->issetS('setwrap') ? 'Yes' : 'No') . "
"; +// test __get/__set +$session->setwrap = 'YES, magic set _SESSION var'; +print "[READ MAGIC] A setwrap: " . $session->setwrap . "
"; +print "[READ MAGIC] Isset: " . (isset($session->setwrap) ? 'Yes' : 'No') . "
"; +unset($session->setwrap); +print "[READ MAGIC] unset setwrap: " . $session->setwrap . "
"; +print "[READ MAGIC] unset Isset: " . (isset($session->setwrap) ? 'Yes' : 'No') . "
"; + // differnt session name $session_name = 'class-test-session-ALT'; if (false === ($session_id = $session->startSession($session_name))) { diff --git a/www/includes/admin_header.php b/www/includes/admin_header.php index 98c4ba82..9476b00b 100644 --- a/www/includes/admin_header.php +++ b/www/includes/admin_header.php @@ -50,7 +50,7 @@ $session = new \CoreLibs\Create\Session($SET_SESSION_NAME); // create logger $log = new CoreLibs\Debug\Logging([ 'log_folder' => BASE . LOG, - 'file_id' => LOG_FILE_ID, + 'file_id' => $LOG_FILE_ID, 'print_file_date' => true, 'debug_all' => $DEBUG_ALL ?? false, 'echo_all' => $ECHO_ALL ?? false, diff --git a/www/lib/CoreLibs/Create/Session.php b/www/lib/CoreLibs/Create/Session.php index 7b6e9dc6..448b0e77 100644 --- a/www/lib/CoreLibs/Create/Session.php +++ b/www/lib/CoreLibs/Create/Session.php @@ -15,8 +15,8 @@ namespace CoreLibs\Create; class Session { - /** @var string list for errors*/ - private $error_str = ''; + /** @var string list for errors */ + private $session_intern_error_str = ''; /** * init a session, if array is empty or array does not have session_name set @@ -32,23 +32,54 @@ class Session } /** - * check if we are in CLI, we set this, so we can mock this too + * check if we are in CLI, we set this, so we can mock this + * Not this is just a wrapper for the static System::checkCLI call * - * @return bool + * @return bool True if we are in a CLI enviroment, or false for everything else */ - private function checkCLI(): bool + public function checkCliStatus(): bool { return \CoreLibs\Get\System::checkCLI(); } + /** + * Set session name call. If not valid session name, will return false + * + * @param string $session_name A valid string for session name + * @return bool True if session name is valid, + * False if not + */ + public function setSessionName(string $session_name): bool + { + if (!$this->checkValidSessionName($session_name)) { + return false; + } + session_name($session_name); + return true; + } + + /** + * Start session + * startSession should be called for complete check + * If this is called without any name set before the php.ini name is + * used. + * + * @return void + */ + public function startSessionCall(): void + { + session_start(); + } + /** * Return set error string, empty if none set + * Error strings are only set in the startSession method * * @return string Last error string */ public function getErrorStr(): string { - return $this->error_str; + return $this->session_intern_error_str; } /** @@ -88,13 +119,13 @@ class Session public function startSession(?string $session_name = null) { // we can't start sessions on command line - if ($this->checkCLI()) { - $this->error_str = '[SESSION] No sessions in php cli'; + if ($this->checkCliStatus()) { + $this->session_intern_error_str = '[SESSION] No sessions in php cli'; return false; } // if session are OFF if ($this->getSessionStatus() === PHP_SESSION_DISABLED) { - $this->error_str = '[SESSION] Sessions are disabled'; + $this->session_intern_error_str = '[SESSION] Sessions are disabled'; return false; } // session_status @@ -108,20 +139,23 @@ class Session if (!empty($session_name)) { // invalid session name, abort if (!$this->checkValidSessionName($session_name)) { - $this->error_str = '[SESSION] Invalid session name: ' . $session_name; + $this->session_intern_error_str = '[SESSION] Invalid session name: ' . $session_name; return false; } - session_name($session_name); + $this->setSessionName($session_name); } // start session - session_start(); + $this->startSessionCall(); } // if we still have no active session if (!$this->checkActiveSession()) { - $this->error_str = '[SESSION] Failed to activate session'; + $this->session_intern_error_str = '[SESSION] Failed to activate session'; return false; } - return $this->getSessionId(); + if (false === ($session_id = $this->getSessionId())) { + $this->session_intern_error_str = '[SESSION] getSessionId did not return a session id'; + } + return $session_id; } /** @@ -180,12 +214,125 @@ class Session * * https://www.php.net/manual/en/function.session-status.php * - * @return int + * @return int See possible return int values above */ public function getSessionStatus(): int { return session_status(); } + + // _SESSION set/unset methods + + /** + * unset all _SESSION entries + * + * @return void + */ + public function unsetAllS(): void + { + foreach (array_keys($_SESSION ?? []) as $name) { + unset($_SESSION[$name]); + } + } + + /** + * set _SESSION entry 'name' with any value + * + * @param string|int $name array name in _SESSION + * @param mixed $value value to set (can be anything) + * @return void + */ + public function setS($name, $value): void + { + $_SESSION[$name] = $value; + } + + /** + * get _SESSION 'name' entry or empty string if not set + * + * @param string|int $name value key to get from _SESSION + * @return mixed value stored in _SESSION + */ + public function getS($name) + { + return $_SESSION[$name] ?? ''; + } + + /** + * Check if a name is set in the _SESSION array + * + * @param string|int $name Name to check for + * @return bool True for set, False fornot set + */ + public function issetS($name): bool + { + return isset($_SESSION[$name]); + } + + /** + * unset one _SESSION entry 'name' if exists + * + * @param string|int $name _SESSION key name to remove + * @return void + */ + public function unsetS($name): void + { + if (isset($_SESSION[$name])) { + unset($_SESSION[$name]); + } + } + + // set/get below + // ->var = value; + + /** + * Undocumented function + * + * @param string|int $name + * @param mixed $value + * @return void + */ + public function __set($name, $value): void + { + $_SESSION[$name] = $value; + } + + /** + * Undocumented function + * + * @param string|int $name + * @return mixed + */ + public function __get($name) + { + if (isset($_SESSION[$name])) { + return $_SESSION[$name]; + } + } + + /** + * Undocumented function + * + * @param string|int $name + * @return bool + */ + public function __isset($name): bool + { + return isset($_SESSION[$name]); + } + + /** + * Undocumented function + * + * @param string|int $name + * @return void + */ + public function __unset($name): void + { + if (isset($_SESSION[$name])) { + unset($_SESSION[$name]); + } + } } // __END__ diff --git a/www/lib/CoreLibs/DB/IO.php b/www/lib/CoreLibs/DB/IO.php index 50558090..d79c8a7d 100644 --- a/www/lib/CoreLibs/DB/IO.php +++ b/www/lib/CoreLibs/DB/IO.php @@ -1384,7 +1384,7 @@ class IO // we only compare the first two preg_match( "/^(\d{1,})\.(\d{1,})\.?(\d{1,})?/", - $this->db_functions->__dbVersion(), + $this->dbVersion(), $matches ); $master = $matches[1];