Merge pull request #487 from ayushchd/unit_testing_2

UTs for libraries/config/*, added validator class
This commit is contained in:
Michal Čihař 2013-07-11 07:34:59 -07:00
commit e651c7aaf2
10 changed files with 2265 additions and 598 deletions

View File

@ -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
*/

View File

@ -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();

View File

@ -133,6 +133,10 @@ function PMA_displayInput($path, $name, $type, $value, $description = '',
global $_FormDisplayGroup;
static $icons; // An array of IMG tags used further below in the function
if (defined('TESTSUITE')) {
$icons = null;
}
$is_setup_script = defined('PMA_SETUP');
if ($icons === null) { // if the static variables have not been initialised
$icons = array();

View File

@ -0,0 +1,587 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Validaition class for various validation functions
*
* Validation function takes two argument: id for which it is called
* and array of fields' values (usually values for entire formset, as defined
* in forms.inc.php).
* The function must always return an array with an error (or error array)
* assigned to a form element (formset name or field path). Even if there are
* no errors, key must be set with an empty value.
*
* Valdiation functions are assigned in $cfg_db['_validators'] (config.values.php).
*
* @package PhpMyAdmin
*/
class PMA_Validator
{
/**
* Returns validator list
*
* @return array
*/
public static function config_get_validators()
{
static $validators = null;
if ($validators === null) {
$cf = ConfigFile::getInstance();
$validators = $cf->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 <b>and</b> 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)));
}
}
?>

View File

@ -1,584 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Various validation functions
*
* Validation function takes two argument: id for which it is called
* and array of fields' values (usually values for entire formset, as defined
* in forms.inc.php).
* The function must always return an array with an error (or error array)
* assigned to a form element (formset name or field path). Even if there are
* no errors, key must be set with an empty value.
*
* Valdiation functions are assigned in $cfg_db['_validators'] (config.values.php).
*
* @package PhpMyAdmin
*/
/**
* Returns validator list
*
* @return array
*/
function PMA_config_get_validators()
{
static $validators = null;
if ($validators === null) {
$cf = ConfigFile::getInstance();
$validators = $cf->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 <b>and</b> 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)));
}
?>

View File

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

View File

@ -0,0 +1,593 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* tests for FormDisplay class in config folder
*
* @package PhpMyAdmin-test
*/
require_once 'libraries/config/ConfigFile.class.php';
require_once 'libraries/config/FormDisplay.class.php';
require_once 'libraries/Util.class.php';
require_once 'libraries/Theme.class.php';
require_once 'libraries/Config.class.php';
require_once 'libraries/php-gettext/gettext.inc';
require_once 'libraries/user_preferences.lib.php';
/**
* Tests for PMA_FormDisplay class
*
* @package PhpMyAdmin-test
*/
class PMA_FormDisplay_Test extends PHPUnit_Framework_TestCase
{
protected $object;
/**
* Configures global environment.
*
* @return void
*/
function setup()
{
$_SESSION['PMA_Theme'] = new PMA_Theme();
$GLOBALS['pmaThemePath'] = $_SESSION['PMA_Theme']->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(
'<dl><dt>Servers_test2_name</dt>' .
'<dd>e1</dd></dl><dl><dt>foobar123</dt><dd>' .
'e2</dd><dd>e3</dd></dl>'
);
$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_&amp;server=0&amp;lang=en&amp" .
";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&amp;server=0&amp;lang=en&amp;token=token",
$this->object->getWikiLink('Servers/1/AllowDeny')
);
$this->assertEquals(
"./url.php?url=http%3A%2F%2Fwiki.phpmyadmin.net%2Fpma%2FConfig%23" .
"format_2&amp;server=0&amp;lang=en&amp;token=token",
$this->object->getWikiLink('Import/format')
);
$this->assertEquals(
"./url.php?url=http%3A%2F%2Fwiki.phpmyadmin.net%2Fpma%2FConfig%23" .
"test&amp;server=0&amp;lang=en&amp;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']
);
}
}
?>

View File

@ -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
);
}
}

View File

@ -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"
)
);

View File

