From 7a902b5681b733904cd406c52bb206e78dcd2473 Mon Sep 17 00:00:00 2001 From: Clemens Schwaighofer Date: Fri, 25 Feb 2022 18:08:10 +0900 Subject: [PATCH] Update hash class unit tests, work on DB IO unit tests --- 4dev/tests/CoreLibsCreateHashTest.php | 68 ++++++++- 4dev/tests/CoreLibsDBIOTest.php | 209 ++++++++++++++++++++------ www/lib/CoreLibs/ACL/Login.php | 2 +- www/lib/CoreLibs/DB/IO.php | 114 +++++++++----- 4 files changed, 306 insertions(+), 87 deletions(-) diff --git a/4dev/tests/CoreLibsCreateHashTest.php b/4dev/tests/CoreLibsCreateHashTest.php index 58c58c81..c8866afe 100644 --- a/4dev/tests/CoreLibsCreateHashTest.php +++ b/4dev/tests/CoreLibsCreateHashTest.php @@ -80,7 +80,7 @@ final class CoreLibsCreateHashTest extends TestCase foreach ([null, 'crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat'] as $_hash_type) { // default value test if ($_hash_type === null) { - $hash_type = 'crc32b'; + $hash_type = \CoreLibs\Create\Hash::STANDARD_HASH_SHORT; } else { $hash_type = $_hash_type; } @@ -94,6 +94,31 @@ final class CoreLibsCreateHashTest extends TestCase return $list; } + /** + * Undocumented function + * + * @return array + */ + public function hashLongProvider(): array + { + $hash_source = 'Some String Text'; + return [ + 'Long Hash check: ' . \CoreLibs\Create\Hash::STANDARD_HASH_LONG => [ + $hash_source, + hash(\CoreLibs\Create\Hash::STANDARD_HASH_LONG, $hash_source) + ], + ]; + } + + public function uniqIdLongProvider(): array + { + return [ + 'uniq id long: ' . \CoreLibs\Create\Hash::STANDARD_HASH_LONG => [ + strlen(hash(\CoreLibs\Create\Hash::STANDARD_HASH_LONG, 'A')) + ], + ]; + } + /** * Undocumented function * @@ -172,20 +197,57 @@ final class CoreLibsCreateHashTest extends TestCase /** * Undocumented function * - * @covers ::__uniqueID + * @covers ::__uniqueId * @testWith [8] * @testdox __uniqId will be length $expected [$_dataName] * * @param integer $expected * @return void */ - public function testUniqID(int $expected): void + public function testUniqId(int $expected): void { $this->assertEquals( $expected, strlen(\CoreLibs\Create\Hash::__uniqId()) ); } + + /** + * Undocumented function + * + * @covers ::__hashLong + * @dataProvider hashLongProvider + * @testdox __hashLong $input will be $expected [$_dataName] + * + * @param string $input + * @param string $expected + * @return void + */ + public function testHashLong(string $input, string $expected): void + { + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::__hashLong($input) + ); + } + + /** + * Undocumented function + * + * @covers ::__uniqueIdLong + * @dataProvider uniqIdLongProvider + * @testdox __uniqIdLong will be length $expected [$_dataName] + * + * @param integer $expected + * @return void + */ + public function testUniqIdLong(int $expected): void + { + $this->assertEquals( + $expected, + strlen(\CoreLibs\Create\Hash::__uniqIdLong()) + ); + } } // __END__ diff --git a/4dev/tests/CoreLibsDBIOTest.php b/4dev/tests/CoreLibsDBIOTest.php index 89d8cb8e..3266b72d 100644 --- a/4dev/tests/CoreLibsDBIOTest.php +++ b/4dev/tests/CoreLibsDBIOTest.php @@ -15,39 +15,38 @@ use PHPUnit\Framework\TestCase; */ final class CoreLibsDBIOTest extends TestCase { - private static $db_config = []; + private static $db_config = [ + // self localhost/ip connection + 'valid' => [ + 'db_name' => 'corelibs_db_io_test', + 'db_user' => 'corelibs_db_io_test', + 'db_pass' => 'corelibs_db_io_test', + 'db_host' => 'localhost', + 'db_port' => 5432, + 'db_schema' => 'public', + 'db_type' => 'pgsql', + 'db_encoding' => '', + 'db_ssl' => 'allow', // allow, disable, require, prefer + 'db_debug' => true, + ], + 'invalid' => [ + 'db_name' => '', + 'db_user' => '', + 'db_pass' => '', + 'db_host' => '', + 'db_port' => 5432, + 'db_schema' => 'public', + 'db_type' => 'pgsql', + 'db_encoding' => '', + 'db_ssl' => 'allow', // allow, disable, require, prefer + 'db_debug' => true, + ], + ]; private static $log; public static function setUpBeforeClass(): void { // define basic connection set valid and one invalid - self::$db_config = [ - // self localhost/ip connection - 'valid' => [ - 'db_name' => 'corelibs_db_io_test', - 'db_user' => 'corelibs_db_io_test', - 'db_pass' => 'corelibs_db_io_test', - 'db_host' => 'localhost', - 'db_port' => 5432, - 'db_schema' => 'public', - 'db_type' => 'pgsql', - 'db_encoding' => '', - 'db_ssl' => 'allow', // allow, disable, require, prefer - 'db_debug' => true, - ], - 'invalid' => [ - 'db_name' => '', - 'db_user' => '', - 'db_pass' => '', - 'db_host' => '', - 'db_port' => 5432, - 'db_schema' => 'public', - 'db_type' => 'pgsql', - 'db_encoding' => '', - 'db_ssl' => 'allow', // allow, disable, require, prefer - 'db_debug' => true, - ], - ]; self::$log = new \CoreLibs\Debug\Logging([ // 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log', 'log_folder' => DIRECTORY_SEPARATOR . 'tmp', @@ -73,19 +72,95 @@ final class CoreLibsDBIOTest extends TestCase // print_r(self::$db_config); } - // - connect to DB test (getConnectionStatus) + // - connect to DB test (dbGetConnectionStatus) // - connected get dbInfo data check (show true, false) // - disconnect: dbClose + + /** + * connection DB strings + * + * @return array + */ + public function connectionProvider(): array + { + // 0: connection array + // 1: status after connection + // 2: info string + return [ + 'invalid connection' => [ + self::$db_config['invalid'], + false, + "-DB-info-> Connected to db '' with schema 'public' as user " + . "'' at host '' on port '5432' with ssl mode 'allow' **** " + . "-DB-info-> DB IO Class debug output: Yes **** ", + null, + ], + 'valid connection' => [ + self::$db_config['valid'], + true, + "-DB-info-> Connected to db 'corelibs_db_io_test' with " + . "schema 'public' as user 'corelibs_db_io_test' at host " + . "'localhost' on port '5432' with ssl mode 'allow' **** " + . "-DB-info-> DB IO Class debug output: Yes **** ", + null, + ], + ]; + } + + /** + * Connection tests + * + * @covers ::__connectToDB + * @dataProvider connectionProvider + * @testdox Connection will be $expected [$_dataName] + * + * @return void + */ + public function testConnection( + array $connection, + bool $expected_status, + string $expected_string + ): void { + $db = new \CoreLibs\DB\IO( + $connection, + self::$log + ); + $this->assertEquals( + $db->dbGetConnectionStatus(), + $expected_status + ); + $this->assertEquals( + $db->dbInfo(false, true), + $expected_string + ); + + // print "DB: " . $db->dbInfo(false, true) . "\n"; + if ($db->dbGetConnectionStatus()) { + // db close check + $db->dbClose(); + $this->assertEquals( + $db->dbGetConnectionStatus(), + false + ); + } else { + // TODO: error checks + // print "LAST ERROR: " . $db->dbGetLastError(true) . "\n"; + // print "ERRORS: " . print_r($db->dbGetErrorHistory(true), true) . "\n"; + } + } + // - connected get all default settings via get - // dbGetDebug, dbGetMaxQueryCall, dbGetSchema, dbGetEncoding, - // dbVerions, dbCompareVersion + // dbGetDebug, dbGetSchema, dbGetEncoding, dbGetMaxQueryCall // dbGetSetting (name, user, ecnoding, schema, host, port, ssl, debug, password) // - connected set - // dbSetMaxQueryCall, dbSetDebug, dbToggleDebug, dbSetSchema, dbSetEncoding + // dbSetMaxQueryCall, , + // dbSetDebug, dbToggleDebug, dbSetSchema, dbSetEncoding + // - db execution tests // dbReturn, dbDumpData, dbCacheReset, dbExec, dbExecAsync, dbCheckAsync // dbFetchArray, dbReturnRow, dbReturnArray, dbCursorPos, dbCursorNumRows, // dbShowTableMetaData, dbPrepare, dbExecute + // - connected stand alone tests // dbEscapeString, dbEscapeLiteral, dbEscapeBytea, dbSqlEscape, dbArrayParse // - complex write sets // dbWriteData, dbWriteDataExt @@ -100,21 +175,71 @@ final class CoreLibsDBIOTest extends TestCase // getInsertReturn, getReturning, getInsertPK, getReturningExt, // getCursorExt, getNumRows - public function testConnection() + // public function testDbSettings(): void + // { + // // + // } + + // - connected version test + // dbVerions, dbCompareVersion + + /** + * Undocumented function + * + * @return array + */ + public function versionProvider(): array { - // - $db = new \CoreLibs\DB\IO( - self::$db_config['invalid'], - self::$log - ); - print "INIT ERROR INVALID: " . $db->getConnectionStatus() . "\n"; - print "LAST ERROR: " . $db->dbGetLastError(true) . "\n"; - print "ERRORS: " . print_r($db->dbGetErrorHistory(true), true) . "\n"; + return [ + 'compare = ok' => [ '=13.5.0', true ], + 'compare = bad' => [ '=9.2.0', false ], + 'compare < ok' => [ '<20.0.0', true ], + 'compare < bad' => [ '<9.2.0', false ], + 'compare <= ok a' => [ '<=20.0.0', true ], + 'compare <= ok b' => [ '<=13.5.0', true ], + 'compare <= false' => [ '<=9.2.0', false ], + 'compare > ok' => [ '>9.2.0', true ], + 'compare > bad' => [ '>20.2.0', false ], + 'compare >= ok a' => [ '>=13.5.0', true ], + 'compare >= ok b' => [ '>=9.2.0', true ], + 'compare >= bad' => [ '>=20.0.0', false ], + ]; + } + + /** + * NOTE + * Version tests will fail if versions change + * Current base as Version 13.5 for equal check + * I can't mock a function on the same class when it is called in a method + * NOTE + * + * @covers ::dbCompareVersion + * @dataProvider versionProvider + * @testdox Version $input compares as $expected [$_dataName] + * + * @return void + */ + public function testDbVerson(string $input, bool $expected): void + { + // connect to valid DB $db = new \CoreLibs\DB\IO( self::$db_config['valid'], self::$log ); - print "INIT ERROR VALID: " . $db->getConnectionStatus() . "\n"; + + // print "DB VERSION: " . $db->dbVersion() . "\n"; + + // Create a stub for the SomeClass class. + // $stub = $this->createMock(\CoreLibs\DB\IO::class); + // $stub->method('dbVersion') + // ->willReturn('13.1.0'); + + $this->assertEquals( + $db->dbCompareVersion($input), + $expected + ); + + // print "IT HAS TO BE 13.1.0: " . $stub->dbVersion() . "\n"; } /** diff --git a/www/lib/CoreLibs/ACL/Login.php b/www/lib/CoreLibs/ACL/Login.php index 484758b5..9363e6be 100644 --- a/www/lib/CoreLibs/ACL/Login.php +++ b/www/lib/CoreLibs/ACL/Login.php @@ -178,7 +178,7 @@ class Login extends \CoreLibs\DB\IO // set internal page name $this->page_name = \CoreLibs\Get\System::getPageName(); // set db special errors - if ($this->db_init_error === true) { + if (!$this->dbGetConnectionStatus()) { echo 'Could not connect to DB
'; // if I can't connect to the DB to auth exit hard. No access allowed exit; diff --git a/www/lib/CoreLibs/DB/IO.php b/www/lib/CoreLibs/DB/IO.php index 1d3131fc..a92ad937 100644 --- a/www/lib/CoreLibs/DB/IO.php +++ b/www/lib/CoreLibs/DB/IO.php @@ -339,7 +339,7 @@ class IO private $warning_history = []; // error thrown on class init if we cannot connect to db /** @var bool */ - protected $db_init_error = false; + protected $db_connection_closed = false; // sub include with the database functions /** @var \CoreLibs\DB\SQL\PgSQL */ private $db_functions; @@ -463,17 +463,17 @@ class IO } else { // abort error $this->__dbError(10); - $this->db_init_error = true; + $this->db_connection_closed = true; } if (!is_object($this->db_functions)) { $this->__dbError(100); - $this->db_init_error = true; + $this->db_connection_closed = true; } // connect to DB if (!$this->__connectToDB()) { $this->__dbError(16); - $this->db_init_error = true; + $this->db_connection_closed = true; } } @@ -1071,18 +1071,19 @@ class IO if ($this->dbh) { $this->db_functions->__dbClose(); $this->dbh = null; + $this->db_connection_closed = true; } } /** * returns the db init error - * if failed to connect it is set to true - * else false - * @return bool connection failure status + * if failed to connect it is set to false + * else true + * @return bool Connection status */ - public function getConnectionStatus(): bool + public function dbGetConnectionStatus(): bool { - return $this->db_init_error; + return $this->db_connection_closed ? false : true; } /** @@ -1131,12 +1132,16 @@ class IO /** * prints out status info from the connected DB (might be usefull for debug stuff) - * @param bool|boolean $show show db connection info, default true - * if set to false won't write to error_msg var - * @return string db connection information string + * @param bool $log Show db connection info, default true + * if set to false won't write to error_msg var + * @param bool $strip Strip all HTML + * @return string db connection information string */ - public function dbInfo(bool $show = true): string + public function dbInfo(bool $log = true, bool $strip = false): string { + $html_tags = ['{b}', '{/b}', '{br}']; + $replace_html = ['', '', '
']; + $replace_text = ['', '', ' **** ']; $string = ''; $string .= '{b}-DB-info->{/b} Connected to db {b}\'' . $this->db_name . '\'{/b} '; $string .= 'with schema {b}\'' . $this->db_schema . '\'{/b} '; @@ -1145,14 +1150,22 @@ class IO $string .= 'on port {b}\'' . $this->db_port . '\'{/b} '; $string .= 'with ssl mode {b}\'' . $this->db_ssl . '\'{/b}{br}'; $string .= '{b}-DB-info->{/b} DB IO Class debug output: {b}' . ($this->db_debug ? 'Yes' : 'No') . '{/b}'; - if ($show === true) { + if ($log === true) { // if debug, remove / change b - $this->__dbDebug('db', str_replace(['{b}', '{/b}', '{br}'], ['', '', ' **** '], $string), 'dbInfo'); + $this->__dbDebug('db', str_replace( + $html_tags, + $replace_text, + $string + ), 'dbInfo'); } else { $string = $string . '{br}'; } - // for direct print, change to html - return str_replace(['{b}', '{/b}', '{br}'], ['', '', '
'], $string); + // for direct print, change to html or strip if flagged + return str_replace( + $html_tags, + $strip === false ? $replace_html : $replace_text, + $string + ); } /** @@ -1177,7 +1190,7 @@ class IO $compare = $matches[1]; $to_master = $matches[2]; $to_minor = $matches[3]; - if (!$compare || !$to_master || !$to_minor) { + if (!$compare || !strlen($to_master) || !strlen($to_minor)) { return false; } else { $to_version = $to_master . ($to_minor < 10 ? '0' : '') . $to_minor; @@ -1289,6 +1302,33 @@ class IO return is_array($__db_array_parse) ? $__db_array_parse : []; } + // *************************** + // DEBUG DATA DUMP + // *************************** + + /** + * dumps ALL data for this query, OR if no query given all in cursor_ext array + * @param string $query Query, if given, only from this quey (if found) + * else current cursor + * @return string Formated string with all the data in the array + */ + public function dbDumpData($query = ''): string + { + // set start array + if ($query) { + $array = $this->cursor_ext[Hash::__hashLong($query)] ?? []; + } else { + $array = $this->cursor_ext; + } + $string = ''; + if (is_array($array)) { + $this->nbsp = ''; + $string .= $this->__printArray($array); + $this->__dbDebug('db', $string, 'dbDumpData'); + } + return $string; + } + // *************************** // DATA WRITE CONVERSION // *************************** @@ -1383,29 +1423,6 @@ class IO // QUERY EXECUSION AND DATA READ // *************************** - /** - * dumps ALL data for this query, OR if no query given all in cursor_ext array - * @param string $query Query, if given, only from this quey (if found) - * else current cursor - * @return string Formated string with all the data in the array - */ - public function dbDumpData($query = ''): string - { - // set start array - if ($query) { - $array = $this->cursor_ext[Hash::__hashLong($query)] ?? []; - } else { - $array = $this->cursor_ext; - } - $string = ''; - if (is_array($array)) { - $this->nbsp = ''; - $string .= $this->__printArray($array); - $this->__dbDebug('db', $string, 'dbDumpData'); - } - return $string; - } - /** * single running function, if called creates hash from * query string and so can itself call exec/return calls @@ -2633,6 +2650,21 @@ class IO // DEPEREACTED CALLS /******************************** */ + /** + * returns the db init error + * if failed to connect it is set to true + * else false + * @return bool connection failure status + * @deprecated Use dbGetConnectionStatus() and True means correct connection + */ + public function getConnectionStatus(): bool + { + trigger_error('Method ' . __METHOD__ . ' is deprecated, ' + . 'use dbGetConnectionStatus() with True for successful connection', E_USER_DEPRECATED); + // reverse because before it was reverse + return $this->dbGetConnectionStatus() ? false : true; + } + /** * Sets error number that was last * So we always have the last error number stored even if a new one is created