From 0558150dc5478379581b212a32dbcc7afff9e4c0 Mon Sep 17 00:00:00 2001 From: ayushchd Date: Thu, 11 Jul 2013 13:58:51 +0545 Subject: [PATCH 01/44] Reset ConfigFile Instance --- test/libraries/PMA_ConfigFile_test.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/libraries/PMA_ConfigFile_test.php b/test/libraries/PMA_ConfigFile_test.php index 4e0fa6a563..de12c76c2e 100644 --- a/test/libraries/PMA_ConfigFile_test.php +++ b/test/libraries/PMA_ConfigFile_test.php @@ -44,6 +44,11 @@ class PMA_ConfigFile_Test extends PHPUnit_Framework_TestCase unset($_SESSION[$this->readAttribute($this->object, "_id")]); unset($this->object); + + // reset the instance + $attr_instance = new ReflectionProperty("ConfigFile", "_instance"); + $attr_instance->setAccessible(true); + $attr_instance->setValue(null, null); } /** From f7e9e262c161950355ee7af3b5732b01d37860a5 Mon Sep 17 00:00:00 2001 From: ayushchd Date: Thu, 11 Jul 2013 13:59:49 +0545 Subject: [PATCH 02/44] Tests for setup/* and user_prefs* --- setup/lib/form_processing.lib.php | 9 +- test/libraries/PMA_ConfigGenerator_test.php | 203 +++++++ test/libraries/PMA_Form_Processing_test.php | 117 ++++ test/libraries/PMA_Index_test.php | 540 +++++++++++++++++++ test/libraries/PMA_user_preferences_test.php | 471 ++++++++++++++++ 5 files changed, 1338 insertions(+), 2 deletions(-) create mode 100644 test/libraries/PMA_ConfigGenerator_test.php create mode 100644 test/libraries/PMA_Form_Processing_test.php create mode 100644 test/libraries/PMA_Index_test.php create mode 100644 test/libraries/PMA_user_preferences_test.php diff --git a/setup/lib/form_processing.lib.php b/setup/lib/form_processing.lib.php index d9b6e6aea3..ed013896f6 100644 --- a/setup/lib/form_processing.lib.php +++ b/setup/lib/form_processing.lib.php @@ -21,7 +21,10 @@ function process_formset(FormDisplay $form_display) // drop post data header('HTTP/1.1 303 See Other'); header('Location: index.php'); - exit; + echo 'here'; + if (!defined('TESTSUITE')) { + exit; + } } if (!$form_display->process(false)) { // handle form view and failed POST @@ -55,7 +58,9 @@ function process_formset(FormDisplay $form_display) // drop post data header('HTTP/1.1 303 See Other'); header('Location: index.php'); - exit; + if (!defined('TESTSUITE')) { + exit; + } } } } diff --git a/test/libraries/PMA_ConfigGenerator_test.php b/test/libraries/PMA_ConfigGenerator_test.php new file mode 100644 index 0000000000..e906e277bb --- /dev/null +++ b/test/libraries/PMA_ConfigGenerator_test.php @@ -0,0 +1,203 @@ +setAccessible(true); + $attr_instance->setValue(null, null); + + $GLOBALS['server'] = 0; + $cf = ConfigFile::getInstance(); + $_SESSION['ConfigFile0']['Servers'] = array( + array(1, 2, 3) + ); + + $cf->setPersistKeys(array("1/", 2)); + + $result = ConfigGenerator::getConfigFile(); + + $this->assertContains( + "assertContains( + "/* Servers configuration */\n" . + '$i = 0;' . "\n\n" . + "/* Server: localhost [0] */\n" . + '$i++;' . "\n" . + '$cfg[\'Servers\'][$i][\'0\'] = 1;' . "\n" . + '$cfg[\'Servers\'][$i][\'1\'] = 2;' . "\n" . + '$cfg[\'Servers\'][$i][\'2\'] = 3;' . "\n\n" . + "/* End of servers configuration */\n\n", + $result + ); + + $this->assertContains( + '?>', + $result + ); + } + + /** + * Test for ConfigGenerator::_getVarExport + * + * @return void + */ + public function testGetVarExport() + { + $reflection = new \ReflectionClass('ConfigGenerator'); + $method = $reflection->getMethod('_getVarExport'); + $method->setAccessible(true); + + $this->assertEquals( + '$cfg[\'var_name\'] = array (' . + "\n);\n", + $method->invoke(null, 'var_name', array(), "\n") + ); + + $this->assertEquals( + '$cfg[\'var_name\'] = array(1, 2, 3);' . "\n", + $method->invoke( + null, + 'var_name', + array(1, 2, 3), + "\n" + ) + ); + + $this->assertEquals( + '$cfg[\'var_name\'][\'1a\'] = \'foo\';' . "\n" . + '$cfg[\'var_name\'][\'b\'] = \'bar\';' . "\n", + $method->invoke( + null, + 'var_name', + array( + '1a' => 'foo', + 'b' => 'bar' + ), + "\n" + ) + ); + } + + /** + * Test for ConfigGenerator::_isZeroBasedArray + * + * @return void + */ + public function testIsZeroBasedArray() + { + $reflection = new \ReflectionClass('ConfigGenerator'); + $method = $reflection->getMethod('_isZeroBasedArray'); + $method->setAccessible(true); + + $this->assertFalse( + $method->invoke( + null, + array( + 'a' => 1, + 'b' => 2 + ) + ) + ); + + $this->assertFalse( + $method->invoke( + null, + array( + 0 => 1, + 1 => 2, + 3 => 3, + ) + ) + ); + + $this->assertTrue( + $method->invoke( + null, + array() + ) + ); + + $this->assertTrue( + $method->invoke( + null, + array(1, 2, 3) + ) + ); + } + + /** + * Test for ConfigGenerator::_exportZeroBasedArray + * + * @return void + */ + public function testExportZeroBasedArray() + { + $reflection = new \ReflectionClass('ConfigGenerator'); + $method = $reflection->getMethod('_exportZeroBasedArray'); + $method->setAccessible(true); + + $arr = array(1, 2, 3, 4); + + $result = $method->invoke(null, $arr, "\n"); + + $this->assertEquals( + 'array(1, 2, 3, 4)', + $result + ); + + $arr = array(1, 2, 3, 4, 7, 'foo'); + + $result = $method->invoke(null, $arr, "\n"); + + $this->assertEquals( + 'array(' . "\n" . + ' 1,' . "\n" . + ' 2,' . "\n" . + ' 3,' . "\n" . + ' 4,' . "\n" . + ' 7,' . "\n" . + ' \'foo\')', + $result + ); + } +} +?> diff --git a/test/libraries/PMA_Form_Processing_test.php b/test/libraries/PMA_Form_Processing_test.php new file mode 100644 index 0000000000..bfc3d95f82 --- /dev/null +++ b/test/libraries/PMA_Form_Processing_test.php @@ -0,0 +1,117 @@ +getMockBuilder('FormDisplay') + ->disableOriginalConstructor() + ->setMethods(array('process', 'display')) + ->getMock(); + + $formDisplay->expects($this->once()) + ->method('process') + ->with(false) + ->will($this->returnValue(false)); + + $formDisplay->expects($this->once()) + ->method('display') + ->with(true, true); + + process_formset($formDisplay); + + // case 2 + $formDisplay = $this->getMockBuilder('FormDisplay') + ->disableOriginalConstructor() + ->setMethods(array('process', 'hasErrors', 'displayErrors')) + ->getMock(); + + $formDisplay->expects($this->once()) + ->method('process') + ->with(false) + ->will($this->returnValue(true)); + + $formDisplay->expects($this->once()) + ->method('hasErrors') + ->with() + ->will($this->returnValue(true)); + + ob_start(); + process_formset($formDisplay); + $result = ob_get_clean(); + + $this->assertContains( + '
', + $result + ); + + $this->assertContains( + '', + $result + ); + + $this->assertContains( + '', + $result + ); + + $this->assertContains( + '', + $result + ); + + // case 3 + $formDisplay = $this->getMockBuilder('FormDisplay') + ->disableOriginalConstructor() + ->setMethods(array('process', 'hasErrors')) + ->getMock(); + + $formDisplay->expects($this->once()) + ->method('process') + ->with(false) + ->will($this->returnValue(true)); + + $formDisplay->expects($this->once()) + ->method('hasErrors') + ->with() + ->will($this->returnValue(false)); + + process_formset($formDisplay); + + $this->assertEquals( + 'HTTP/1.1 303 See OtherLocation: index.php', + $GLOBALS['header'] + ); + + } + + +} +?> diff --git a/test/libraries/PMA_Index_test.php b/test/libraries/PMA_Index_test.php new file mode 100644 index 0000000000..8e68b63222 --- /dev/null +++ b/test/libraries/PMA_Index_test.php @@ -0,0 +1,540 @@ +assertEquals( + array( + array( + array( + 0 => 'foo', + 'fresh' => false, + 'active' => false + ), + array( + 0 => 'bar', + 'fresh' => false, + 'active' => false + ) + ) + ), + $_SESSION['messages'] + ); + + // case 2 + + unset($_SESSION['messages']); + messages_begin(); + $this->assertEquals( + array( + 'error' => array(), + 'notice' => array() + ), + $_SESSION['messages'] + ); + } + + /** + * Test for messages_set + * + * @return void + */ + public function testMessagesSet() + { + messages_set('type', '123', 'testTitle', 'msg'); + + $this->assertEquals( + array( + 'fresh' => true, + 'active' => true, + 'title' => 'testTitle', + 'message' => 'msg' + ), + $_SESSION['messages']['type']['123'] + ); + } + + /** + * Test for messages_end + * + * @return void + */ + public function testMessagesEnd() + { + $_SESSION['messages'] = array( + array( + array('msg' => 'foo', 'active' => false), + array('msg' => 'bar', 'active' => true), + ) + ); + + messages_end(); + + $this->assertEquals( + array( + array( + '1' => array( + 'msg' => 'bar', + 'active' => 1 + ) + ) + ), + $_SESSION['messages'] + ); + } + + /** + * Test for messages_show_html + * + * @return void + */ + public function testMessagesShowHTML() + { + $_SESSION['messages'] = array( + 'type' => array( + array('title' => 'foo', 'message' => '123', 'fresh' => false), + array('title' => 'bar', 'message' => '321', 'fresh' => true), + ) + ); + + ob_start(); + messages_show_html(); + $result = ob_get_clean(); + + $this->assertContains( + '