@ -0,0 +1,821 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* tests for FromDisplay.tpl.php
*
* @package PhpMyAdmin-test
*/
require_once 'libraries/config/ConfigFile.class.php';
require_once 'libraries/config/FormDisplay.tpl.php';
require_once 'libraries/Util.class.php';
require_once 'libraries/Theme.class.php';
require_once 'libraries/Config.class.php';
require_once 'libraries/php-gettext/gettext.inc';
require_once 'libraries/user_preferences.lib.php';
/**
* Tests for FromDisplay.tpl.php
*
* @package PhpMyAdmin-test
*/
class PMA_FormDisplay_Tpl_Test extends PHPUnit_Framework_TestCase
{
/**
* 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;
}
/**
* 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(
'<form method="get" action="http://www.phpmyadmin.net" ' .
'class="config-form disableAjax">'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<input type="hidden" name="tab_hash" value="" />'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<input type="hidden" name="check_page_refresh" ' .
'id="check_page_refresh" value="" />'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<input type="hidden" name="lang" value="en" />'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<input type="hidden" name="token" value="token" />'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<input type="hidden" name="0" value="1" />'
),
$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('<ul class="tabs">'),
$result
);
$this->assertTag(
$this->_getTagArray('<a href="#0">', array('content' => 'one')),
$result
);
$this->assertTag(
$this->_getTagArray('<a href="#1">', array('content' => 'two')),
$result
);
$this->assertTag(
$this->_getTagArray('<div class="tabs_contents">'),
$result
);
}
/**
* Test for PMA_displayFieldsetTop()
*
* @return void
*/
public function testDisplayFieldsetTop()
{
$attributes = array('name' => 'attrname');
$errors = array('e1', 'e2');
ob_start();
PMA_displayFieldsetTop("TitleTest", "DescTest", $errors, $attributes);
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<fieldset class="optbox" name="attrname">'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<legend>',
array(
'content' => 'TitleTest',
'parent' => array('tag' => 'fieldset')
)
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<p>',
array(
'content' => 'DescTest',
)
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<dl class="errors">'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<dd>',
array('content' => 'e1', 'parent' => array('tag' => 'dl'))
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<dd>',
array('content' => 'e2', 'parent' => array('tag' => 'dl'))
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<table width="100%" cellspacing="0">'
),
$result
);
}
/**
* Test for PMA_displayInput()
*
* @return void
*/
public function testDisplayInput()
{
if (!function_exists('runkit_constant_remove')) {
$this->markTestSkipped('Cannot modify constant');
}
$_SESSION['PMA_Theme'] = new PMA_Theme();
$GLOBALS['pmaThemeImage'] = 'testImage';
$GLOBALS['_FormDislayGroup'] = 1;
$opts = array();
$opts['errors'] = array('e1');
$opts['userprefs_allow'] = false;
$opts['setvalue'] = ':group';
$opts['doc'] = "http://doclink";
$opts['wiki'] = "http://wikilink";
$opts['comment'] = "testComment";
$opts['show_restore_default'] = true;
ob_start();
PMA_displayInput(
'test/path', 'testName', 'text', 'val',
'desc', false, $opts
);
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<tr class="group-header-field group-header-1 disabled-field">'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<label for="test/path">',
array('content' => 'testName')
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<a href="http://doclink" target="documentation">',
array(
'parent' => array(
'tag' => 'span',
'attributes' => array('class' => 'doc')
)
)
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<img src="testImageb_help.png" title="Documentation" ' .
'alt="Documentation" />',
array(
'parent' => array('tag' => 'a')
)
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<a href="http://wikilink" target="wiki">'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<img src="testImageb_info.png" title="Wiki" alt="Wiki" />'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<span class="disabled-notice">'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<small>',
array('content' => 'desc')
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<input type="text" size="60" name="test/path" id="test/path" ' .
'class="custom field-error" value="val" />'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<span class="field-comment-mark" title="testComment">',
array('content' => 'i')
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<a class="restore-default" href="#test/path" ' .
'style="display:none">'
),
$result
);
$this->assertContains(
'<dl class="inline_errors"><dd>e1</dd></dl>',
$result
);
// second case
define('PMA_SETUP', true);
$GLOBALS['_FormDislayGroup'] = 0;
$GLOBALS['cfg']['ThemePath'] = 'themePath';
$opts = array();
$opts['errors'] = array();
$opts['setvalue'] = 'setVal';
$opts['comment'] = "testComment";
$opts['show_restore_default'] = true;
$opts['userprefs_comment'] = 'userprefsComment';
$opts['userprefs_allow'] = true;
ob_start();
PMA_displayInput(
'test/path', 'testName', 'checkbox', 'val',
'', false, $opts
);
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<tr class="group-field group-field-1">'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<input type="checkbox" name="test/path" id="test/path" ' .
'checked="checked" />',
array(
'parent' => array(
'tag' => 'span',
'attributes' => array('class' => 'checkbox custom')
)
)
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<a class="userprefs-comment" title="userprefsComment">',
array('child' => array('tag' => 'img'))
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<td class="userprefs-allow" title="Allow users to customize ' .
'this value">',
array(
'child' => $this->_getTagArray(
'<input type="checkbox" name="test/path-userprefs-allow" ' .
'checked="checked"/>'
)
)
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<a class="set-value" href="#test/path=setVal" ' .
'title="Set value: setVal" style="display:none">',
array('child' => array('tag' => 'img'))
),
$result
);
// short_text
$GLOBALS['_FormDislayGroup'] = 0;
$GLOBALS['cfg']['ThemePath'] = 'themePath';
$opts = array();
$opts['errors'] = array();
ob_start();
PMA_displayInput(
'test/path', 'testName', 'short_text', 'val',
'', true, $opts
);
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<input type="text" size="25" name="test/path" id="test/path" ' .
'value="val" />'
),
$result
);
// number_text
ob_start();
PMA_displayInput(
'test/path', 'testName', 'number_text', 'val',
'', true, $opts
);
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<input type="text" size="15" name="test/path" ' .
'id="test/path" value="val" />'
),
$result
);
// select case 1
$opts['values_escaped'] = true;
$opts['values_disabled'] = array(1, 2);
$opts['values'] = array(
1 => 'test',
'key1' => true,
'key2' => false,
);
ob_start();
PMA_displayInput(
'test/path', 'testName', 'select', true,
'', true, $opts
);
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<select name="test/path" id="test/path">'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<select name="test/path" id="test/path">'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<option value="1" selected="selected" disabled="disabled">',
array(
'parent' => array('tag' => 'select'),
'content' => "test"
)
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<option value="key1">',
array(
'parent' => array('tag' => 'select'),
'content' => "yes"
)
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<option value="key2">',
array(
'parent' => array('tag' => 'select'),
'content' => "no"
)
),
$result
);
// select case 2
$opts['values_escaped'] = false;
$opts['values_disabled'] = array(1, 2);
$opts['values'] = array(
'a<b' => 'c&d',
'key1' => true,
'key2' => false,
);
ob_start();
PMA_displayInput(
'test/path', 'testName', 'select', false,
'', true, $opts
);
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<select name="test/path" id="test/path">'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<select name="test/path" id="test/path">'
),
$result
);
// assertTag doesn't seem to work with htmlentities
$this->assertContains(
'<option value="a&lt;b">c&amp;d</option>',
$result
);
// list
ob_start();
PMA_displayInput(
'test/path', 'testName', 'list', array('foo', 'bar'),
'', true, $opts
);
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<textarea cols="40" rows="5" name="test/path" id="test/path">',
array(
'content' => "foo\nbar"
)
),
$result
);
runkit_constant_remove('PMA_SETUP');
}
/**
* Test for PMA_displayGroupHeader()
*
* @return void
*/
public function testDisplayGroupHeader()
{
if (!function_exists('runkit_constant_remove')) {
$this->markTestSkipped('Cannot modify constant');
}
$this->assertNull(
PMA_displayGroupHeader('')
);
$GLOBALS['_FormDisplayGroup'] = 3;
if (!defined('PMA_SETUP')) {
define('PMA_SETUP', true);
}
ob_start();
PMA_displayGroupHeader('headerText');
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<tr class="group-header group-header-4">',
array(
'child' => $this->_getTagArray(
'<th colspan="3">',
array(
'content' => 'headerText'
)
)
)
),
$result
);
// without PMA_SETUP
runkit_constant_remove('PMA_SETUP');
$GLOBALS['_FormDisplayGroup'] = 3;
ob_start();
PMA_displayGroupHeader('headerText');
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<tr class="group-header group-header-4">',
array(
'child' => $this->_getTagArray(
'<th colspan="2">',
array(
'content' => 'headerText'
)
)
)
),
$result
);
}
/**
* Test for PMA_displayGroupFooter()
*
* @return void
*/
public function testDisplayGroupFooter()
{
$GLOBALS['_FormDisplayGroup'] = 3;
PMA_displayGroupFooter();
$this->assertEquals(
2,
$GLOBALS['_FormDisplayGroup']
);
}
/**
* Test for PMA_displayFieldsetBottom()
*
* @return void
*/
public function testDisplayFieldsetBottom()
{
if (!function_exists('runkit_constant_remove')) {
$this->markTestSkipped('Cannot modify constant');
}
// with PMA_SETUP
if (!defined('PMA_SETUP')) {
define('PMA_SETUP', true);
}
ob_start();
PMA_displayFieldsetBottom();
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<td colspan="3" class="lastrow">'
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<input type="submit" name="submit_save" value="Apply"',
array(
'parent' => array('tag' => 'td')
)
),
$result
);
$this->assertTag(
$this->_getTagArray(
'<input type="button" name="submit_reset" value="Reset" />',
array(
'parent' => array('tag' => 'td')
)
),
$result
);
$this->assertContains(
'</fieldset>',
$result
);
// without PMA_SETUP
runkit_constant_remove('PMA_SETUP');
ob_start();
PMA_displayFieldsetBottom();
$result = ob_get_clean();
$this->assertTag(
$this->_getTagArray(
'<td colspan="2" class="lastrow">'
),
$result
);
}
/**
* Test for PMA_displayFieldsetBottomSimple()
*
* @return void
*/
public function testDisplayFieldsetBottomSimple()
{
$this->expectOutputString(
'</table></fieldset>'
);
PMA_displayFieldsetBottomSimple();
}
/**
* Test for PMA_displayTabsBottom()
*
* @return void
*/
public function testDisplayTabsBottom()
{
$this->expectOutputString(
"</div>\n"
);
PMA_displayTabsBottom();
}
/**
* Test for PMA_displayFormBottom()
*
* @return void
*/
public function testDisplayFormBottom()
{
$this->expectOutputString(
"</form>\n"
);
PMA_displayFormBottom();
}
/**
* Test for PMA_addJsValidate()
*
* @return void
*/
public function testAddJsValidate()
{
$validators = array(
'one' => array('\\\';', '\r\n\\\'<scrIpt></\' + \'script>'),
'two' => array()
);
$js = array();
PMA_addJsValidate('testID', $validators, $js);
$this->assertEquals(
array(
'validateField(\'testID\', \'\\\';\', true, [\'\\\\r\\\\n\\\\\\\'' .
'<scrIpt></\\\' + \\\'script>\'])',
'validateField(\'testID\', \'\', true)'
),
$js
);
}
/**
* Test for PMA_displayJavascript()
*
* @return void
*/
public function testDisplayJavascript()
{
$this->assertNull(
PMA_displayJavascript(array())
);
$this->expectOutputString(
"<script type=\"text/javascript\">\n" .
"var i = 1;\n" .
"i++;\n" .
"</script>\n"
);
PMA_displayJavascript(array('var i = 1', 'i++'));
}
/**
* Test for PMA_displayErrors()
*
* @return void
*/
public function testDisplayErrors()
{
$errors = array('<err1>', '&err2');
$this->expectOutputString(
'<dl><dt>err&quot;Name1&quot;</dt>' .
'<dd>&lt;err1&gt;</dd><dd>&amp;err2</dd></dl>'
);
PMA_displayErrors('err"Name1"', $errors);
}
}
?>