foo

123
', + $result + ); + + $this->assertContains( + '

bar

321
', + $result + ); + + $this->assertContains( + '", + $result + ); + } + + /** + * Test for PMA_version_check + * + * @return void + */ + public function testPMAVersionCheckCase1() + { + $pmaconfig = $this->getMockBuilder('PMA_Config') + ->disableOriginalConstructor() + ->getMock(); + + $pmaconfig->expects($this->once()) + ->method('get') + ->with('PMA_VERSION') + ->will($this->returnValue('1.0.2')); + + $GLOBALS['PMA_Config'] = $pmaconfig; + + PMA_version_check(); + + $this->assertArrayHasKey( + 'notice', + $_SESSION['messages'] + ); + $var = array_values($_SESSION['messages']['notice']); + $notice = array_shift($var); + + $this->assertEquals( + 1, + $notice['fresh'] + ); + + $this->assertEquals( + 1, + $notice['active'] + ); + + $this->assertEquals( + 'Version check', + $notice['title'] + ); + + $this->assertContains( + "A newer version of phpMyAdmin is available", + $notice['message'] + ); + } + + /** + * Test for PMA_version_check + * + * @return void + */ + public function testPMAVersionCheckCase2() + { + $pmaconfig = $this->getMockBuilder('PMA_Config') + ->disableOriginalConstructor() + ->getMock(); + + $pmaconfig->expects($this->once()) + ->method('get') + ->with('PMA_VERSION') + ->will($this->returnValue('100.0.0-dev0')); + + $GLOBALS['PMA_Config'] = $pmaconfig; + + PMA_version_check(); + + $this->assertArrayHasKey( + 'notice', + $_SESSION['messages'] + ); + $var = array_values($_SESSION['messages']['notice']); + $notice = array_shift($var); + + $this->assertEquals( + 1, + $notice['fresh'] + ); + + $this->assertEquals( + 1, + $notice['active'] + ); + + $this->assertEquals( + 'Version check', + $notice['title'] + ); + + $this->assertContains( + "You are using Git version", + $notice['message'] + ); + } + + /** + * Test for PMA_version_check + * + * @return void + */ + public function testPMAVersionCheckCase3() + { + $pmaconfig = $this->getMockBuilder('PMA_Config') + ->disableOriginalConstructor() + ->getMock(); + + $pmaconfig->expects($this->once()) + ->method('get') + ->with('PMA_VERSION') + ->will($this->returnValue('100.0.0-dev2')); + + $GLOBALS['PMA_Config'] = $pmaconfig; + + PMA_version_check(); + + $this->assertArrayHasKey( + 'notice', + $_SESSION['messages'] + ); + $var = array_values($_SESSION['messages']['notice']); + $notice = array_shift($var); + + $this->assertEquals( + 1, + $notice['fresh'] + ); + + $this->assertEquals( + 1, + $notice['active'] + ); + + $this->assertEquals( + 'Version check', + $notice['title'] + ); + + $this->assertContains( + "No newer stable version is available", + $notice['message'] + ); + } + + /** + * Test for version_to_int + * + * @param string $version Version String + * @param int $expected Expected int + * + * @return void + * @dataProvider versionToIntProvider + */ + public function testVersionToInt($version, $expected) + { + $this->assertEquals( + version_to_int($version), + $expected + ); + } + + /** + * Data Provider for testVersionToInt + * + * @return array Test data + */ + public function versionToIntProvider() + { + return array( + array('1.0.0', 1000050), + array('2.0.0.2-dev', 2000052), + array('3.4.2.1', 3040251), + array('3.4.2-dev3', 3040203), + array('3.4.2-dev', 3040200), + array('3.4.2-pl', 3040260), + array('3.4.2-pl3', 3040263), + array('4.4.2-rc22', 4040252), + array('4.4.2-rc', 4040230), + array('4.4.22-beta22', 4042242), + array('4.4.22-beta', 4042220), + array('4.4.21-alpha22', 4042132), + array('4.4.20-alpha', 4042010), + array('4.40.20-alpha-dev', 4402010), + array('4.4a', false), + array('4.4.4-test', false) + ); + } + + /** + * Test for check_config_rw + * + * @return void + */ + public function testCheckConfigRW() + { + if (!function_exists('runkit_constant_redefine')) { + $this->markTestSkipped('Cannot redefine constant'); + } + + $redefine = null; + $GLOBALS['cfg']['AvailableCharsets'] = array(); + if (!defined('SETUP_CONFIG_FILE')) { + define('SETUP_CONFIG_FILE', 'test/test_data/configfile'); + } else { + $redefine = 'SETUP_CONFIG_FILE'; + runkit_constant_redefine( + 'SETUP_CONFIG_FILE', + 'test/test_data/configfile' + ); + } + $is_readable = false; + $is_writable = false; + $file_exists = false; + + check_config_rw($is_readable, $is_writable, $file_exists); + + $this->assertTrue( + $is_readable + ); + + $this->assertTrue( + $is_writable + ); + + $this->assertFalse( + $file_exists + ); + + runkit_constant_redefine( + 'SETUP_CONFIG_FILE', + 'test/test_data/test.file' + ); + + check_config_rw($is_readable, $is_writable, $file_exists); + + $this->assertTrue( + $is_readable + ); + + $this->assertTrue( + $is_writable + ); + + $this->assertFalse( + $file_exists + ); + + if ($redefine !== null) { + runkit_constant_redefine('SETUP_CONFIG_FILE', $redefine); + } else { + runkit_constant_remove('SETUP_CONFIG_FILE'); + } + } + + /** + * Test for perform_config_checks + * + * @return void + */ + public function testPerformConfigChecks() + { + + $GLOBALS['cfg']['AvailableCharsets'] = array(); + $GLOBALS['cfg']['ServerDefault'] = 0; + + $cf = ConfigFile::getInstance(); + $reflection = new \ReflectionProperty('ConfigFile', '_id'); + $reflection->setAccessible(true); + $sessionID = $reflection->getValue($cf); + + $_SESSION[$sessionID]['Servers'] = array( + '1' => array( + 'host' => 'localhost', + 'ssl' => false, + 'extension' => 'mysql', + 'auth_type' => 'config', + 'user' => 'username', + 'password' => 'password', + 'AllowRoot' => true, + 'AllowNoPassword' => true, + ) + ); + + $_SESSION[$sessionID]['ForceSSL'] = false; + $_SESSION[$sessionID]['AllowArbitraryServer'] = true; + $_SESSION[$sessionID]['LoginCookieValidity'] = 5000; + $_SESSION[$sessionID]['LoginCookieStore'] = 4000; + $_SESSION[$sessionID]['SaveDir'] = true; + $_SESSION[$sessionID]['TempDir'] = true; + $_SESSION[$sessionID]['GZipDump'] = true; + $_SESSION[$sessionID]['BZipDump'] = true; + $_SESSION[$sessionID]['ZipDump'] = true; + + $noticeArrayKeys = array( + 'TempDir', + 'SaveDir', + 'LoginCookieValidity', + 'AllowArbitraryServer', + 'ForceSSL', + 'Servers/1/AllowNoPassword', + 'Servers/1/auth_type', + 'Servers/1/extension', + 'Servers/1/ssl' + ); + + $errorArrayKeys = array( + 'LoginCookieValidity' + ); + + if (@!function_exists('gzopen') || @!function_exists('gzencode')) { + $errorArrayKeys[] = 'GZipDump'; + } + + if (@!function_exists('bzopen') || @!function_exists('bzcompress')) { + $errorArrayKeys[] = 'BZipDump'; + } + + if (!@function_exists('zip_open')) { + $errorArrayKeys[] = 'ZipDump_import'; + } + + if (!@function_exists('gzcompress')) { + $errorArrayKeys[] = 'ZipDump_export'; + } + + perform_config_checks(); + + foreach ($noticeArrayKeys as $noticeKey) { + $this->assertArrayHasKey( + $noticeKey, + $_SESSION['messages']['notice'] + ); + } + + foreach ($errorArrayKeys as $errorKey) { + $this->assertArrayHasKey( + $errorKey, + $_SESSION['messages']['error'] + ); + } + + + // case 2 + + unset($_SESSION[$sessionID]); + + $_SESSION[$sessionID]['Servers'] = array( + '1' => array( + 'host' => 'localhost', + 'auth_type' => 'cookie' + ) + ); + perform_config_checks(); + $this->assertArrayHasKey( + 'blowfish_secret_created', + $_SESSION['messages']['notice'] + ); + + // case 3 + + $_SESSION[$sessionID]['blowfish_secret'] = 'sec'; + + $_SESSION[$sessionID]['Servers'] = array( + '1' => array( + 'host' => 'localhost', + 'auth_type' => 'cookie' + ) + ); + perform_config_checks(); + $this->assertArrayHasKey( + 'blowfish_warnings2', + $_SESSION['messages']['error'] + ); + + } +} +?> diff --git a/test/libraries/PMA_user_preferences_test.php b/test/libraries/PMA_user_preferences_test.php new file mode 100644 index 0000000000..f71420aa63 --- /dev/null +++ b/test/libraries/PMA_user_preferences_test.php @@ -0,0 +1,471 @@ + 'testval123', + 'Server/only_db' => 'test213' + ); + $GLOBALS['cfg']['AvailableCharsets'] = array(); + $GLOBALS['forms'] = array( + 'form1' => array( + array('Servers/1/hide_db', 'bar'), + array('test' => 'val') + ) + ); + + PMA_userprefsPageInit(); + + $this->assertEquals( + array( + 'Servers' => array( + 1 => array( + 'hide_db' => 'testval123' + ) + ) + ), + $_SESSION['ConfigFile' . $GLOBALS['server']] + ); + } + + /** + * Test for PMA_loadUserprefs + * + * @return void + */ + public function testLoadUserprefs() + { + $_SESSION['relation'][$GLOBALS['server']]['userconfigwork'] = null; + unset($_SESSION['userconfig']); + + $result = PMA_loadUserprefs(); + + $this->assertCount( + 3, + $result + ); + + $this->assertEquals( + array(), + $result['config_data'] + ); + + $this->assertEquals( + time(), + $result['mtime'], + 10 + ); + + $this->assertEquals( + 'session', + $result['type'] + ); + + // case 2 + $_SESSION['relation'][$GLOBALS['server']]['userconfigwork'] = 1; + $_SESSION['relation'][$GLOBALS['server']]['db'] = "pma'db"; + $_SESSION['relation'][$GLOBALS['server']]['userconfig'] = "testconf"; + $_SESSION['relation'][$GLOBALS['server']]['user'] = "user"; + $GLOBALS['controllink'] = null; + + $dbi = $this->getMockBuilder('PMA_DatabaseInterface') + ->disableOriginalConstructor() + ->getMock(); + + $query = ' + SELECT `config_data`, UNIX_TIMESTAMP(`timevalue`) ts + FROM `pma\'db`.`testconf` + WHERE `username` = \'user\''; + + $dbi->expects($this->once()) + ->method('fetchSingleRow') + ->with($query, 'ASSOC', null) + ->will( + $this->returnValue( + array( + 'ts' => '123', + 'config_data' => json_encode(array(1, 2)) + ) + ) + ); + $GLOBALS['dbi'] = $dbi; + + $result = PMA_loadUserprefs(); + + $this->assertEquals( + array( + 'config_data' => array(1, 2), + 'mtime' => 123, + 'type' => 'db' + ), + $result + ); + } + + /** + * Test for PMA_saveUserprefs + * + * @return void + */ + public function testSaveUserprefs() + { + $GLOBALS['server'] = 2; + $_SESSION['relation'][2]['userconfigwork'] = null; + unset($_SESSION['userconfig']); + + $result = PMA_saveUserprefs(array(1)); + + $this->assertTrue( + $result + ); + + $this->assertCount( + 2, + $_SESSION['userconfig'] + ); + + $this->assertEquals( + array(1), + $_SESSION['userconfig']['db'] + ); + + $this->assertEquals( + time(), + $_SESSION['userconfig']['ts'], + 10 + ); + + $assert = true; + + if (isset($_SESSION['cache']['server_2']['userprefs'])) { + $assert = false; + } + + $this->assertTrue( + $assert + ); + + // case 2 + $_SESSION['relation'][$GLOBALS['server']]['userconfigwork'] = 1; + $_SESSION['relation'][$GLOBALS['server']]['db'] = "pmadb"; + $_SESSION['relation'][$GLOBALS['server']]['userconfig'] = "testconf"; + $_SESSION['relation'][$GLOBALS['server']]['user'] = "user"; + $GLOBALS['controllink'] = null; + + $query1 = ' + SELECT `username` + FROM `pmadb`.`testconf` + WHERE `username` = \'user\''; + + $query2 = ' + UPDATE `pmadb`.`testconf` + SET `config_data` = \'' . json_encode(array(1)) . '\' + WHERE `username` = \'user\''; + + $dbi = $this->getMockBuilder('PMA_DatabaseInterface') + ->disableOriginalConstructor() + ->getMock(); + + $dbi->expects($this->once()) + ->method('fetchValue') + ->with($query1, 0, 0, null) + ->will($this->returnValue(true)); + + $dbi->expects($this->once()) + ->method('tryQuery') + ->with($query2, null) + ->will($this->returnValue(true)); + + $GLOBALS['dbi'] = $dbi; + $this->assertTrue( + PMA_saveUserprefs(array(1)) + ); + + // case 3 + + $query1 = ' + SELECT `username` + FROM `pmadb`.`testconf` + WHERE `username` = \'user\''; + + $query2 = ' + INSERT INTO `pmadb`.`testconf` (`username`, `config_data`) + VALUES (\'user\', + \'' . json_encode(array(1)) . '\')'; + + $dbi = $this->getMockBuilder('PMA_DatabaseInterface') + ->disableOriginalConstructor() + ->getMock(); + + $dbi->expects($this->once()) + ->method('fetchValue') + ->with($query1, 0, 0, null) + ->will($this->returnValue(false)); + + $dbi->expects($this->once()) + ->method('tryQuery') + ->with($query2, null) + ->will($this->returnValue(false)); + + $dbi->expects($this->once()) + ->method('getError') + ->with(null) + ->will($this->returnValue("err1")); + + $GLOBALS['dbi'] = $dbi; + + $result = PMA_saveUserprefs(array(1)); + + $this->assertEquals( + 'Could not save configuration

err1', + $result->getMessage() + ); + } + + /** + * Test for PMA_applyUserprefs + * + * @return void + */ + public function testApplyUserprefs() + { + $GLOBALS['cfg']['UserprefsDisallow'] = array( + 'test' => 'val', + 'foo' => 'bar' + ); + $GLOBALS['cfg']['UserprefsDeveloperTab'] = null; + $result = PMA_applyUserprefs( + array( + 'DBG/sql' => true, + 'Error_Handler/display' => true, + 'Error_Handler/gather' => false, + 'Servers/foobar' => '123', + 'Server/hide_db' => true + ) + ); + + $this->assertEquals( + array( + 'Server' => array( + 'hide_db' => 1 + ) + ), + $result + ); + } + + /** + * Test for PMA_readUserprefsFieldNames + * This test would only work when executed with other tests. + * This is to test "static" nature of this function + * + * @return void + */ + public function testReadUserprefsFieldNames() + { + $this->assertEquals( + array('Servers/1/hide_db', 'bar', 'test'), + PMA_readUserprefsFieldNames(array()) + ); + } + + /** + * Test for PMA_persistOption + * + * @return void + */ + public function testPersistOption() + { + $_SESSION['relation'][$GLOBALS['server']]['userconfigwork'] = null; + $_SESSION['userconfig'] = array(); + $_SESSION['userconfig']['ts'] = "123"; + $_SESSION['userconfig']['db'] = array( + 'Server/hide_db' => true, + 'Server/only_db' => true, + ); + + $GLOBALS['server'] = 2; + $_SESSION['relation'][2]['userconfigwork'] = null; + + $this->assertNull( + PMA_persistOption('Server/hide_db', 'val', 'val') + ); + + $this->assertNull( + PMA_persistOption('Server/hide_db', 'val2', 'val') + ); + + $this->assertNull( + PMA_persistOption('Server/hide_db2', 'val', 'val') + ); + } + + /** + * Test for PMA_userprefsRedirect + * + * @return void + */ + public function testUserprefsRedirect() + { + if (!function_exists('runkit_constant_redefine')) { + $this->markTestSkipped('Cannot redefine constant'); + } + + $GLOBALS['cfg']['PmaAbsoluteUri'] = 'http://www.phpmyadmin.net'; + $GLOBALS['cfg']['ServerDefault'] = 1; + $GLOBALS['lang'] = ''; + + $redefine = null; + if (!defined('PMA_IS_IIS')) { + define('PMA_IS_IIS', false); + } else { + $redefine = PMA_IS_IIS; + runkit_constant_redefine('PMA_IS_IIS', false); + } + + PMA_userprefsRedirect( + 'file.html', + array('a' => 'b'), + 'h ash' + ); + + $this->assertContains( + 'Location: http://www.phpmyadmin.netfile.html?a=b&saved=1&server=0&' . + 'token=token#h+ash', + $GLOBALS['header'] + ); + + if ($redefine !== null) { + runkit_constant_redefine('PMA_IS_IIS', $redefine); + } else { + runkit_constant_remove('PMA_IS_IIS'); + } + } + + /** + * Test for PMA_userprefsAutoloadGetHeader + * + * @return void + */ + public function testUserprefsAutoloadGetHeader() + { + $_SESSION['userprefs_autoload'] = false; + $_REQUEST['prefs_autoload'] = 'hide'; + + $this->assertEquals( + '', + PMA_userprefsAutoloadGetHeader() + ); + + $this->assertTrue( + $_SESSION['userprefs_autoload'] + ); + + $_REQUEST['prefs_autoload'] = 'nohide'; + $GLOBALS['cfg']['ServerDefault'] = 1; + $GLOBALS['PMA_PHP_SELF'] = 'phpunit'; + $result = PMA_userprefsAutoloadGetHeader(); + + $this->assertTag( + $this->_getTagArray( + '
' + ), + $result + ); + + $this->assertTag( + $this->_getTagArray( + 'assertTag( + $this->_getTagArray( + '' + ), + $result + ); + + $this->assertTag( + $this->_getTagArray( + '' + ), + $result + ); + + $this->assertTag( + $this->_getTagArray( + '' + ), + $result + ); + } + + /** + * Return the tag array to be used with assertTag by parsing + * a given HTML element + * + * @param string $elementHTML HTML for element to be parsed + * @param array $arr Additional array elements like content, parent + * + * @return array Tag array to be used with assertTag + */ + private function _getTagArray($elementHTML, $arr = array()) + { + + // get attributes + preg_match_all("/\s+(.*?)\=\s*\"(.*?)\"/is", $elementHTML, $matches); + foreach ($matches[1] as $key => $val) { + $arr['attributes'][trim($val)] = trim($matches[2][$key]); + } + $matches = array(); + + // get tag + preg_match("/^\<(.*?)(\s|\>)/i", $elementHTML, $matches); + if (isset($matches[1])) { + $arr['tag'] = trim($matches[1]); + } + + return $arr; + } + +} +?> From 2e599927d79c64fa516d9f82f3b3d40ebaf698f9 Mon Sep 17 00:00:00 2001 From: ayushchd Date: Thu, 11 Jul 2013 14:29:20 +0545 Subject: [PATCH 03/44] Convert validate.lib.php to class PMA_Validator --- libraries/config.values.php | 2 +- libraries/config/FormDisplay.class.php | 8 +- libraries/config/Validator.class.php | 587 +++++++++++++++++++++++++ libraries/config/validate.lib.php | 584 ------------------------ setup/validate.php | 4 +- 5 files changed, 594 insertions(+), 591 deletions(-) create mode 100644 libraries/config/Validator.class.php delete mode 100644 libraries/config/validate.lib.php diff --git a/libraries/config.values.php b/libraries/config.values.php index 4a496296c8..da9cce8dfb 100644 --- a/libraries/config.values.php +++ b/libraries/config.values.php @@ -193,7 +193,7 @@ $cfg_db['_overrides']['Servers/1/extension'] = extension_loaded('mysqli') ? 'mysqli' : 'mysql'; /** - * Basic validator assignments (functions from libraries/config/validate.lib.php + * Basic validator assignments (functions from libraries/config/Validator.class.php * and 'validators' object in js/config.js) * Use only full paths and form ids */ diff --git a/libraries/config/FormDisplay.class.php b/libraries/config/FormDisplay.class.php index 7cc7fdac98..3b155ff4e8 100644 --- a/libraries/config/FormDisplay.class.php +++ b/libraries/config/FormDisplay.class.php @@ -17,7 +17,7 @@ * Core libraries. */ require_once './libraries/config/FormDisplay.tpl.php'; -require_once './libraries/config/validate.lib.php'; +require_once './libraries/config/Validator.class.php'; require_once './libraries/js_escape.lib.php'; /** @@ -91,7 +91,7 @@ class FormDisplay 'error_invalid_value' => __('Incorrect value'), 'error_value_lte' => __('Value must be equal or lower than %s')); // initialize validators - PMA_config_get_validators(); + PMA_Validator::config_get_validators(); } /** @@ -164,7 +164,7 @@ class FormDisplay } // run validation - $errors = PMA_config_validate($paths, $values, false); + $errors = PMA_Validator::config_validate($paths, $values, false); // change error keys from canonical paths to work paths if (is_array($errors) && count($errors) > 0) { @@ -198,7 +198,7 @@ class FormDisplay $js = array(); $js_default = array(); $tabbed_form = $tabbed_form && (count($this->_forms) > 1); - $validators = PMA_config_get_validators(); + $validators = PMA_Validator::config_get_validators(); PMA_displayFormTop(); diff --git a/libraries/config/Validator.class.php b/libraries/config/Validator.class.php new file mode 100644 index 0000000000..2cfed3da7c --- /dev/null +++ b/libraries/config/Validator.class.php @@ -0,0 +1,587 @@ +getDbEntry('_validators', array()); + if (!defined('PMA_SETUP')) { + // not in setup script: load additional validators for user + // preferences we need original config values not overwritten + // by user preferences, creating a new PMA_Config instance is a + // better idea than hacking into its code + $org_cfg = $cf->getOrgConfigObj(); + $uvs = $cf->getDbEntry('_userValidators', array()); + foreach ($uvs as $field => $uv_list) { + $uv_list = (array)$uv_list; + foreach ($uv_list as &$uv) { + if (!is_array($uv)) { + continue; + } + for ($i = 1; $i < count($uv); $i++) { + if (substr($uv[$i], 0, 6) == 'value:') { + $uv[$i] = PMA_arrayRead( + substr($uv[$i], 6), $org_cfg->settings + ); + } + } + } + $validators[$field] = isset($validators[$field]) + ? array_merge((array)$validators[$field], $uv_list) + : $uv_list; + } + } + } + return $validators; + } + + /** + * Runs validation $validator_id on values $values and returns error list. + * + * Return values: + * o array, keys - field path or formset id, values - array of errors + * when $isPostSource is true values is an empty array to allow for error list + * cleanup in HTML documen + * o false - when no validators match name(s) given by $validator_id + * + * @param string|array $validator_id ID of validator(s) to run + * @param array &$values Values to validate + * @param bool $isPostSource tells whether $values are directly from + * POST request + * + * @return bool|array + */ + public static function config_validate($validator_id, &$values, $isPostSource) + { + // find validators + $validator_id = (array) $validator_id; + $validators = static::config_get_validators(); + $vids = array(); + $cf = ConfigFile::getInstance(); + foreach ($validator_id as &$vid) { + $vid = $cf->getCanonicalPath($vid); + if (isset($validators[$vid])) { + $vids[] = $vid; + } + } + if (empty($vids)) { + return false; + } + + // create argument list with canonical paths and remember path mapping + $arguments = array(); + $key_map = array(); + foreach ($values as $k => $v) { + $k2 = $isPostSource ? str_replace('-', '/', $k) : $k; + $k2 = strpos($k2, '/') ? $cf->getCanonicalPath($k2) : $k2; + $key_map[$k2] = $k; + $arguments[$k2] = $v; + } + + // validate + $result = array(); + foreach ($vids as $vid) { + // call appropriate validation functions + foreach ((array)$validators[$vid] as $validator) { + $vdef = (array) $validator; + $vname = array_shift($vdef); + $args = array_merge(array($vid, &$arguments), $vdef); + $r = call_user_func_array($vname, $args); + + // merge results + if (is_array($r)) { + foreach ($r as $key => $error_list) { + // skip empty values if $isPostSource is false + if (! $isPostSource && empty($error_list)) { + continue; + } + if (! isset($result[$key])) { + $result[$key] = array(); + } + $result[$key] = array_merge($result[$key], (array)$error_list); + } + } + } + } + + // restore original paths + $new_result = array(); + foreach ($result as $k => $v) { + $k2 = isset($key_map[$k]) ? $key_map[$k] : $k; + $new_result[$k2] = $v; + } + return empty($new_result) ? true : $new_result; + } + + /** + * Empty error handler, used to temporarily restore PHP internal error handler + * + * @return bool + */ + public static function null_error_handler() + { + return false; + } + + /** + * Ensures that $php_errormsg variable will be registered in case of an error + * and enables output buffering (when $start = true). + * Called with $start = false disables output buffering end restores + * html_errors and track_errors. + * + * @param boolean $start Whether to start buffering + * + * @return void + */ + public static function testPHPErrorMsg($start = true) + { + static $old_html_errors, $old_track_errors, $old_error_reporting; + static $old_display_errors; + if ($start) { + $old_html_errors = ini_get('html_errors'); + $old_track_errors = ini_get('track_errors'); + $old_display_errors = ini_get('display_errors'); + $old_error_reporting = error_reporting(E_ALL); + ini_set('html_errors', false); + ini_set('track_errors', true); + ini_set('display_errors', true); + set_error_handler("PMA_Validator", "null_error_handler"); + ob_start(); + } else { + ob_end_clean(); + restore_error_handler(); + error_reporting($old_error_reporting); + ini_set('html_errors', $old_html_errors); + ini_set('track_errors', $old_track_errors); + ini_set('display_errors', $old_display_errors); + } + } + + /** + * Test database connection + * + * @param string $extension 'drizzle', 'mysql' or 'mysqli' + * @param string $connect_type 'tcp' or 'socket' + * @param string $host host name + * @param string $port tcp port to use + * @param string $socket socket to use + * @param string $user username to use + * @param string $pass password to use + * @param string $error_key key to use in return array + * + * @return bool|array + */ + public static function testDBConnection( + $extension, + $connect_type, + $host, + $port, + $socket, + $user, + $pass = null, + $error_key = 'Server' + ) { + // static::testPHPErrorMsg(); + $socket = empty($socket) || $connect_type == 'tcp' ? null : $socket; + $port = empty($port) || $connect_type == 'socket' ? null : ':' . $port; + $error = null; + if ($extension == 'drizzle') { + while (1) { + $drizzle = @drizzle_create(); + if (! $drizzle) { + $error = __('Could not initialize Drizzle connection library'); + break; + } + $conn = $socket + ? @drizzle_con_add_uds($socket, $user, $pass, null, 0) + : @drizzle_con_add_tcp( + $drizzle, $host, $port, $user, $pass, null, 0 + ); + if (! $conn) { + $error = __('Could not connect to Drizzle server'); + drizzle_free($drizzle); + break; + } + // connection object is set up but we have to send some query + // to actually connect + $res = @drizzle_query($conn, 'SELECT 1'); + if (! $res) { + $error = __('Could not connect to Drizzle server'); + } else { + drizzle_result_free($res); + } + drizzle_con_free($conn); + drizzle_free($drizzle); + break; + } + } else if ($extension == 'mysql') { + $conn = @mysql_connect($host . $socket . $port, $user, $pass); + if (! $conn) { + $error = __('Could not connect to MySQL server'); + } else { + mysql_close($conn); + } + } else { + $conn = @mysqli_connect($host, $user, $pass, null, $port, $socket); + if (! $conn) { + $error = __('Could not connect to MySQL server'); + } else { + mysqli_close($conn); + } + } + // static::testPHPErrorMsg(false); + if (isset($php_errormsg)) { + $error .= " - $php_errormsg"; + } + return is_null($error) ? true : array($error_key => $error); + } + + /** + * Validate server config + * + * @param string $path path to config, not used + * @param array $values config values + * + * @return array + */ + public static function validateServer($path, $values) + { + $result = array( + 'Server' => '', + 'Servers/1/user' => '', + 'Servers/1/SignonSession' => '', + 'Servers/1/SignonURL' => '' + ); + $error = false; + if ($values['Servers/1/auth_type'] == 'config' + && empty($values['Servers/1/user']) + ) { + $result['Servers/1/user'] + = __('Empty username while using config authentication method'); + $error = true; + } + if ($values['Servers/1/auth_type'] == 'signon' + && empty($values['Servers/1/SignonSession']) + ) { + $result['Servers/1/SignonSession'] = __( + 'Empty signon session name ' + . 'while using signon authentication method' + ); + $error = true; + } + if ($values['Servers/1/auth_type'] == 'signon' + && empty($values['Servers/1/SignonURL']) + ) { + $result['Servers/1/SignonURL'] + = __('Empty signon URL while using signon authentication method'); + $error = true; + } + + if (! $error && $values['Servers/1/auth_type'] == 'config') { + $password = $values['Servers/1/nopassword'] ? null + : $values['Servers/1/password']; + $test = static::testDBConnection( + $values['Servers/1/extension'], + $values['Servers/1/connect_type'], + $values['Servers/1/host'], + $values['Servers/1/port'], + $values['Servers/1/socket'], + $values['Servers/1/user'], + $password, + 'Server' + ); + if ($test !== true) { + $result = array_merge($result, $test); + } + } + return $result; + } + + /** + * Validate pmadb config + * + * @param string $path path to config, not used + * @param array $values config values + * + * @return array + */ + public static function validatePMAStorage($path, $values) + { + $result = array( + 'Server_pmadb' => '', + 'Servers/1/controluser' => '', + 'Servers/1/controlpass' => '' + ); + $error = false; + + if ($values['Servers/1/pmadb'] == '') { + return $result; + } + + $result = array(); + if ($values['Servers/1/controluser'] == '') { + $result['Servers/1/controluser'] + = __('Empty phpMyAdmin control user while using pmadb'); + $error = true; + } + if ($values['Servers/1/controlpass'] == '') { + $result['Servers/1/controlpass'] + = __('Empty phpMyAdmin control user password while using pmadb'); + $error = true; + } + if (! $error) { + $test = static::testDBConnection( + $values['Servers/1/extension'], $values['Servers/1/connect_type'], + $values['Servers/1/host'], $values['Servers/1/port'], + $values['Servers/1/socket'], $values['Servers/1/controluser'], + $values['Servers/1/controlpass'], 'Server_pmadb' + ); + if ($test !== true) { + $result = array_merge($result, $test); + } + } + return $result; + } + + + /** + * Validates regular expression + * + * @param string $path path to config + * @param array $values config values + * + * @return array + */ + public static function validateRegex($path, $values) + { + $result = array($path => ''); + + if ($values[$path] == '') { + return $result; + } + + static::testPHPErrorMsg(); + + $matches = array(); + // in libraries/List_Database.class.php _checkHideDatabase(), + // a '/' is used as the delimiter for hide_db + preg_match('/' . $values[$path] . '/', '', $matches); + + static::testPHPErrorMsg(false); + + if (isset($php_errormsg)) { + $error = preg_replace('/^preg_match\(\): /', '', $php_errormsg); + return array($path => $error); + } + + return $result; + } + + /** + * Validates TrustedProxies field + * + * @param string $path path to config + * @param array $values config values + * + * @return array + */ + public static function validateTrustedProxies($path, $values) + { + $result = array($path => array()); + + if (empty($values[$path])) { + return $result; + } + + if (is_array($values[$path])) { + // value already processed by FormDisplay::save + $lines = array(); + foreach ($values[$path] as $ip => $v) { + $lines[] = preg_match('/^-\d+$/', $ip) + ? $v + : $ip . ': ' . $v; + } + } else { + // AJAX validation + $lines = explode("\n", $values[$path]); + } + foreach ($lines as $line) { + $line = trim($line); + $matches = array(); + // we catch anything that may (or may not) be an IP + if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) { + $result[$path][] = __('Incorrect value:') . ' ' . $line; + continue; + } + // now let's check whether we really have an IP address + if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false + && filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false + ) { + $ip = htmlspecialchars(trim($matches[1])); + $result[$path][] = sprintf(__('Incorrect IP address: %s'), $ip); + continue; + } + } + + return $result; + } + + /** + * Tests integer value + * + * @param string $path path to config + * @param array $values config values + * @param bool $allow_neg allow negative values + * @param bool $allow_zero allow zero + * @param int $max_value max allowed value + * @param string $error_string error message key: + * $GLOBALS["strConfig$error_lang_key"] + * + * @return string empty string if test is successful + */ + public static function validateNumber( + $path, + $values, + $allow_neg, + $allow_zero, + $max_value, + $error_string + ) { + if ($values[$path] === '') { + return ''; + } + + if (intval($values[$path]) != $values[$path] + || (! $allow_neg && $values[$path] < 0) + || (! $allow_zero && $values[$path] == 0) + || $values[$path] > $max_value + ) { + return $error_string; + } + + return ''; + } + + /** + * Validates port number + * + * @param string $path path to config + * @param array $values config values + * + * @return array + */ + public static function validatePortNumber($path, $values) + { + return array( + $path => static::validateNumber( + $path, + $values, + false, + false, + 65535, + __('Not a valid port number') + ) + ); + } + + /** + * Validates positive number + * + * @param string $path path to config + * @param array $values config values + * + * @return array + */ + public static function validatePositiveNumber($path, $values) + { + return array( + $path => static::validateNumber( + $path, + $values, + false, + false, + PHP_INT_MAX, + __('Not a positive number') + ) + ); + } + + /** + * Validates non-negative number + * + * @param string $path path to config + * @param array $values config values + * + * @return array + */ + public static function validateNonNegativeNumber($path, $values) + { + return array( + $path => static::validateNumber( + $path, + $values, + false, + true, + PHP_INT_MAX, + __('Not a non-negative number') + ) + ); + } + + /** + * Validates value according to given regular expression + * Pattern and modifiers must be a valid for PCRE and JavaScript RegExp + * + * @param string $path path to config + * @param array $values config values + * @param string $regex regullar expression to match + * + * @return array + */ + public static function validateByRegex($path, $values, $regex) + { + $result = preg_match($regex, $values[$path]); + return array($path => ($result ? '' : __('Incorrect value'))); + } + + /** + * Validates upper bound for numeric inputs + * + * @param string $path path to config + * @param array $values config values + * @param int $max_value maximal allowed value + * + * @return array + */ + public static function validateUpperBound($path, $values, $max_value) + { + $result = $values[$path] <= $max_value; + return array($path => ($result ? '' + : sprintf(__('Value must be equal or lower than %s'), $max_value))); + } +} +?> diff --git a/libraries/config/validate.lib.php b/libraries/config/validate.lib.php deleted file mode 100644 index 08092e621e..0000000000 --- a/libraries/config/validate.lib.php +++ /dev/null @@ -1,584 +0,0 @@ -getDbEntry('_validators', array()); - if (!defined('PMA_SETUP')) { - // not in setup script: load additional validators for user - // preferences we need original config values not overwritten - // by user preferences, creating a new PMA_Config instance is a - // better idea than hacking into its code - $org_cfg = $cf->getOrgConfigObj(); - $uvs = $cf->getDbEntry('_userValidators', array()); - foreach ($uvs as $field => $uv_list) { - $uv_list = (array)$uv_list; - foreach ($uv_list as &$uv) { - if (!is_array($uv)) { - continue; - } - for ($i = 1; $i < count($uv); $i++) { - if (substr($uv[$i], 0, 6) == 'value:') { - $uv[$i] = PMA_arrayRead( - substr($uv[$i], 6), $org_cfg->settings - ); - } - } - } - $validators[$field] = isset($validators[$field]) - ? array_merge((array)$validators[$field], $uv_list) - : $uv_list; - } - } - } - return $validators; -} - -/** - * Runs validation $validator_id on values $values and returns error list. - * - * Return values: - * o array, keys - field path or formset id, values - array of errors - * when $isPostSource is true values is an empty array to allow for error list - * cleanup in HTML documen - * o false - when no validators match name(s) given by $validator_id - * - * @param string|array $validator_id ID of validator(s) to run - * @param array &$values Values to validate - * @param bool $isPostSource tells whether $values are directly from - * POST request - * - * @return bool|array - */ -function PMA_config_validate($validator_id, &$values, $isPostSource) -{ - // find validators - $validator_id = (array) $validator_id; - $validators = PMA_config_get_validators(); - $vids = array(); - $cf = ConfigFile::getInstance(); - foreach ($validator_id as &$vid) { - $vid = $cf->getCanonicalPath($vid); - if (isset($validators[$vid])) { - $vids[] = $vid; - } - } - if (empty($vids)) { - return false; - } - - // create argument list with canonical paths and remember path mapping - $arguments = array(); - $key_map = array(); - foreach ($values as $k => $v) { - $k2 = $isPostSource ? str_replace('-', '/', $k) : $k; - $k2 = strpos($k2, '/') ? $cf->getCanonicalPath($k2) : $k2; - $key_map[$k2] = $k; - $arguments[$k2] = $v; - } - - // validate - $result = array(); - foreach ($vids as $vid) { - // call appropriate validation functions - foreach ((array)$validators[$vid] as $validator) { - $vdef = (array) $validator; - $vname = array_shift($vdef); - $args = array_merge(array($vid, &$arguments), $vdef); - $r = call_user_func_array($vname, $args); - - // merge results - if (is_array($r)) { - foreach ($r as $key => $error_list) { - // skip empty values if $isPostSource is false - if (! $isPostSource && empty($error_list)) { - continue; - } - if (! isset($result[$key])) { - $result[$key] = array(); - } - $result[$key] = array_merge($result[$key], (array)$error_list); - } - } - } - } - - // restore original paths - $new_result = array(); - foreach ($result as $k => $v) { - $k2 = isset($key_map[$k]) ? $key_map[$k] : $k; - $new_result[$k2] = $v; - } - return empty($new_result) ? true : $new_result; -} - -/** - * Empty error handler, used to temporarily restore PHP internal error handler - * - * @return bool - */ -function PMA_null_error_handler() -{ - return false; -} - -/** - * Ensures that $php_errormsg variable will be registered in case of an error - * and enables output buffering (when $start = true). - * Called with $start = false disables output buffering end restores - * html_errors and track_errors. - * - * @param boolean $start Whether to start buffering - * - * @return void - */ -function PMA_testPHPErrorMsg($start = true) -{ - static $old_html_errors, $old_track_errors, $old_error_reporting; - static $old_display_errors; - if ($start) { - $old_html_errors = ini_get('html_errors'); - $old_track_errors = ini_get('track_errors'); - $old_display_errors = ini_get('display_errors'); - $old_error_reporting = error_reporting(E_ALL); - ini_set('html_errors', false); - ini_set('track_errors', true); - ini_set('display_errors', true); - set_error_handler("PMA_null_error_handler"); - ob_start(); - } else { - ob_end_clean(); - restore_error_handler(); - error_reporting($old_error_reporting); - ini_set('html_errors', $old_html_errors); - ini_set('track_errors', $old_track_errors); - ini_set('display_errors', $old_display_errors); - } -} - -/** - * Test database connection - * - * @param string $extension 'drizzle', 'mysql' or 'mysqli' - * @param string $connect_type 'tcp' or 'socket' - * @param string $host host name - * @param string $port tcp port to use - * @param string $socket socket to use - * @param string $user username to use - * @param string $pass password to use - * @param string $error_key key to use in return array - * - * @return bool|array - */ -function PMA_testDBConnection( - $extension, - $connect_type, - $host, - $port, - $socket, - $user, - $pass = null, - $error_key = 'Server' -) { - // PMA_testPHPErrorMsg(); - $socket = empty($socket) || $connect_type == 'tcp' ? null : $socket; - $port = empty($port) || $connect_type == 'socket' ? null : ':' . $port; - $error = null; - if ($extension == 'drizzle') { - while (1) { - $drizzle = @drizzle_create(); - if (! $drizzle) { - $error = __('Could not initialize Drizzle connection library'); - break; - } - $conn = $socket - ? @drizzle_con_add_uds($socket, $user, $pass, null, 0) - : @drizzle_con_add_tcp( - $drizzle, $host, $port, $user, $pass, null, 0 - ); - if (! $conn) { - $error = __('Could not connect to Drizzle server'); - drizzle_free($drizzle); - break; - } - // connection object is set up but we have to send some query - // to actually connect - $res = @drizzle_query($conn, 'SELECT 1'); - if (! $res) { - $error = __('Could not connect to Drizzle server'); - } else { - drizzle_result_free($res); - } - drizzle_con_free($conn); - drizzle_free($drizzle); - break; - } - } else if ($extension == 'mysql') { - $conn = @mysql_connect($host . $socket . $port, $user, $pass); - if (! $conn) { - $error = __('Could not connect to MySQL server'); - } else { - mysql_close($conn); - } - } else { - $conn = @mysqli_connect($host, $user, $pass, null, $port, $socket); - if (! $conn) { - $error = __('Could not connect to MySQL server'); - } else { - mysqli_close($conn); - } - } - // PMA_testPHPErrorMsg(false); - if (isset($php_errormsg)) { - $error .= " - $php_errormsg"; - } - return is_null($error) ? true : array($error_key => $error); -} - -/** - * Validate server config - * - * @param string $path path to config, not used - * @param array $values config values - * - * @return array - */ -function PMA_validateServer($path, $values) -{ - $result = array( - 'Server' => '', - 'Servers/1/user' => '', - 'Servers/1/SignonSession' => '', - 'Servers/1/SignonURL' => '' - ); - $error = false; - if ($values['Servers/1/auth_type'] == 'config' - && empty($values['Servers/1/user']) - ) { - $result['Servers/1/user'] - = __('Empty username while using config authentication method'); - $error = true; - } - if ($values['Servers/1/auth_type'] == 'signon' - && empty($values['Servers/1/SignonSession']) - ) { - $result['Servers/1/SignonSession'] = __( - 'Empty signon session name ' - . 'while using signon authentication method' - ); - $error = true; - } - if ($values['Servers/1/auth_type'] == 'signon' - && empty($values['Servers/1/SignonURL']) - ) { - $result['Servers/1/SignonURL'] - = __('Empty signon URL while using signon authentication method'); - $error = true; - } - - if (! $error && $values['Servers/1/auth_type'] == 'config') { - $password = $values['Servers/1/nopassword'] ? null - : $values['Servers/1/password']; - $test = PMA_testDBConnection( - $values['Servers/1/extension'], - $values['Servers/1/connect_type'], - $values['Servers/1/host'], - $values['Servers/1/port'], - $values['Servers/1/socket'], - $values['Servers/1/user'], - $password, - 'Server' - ); - if ($test !== true) { - $result = array_merge($result, $test); - } - } - return $result; -} - -/** - * Validate pmadb config - * - * @param string $path path to config, not used - * @param array $values config values - * - * @return array - */ -function PMA_validatePMAStorage($path, $values) -{ - $result = array( - 'Server_pmadb' => '', - 'Servers/1/controluser' => '', - 'Servers/1/controlpass' => '' - ); - $error = false; - - if ($values['Servers/1/pmadb'] == '') { - return $result; - } - - $result = array(); - if ($values['Servers/1/controluser'] == '') { - $result['Servers/1/controluser'] - = __('Empty phpMyAdmin control user while using pmadb'); - $error = true; - } - if ($values['Servers/1/controlpass'] == '') { - $result['Servers/1/controlpass'] - = __('Empty phpMyAdmin control user password while using pmadb'); - $error = true; - } - if (! $error) { - $test = PMA_testDBConnection( - $values['Servers/1/extension'], $values['Servers/1/connect_type'], - $values['Servers/1/host'], $values['Servers/1/port'], - $values['Servers/1/socket'], $values['Servers/1/controluser'], - $values['Servers/1/controlpass'], 'Server_pmadb' - ); - if ($test !== true) { - $result = array_merge($result, $test); - } - } - return $result; -} - - -/** - * Validates regular expression - * - * @param string $path path to config - * @param array $values config values - * - * @return array - */ -function PMA_validateRegex($path, $values) -{ - $result = array($path => ''); - - if ($values[$path] == '') { - return $result; - } - - PMA_testPHPErrorMsg(); - - $matches = array(); - // in libraries/List_Database.class.php _checkHideDatabase(), - // a '/' is used as the delimiter for hide_db - preg_match('/' . $values[$path] . '/', '', $matches); - - PMA_testPHPErrorMsg(false); - - if (isset($php_errormsg)) { - $error = preg_replace('/^preg_match\(\): /', '', $php_errormsg); - return array($path => $error); - } - - return $result; -} - -/** - * Validates TrustedProxies field - * - * @param string $path path to config - * @param array $values config values - * - * @return array - */ -function PMA_validateTrustedProxies($path, $values) -{ - $result = array($path => array()); - - if (empty($values[$path])) { - return $result; - } - - if (is_array($values[$path])) { - // value already processed by FormDisplay::save - $lines = array(); - foreach ($values[$path] as $ip => $v) { - $lines[] = preg_match('/^-\d+$/', $ip) - ? $v - : $ip . ': ' . $v; - } - } else { - // AJAX validation - $lines = explode("\n", $values[$path]); - } - foreach ($lines as $line) { - $line = trim($line); - $matches = array(); - // we catch anything that may (or may not) be an IP - if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) { - $result[$path][] = __('Incorrect value:') . ' ' . $line; - continue; - } - // now let's check whether we really have an IP address - if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false - && filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false - ) { - $ip = htmlspecialchars(trim($matches[1])); - $result[$path][] = sprintf(__('Incorrect IP address: %s'), $ip); - continue; - } - } - - return $result; -} - -/** - * Tests integer value - * - * @param string $path path to config - * @param array $values config values - * @param bool $allow_neg allow negative values - * @param bool $allow_zero allow zero - * @param int $max_value max allowed value - * @param string $error_string error message key: - * $GLOBALS["strConfig$error_lang_key"] - * - * @return string empty string if test is successful - */ -function PMA_validateNumber( - $path, - $values, - $allow_neg, - $allow_zero, - $max_value, - $error_string -) { - if ($values[$path] === '') { - return ''; - } - - if (intval($values[$path]) != $values[$path] - || (! $allow_neg && $values[$path] < 0) - || (! $allow_zero && $values[$path] == 0) - || $values[$path] > $max_value - ) { - return $error_string; - } - - return ''; -} - -/** - * Validates port number - * - * @param string $path path to config - * @param array $values config values - * - * @return array - */ -function PMA_validatePortNumber($path, $values) -{ - return array( - $path => PMA_validateNumber( - $path, - $values, - false, - false, - 65535, - __('Not a valid port number') - ) - ); -} - -/** - * Validates positive number - * - * @param string $path path to config - * @param array $values config values - * - * @return array - */ -function PMA_validatePositiveNumber($path, $values) -{ - return array( - $path => PMA_validateNumber( - $path, - $values, - false, - false, - PHP_INT_MAX, - __('Not a positive number') - ) - ); -} - -/** - * Validates non-negative number - * - * @param string $path path to config - * @param array $values config values - * - * @return array - */ -function PMA_validateNonNegativeNumber($path, $values) -{ - return array( - $path => PMA_validateNumber( - $path, - $values, - false, - true, - PHP_INT_MAX, - __('Not a non-negative number') - ) - ); -} - -/** - * Validates value according to given regular expression - * Pattern and modifiers must be a valid for PCRE and JavaScript RegExp - * - * @param string $path path to config - * @param array $values config values - * @param string $regex regullar expression to match - * - * @return array - */ -function PMA_validateByRegex($path, $values, $regex) -{ - $result = preg_match($regex, $values[$path]); - return array($path => ($result ? '' : __('Incorrect value'))); -} - -/** - * Validates upper bound for numeric inputs - * - * @param string $path path to config - * @param array $values config values - * @param int $max_value maximal allowed value - * - * @return array - */ -function PMA_validateUpperBound($path, $values, $max_value) -{ - $result = $values[$path] <= $max_value; - return array($path => ($result ? '' - : sprintf(__('Value must be equal or lower than %s'), $max_value))); -} -?> diff --git a/setup/validate.php b/setup/validate.php index 2cb8c93ca8..393af94deb 100644 --- a/setup/validate.php +++ b/setup/validate.php @@ -12,7 +12,7 @@ require './lib/common.inc.php'; $validators = array(); -require './libraries/config/validate.lib.php'; +require './libraries/config/Validator.class.php'; header('Content-type: application/json'); @@ -22,7 +22,7 @@ if (!($values instanceof stdClass)) { PMA_fatalError(__('Wrong data')); } $values = (array)$values; -$result = PMA_config_validate($vids, $values, true); +$result = PMA_Validator::config_validate($vids, $values, true); if ($result === false) { $result = 'Wrong data or no validation for ' . $vids; } From ce71f173a0bae8244534e17ad7f8bbb30f3ca2c6 Mon Sep 17 00:00:00 2001 From: ayushchd Date: Thu, 11 Jul 2013 14:30:10 +0545 Subject: [PATCH 04/44] Fix test cases for PMA_ConfigFile --- test/libraries/PMA_ConfigFile_test.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/libraries/PMA_ConfigFile_test.php b/test/libraries/PMA_ConfigFile_test.php index 4e0fa6a563..3faef432c5 100644 --- a/test/libraries/PMA_ConfigFile_test.php +++ b/test/libraries/PMA_ConfigFile_test.php @@ -748,7 +748,7 @@ class PMA_ConfigFile_Test extends PHPUnit_Framework_TestCase { $this->assertEquals( null, - $this->object->getServerName('foobar123') + $this->object->removeServer(1) ); $objectID = $this->readAttribute($this->object, "_id"); @@ -902,7 +902,8 @@ class PMA_ConfigFile_Test extends PHPUnit_Framework_TestCase $attrReadMapping->setValue( $this->object, array( - "2" => "two" + "2" => "two", + "3" => "foobar" ) ); From 32157f342553cf64a8fd2f84df3cccc8388893e1 Mon Sep 17 00:00:00 2001 From: ayushchd Date: Thu, 11 Jul 2013 14:30:57 +0545 Subject: [PATCH 05/44] Add tests for PMA_Form and PMA_FormDisplay --- test/classes/config/PMA_FormDisplay_test.php | 593 ++++++++++++++ test/classes/config/PMA_Form_test.php | 255 +++++- test/libraries/PMA_FormDisplay_tpl_test.php | 821 +++++++++++++++++++ 3 files changed, 1664 insertions(+), 5 deletions(-) create mode 100644 test/classes/config/PMA_FormDisplay_test.php create mode 100644 test/libraries/PMA_FormDisplay_tpl_test.php diff --git a/test/classes/config/PMA_FormDisplay_test.php b/test/classes/config/PMA_FormDisplay_test.php new file mode 100644 index 0000000000..1e682b22de --- /dev/null +++ b/test/classes/config/PMA_FormDisplay_test.php @@ -0,0 +1,593 @@ +getPath(); + $GLOBALS['pmaThemeImage'] = 'theme/'; + $GLOBALS['PMA_Config'] = new PMA_Config(); + $GLOBALS['PMA_Config']->enableBc(); + $GLOBALS['server'] = 0; + $this->object = new FormDisplay(); + } + + /** + * tearDown for test cases + * + * @return void + */ + protected function tearDown() + { + unset($this->object); + } + + /** + * Test for FormDisplay::__constructor + * + * @return void + */ + public function testFormDisplayContructor() + { + $this->assertCount( + 5, + $this->readAttribute($this->object, '_jsLangStrings') + ); + } + + /** + * Test for FormDisplay::registerForm + * + * @return void + */ + public function testRegisterForm() + { + $reflection = new \ReflectionClass('FormDisplay'); + + $attrForms = $reflection->getProperty('_forms'); + $attrForms->setAccessible(true); + + $array = array( + "Servers" => array( + "1" => array( + 'test' => 1, + 1 => ':group:end' + ) + ) + ); + + $this->object->registerForm('pma_testform', $array, 2); + $_forms = $attrForms->getValue($this->object); + $this->assertInstanceOf( + 'Form', + $_forms['pma_testform'] + ); + + $this->assertEquals( + array( + "Servers/2/test" => "Servers/1/test", + "Servers/2/:group:end:0" => "Servers/1/:group:end:0" + ), + $this->readAttribute($this->object, '_systemPaths') + ); + + $this->assertEquals( + array( + "Servers/2/test" => "Servers-2-test", + "Servers/2/:group:end:0" => "Servers-2-:group:end:0" + ), + $this->readAttribute($this->object, '_translatedPaths') + ); + } + + /** + * Test for FormDisplay::process + * + * @return void + */ + public function testProcess() + { + $this->assertFalse( + $this->object->process(true, true) + ); + + $this->object = $this->getMockBuilder('FormDisplay') + ->disableOriginalConstructor() + ->setMethods(array('save')) + ->getMock(); + + $attrForms = new \ReflectionProperty('FormDisplay', '_forms'); + $attrForms->setAccessible(true); + $attrForms->setValue($this->object, array(1, 2, 3)); + + $this->object->expects($this->once()) + ->method('save') + ->with(array(0, 1, 2), false) + ->will($this->returnValue(true)); + + $this->assertTrue( + $this->object->process(false, false) + ); + + $attrForms->setValue($this->object, array()); + + $this->assertFalse( + $this->object->process(false, false) + ); + } + + /** + * Test for FormDisplay::displayErrors + * + * @return void + */ + public function testDisplayErrors() + { + $reflection = new \ReflectionClass('FormDisplay'); + + $attrIsValidated = $reflection->getProperty('_isValidated'); + $attrIsValidated->setAccessible(true); + $attrIsValidated->setValue($this->object, true); + + $attrIsValidated = $reflection->getProperty('_errors'); + $attrIsValidated->setAccessible(true); + $attrIsValidated->setValue($this->object, array()); + + $this->assertNull( + $this->object->displayErrors() + ); + + $arr = array( + "Servers/1/test" => array('e1'), + "foobar" => array('e2', 'e3') + ); + + $sysArr = array( + "Servers/1/test" => "Servers/1/test2" + ); + + $attrSystemPaths = $reflection->getProperty('_systemPaths'); + $attrSystemPaths->setAccessible(true); + $attrSystemPaths->setValue($this->object, $sysArr); + + $attrIsValidated->setValue($this->object, $arr); + + $GLOBALS['strConfigForm_foobar'] = 'foobar123'; + + $this->expectOutputString( + '
Servers_test2_name
' . + '
e1
foobar123
' . + 'e2
e3
' + ); + + $this->object->displayErrors(); + } + + /** + * Test for FormDisplay::fixErrors + * + * @return void + */ + public function testFixErrors() + { + $reflection = new \ReflectionClass('FormDisplay'); + + $attrIsValidated = $reflection->getProperty('_isValidated'); + $attrIsValidated->setAccessible(true); + $attrIsValidated->setValue($this->object, true); + + $attrIsValidated = $reflection->getProperty('_errors'); + $attrIsValidated->setAccessible(true); + $attrIsValidated->setValue($this->object, array()); + + $this->assertNull( + $this->object->fixErrors() + ); + + $arr = array( + "Servers/1/test" => array('e1'), + "Servers/2/test" => array('e2', 'e3'), + "Servers/3/test" => array() + ); + + $sysArr = array( + "Servers/1/test" => "Servers/1/connect_type" + ); + + $attrSystemPaths = $reflection->getProperty('_systemPaths'); + $attrSystemPaths->setAccessible(true); + $attrSystemPaths->setValue($this->object, $sysArr); + + $attrIsValidated->setValue($this->object, $arr); + + $this->object->fixErrors(); + + $this->assertEquals( + array( + 'Servers' => array( + '1' => array( + 'test' => 'tcp' + ) + ) + ), + $_SESSION['ConfigFile0'] + ); + } + + /** + * Test for FormDisplay::_validateSelect + * + * @return void + */ + public function testValidateSelect() + { + $attrValidateSelect = new \ReflectionMethod( + 'FormDisplay', + '_validateSelect' + ); + $attrValidateSelect->setAccessible(true); + + $arr = array('foo' => 'var'); + $value = 'foo'; + $this->assertTrue( + $attrValidateSelect->invokeArgs( + $this->object, + array(&$value, $arr) + ) + ); + + $arr = array('' => 'foobar'); + $value = null; + $this->assertTrue( + $attrValidateSelect->invokeArgs( + $this->object, + array(&$value, $arr) + ) + ); + $this->assertEquals( + "string", + gettype($value) + ); + + $arr = array(0 => 'foobar'); + $value = 0; + $this->assertTrue( + $attrValidateSelect->invokeArgs( + $this->object, + array(&$value, $arr) + ) + ); + + $arr = array('1' => 'foobar'); + $value = 0; + $this->assertFalse( + $attrValidateSelect->invokeArgs( + $this->object, + array(&$value, $arr) + ) + ); + } + + /** + * Test for FormDisplay::hasErrors + * + * @return void + */ + public function testHasErrors() + { + $attrErrors = new \ReflectionProperty('FormDisplay', '_errors'); + $attrErrors->setAccessible(true); + + $this->assertFalse( + $this->object->hasErrors() + ); + + $attrErrors->setValue( + $this->object, + array(1, 2) + ); + + $this->assertTrue( + $this->object->hasErrors() + ); + } + + /** + * Test for FormDisplay::getDocLink + * + * @return void + */ + public function testGetDocLink() + { + $this->assertEquals( + "./url.php?url=http%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2F" . + "config.html%23cfg_Servers_3_test_2_&server=0&lang=en&" . + ";token=token", + $this->object->getDocLink("Servers/3/test/2/") + ); + + $this->assertEquals( + '', + $this->object->getDocLink("Import") + ); + + $this->assertEquals( + '', + $this->object->getDocLink("Export") + ); + } + + /** + * Test for FormDisplay::getWikiLink + * + * @return void + */ + public function testGetWikiLink() + { + $this->assertEquals( + "./url.php?url=http%3A%2F%2Fwiki.phpmyadmin.net%2Fpma%2FConfig%23" . + "AllowDeny.29&server=0&lang=en&token=token", + $this->object->getWikiLink('Servers/1/AllowDeny') + ); + + $this->assertEquals( + "./url.php?url=http%3A%2F%2Fwiki.phpmyadmin.net%2Fpma%2FConfig%23" . + "format_2&server=0&lang=en&token=token", + $this->object->getWikiLink('Import/format') + ); + + $this->assertEquals( + "./url.php?url=http%3A%2F%2Fwiki.phpmyadmin.net%2Fpma%2FConfig%23" . + "test&server=0&lang=en&token=token", + $this->object->getWikiLink('Export/test') + ); + + } + + /** + * Test for FormDisplay::_getOptName + * + * @return void + */ + public function testGetOptName() + { + $method = new \ReflectionMethod('FormDisplay', '_getOptName'); + $method->setAccessible(true); + + $this->assertEquals( + "Servers_", + $method->invoke($this->object, "Servers/1/") + ); + + $this->assertEquals( + "Servers_23_", + $method->invoke($this->object, "Servers/1/23/") + ); + } + + /** + * Test for FormDisplay::_loadUserprefsInfo + * + * @return void + */ + public function testLoadUserprefsInfo() + { + $method = new \ReflectionMethod('FormDisplay', '_loadUserprefsInfo'); + $method->setAccessible(true); + + $attrUserprefs = new \ReflectionProperty( + 'FormDisplay', + '_userprefsDisallow' + ); + + $attrUserprefs->setAccessible(true); + $method->invoke($this->object, null); + $this->assertEquals( + array(), + $attrUserprefs->getValue($this->object) + ); + } + + /** + * Test for FormDisplay::_setComments + * + * @return void + */ + public function testSetComments() + { + if (!function_exists('runkit_constant_redefine')) { + $this->markTestSkipped('Cannot redefine constant'); + } + + $method = new \ReflectionMethod('FormDisplay', '_setComments'); + $method->setAccessible(true); + + // recoding + $opts['values']['iconv'] = 'testIconv'; + $opts['values']['recode'] = 'testRecode'; + + $expect = $opts; + + $method->invokeArgs( + $this->object, + array('RecodingEngine', &$opts) + ); + + $expect['comment'] = ''; + if (!function_exists('iconv')) { + $expect['values']['iconv'] .= " (unavailable)"; + $expect['comment'] = '"iconv" requires iconv extension'; + } + if (!function_exists('recode_string')) { + $expect['values']['recode'] .= " (unavailable)"; + $expect['comment'] .= ($expect['comment'] ? ", " : '') . + '"recode" requires recode extension'; + } + $expect['comment_warning'] = 1; + + $this->assertEquals( + $expect, + $opts + ); + + // ZipDump, GZipDump, BZipDump + $method->invokeArgs( + $this->object, + array('ZipDump', &$opts) + ); + + $comment = ''; + if (!function_exists("zip_open")) { + $comment = 'Compressed import will not work due to missing function ' . + 'zip_open.'; + } + if (!function_exists("gzcompress")) { + $comment .= ($comment ? '; ' : '') . 'Compressed export will not work ' . + 'due to missing function gzcompress.'; + } + + $this->assertEquals( + $comment, + $opts['comment'] + ); + + $this->assertTrue( + $opts['comment_warning'] + ); + + $method->invokeArgs( + $this->object, + array('GZipDump', &$opts) + ); + + $comment = ''; + if (!function_exists("gzopen")) { + $comment = 'Compressed import will not work due to missing function ' . + 'gzopen.'; + } + if (!function_exists("gzencode")) { + $comment .= ($comment ? '; ' : '') . 'Compressed export will not work ' . + 'due to missing function gzencode.'; + } + + $this->assertEquals( + $comment, + $opts['comment'] + ); + + $this->assertTrue( + $opts['comment_warning'] + ); + + $method->invokeArgs( + $this->object, + array('BZipDump', &$opts) + ); + + $comment = ''; + if (!function_exists("gzopen")) { + $comment = 'Compressed import will not work due to missing function ' . + 'bzopen.'; + } + if (!function_exists("bzcompress")) { + $comment .= ($comment ? '; ' : '') . 'Compressed export will not work ' . + 'due to missing function bzcompress.'; + } + + $this->assertEquals( + $comment, + $opts['comment'] + ); + + $this->assertTrue( + $opts['comment_warning'] + ); + + // SQLValidate + + $GLOBALS['cfg']['SQLValidator']['use'] = false; + + $method->invokeArgs( + $this->object, + array('SQLQuery/Validate', &$opts) + ); + + $this->assertEquals( + "SQL Validator is disabled", + $opts['comment'] + ); + + $this->assertTrue( + $opts['comment_warning'] + ); + + if (defined('PMA_SETUP')) { + runkit_constant_remove('PMA_SETUP'); + } + + $GLOBALS['cfg']['MaxDbList'] = 10; + $GLOBALS['cfg']['MaxTableList'] = 10; + $GLOBALS['cfg']['QueryHistoryMax'] = 10; + + $method->invokeArgs( + $this->object, + array('MaxDbList', &$opts) + ); + + $this->assertEquals( + "maximum 10", + $opts['comment'] + ); + + $method->invokeArgs( + $this->object, + array('MaxTableList', &$opts) + ); + + $this->assertEquals( + "maximum 10", + $opts['comment'] + ); + + $method->invokeArgs( + $this->object, + array('QueryHistoryMax', &$opts) + ); + + $this->assertEquals( + "maximum 10", + $opts['comment'] + ); + + } + + +} +?> diff --git a/test/classes/config/PMA_Form_test.php b/test/classes/config/PMA_Form_test.php index 150078992a..095561abfd 100644 --- a/test/classes/config/PMA_Form_test.php +++ b/test/classes/config/PMA_Form_test.php @@ -13,9 +13,15 @@ require_once 'libraries/Theme.class.php'; require_once 'libraries/Config.class.php'; require_once 'libraries/php-gettext/gettext.inc'; - +/** + * Tests for PMA_Form class + * + * @package PhpMyAdmin-test + */ class PMA_Form_Test extends PHPUnit_Framework_TestCase { + protected $object; + /** * Configures global environment. * @@ -29,22 +35,261 @@ class PMA_Form_Test extends PHPUnit_Framework_TestCase $GLOBALS['PMA_Config'] = new PMA_Config(); $GLOBALS['PMA_Config']->enableBc(); $GLOBALS['server'] = 0; + $this->object = new Form('pma_form_name', array('pma_form1','pma_form2'), 1); } + /** + * tearDown for test cases + * + * @return void + */ + protected function tearDown() + { + unset($this->object); + } + + /** + * Test for Form::__constructor + * + * @return void + */ public function testContructor() { - $form = new Form('pma_form_name', array('pma_form1','pma_form2'), 1); $this->assertEquals( 1, - $form->index + $this->object->index ); $this->assertEquals( 'pma_form_name', - $form->name + $this->object->name ); $this->assertArrayHasKey( 'pma_form1', - $form->fields + $this->object->fields + ); + } + + /** + * Test for Form::getOptionType + * + * @return void + */ + public function testGetOptionType() + { + $attrFieldsTypes = new \ReflectionProperty('Form', '_fieldsTypes'); + $attrFieldsTypes->setAccessible(true); + $attrFieldsTypes->setValue( + $this->object, + array("7" => "Seven") + ); + + $this->assertNull( + $this->object->getOptionType("123/4/5/6") + ); + + $this->assertEquals( + "Seven", + $this->object->getOptionType("123/4/5/7") + ); + } + + /** + * Test for Form::getOptionValueList + * + * @return void + */ + public function testGetOptionValueList() + { + $this->assertEquals( + array('NHibernate C# DO', 'NHibernate XML'), + $this->object->getOptionValueList("Export/codegen_format") + ); + + $this->assertEquals( + array( + 'auto' => 'auto', + '1' => 1, + '0' => 0 + ), + $this->object->getOptionValueList("OBGzip") + ); + + $this->assertEquals( + array( + 'none' => 'Nowhere', + 'left' => 'Left', + 'right' => 'Right', + 'both' => "Both" + ), + $this->object->getOptionValueList("RowActionLinks") + ); + } + + /** + * Test for Form::_readFormPathsCallback + * + * @return void + */ + public function testReadFormPathsCallBack() + { + $reflection = new \ReflectionClass('Form'); + $method = $reflection->getMethod('_readFormPathsCallback'); + $method->setAccessible(true); + + $array = array( + "foo" => array( + "bar" => array( + 'test' => 1, + 1 => ':group:end' + ) + ) + ); + + $method->invoke($this->object, $array, 'foo', 'pref'); + + $result = $this->object->fields; + + $this->assertCount( + 4, + $result + ); + + $this->assertEquals( + "pma_form1", + $result['pma_form1'] + ); + + $this->assertEquals( + "pma_form2", + $result['pma_form2'] + ); + + $this->assertEquals( + "preffoo/foo/bar/test", + $result[0] + ); + + // needs regexp because the counter is static + + $this->assertRegExp( + '/^preffoo\/foo\/bar\/\:group\:end\:\d+$/', + $result[1] + ); + } + + /** + * Test for Form::readFormPaths + * + * @return void + */ + public function testReadFormPaths() + { + $reflection = new \ReflectionClass('Form'); + $method = $reflection->getMethod('readFormPaths'); + $method->setAccessible(true); + + $array = array( + "foo" => array( + "bar" => array( + 'test' => 1, + 1 => ':group:end' + ) + ) + ); + + $method->invoke($this->object, $array); + + $result = $this->object->fields; + + $this->assertCount( + 2, + $result + ); + + $this->assertEquals( + "foo/bar/test", + $result['test'] + ); + + unset($result['test']); + + // needs regexp because the counter is static + + $keys = array_keys($result); + $key = $keys[0]; + + $this->assertRegexp( + "/^\:group\:end\:(\d+)$/", + $key + ); + + preg_match("/^\:group\:end\:(\d+)$/", $key, $matches); + $digit = $matches[1]; + + $this->assertEquals( + "foo/bar/:group:end:" . $digit, + $result[':group:end:' . $digit] + ); + } + + /** + * Test for Form::readTypes + * + * @return void + */ + public function testReadTypes() + { + $reflection = new \ReflectionClass('Form'); + $method = $reflection->getMethod('readTypes'); + $method->setAccessible(true); + + $this->object->fields = array( + "pma_form1" => "Servers/1/port", + "pma_form2" => "Servers/1/connect_type", + ":group:end:0" => "preffoo/foo/bar/test", + "1" => "preffoo/foo/bar/:group:end:0" + ); + + $attrFieldsTypes = $reflection->getProperty('_fieldsTypes'); + $attrFieldsTypes->setAccessible(true); + + $method->invoke($this->object, null); + + $this->assertEquals( + array( + "pma_form1" => "integer", + "pma_form2" => "select", + ":group:end:0" => "group", + "1" => "NULL" + ), + $attrFieldsTypes->getValue($this->object) + ); + } + + /** + * Test for Form::loadForm + * + * @return void + */ + public function testLoadForm() + { + $this->object = $this->getMockBuilder('Form') + ->disableOriginalConstructor() + ->setMethods(array('readFormPaths', 'readTypes')) + ->getMock(); + + $this->object->expects($this->exactly(1)) + ->method('readFormPaths') + ->with('testForm'); + + $this->object->expects($this->exactly(1)) + ->method('readTypes'); + + $this->object->loadForm('pmaform', 'testForm'); + + $this->assertEquals( + 'pmaform', + $this->object->name ); } } diff --git a/test/libraries/PMA_FormDisplay_tpl_test.php b/test/libraries/PMA_FormDisplay_tpl_test.php new file mode 100644 index 0000000000..97ceed7d8d --- /dev/null +++ b/test/libraries/PMA_FormDisplay_tpl_test.php @@ -0,0 +1,821 @@ + $val) { + $arr['attributes'][trim($val)] = trim($matches[2][$key]); + } + $matches = array(); + + // get tag + preg_match("/^\<(.*?)(\s|\>)/i", $elementHTML, $matches); + if (isset($matches[1])) { + $arr['tag'] = trim($matches[1]); + } + + return $arr; + } + + /** + * Test for PMA_displayFormTop() + * + * @return void + */ + public function testDisplayFormTop() + { + $_SERVER['REQUEST_URI'] = 'http://www.phpmyadmin.net'; + $GLOBALS['cfg']['ServerDefault'] = ''; + ob_start(); + PMA_displayFormTop(null, 'posted', array(1)); + $result = ob_get_clean(); + + $this->assertTag( + $this->_getTagArray( + '' + ), + $result + ); + + $this->assertTag( + $this->_getTagArray( + '' + ), + $result + ); + + $this->assertTag( + $this->_getTagArray( + '' + ), + $result + ); + + $this->assertTag( + $this->_getTagArray( + '' + ), + $result + ); + + $this->assertTag( + $this->_getTagArray( + '' + ), + $result + ); + + $this->assertTag( + $this->_getTagArray( + '' + ), + $result + ); + } + + /** + * Test for PMA_displayTabsTop() + * + * @return void + */ + public function testDisplayTabsTop() + { + ob_start(); + PMA_displayTabsTop(array('one', 'two')); + $result = ob_get_clean(); + + $this->assertTag( + $this->_getTagArray('