diff options
author | Nils Adermann <naderman@naderman.de> | 2010-11-20 17:00:05 +0100 |
---|---|---|
committer | Nils Adermann <naderman@naderman.de> | 2010-11-20 17:00:05 +0100 |
commit | 7f21a5f46156660d7ea6a4bdb59166ac553e2be8 (patch) | |
tree | 3963b4075f58c43ffc01fe290b04a800668bc53c /tests | |
parent | c4e02a191628b4b9f7b6340f2876607663baeb5a (diff) | |
parent | af4c2a3eb15fc4318b23dcb7794c230cf3ec2a0f (diff) | |
download | forums-7f21a5f46156660d7ea6a4bdb59166ac553e2be8.tar forums-7f21a5f46156660d7ea6a4bdb59166ac553e2be8.tar.gz forums-7f21a5f46156660d7ea6a4bdb59166ac553e2be8.tar.bz2 forums-7f21a5f46156660d7ea6a4bdb59166ac553e2be8.tar.xz forums-7f21a5f46156660d7ea6a4bdb59166ac553e2be8.zip |
Merge commit 'release-3.0.8'
* commit 'release-3.0.8': (393 commits)
[prep-release-3.0.8] Incrementing version number to 3.0.8 and update changelog
[ticket/9903] Script for detecting potentially malicious flash bbcodes
[ticket/9904] Update WebPI Parameters.xml to work with WebMatrix.
[ticket/9899] Change recaptcha theme from default to 'clean' in the ACP.
[ticket/9509] Fix a typo and wrong period placement
[ticket/9903] Fix XSS in BBcode-parser's Flash-BBcode.
[develop-olympus] Updating changelog for last minute 3.0.8-RC1 fixes.
[ticket/9140] Check current board version in incremental update packages
[ticket/9891] Updater drops language-selection after database-update
[develop-olympus] Updating changelog with latest changes for 3.0.8-RC1
[ticket/9884] Reduce queue interval to 60 seconds, email package size to 20
[ticket/9886] Update fails on PostgreSQL because of an error in _add_module
[ticket/9888] Update fails when Bing [Bot] was already added to the users table
[develop-olympus] Bumping version number for 3.0.8-RC1.
[ticket/9885] Fix extension group name updater. Loop through all languages.
[ticket/9847] Fix typo in search synonyms. Use british english for 'judgement'.
[ticket/9883] Change an American English spelling to British English.
[task/phing-build] Correct the path for update package patch files.
[ticket/9880] Change "antibot" to "anti-spambot".
[ticket/9696] Surpress is_dir() notice when using SQLite with open_basedir.
...
Diffstat (limited to 'tests')
46 files changed, 3467 insertions, 0 deletions
diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.txt new file mode 100644 index 0000000000..74a0635c1a --- /dev/null +++ b/tests/RUNNING_TESTS.txt @@ -0,0 +1,57 @@ +Running Tests +============= + +Prerequisites +============= + +PHPUnit +------- + +phpBB unit tests use PHPUnit framework. Version 3.3 or better is required +to run the tests. PHPUnit prefers to be installed via PEAR; refer to +http://www.phpunit.de/ for more information. + +PHP extensions +-------------- + +Unit tests use several PHP extensions that board code does not use. Currently +the following PHP extensions must be installed and enabled to run unit tests: + +- ctype + +Database Tests +-------------- +By default all tests requiring a database connection will use sqlite. If you +do not have sqlite installed the tests will be skipped. If you wish to run the +tests on a different database you have to create a test_config.php file within +your tests directory following the same format as phpBB's config.php. An example +for mysqli can be found below. More information on configuration options can be +found on the wiki (see below). + + <?php + $dbms = 'mysqli'; + $dbhost = 'localhost'; + $dbport = ''; + $dbname = 'database'; + $dbuser = 'user'; + $dbpasswd = 'password'; + +Alternatively you can specify parameters in the environment, so e.g. the following +will run phpunit with the same parameters as in the shown test_config.php file: + + $ PHPBB_TEST_DBMS='mysqli' PHPBB_TEST_DBHOST='localhost' \ + PHPBB_TEST_DBNAME='database' PHPBB_TEST_DBUSER='user' \ + PHPBB_TEST_DBPASSWD='password' phpunit all_tests.php + +Running +======= + +Once the prerequisites are installed, run the tests from tests directory: + + $ phpunit all_tests.php + +More Information +================ + +Further information is available on phpbb wiki: +http://wiki.phpbb.com/display/DEV/Unit+Tests diff --git a/tests/all_tests.php b/tests/all_tests.php new file mode 100644 index 0000000000..d1d711c4d7 --- /dev/null +++ b/tests/all_tests.php @@ -0,0 +1,69 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +error_reporting(E_ALL); + +if (!defined('PHPUnit_MAIN_METHOD')) +{ + define('PHPUnit_MAIN_METHOD', 'phpbb_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'utf/all_tests.php'; +require_once 'request/all_tests.php'; +require_once 'security/all_tests.php'; +require_once 'template/all_tests.php'; +require_once 'text_processing/all_tests.php'; +require_once 'dbal/all_tests.php'; +require_once 'regex/all_tests.php'; +require_once 'network/all_tests.php'; +require_once 'random/all_tests.php'; + +// exclude the test directory from code coverage reports +if (version_compare(PHPUnit_Runner_Version::id(), '3.5.0') >= 0) +{ + PHP_CodeCoverage_Filter::getInstance()->addDirectoryToBlacklist('./'); +} +else +{ + PHPUnit_Util_Filter::addDirectoryToFilter('./'); +} + +class phpbb_all_tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite('phpBB'); + + $suite->addTest(phpbb_utf_all_tests::suite()); + $suite->addTest(phpbb_request_all_tests::suite()); + $suite->addTest(phpbb_security_all_tests::suite()); + $suite->addTest(phpbb_template_all_tests::suite()); + $suite->addTest(phpbb_text_processing_all_tests::suite()); + $suite->addTest(phpbb_dbal_all_tests::suite()); + $suite->addTest(phpbb_regex_all_tests::suite()); + $suite->addTest(phpbb_network_all_tests::suite()); + $suite->addTest(phpbb_random_all_tests::suite()); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_all_tests::main') +{ + phpbb_all_tests::main(); +} + diff --git a/tests/dbal/all_tests.php b/tests/dbal/all_tests.php new file mode 100644 index 0000000000..cfa8176246 --- /dev/null +++ b/tests/dbal/all_tests.php @@ -0,0 +1,42 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ + define('PHPUnit_MAIN_METHOD', 'phpbb_dbal_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'dbal/select.php'; +require_once 'dbal/write.php'; + +class phpbb_dbal_all_tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite('phpBB Database Abstraction Layer'); + + $suite->addTestSuite('phpbb_dbal_select_test'); + $suite->addTestSuite('phpbb_dbal_write_test'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_dbal_all_tests::main') +{ + phpbb_dbal_all_tests::main(); +} diff --git a/tests/dbal/fixtures/config.xml b/tests/dbal/fixtures/config.xml new file mode 100644 index 0000000000..019f582a91 --- /dev/null +++ b/tests/dbal/fixtures/config.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_config"> + <column>config_name</column> + <column>config_value</column> + <column>is_dynamic</column> + <row> + <value>config1</value> + <value>foo</value> + <value>0</value> + </row> + <row> + <value>config2</value> + <value>bar</value> + <value>1</value> + </row> + </table> +</dataset> diff --git a/tests/dbal/fixtures/three_users.xml b/tests/dbal/fixtures/three_users.xml new file mode 100644 index 0000000000..a6789f4a01 --- /dev/null +++ b/tests/dbal/fixtures/three_users.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_users"> + <column>user_id</column> + <column>username_clean</column> + <row> + <value>1</value> + <value>barfoo</value> + </row> + <row> + <value>2</value> + <value>foobar</value> + </row> + <row> + <value>3</value> + <value>bertie</value> + </row> + </table> +</dataset> diff --git a/tests/dbal/select.php b/tests/dbal/select.php new file mode 100644 index 0000000000..70f27549d2 --- /dev/null +++ b/tests/dbal/select.php @@ -0,0 +1,321 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/functions.php'; + +class phpbb_dbal_select_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/three_users.xml'); + } + + public static function return_on_error_select_data() + { + return array( + array('phpbb_users', "username_clean = 'bertie'", array(array('username_clean' => 'bertie'))), + array('phpbb_users', 'username_clean syntax_error', false), + ); + } + + /** + * @dataProvider return_on_error_select_data + */ + public function test_return_on_error_select($table, $where, $expected) + { + $db = $this->new_dbal(); + + $db->sql_return_on_error(true); + + $result = $db->sql_query('SELECT username_clean + FROM ' . $table . ' + WHERE ' . $where . ' + ORDER BY user_id ASC'); + + $db->sql_return_on_error(false); + + $this->assertEquals($expected, $db->sql_fetchrowset($result)); + } + + public static function fetchrow_data() + { + return array( + array('', array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'), + array('username_clean' => 'bertie'))), + array('user_id = 2', array(array('username_clean' => 'foobar'))), + array("username_clean = 'bertie'", array(array('username_clean' => 'bertie'))), + array("username_clean = 'phpBB'", array()), + ); + } + + /** + * @dataProvider fetchrow_data + */ + public function test_fetchrow($where, $expected) + { + $db = $this->new_dbal(); + + $result = $db->sql_query('SELECT username_clean + FROM phpbb_users + ' . (($where) ? ' WHERE ' . $where : '') . ' + ORDER BY user_id ASC'); + + $ary = array(); + while ($row = $db->sql_fetchrow($result)) + { + $ary[] = $row; + } + $db->sql_freeresult($result); + + $this->assertEquals($expected, $ary); + } + + /** + * @dataProvider fetchrow_data + */ + public function test_fetchrowset($where, $expected) + { + $db = $this->new_dbal(); + + $result = $db->sql_query('SELECT username_clean + FROM phpbb_users + ' . (($where) ? ' WHERE ' . $where : '') . ' + ORDER BY user_id ASC'); + + $this->assertEquals($expected, $db->sql_fetchrowset($result)); + + $db->sql_freeresult($result); + } + + public static function fetchfield_data() + { + return array( + array('', array('barfoo', 'foobar', 'bertie')), + array('user_id = 2', array('foobar')), + ); + } + + /** + * @dataProvider fetchfield_data + */ + public function test_fetchfield($where, $expected) + { + $db = $this->new_dbal(); + + $result = $db->sql_query('SELECT username_clean + FROM phpbb_users + ' . (($where) ? ' WHERE ' . $where : '') . ' + ORDER BY user_id ASC'); + + $ary = array(); + while ($row = $db->sql_fetchfield('username_clean')) + { + $ary[] = $row; + } + $db->sql_freeresult($result); + + $this->assertEquals($expected, $ary); + } + + public static function query_limit_data() + { + return array( + array(0, 0, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'), + array('username_clean' => 'bertie'))), + array(0, 1, array(array('username_clean' => 'foobar'), + array('username_clean' => 'bertie'))), + array(1, 0, array(array('username_clean' => 'barfoo'))), + array(1, 2, array(array('username_clean' => 'bertie'))), + array(2, 0, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'))), + array(2, 2, array(array('username_clean' => 'bertie'))), + array(2, 5, array()), + array(10, 1, array(array('username_clean' => 'foobar'), + array('username_clean' => 'bertie'))), + array(10, 5, array()), + ); + } + + /** + * @dataProvider query_limit_data + */ + public function test_query_limit($total, $offset, $expected) + { + $db = $this->new_dbal(); + + $result = $db->sql_query_limit('SELECT username_clean + FROM phpbb_users + ORDER BY user_id ASC', $total, $offset); + + $ary = array(); + while ($row = $db->sql_fetchrow($result)) + { + $ary[] = $row; + } + $db->sql_freeresult($result); + + $this->assertEquals($expected, $ary); + } + + public static function like_expression_data() + { + // * = any_char; # = one_char + return array( + array('barfoo', array(array('username_clean' => 'barfoo'))), + array('bar', array()), + array('bar*', array(array('username_clean' => 'barfoo'))), + array('*bar*', array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'))), + array('b*r', array()), + array('b*e', array(array('username_clean' => 'bertie'))), + array('#b*e', array()), + array('b####e', array(array('username_clean' => 'bertie'))), + ); + } + + /** + * @dataProvider like_expression_data + */ + public function test_like_expression($like_expression, $expected) + { + $db = $this->new_dbal(); + + $like_expression = str_replace('*', $db->any_char, $like_expression); + $like_expression = str_replace('#', $db->one_char, $like_expression); + $where = ($like_expression) ? 'username_clean ' . $db->sql_like_expression($like_expression) : ''; + + $result = $db->sql_query('SELECT username_clean + FROM phpbb_users + ' . (($where) ? ' WHERE ' . $where : '') . ' + ORDER BY user_id ASC'); + + $this->assertEquals($expected, $db->sql_fetchrowset($result)); + + $db->sql_freeresult($result); + } + + public static function in_set_data() + { + return array( + array('user_id', 3, false, false, array(array('username_clean' => 'bertie'))), + array('user_id', 3, false, true, array(array('username_clean' => 'bertie'))), + array('user_id', 3, true, false, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'))), + array('user_id', 3, true, true, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'))), + array('username_clean', 'bertie', false, false, array(array('username_clean' => 'bertie'))), + array('username_clean', 'bertie', false, true, array(array('username_clean' => 'bertie'))), + array('username_clean', 'bertie', true, false, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'))), + array('username_clean', 'bertie', true, true, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'))), + array('user_id', array(3), false, false, array(array('username_clean' => 'bertie'))), + array('user_id', array(3), false, true, array(array('username_clean' => 'bertie'))), + array('user_id', array(3), true, false, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'))), + array('user_id', array(3), true, true, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'))), + array('user_id', array(1, 3), false, false, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'bertie'))), + array('user_id', array(1, 3), false, true, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'bertie'))), + array('user_id', array(1, 3), true, false, array(array('username_clean' => 'foobar'))), + array('user_id', array(1, 3), true, true, array(array('username_clean' => 'foobar'))), + array('username_clean', '', false, false, array()), + array('username_clean', '', false, true, array()), + array('username_clean', '', true, false, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'), + array('username_clean' => 'bertie'))), + array('username_clean', '', true, true, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'), + array('username_clean' => 'bertie'))), + array('user_id', array(), false, true, array()), + array('user_id', array(), true, true, array(array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'), + array('username_clean' => 'bertie'))), + + // These here would throw errors and therefor $result should be false. + // Removing for now because SQLite accepts empty IN() syntax + /*array('user_id', array(), false, false, false, true), + array('user_id', array(), true, false, false, true),*/ + ); + } + + /** + * @dataProvider in_set_data + */ + public function test_in_set($field, $array, $negate, $allow_empty_set, $expected, $catch_error = false) + { + $db = $this->new_dbal(); + + if ($catch_error) + { + $db->sql_return_on_error(true); + } + + $result = $db->sql_query('SELECT username_clean + FROM phpbb_users + WHERE ' . $db->sql_in_set($field, $array, $negate, $allow_empty_set) . ' + ORDER BY user_id ASC'); + + if ($catch_error) + { + $db->sql_return_on_error(false); + } + + $this->assertEquals($expected, $db->sql_fetchrowset($result)); + + $db->sql_freeresult($result); + } + + public static function build_array_data() + { + return array( + array(array('username_clean' => 'barfoo'), array(array('username_clean' => 'barfoo'))), + array(array('username_clean' => 'barfoo', 'user_id' => 1), array(array('username_clean' => 'barfoo'))), + array(array('username_clean' => 'barfoo', 'user_id' => 2), array()), + + // These here would throw errors and therefor $result should be false. + array(array(), false, true), + array('no_array', false, true), + array(0, false, true), + ); + } + + /** + * @dataProvider build_array_data + */ + public function test_build_array($assoc_ary, $expected, $catch_error = false) + { + $db = $this->new_dbal(); + + if ($catch_error) + { + $db->sql_return_on_error(true); + } + + $sql = 'SELECT username_clean + FROM phpbb_users + WHERE ' . $db->sql_build_array('SELECT', $assoc_ary) . ' + ORDER BY user_id ASC'; + $result = $db->sql_query($sql); + + if ($catch_error) + { + $db->sql_return_on_error(false); + } + + $this->assertEquals($expected, $db->sql_fetchrowset($result)); + + $db->sql_freeresult($result); + } +} diff --git a/tests/dbal/write.php b/tests/dbal/write.php new file mode 100644 index 0000000000..01deacda69 --- /dev/null +++ b/tests/dbal/write.php @@ -0,0 +1,172 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/functions.php'; + +class phpbb_dbal_write_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); + } + + public static function build_array_insert_data() + { + return array( + array(array( + 'config_name' => 'test_version', + 'config_value' => '0.0.0', + 'is_dynamic' => 1, + )), + array(array( + 'config_name' => 'second config', + 'config_value' => '10', + 'is_dynamic' => 0, + )), + ); + } + + /** + * @dataProvider build_array_insert_data + */ + public function test_build_array_insert($sql_ary) + { + $db = $this->new_dbal(); + + $sql = 'INSERT INTO phpbb_config ' . $db->sql_build_array('INSERT', $sql_ary); + $result = $db->sql_query($sql); + + $sql = "SELECT * + FROM phpbb_config + WHERE config_name = '" . $sql_ary['config_name'] . "'"; + $result = $db->sql_query_limit($sql, 1); + + $this->assertEquals($sql_ary, $db->sql_fetchrow($result)); + + $db->sql_freeresult($result); + } + + public function test_delete() + { + $db = $this->new_dbal(); + + $sql = "DELETE FROM phpbb_config + WHERE config_name = 'config1'"; + $result = $db->sql_query($sql); + + $sql = 'SELECT * + FROM phpbb_config'; + $result = $db->sql_query($sql); + $rows = $db->sql_fetchrowset($result); + + $this->assertEquals(1, sizeof($rows)); + $this->assertEquals('config2', $rows[0]['config_name']); + + $db->sql_freeresult($result); + } + + public function test_multiple_insert() + { + $db = $this->new_dbal(); + + // empty the table + $sql = 'DELETE FROM phpbb_config'; + $db->sql_query($sql); + + $batch_ary = array( + array( + 'config_name' => 'batch one', + 'config_value' => 'b1', + 'is_dynamic' => 0, + ), + array( + 'config_name' => 'batch two', + 'config_value' => 'b2', + 'is_dynamic' => 1, + ), + ); + + $result = $db->sql_multi_insert('phpbb_config', $batch_ary); + + $sql = 'SELECT * + FROM phpbb_config + ORDER BY config_name ASC'; + $result = $db->sql_query($sql); + + $this->assertEquals($batch_ary, $db->sql_fetchrowset($result)); + + $db->sql_freeresult($result); + } + + public static function update_data() + { + return array( + array( + array( + 'config_value' => '23', + 'is_dynamic' => 0, + ), + " WHERE config_name = 'config1'", + array( + array( + 'config_name' => 'config1', + 'config_value' => '23', + 'is_dynamic' => 0, + ), + array( + 'config_name' => 'config2', + 'config_value' => 'bar', + 'is_dynamic' => 1, + ), + ), + ), + array( + array( + 'config_value' => '0', + 'is_dynamic' => 1, + ), + '', + array( + array( + 'config_name' => 'config1', + 'config_value' => '0', + 'is_dynamic' => 1, + ), + array( + 'config_name' => 'config2', + 'config_value' => '0', + 'is_dynamic' => 1, + ), + ), + ), + ); + } + + /** + * @dataProvider update_data + */ + public function test_update($sql_ary, $where, $expected) + { + $db = $this->new_dbal(); + + $sql = 'UPDATE phpbb_config + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . $where; + $result = $db->sql_query($sql); + + $sql = 'SELECT * + FROM phpbb_config + ORDER BY config_name ASC'; + $result = $db->sql_query($sql); + + $this->assertEquals($expected, $db->sql_fetchrowset($result)); + + $db->sql_freeresult($result); + } +} diff --git a/tests/network/all_tests.php b/tests/network/all_tests.php new file mode 100644 index 0000000000..b500647f81 --- /dev/null +++ b/tests/network/all_tests.php @@ -0,0 +1,40 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ + define('PHPUnit_MAIN_METHOD', 'phpbb_network_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'network/checkdnsrr.php'; + +class phpbb_network_all_tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite('phpBB Network Functions'); + + $suite->addTestSuite('phpbb_network_checkdnsrr_test'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_network_all_tests::main') +{ + phpbb_network_all_tests::main(); +} diff --git a/tests/network/checkdnsrr.php b/tests/network/checkdnsrr.php new file mode 100644 index 0000000000..57fe2761cc --- /dev/null +++ b/tests/network/checkdnsrr.php @@ -0,0 +1,63 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/functions.php'; + +class phpbb_network_checkdnsrr_test extends phpbb_test_case +{ + public function data_provider() + { + return array( + // Existing MX record + array('phpbb.com', 'MX', true), + + // Non-existing MX record + array('does-not-exist.phpbb.com', 'MX', false), + + // Existing A record + array('www.phpbb.com', 'A', true), + + // Non-existing A record + array('does-not-exist.phpbb.com', 'A', false), + + // Existing AAAA record + array('www.six.heise.de', 'AAAA', true), + + // Non-existing AAAA record + array('does-not-exist.phpbb.com', 'AAAA', false), + + // Existing CNAME record + array('news.cnet.com', 'CNAME', true), + + // Non-existing CNAME record + array('does-not-exist.phpbb.com', 'CNAME', false), + + // Existing NS record + array('phpbb.com', 'NS', true), + + // Non-existing NS record + array('does-not-exist', 'NS', false), + + // Existing TXT record + array('phpbb.com', 'TXT', true), + + // Non-existing TXT record + array('does-not-exist', 'TXT', false), + ); + } + + /** + * @dataProvider data_provider + */ + public function test_checkdnsrr($host, $type, $expected) + { + $this->assertEquals($expected, phpbb_checkdnsrr($host, $type)); + } +} diff --git a/tests/random/all_tests.php b/tests/random/all_tests.php new file mode 100644 index 0000000000..c6ffe78024 --- /dev/null +++ b/tests/random/all_tests.php @@ -0,0 +1,40 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ + define('PHPUnit_MAIN_METHOD', 'phpbb_random_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'random/gen_rand_string.php'; + +class phpbb_random_all_tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite('phpBB Random Functions'); + + $suite->addTestSuite('phpbb_random_gen_rand_string_test'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_random_all_tests::main') +{ + phpbb_random_all_tests::main(); +} diff --git a/tests/random/gen_rand_string.php b/tests/random/gen_rand_string.php new file mode 100644 index 0000000000..cd58d14ed3 --- /dev/null +++ b/tests/random/gen_rand_string.php @@ -0,0 +1,63 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/functions.php'; + +class phpbb_random_gen_rand_string_test extends phpbb_test_case +{ + const TEST_COUNT = 100; + const MIN_STRING_LENGTH = 1; + const MAX_STRING_LENGTH = 15; + + public function setUp() + { + global $config; + + if (!is_array($config)) + { + $config = array(); + } + + $config['rand_seed'] = ''; + $config['rand_seed_last_update'] = time() + 600; + } + + public function test_gen_rand_string() + { + for ($tests = 0; $tests <= self::TEST_COUNT; ++$tests) + { + for ($num_chars = self::MIN_STRING_LENGTH; $num_chars <= self::MAX_STRING_LENGTH; ++$num_chars) + { + $random_string = gen_rand_string($num_chars); + $random_string_length = strlen($random_string); + + $this->assertTrue($random_string_length >= self::MIN_STRING_LENGTH); + $this->assertTrue($random_string_length <= $num_chars); + $this->assertRegExp('#^[A-Z0-9]+$#', $random_string); + } + } + } + + public function test_gen_rand_string_friendly() + { + for ($tests = 0; $tests <= self::TEST_COUNT; ++$tests) + { + for ($num_chars = self::MIN_STRING_LENGTH; $num_chars <= self::MAX_STRING_LENGTH; ++$num_chars) + { + $random_string = gen_rand_string_friendly($num_chars); + $random_string_length = strlen($random_string); + + $this->assertTrue($random_string_length >= self::MIN_STRING_LENGTH); + $this->assertTrue($random_string_length <= $num_chars); + $this->assertRegExp('#^[A-NP-Z1-9]+$#', $random_string); + } + } + } +} diff --git a/tests/regex/all_tests.php b/tests/regex/all_tests.php new file mode 100644 index 0000000000..316a9d4a58 --- /dev/null +++ b/tests/regex/all_tests.php @@ -0,0 +1,46 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ + define('PHPUnit_MAIN_METHOD', 'phpbb_regex_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'regex/email.php'; +require_once 'regex/ipv4.php'; +require_once 'regex/ipv6.php'; +require_once 'regex/url.php'; + +class phpbb_regex_all_tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite('phpBB Regular Expressions'); + + $suite->addTestSuite('phpbb_regex_email_test'); + $suite->addTestSuite('phpbb_regex_ipv4_test'); + $suite->addTestSuite('phpbb_regex_ipv6_test'); + $suite->addTestSuite('phpbb_regex_url_test'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_regex_all_tests::main') +{ + phpbb_regex_all_tests::main(); +} diff --git a/tests/regex/email.php b/tests/regex/email.php new file mode 100644 index 0000000000..8658b8af36 --- /dev/null +++ b/tests/regex/email.php @@ -0,0 +1,119 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/functions.php'; + +class phpbb_regex_email_test extends phpbb_test_case +{ + protected $regex; + + public function setUp() + { + $this->regex = '#^' . get_preg_expression('email') . '$#i'; + } + + public function positive_match_data() + { + return array( + array('nobody@phpbb.com'), + array('Nobody@sub.phpbb.com'), + array('alice.bob@foo.phpbb.com'), + array('alice-foo@bar.phpbb.com'), + array('alice_foo@bar.phpbb.com'), + array('alice+tag@foo.phpbb.com'), + array('alice&tag@foo.phpbb.com'), + + //array('"John Doe"@example.com'), + //array('Alice@[192.168.2.1]'), // IPv4 + //array('Bob@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]'), // IPv6 + + // http://fightingforalostcause.net/misc/2006/compare-email-regex.php + array('l3tt3rsAndNumb3rs@domain.com'), + array('has-dash@domain.com'), + array('hasApostrophe.o\'leary@domain.org'), + array('uncommonTLD@domain.museum'), + array('uncommonTLD@domain.travel'), + array('uncommonTLD@domain.mobi'), + array('countryCodeTLD@domain.uk'), + array('countryCodeTLD@domain.rw'), + array('numbersInDomain@911.com'), + array('underscore_inLocal@domain.net'), + array('IPInsteadOfDomain@127.0.0.1'), + array('IPAndPort@127.0.0.1:25'), + array('subdomain@sub.domain.com'), + array('local@dash-inDomain.com'), + array('dot.inLocal@foo.com'), + array('a@singleLetterLocal.org'), + array('singleLetterDomain@x.org'), + array('&*=?^+{}\'~@validCharsInLocal.net'), + array('foor@bar.newTLD'), + ); + } + + public function negative_match_data() + { + return array( + array('foo.example.com'), // @ is missing + array('.foo.example.com'), // . as first character + array('Foo.@example.com'), // . is last in local part + array('foo..123@example.com'), // . doubled + array('a@b@c@example.com'), // @ doubled + + array('()[]\;:,<>@example.com'), // invalid characters + array('abc(def@example.com'), // invalid character ( + array('abc)def@example.com'), // invalid character ) + array('abc[def@example.com'), // invalid character [ + array('abc]def@example.com'), // invalid character ] + array('abc\def@example.com'), // invalid character \ + array('abc;def@example.com'), // invalid character ; + array('abc:def@example.com'), // invalid character : + array('abc,def@example.com'), // invalid character , + array('abc<def@example.com'), // invalid character < + array('abc>def@example.com'), // invalid character > + + // http://fightingforalostcause.net/misc/2006/compare-email-regex.php + array('missingDomain@.com'), + array('@missingLocal.org'), + array('missingatSign.net'), + array('missingDot@com'), + array('two@@signs.com'), + array('colonButNoPort@127.0.0.1:'), + array(''), + array('someone-else@127.0.0.1.26'), + array('.localStartsWithDot@domain.com'), + array('localEndsWithDot.@domain.com'), + array('two..consecutiveDots@domain.com'), + array('domainStartsWithDash@-domain.com'), + array('domainEndsWithDash@domain-.com'), + array('numbersInTLD@domain.c0m'), + array('missingTLD@domain.'), + array('! "#$%(),/;<>[]`|@invalidCharsInLocal.org'), + array('invalidCharsInDomain@! "#$%(),/;<>_[]`|.org'), + array('local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org'), + ); + } + + /** + * @dataProvider positive_match_data + */ + public function test_positive_match($email) + { + $this->assertEquals(1, preg_match($this->regex, $email)); + } + + /** + * @dataProvider negative_match_data + */ + public function test_negative_match($email) + { + $this->assertEquals(0, preg_match($this->regex, $email)); + } +} + diff --git a/tests/regex/ipv4.php b/tests/regex/ipv4.php new file mode 100644 index 0000000000..9d131ad0ca --- /dev/null +++ b/tests/regex/ipv4.php @@ -0,0 +1,72 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/functions.php'; + +class phpbb_regex_ipv4_test extends phpbb_test_case +{ + protected $regex; + + public function setUp() + { + $this->regex = get_preg_expression('ipv4'); + } + + public function positive_match_data() + { + return array( + array('0.0.0.0'), + array('127.0.0.1'), + array('192.168.0.1'), + array('255.255.255.255'), + ); + } + + public function negative_match_data() + { + return array( + // IPv6 addresses + array('2001:0db8:85a3:0000:0000:8a2e:0370:1337'), + array('2001:db8:85a3:c:d:8a2e:370:1337'), + array('2001:db8:85a3::8a2e:370:1337'), + array('2001:db8:0:1::192.168.0.2'), + array('0:0:0:0:0:0:0:1'), + array('0:0::0:0:1'), + array('::1'), + + // Out of scope + array('255.255.255.256'), + + // Other tests + array('a.b.c.d'), + array('11.22.33.'), + array('11.22.33'), + array('11.22'), + array('11'), + ); + } + + /** + * @dataProvider positive_match_data + */ + public function test_positive_match($address) + { + $this->assertEquals(1, preg_match($this->regex, $address)); + } + + /** + * @dataProvider negative_match_data + */ + public function test_negative_match($address) + { + $this->assertEquals(0, preg_match($this->regex, $address)); + } +} + diff --git a/tests/regex/ipv6.php b/tests/regex/ipv6.php new file mode 100644 index 0000000000..3d7a72e492 --- /dev/null +++ b/tests/regex/ipv6.php @@ -0,0 +1,143 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/functions.php'; + +class phpbb_regex_ipv6_test extends phpbb_test_case +{ + protected $regex; + + public function setUp() + { + $this->regex = get_preg_expression('ipv6'); + } + + public function positive_match_data() + { + return array( + // Full length IPv6 address + array('2001:0db8:85a3:0000:0000:8a2e:0370:1337'), + array('0000:0000:0000:0000:0000:0000:0000:0001'), + array('3FFE:0b00:0000:0000:0001:0000:0000:000a'), + array('3ffe:0b00:0000:0000:0001:0000:0000:000a'), + array('2002:0db8:0000:0000:0000:dead:1337:d00d'), + + // No leading zeroes in the group + array('2001:db8:85a3:0:0:8a2e:370:1337'), + array('2001:db8:85a3:c:d:8a2e:370:1337'), + + // Consecutive all-zero groups + array('2001:db8:85a3::8a2e:370:1337'), + array('1::2:3:4:5:6:7'), + array('1::2:3:4:5:6'), + array('1::2:3:4:5'), + array('1::2:3:4'), + array('1::2:3'), + array('1::2'), + + // Last 32bit in dotted quad notation + array('2001:db8:0:1::192.168.0.2'), + + // IPv4-compatible IPv6 address + array('::13.1.68.3'), + array('0:0:0:0:0:0:13.1.68.3'), + + // IPv4-mapped IPv6 address + array('::ffff:c000:280'), + array('::ffff:c000:0280'), + array('::ffff:192.0.2.128'), + array('0:0:0:0:0:ffff:c000:280'), + array('0:0:0:0:0:ffff:c000:0280'), + array('0:0:0:0:0:ffff:192.0.2.128'), + array('0000:0000:0000:0000:0000:ffff:c000:280'), + array('0000:0000:0000:0000:0000:ffff:c000:0280'), + array('0000:0000:0000:0000:0000:ffff:192.0.2.128'), + + // No trailing zeroes + array('fe80::'), + array('2002::'), + array('2001:db8::'), + array('2001:0db8:1234::'), + array('1:2:3:4:5:6::'), + array('1:2:3:4:5::'), + array('1:2:3:4::'), + array('1:2:3::'), + array('1:2::'), + + // No leading zeroes + array('::2:3:4:5:6:7:8'), + array('::2:3:4:5:6:7'), + array('::2:3:4:5:6'), + array('::2:3:4:5'), + array('::2:3:4'), + array('::2:3'), + array('::1'), + array('::8'), + array('::c'), + array('::abcd'), + + // All zeroes + array('::'), + array('0:0:0:0:0:0:0:0'), + array('0000:0000:0000:0000:0000:0000:0000:0000'), + + // More tests + array('2::10'), + array('0:0::0:0:1'), + array('0:0:0:0:0:0:0:1'), + array('::ffff:0:0'), + ); + } + + public function negative_match_data() + { + return array( + // Empty address + array(''), + + // IPv4 address + array('192.168.0.2'), + + // Out of scope + array('abcd:efgh:0000::0'), + array('::ffff:192.168.255.256'), + + // Double :: + array('2001::23de::2002'), + array('3ffe:b00::1::b'), + array('::1111:2222:3333:4444:5555:6666::'), + + // Too many blocks + array('2001:0db8:85a3:08d3:1319:8a2e:0370:1337:4430'), + + // More tests + array('02001:0000:1234:0000:0000:C1C0:ABCD:9876'), + array('2001:0000:1234: 0000:0000:C1C0:ABCD:9876'), + array('::ffff:192x168.255.255'), + ); + } + + /** + * @dataProvider positive_match_data + */ + public function test_positive_match($address) + { + $this->assertEquals(1, preg_match($this->regex, $address)); + } + + /** + * @dataProvider negative_match_data + */ + public function test_negative_match($address) + { + $this->assertEquals(0, preg_match($this->regex, $address)); + } +} + diff --git a/tests/regex/url.php b/tests/regex/url.php new file mode 100644 index 0000000000..678b7d108f --- /dev/null +++ b/tests/regex/url.php @@ -0,0 +1,34 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/functions.php'; + +class phpbb_regex_url_test extends phpbb_test_case +{ + public function url_test_data() + { + return array( + array('http://www.phpbb.com/community/', 1), + array('http://www.phpbb.com/path/file.ext#section', 1), + array('ftp://ftp.phpbb.com/', 1), + array('sip://bantu@phpbb.com', 1), + + array('www.phpbb.com/community/', 0), + ); + } + + /** + * @dataProvider url_test_data + */ + public function test_url($url, $expected) + { + $this->assertEquals($expected, preg_match('#^' . get_preg_expression('url') . '$#i', $url)); + } +} diff --git a/tests/request/all_tests.php b/tests/request/all_tests.php new file mode 100644 index 0000000000..1ee3029b36 --- /dev/null +++ b/tests/request/all_tests.php @@ -0,0 +1,41 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ + define('PHPUnit_MAIN_METHOD', 'phpbb_request_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'request/request_var.php'; + +class phpbb_request_all_tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite('phpBB Request Parameter Handling'); + + $suite->addTestSuite('phpbb_request_request_var_test'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_request_all_tests::main') +{ + phpbb_request_all_tests::main(); +} + diff --git a/tests/request/request_var.php b/tests/request/request_var.php new file mode 100644 index 0000000000..b1dacef3fd --- /dev/null +++ b/tests/request/request_var.php @@ -0,0 +1,180 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/functions.php'; + +class phpbb_request_request_var_test extends phpbb_test_case +{ + /** + * @dataProvider request_variables + */ + public function test_post($variable_value, $default, $multibyte, $expected) + { + $variable_name = 'name'; + $this->unset_variables($variable_name); + + $_POST[$variable_name] = $variable_value; + $_REQUEST[$variable_name] = $variable_value; + + $result = request_var($variable_name, $default, $multibyte); + + $label = 'Requesting POST variable, converting from ' . gettype($variable_value) . ' to ' . gettype($default) . (($multibyte) ? ' multibyte' : ''); + $this->assertEquals($expected, $result, $label); + } + + /** + * @dataProvider request_variables + */ + public function test_get($variable_value, $default, $multibyte, $expected) + { + $variable_name = 'name'; + $this->unset_variables($variable_name); + + $_GET[$variable_name] = $variable_value; + $_REQUEST[$variable_name] = $variable_value; + + $result = request_var($variable_name, $default, $multibyte); + + $label = 'Requesting GET variable, converting from ' . gettype($variable_value) . ' to ' . gettype($default) . (($multibyte) ? ' multibyte' : ''); + $this->assertEquals($expected, $result, $label); + } + + /** + * @dataProvider request_variables + */ + public function test_cookie($variable_value, $default, $multibyte, $expected) + { + $variable_name = 'name'; + $this->unset_variables($variable_name); + + $_GET[$variable_name] = false; + $_POST[$variable_name] = false; + $_REQUEST[$variable_name] = false; + $_COOKIE[$variable_name] = $variable_value; + + $result = request_var($variable_name, $default, $multibyte, true); + + $label = 'Requesting COOKIE variable, converting from ' . gettype($variable_value) . ' to ' . gettype($default) . (($multibyte) ? ' multibyte' : ''); + $this->assertEquals($expected, $result, $label); + } + + /** + * Helper for unsetting globals + */ + private function unset_variables($var) + { + unset($_GET[$var], $_POST[$var], $_REQUEST[$var], $_COOKIE[$var]); + } + + public static function request_variables() + { + return array( + // strings + array('abc', '', false, 'abc'), + array(' some spaces ', '', true, 'some spaces'), + array("\r\rsome\rcarriage\r\rreturns\r", '', true, "some\ncarriage\n\nreturns"), + array("\n\nsome\ncarriage\n\nreturns\n", '', true, "some\ncarriage\n\nreturns"), + array("\r\n\r\nsome\r\ncarriage\r\n\r\nreturns\r\n", '', true, "some\ncarriage\n\nreturns"), + array("we\xC2\xA1rd\xE1\x9A\x80ch\xCE\xB1r\xC2\xADacters", '', true, "we\xC2\xA1rd\xE1\x9A\x80ch\xCE\xB1r\xC2\xADacters"), + array("we\xC2\xA1rd\xE1\x9A\x80ch\xCE\xB1r\xC2\xADacters", '', false, "we??rd???ch??r??acters"), + array("Some <html> \"entities\" like &", '', true, "Some <html> "entities" like &"), + + // integers + array('1234', 0, false, 1234), + array('abc', 12, false, 0), + array('324abc', 0, false, 324), + + // string to array + array('123', array(0), false, array()), + array('123', array(''), false, array()), + + // 1 dimensional arrays + array( + // input: + array('123', 'abc'), + // default: + array(''), + false, + // expected: + array('123', 'abc') + ), + array( + // input: + array('123', 'abc'), + // default: + array(999), + false, + // expected: + array(123, 0) + ), + array( + // input: + array('xyz' => '123', 'abc' => 'abc'), + // default: + array('' => ''), + false, + // expected: + array('xyz' => '123', 'abc' => 'abc') + ), + array( + // input: + array('xyz' => '123', 'abc' => 'abc'), + // default: + array('' => 0), + false, + // expected: + array('xyz' => 123, 'abc' => 0) + ), + + // 2 dimensional arrays + array( + // input: + '', + // default: + array(array(0)), + false, + // expected: + array() + ), + array( + // input: + array( + 'xyz' => array('123', 'def'), + 'abc' => 'abc' + ), + // default: + array('' => array('')), + false, + // expected: + array( + 'xyz' => array('123', 'def'), + 'abc' => array() + ) + ), + array( + // input: + array( + 'xyz' => array('123', 'def'), + 'abc' => 'abc' + ), + // default: + array('' => array(0)), + false, + // expected: + array( + 'xyz' => array(123, 0), + 'abc' => array() + ) + ), + ); + } + +} + diff --git a/tests/security/all_tests.php b/tests/security/all_tests.php new file mode 100644 index 0000000000..8e3916733f --- /dev/null +++ b/tests/security/all_tests.php @@ -0,0 +1,86 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ + define('PHPUnit_MAIN_METHOD', 'phpbb_security_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'security/extract_current_page.php'; +require_once 'security/redirect.php'; + +class phpbb_security_all_tests extends PHPUnit_Framework_TestSuite +{ + /** + * Set up the required user object and server variables for the suites + */ + protected function setUp() + { + global $user, $phpbb_root_path; + + // Put this into a global function being run by every test to init a proper user session + $_SERVER['HTTP_HOST'] = 'localhost'; + $_SERVER['SERVER_NAME'] = 'localhost'; + $_SERVER['SERVER_ADDR'] = '127.0.0.1'; + $_SERVER['SERVER_PORT'] = 80; + $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; + $_SERVER['QUERY_STRING'] = ''; + $_SERVER['REQUEST_URI'] = '/tests/'; + $_SERVER['SCRIPT_NAME'] = '/tests/index.php'; + $_SERVER['PHP_SELF'] = '/tests/index.php'; + $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14'; + $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3'; + +/* + [HTTP_ACCEPT_ENCODING] => gzip,deflate + [HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.7 + DOCUMENT_ROOT] => /var/www/ + [SCRIPT_FILENAME] => /var/www/tests/index.php +*/ + + // Set no user and trick a bit to circumvent errors + $user = new user(); + $user->lang = true; + $user->browser = (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : ''; + $user->referer = (!empty($_SERVER['HTTP_REFERER'])) ? htmlspecialchars((string) $_SERVER['HTTP_REFERER']) : ''; + $user->forwarded_for = (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? (string) $_SERVER['HTTP_X_FORWARDED_FOR'] : ''; + $user->host = (!empty($_SERVER['HTTP_HOST'])) ? (string) strtolower($_SERVER['HTTP_HOST']) : ((!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME')); + $user->page = session::extract_current_page($phpbb_root_path); + } + + protected function tearDown() + { + global $user; + $user = NULL; + } + + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + // I bet there is a better method calling this... :) + $suite = new phpbb_security_all_tests('phpBB Security Fixes'); + + $suite->addTestSuite('phpbb_security_extract_current_page_test'); + $suite->addTestSuite('phpbb_security_redirect_test'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_security_all_tests::main') +{ + phpbb_security_all_tests::main(); +} diff --git a/tests/security/extract_current_page.php b/tests/security/extract_current_page.php new file mode 100644 index 0000000000..8c72fe1440 --- /dev/null +++ b/tests/security/extract_current_page.php @@ -0,0 +1,53 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; + +require_once '../phpBB/includes/functions.php'; +require_once '../phpBB/includes/session.php'; + +class phpbb_security_extract_current_page_test extends phpbb_test_case +{ + public static function security_variables() + { + return array( + array('http://localhost/phpBB/index.php', 'mark=forums&x="><script>alert(/XSS/);</script>', 'mark=forums&x=%22%3E%3Cscript%3Ealert(/XSS/);%3C/script%3E'), + array('http://localhost/phpBB/index.php', 'mark=forums&x=%22%3E%3Cscript%3Ealert(/XSS/);%3C/script%3E', 'mark=forums&x=%22%3E%3Cscript%3Ealert(/XSS/);%3C/script%3E'), + ); + } + + /** + * @dataProvider security_variables + */ + public function test_query_string_php_self($url, $query_string, $expected) + { + $_SERVER['PHP_SELF'] = $url; + $_SERVER['QUERY_STRING'] = $query_string; + + $result = session::extract_current_page('./'); + + $label = 'Running extract_current_page on ' . $query_string . ' with PHP_SELF filled.'; + $this->assertEquals($expected, $result['query_string'], $label); + } + + /** + * @dataProvider security_variables + */ + public function test_query_string_request_uri($url, $query_string, $expected) + { + $_SERVER['REQUEST_URI'] = $url . '?' . $query_string; + $_SERVER['QUERY_STRING'] = $query_string; + + $result = session::extract_current_page('./'); + + $label = 'Running extract_current_page on ' . $query_string . ' with REQUEST_URI filled.'; + $this->assertEquals($expected, $result['query_string'], $label); + } +} + diff --git a/tests/security/redirect.php b/tests/security/redirect.php new file mode 100644 index 0000000000..37b0a5bb41 --- /dev/null +++ b/tests/security/redirect.php @@ -0,0 +1,58 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; + +require_once '../phpBB/includes/functions.php'; +require_once '../phpBB/includes/session.php'; + +class phpbb_security_redirect_test extends phpbb_test_case +{ + public static function provider() + { + // array(Input -> redirect(), expected triggered error (else false), expected returned result url (else false)) + return array( + array('data://x', false, 'http://localhost/phpBB'), + array('bad://localhost/phpBB/index.php', 'Tried to redirect to potentially insecure url.', false), + array('http://www.otherdomain.com/somescript.php', false, 'http://localhost/phpBB'), + array("http://localhost/phpBB/memberlist.php\n\rConnection: close", 'Tried to redirect to potentially insecure url.', false), + array('javascript:test', false, 'http://localhost/phpBB/../tests/javascript:test'), + array('http://localhost/phpBB/index.php;url=', 'Tried to redirect to potentially insecure url.', false), + ); + } + + protected function setUp() + { + $GLOBALS['config'] = array( + 'force_server_vars' => '0', + ); + } + + /** + * @dataProvider provider + */ + public function test_redirect($test, $expected_error, $expected_result) + { + global $user; + + if ($expected_error !== false) + { + $this->setExpectedTriggerError(E_USER_ERROR, $expected_error); + } + + $result = redirect($test, true); + + // only verify result if we did not expect an error + if ($expected_error === false) + { + $this->assertEquals($expected_result, $result); + } + } +} + diff --git a/tests/template/all_tests.php b/tests/template/all_tests.php new file mode 100644 index 0000000000..ea258c1680 --- /dev/null +++ b/tests/template/all_tests.php @@ -0,0 +1,40 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ + define('PHPUnit_MAIN_METHOD', 'phpbb_template_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'template/template.php'; + +class phpbb_template_all_tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite('phpBB Template Engine'); + + $suite->addTestSuite('phpbb_template_template_test'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_template_all_tests::main') +{ + phpbb_template_all_tests::main(); +} diff --git a/tests/template/template.php b/tests/template/template.php new file mode 100644 index 0000000000..0c2ca8a032 --- /dev/null +++ b/tests/template/template.php @@ -0,0 +1,690 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; + +require_once '../phpBB/includes/template.php'; + +class phpbb_template_template_test extends phpbb_test_case +{ + private $template; + private $template_path; + + // Keep the contents of the cache for debugging? + const PRESERVE_CACHE = true; + + private function display($handle) + { + // allow the templates to throw notices + $error_level = error_reporting(); + error_reporting($error_level & ~E_NOTICE); + + ob_start(); + + try + { + $this->assertTrue($this->template->display($handle, false)); + } + catch (Exception $exception) + { + // reset the error level even when an error occured + // PHPUnit turns trigger_error into exceptions as well + error_reporting($error_level); + ob_end_clean(); + throw $exception; + } + + $result = self::trim_template_result(ob_get_clean()); + + // reset error level + error_reporting($error_level); + return $result; + } + + private static function trim_template_result($result) + { + return str_replace("\n\n", "\n", implode("\n", array_map('trim', explode("\n", trim($result))))); + } + + private function setup_engine() + { + $this->template_path = dirname(__FILE__) . '/templates'; + $this->template = new template(); + $this->template->set_custom_template($this->template_path, 'tests'); + } + + protected function setUp() + { + // Test the engine can be used + $this->setup_engine(); + + if (!is_writable(dirname($this->template->cachepath))) + { + $this->markTestSkipped("Template cache directory is not writable."); + } + + foreach (glob($this->template->cachepath . '*') as $file) + { + unlink($file); + } + + $GLOBALS['config'] = array( + 'load_tplcompile' => true, + 'tpl_allow_php' => false, + ); + } + + protected function tearDown() + { + if (is_object($this->template)) + { + foreach (glob($this->template->cachepath . '*') as $file) + { + unlink($file); + } + } + } + + /** + * @todo put test data into templates/xyz.test + */ + public static function template_data() + { + return array( + /* + array( + '', // File + array(), // vars + array(), // block vars + array(), // destroy + '', // Expected result + ), + */ + array( + 'basic.html', + array(), + array(), + array(), + "pass\npass\n<!-- DUMMY var -->", + ), + array( + 'variable.html', + array('VARIABLE' => 'value'), + array(), + array(), + 'value', + ), + array( + 'if.html', + array(), + array(), + array(), + '0', + ), + array( + 'if.html', + array('S_VALUE' => true), + array(), + array(), + "1\n0", + ), + array( + 'if.html', + array('S_VALUE' => true, 'S_OTHER_VALUE' => true), + array(), + array(), + '1', + ), + array( + 'if.html', + array('S_VALUE' => false, 'S_OTHER_VALUE' => true), + array(), + array(), + '2', + ), + array( + 'loop.html', + array(), + array(), + array(), + "noloop\nnoloop", + ), + array( + 'loop.html', + array(), + array('loop' => array(array())), + array(), + "loop\nloop", + ), + array( + 'loop.html', + array(), + array('loop' => array(array(), array()), 'loop.block' => array(array())), + array(), + "loop\nloop\nloop\nloop", + ), + array( + 'loop.html', + array(), + array('loop' => array(array(), array()), 'loop.block' => array(array()), 'block' => array(array(), array())), + array(), + "loop\nloop\nloop\nloop\nloop#0-block#0\nloop#0-block#1\nloop#1-block#0\nloop#1-block#1", + ), + array( + 'loop_vars.html', + array(), + array('loop' => array(array('VARIABLE' => 'x'))), + array(), + "first\n0\nx\nset\nlast", + ),/* no nested top level loops + array( + 'loop_vars.html', + array(), + array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y'))), + array(), + "first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast", + ), + array( + 'loop_vars.html', + array(), + array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())), + array(), + "first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast\n0\n\n1\nlast inner\ninner loop", + ),*/ + array( + 'loop_advanced.html', + array(), + array('loop' => array(array(), array(), array(), array(), array(), array(), array())), + array(), + "101234561\nx\n101234561\nx\n101234561\nx\n1234561\nx\n1\nx\n101\nx\n234\nx\n10\nx\n561\nx\n561", + ), + array( + 'define.html', + array(), + array('loop' => array(array(), array(), array(), array(), array(), array(), array()), 'test' => array(array()), 'test.deep' => array(array()), 'test.deep.defines' => array(array())), + array(), + "xyz\nabc", + ), + array( + 'expressions.html', + array(), + array(), + array(), + trim(str_repeat("pass", 39)), + ), + array( + 'php.html', + array(), + array(), + array(), + '', + ), + array( + 'include.html', + array('VARIABLE' => 'value'), + array(), + array(), + 'value', + ), + array( + 'loop_vars.html', + array(), + array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())), + array('loop'), + '', + ),/* no top level nested loops + array( + 'loop_vars.html', + array(), + array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())), + array('loop.inner'), + "first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast", + ),*/ + array( + 'lang.html', + array(), + array(), + array(), + "{ VARIABLE }\n{ VARIABLE }", + ), + array( + 'lang.html', + array('L_VARIABLE' => "Value'"), + array(), + array(), + "Value'\nValue\'", + ), + array( + 'lang.html', + array('LA_VARIABLE' => "Value'"), + array(), + array(), + "{ VARIABLE }\nValue'", + ), + ); + } + + public function test_missing_file() + { + $filename = 'file_not_found.html'; + + $this->template->set_filenames(array('test' => $filename)); + $this->assertFileNotExists($this->template_path . '/' . $filename, 'Testing missing file, file cannot exist'); + + $expecting = sprintf('template->_tpl_load_file(): File %s does not exist or is empty', realpath($this->template_path . '/../') . '/templates/' . $filename); + $this->setExpectedTriggerError(E_USER_ERROR, $expecting); + + $this->display('test'); + } + + public function test_empty_file() + { + $expecting = 'template->set_filenames: Empty filename specified for test'; + + $this->setExpectedTriggerError(E_USER_ERROR, $expecting); + $this->template->set_filenames(array('test' => '')); + } + + public function test_invalid_handle() + { + $expecting = 'template->_tpl_load(): No file specified for handle test'; + $this->setExpectedTriggerError(E_USER_ERROR, $expecting); + + $this->display('test'); + } + + private function run_template($file, array $vars, array $block_vars, array $destroy, $expected, $cache_file) + { + $this->template->set_filenames(array('test' => $file)); + $this->template->assign_vars($vars); + + foreach ($block_vars as $block => $loops) + { + foreach ($loops as $_vars) + { + $this->template->assign_block_vars($block, $_vars); + } + } + + foreach ($destroy as $block) + { + $this->template->destroy_block_vars($block); + } + + try + { + $this->assertEquals($expected, $this->display('test'), "Testing $file"); + $this->assertFileExists($cache_file); + } + catch (ErrorException $e) + { + if (file_exists($cache_file)) + { + copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file)); + } + + throw $e; + } + + // For debugging + if (self::PRESERVE_CACHE) + { + copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file)); + } + } + + /** + * @dataProvider template_data + */ + public function test_template($file, array $vars, array $block_vars, array $destroy, $expected) + { + global $phpEx; + $cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.' . $phpEx; + + $this->assertFileNotExists($cache_file); + + $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); + + // Reset the engine state + $this->setup_engine(); + + $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); + } + + /** + * @dataProvider template_data + */ + public function test_assign_display($file, array $vars, array $block_vars, array $destroy, $expected) + { + $this->template->set_filenames(array( + 'test' => $file, + 'container' => 'variable.html', + )); + $this->template->assign_vars($vars); + + foreach ($block_vars as $block => $loops) + { + foreach ($loops as $_vars) + { + $this->template->assign_block_vars($block, $_vars); + } + } + + foreach ($destroy as $block) + { + $this->template->destroy_block_vars($block); + } + + $error_level = error_reporting(); + error_reporting($error_level & ~E_NOTICE); + + $this->assertEquals($expected, self::trim_template_result($this->template->assign_display('test')), "Testing assign_display($file)"); + + $this->template->assign_display('test', 'VARIABLE', false); + + error_reporting($error_level); + + $this->assertEquals($expected, $this->display('container'), "Testing assign_display($file)"); + } + + public function test_php() + { + global $phpEx; + + $GLOBALS['config']['tpl_allow_php'] = true; + + $cache_file = $this->template->cachepath . 'php.html.' . $phpEx; + + $this->assertFileNotExists($cache_file); + + $this->run_template('php.html', array(), array(), array(), 'test', $cache_file); + + $GLOBALS['config']['tpl_allow_php'] = false; + } + + public function test_includephp() + { + $this->markTestIncomplete('Include PHP test file paths are broken'); + + $GLOBALS['config']['tpl_allow_php'] = true; + + $cache_file = $this->template->cachepath . 'includephp.html.' . PHP_EXT; + + $cwd = getcwd(); + chdir(dirname(__FILE__) . '/templates'); + + $this->run_template('includephp.html', array(), array(), array(), 'testing included php', $cache_file); + + $this->template->set_filenames(array('test' => 'includephp.html')); + $this->assertEquals('testing included php', $this->display('test'), "Testing $file"); + + chdir($cwd); + + $GLOBALS['config']['tpl_allow_php'] = false; + } + + public static function alter_block_array_data() + { + return array( + array( + 'outer', + array('VARIABLE' => 'before'), + false, + 'insert', + <<<EOT +outer - 0/4 - before +outer - 1/4 +middle - 0/2 +middle - 1/2 +outer - 2/4 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 3/4 +middle - 0/2 +middle - 1/2 +EOT +, + 'Test inserting before on top level block', + ), + array( + 'outer', + array('VARIABLE' => 'after'), + true, + 'insert', + <<<EOT +outer - 0/4 +middle - 0/2 +middle - 1/2 +outer - 1/4 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/4 +middle - 0/2 +middle - 1/2 +outer - 3/4 - after +EOT +, + 'Test inserting after on top level block', + ), + array( + 'outer', + array('VARIABLE' => 'pos #1'), + 1, + 'insert', + <<<EOT +outer - 0/4 +middle - 0/2 +middle - 1/2 +outer - 1/4 - pos #1 +outer - 2/4 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 3/4 +middle - 0/2 +middle - 1/2 +EOT +, + 'Test inserting at 1 on top level block', + ), + array( + 'outer', + array('VARIABLE' => 'pos #1'), + 0, + 'change', + <<<EOT +outer - 0/3 - pos #1 +middle - 0/2 +middle - 1/2 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, + 'Test inserting at 1 on top level block', + ), + array( + 'outer[0].middle', + array('VARIABLE' => 'before'), + false, + 'insert', + <<<EOT +outer - 0/3 +middle - 0/3 - before +middle - 1/3 +middle - 2/3 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, + 'Test inserting before on nested block', + ), + array( + 'outer[0].middle', + array('VARIABLE' => 'after'), + true, + 'insert', + <<<EOT +outer - 0/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 - after +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, + 'Test inserting after on nested block', + ), + array( + 'outer[0].middle', + array('VARIABLE' => 'pos #1'), + 1, + 'insert', + <<<EOT +outer - 0/3 +middle - 0/3 +middle - 1/3 - pos #1 +middle - 2/3 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, + 'Test inserting at pos 1 on nested block', + ), + array( + 'outer[1].middle', + array('VARIABLE' => 'before'), + false, + 'insert', + <<<EOT +outer - 0/3 +middle - 0/2 +middle - 1/2 +outer - 1/3 +middle - 0/4 - before +middle - 1/4 +middle - 2/4 +middle - 3/4 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, + 'Test inserting before on nested block (pos 1)', + ), + array( + 'outer[].middle', + array('VARIABLE' => 'before'), + false, + 'insert', + <<<EOT +outer - 0/3 +middle - 0/2 +middle - 1/2 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/3 - before +middle - 1/3 +middle - 2/3 +EOT +, + 'Test inserting before on nested block (end)', + ), + array( + 'outer.middle', + array('VARIABLE' => 'before'), + false, + 'insert', + <<<EOT +outer - 0/3 +middle - 0/2 +middle - 1/2 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/3 - before +middle - 1/3 +middle - 2/3 +EOT +, + 'Test inserting before on nested block (end)', + ), + ); + } + +/* + <<<EOT +outer - 0/3 +middle - 0/2 +middle - 1/2 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, +*/ + + /** + * @dataProvider alter_block_array_data + */ + public function test_alter_block_array($alter_block, array $vararray, $key, $mode, $expect, $description) + { + $this->markTestIncomplete('Alter Block Test is broken'); + + $this->template->set_filenames(array('test' => 'loop_nested.html')); + + // @todo Change this + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + + $this->assertEquals("outer - 0/3\nmiddle - 0/2\nmiddle - 1/2\nouter - 1/3\nmiddle - 0/3\nmiddle - 1/3\nmiddle - 2/3\nouter - 2/3\nmiddle - 0/2\nmiddle - 1/2", $this->display('test'), 'Ensuring template is built correctly before modification'); + + $this->template->alter_block_array($alter_block, $vararray, $key, $mode); + $this->assertEquals($expect, $this->display('test'), $description); + } +} + diff --git a/tests/template/templates/_dummy_include.php b/tests/template/templates/_dummy_include.php new file mode 100644 index 0000000000..1de5dddf59 --- /dev/null +++ b/tests/template/templates/_dummy_include.php @@ -0,0 +1,3 @@ +<?php + +echo "testing included php"; diff --git a/tests/template/templates/basic.html b/tests/template/templates/basic.html new file mode 100644 index 0000000000..c1dd690260 --- /dev/null +++ b/tests/template/templates/basic.html @@ -0,0 +1,20 @@ +<!-- IF S_FALSE --> +fail +<!-- ENDIF --> +<!-- IF S_TRUE --> +pass +<!-- ENDIF --> +<!-- IF S_FALSE --> +fail +<!-- ELSEIF S_FALSE and not S_TRUE --> +fail +<!-- ELSE --> +pass +<!-- ENDIF --> +<!-- BEGIN empty --> +fail +<!-- BEGINELSE --> +pass +<!-- END empty --> + +<!-- DUMMY var --> diff --git a/tests/template/templates/define.html b/tests/template/templates/define.html new file mode 100644 index 0000000000..82237d21a3 --- /dev/null +++ b/tests/template/templates/define.html @@ -0,0 +1,8 @@ +<!-- DEFINE $VALUE = 'xyz' --> +{$VALUE} +<!-- DEFINE $VALUE = 'abc' --> +{$VALUE} +<!-- UNDEFINE $VALUE --> +{$VALUE} +<!-- DEFINE $VALUE --> + diff --git a/tests/template/templates/expressions.html b/tests/template/templates/expressions.html new file mode 100644 index 0000000000..c40d967dab --- /dev/null +++ b/tests/template/templates/expressions.html @@ -0,0 +1,86 @@ +<!-- IF 10 is even -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 is even -->fail<!-- ELSE -->pass<!-- ENDIF --> + +<!-- IF not 390 is even -->fail<!-- ELSE -->pass<!-- ENDIF --> + +<!-- IF 9 is odd -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 32 is odd -->fail<!-- ELSE -->pass<!-- ENDIF --> + +<!-- IF 32 is div by 16 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 10 is not even -->fail<!-- ELSE -->pass<!-- ENDIF --> + +<!-- IF 24 == 24 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 24 eq 24 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF ((((((24 == 24)))))) -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 24 != 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 24 <> 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 24 ne 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 24 neq 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 10 lt 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 10 < 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 10 le 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 10 lte 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 10 <= 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 20 le 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 20 lte 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 20 <= 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 9 gt 1 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 > 1 -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 9 >= 1 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 gte 1 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 ge 1 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 >= 9 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 gte 9 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 ge 9 -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF true && (10 > 4) -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF true and (10 > 4) -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF false || true -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF false or true -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF !false -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF not false -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF not not not false -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 6 % 4 == 2 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 24 mod 12 == 0 -->pass<!-- ELSE -->fail<!-- ENDIF --> diff --git a/tests/template/templates/if.html b/tests/template/templates/if.html new file mode 100644 index 0000000000..c502e52f51 --- /dev/null +++ b/tests/template/templates/if.html @@ -0,0 +1,11 @@ +<!-- IF S_VALUE --> +1 +<!-- ELSEIF S_OTHER_VALUE --> +2 +<!-- ELSE --> +0 +<!-- ENDIF --> + +<!-- IF (S_VALUE > S_OTHER_VALUE) --> +0 +<!-- ENDIF --> diff --git a/tests/template/templates/include.html b/tests/template/templates/include.html new file mode 100644 index 0000000000..730d713d65 --- /dev/null +++ b/tests/template/templates/include.html @@ -0,0 +1 @@ +<!-- INCLUDE variable.html --> diff --git a/tests/template/templates/includephp.html b/tests/template/templates/includephp.html new file mode 100644 index 0000000000..3e13fa33fa --- /dev/null +++ b/tests/template/templates/includephp.html @@ -0,0 +1 @@ +<!-- INCLUDEPHP ../templates/_dummy_include.php --> diff --git a/tests/template/templates/lang.html b/tests/template/templates/lang.html new file mode 100644 index 0000000000..2b5ea1cafe --- /dev/null +++ b/tests/template/templates/lang.html @@ -0,0 +1,3 @@ +{L_VARIABLE} + +{LA_VARIABLE} diff --git a/tests/template/templates/loop.html b/tests/template/templates/loop.html new file mode 100644 index 0000000000..de1a10004d --- /dev/null +++ b/tests/template/templates/loop.html @@ -0,0 +1,21 @@ +<!-- BEGIN loop --> +loop +<!-- BEGINELSE --> +noloop +<!-- END loop --> + +<!-- IF .loop --> +loop +<!-- ELSE --> +noloop +<!-- ENDIF --> + +<!-- IF .loop == 2 --> +loop +<!-- ENDIF --> + +<!-- BEGIN loop --> +<!-- BEGIN !block --> +loop#{loop.S_ROW_COUNT}-block#{block.S_ROW_COUNT} +<!-- END !block --> +<!-- END loop --> diff --git a/tests/template/templates/loop_advanced.html b/tests/template/templates/loop_advanced.html new file mode 100644 index 0000000000..c75fe55f03 --- /dev/null +++ b/tests/template/templates/loop_advanced.html @@ -0,0 +1,19 @@ +<!-- BEGIN loop -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(0) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(0,-1) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(1) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(1,1) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(0,1) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(2,4) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(0,-7) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(-2,6) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(-2,-1) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> diff --git a/tests/template/templates/loop_nested.html b/tests/template/templates/loop_nested.html new file mode 100644 index 0000000000..571df97b4c --- /dev/null +++ b/tests/template/templates/loop_nested.html @@ -0,0 +1,8 @@ +<!-- BEGIN outer --> + {outer.S_BLOCK_NAME} - {outer.S_ROW_NUM}/{outer.S_NUM_ROWS}<!-- IF outer.VARIABLE --> - {outer.VARIABLE}<!-- ENDIF --> + + <!-- BEGIN middle --> + {middle.S_BLOCK_NAME} - {middle.S_ROW_NUM}/{middle.S_NUM_ROWS}<!-- IF middle.VARIABLE --> - {middle.VARIABLE}<!-- ENDIF --> + + <!-- END middle --> +<!-- END outer --> diff --git a/tests/template/templates/loop_vars.html b/tests/template/templates/loop_vars.html new file mode 100644 index 0000000000..4f02fd2e6c --- /dev/null +++ b/tests/template/templates/loop_vars.html @@ -0,0 +1,21 @@ +<!-- BEGIN loop --> +<!-- IF loop.S_FIRST_ROW -->first<!-- ENDIF --> + +{loop.S_ROW_COUNT} + +{loop.VARIABLE} + +<!-- IF loop.VARIABLE -->set<!-- ENDIF --> + +<!-- IF loop.S_LAST_ROW --> +last +<!-- ENDIF --> +<!-- BEGIN inner --> + +{inner.S_ROW_COUNT} + +<!-- IF inner.S_LAST_ROW and inner.S_ROW_COUNT and inner.S_NUM_ROWS -->last inner<!-- ENDIF --> + +<!-- END inner --> +<!-- END loop --> +<!-- IF .loop.inner -->inner loop<!-- ENDIF --> diff --git a/tests/template/templates/php.html b/tests/template/templates/php.html new file mode 100644 index 0000000000..07a260cdb3 --- /dev/null +++ b/tests/template/templates/php.html @@ -0,0 +1 @@ +<!-- PHP -->echo "test";<!-- ENDPHP --> diff --git a/tests/template/templates/variable.html b/tests/template/templates/variable.html new file mode 100644 index 0000000000..f68f91597c --- /dev/null +++ b/tests/template/templates/variable.html @@ -0,0 +1 @@ +{VARIABLE} diff --git a/tests/test_framework/framework.php b/tests/test_framework/framework.php new file mode 100644 index 0000000000..3a11cc6df9 --- /dev/null +++ b/tests/test_framework/framework.php @@ -0,0 +1,43 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +define('IN_PHPBB', true); +$phpbb_root_path = '../phpBB/'; +$phpEx = 'php'; +$table_prefix = ''; + +// If we are on PHP >= 6.0.0 we do not need some code +if (version_compare(PHP_VERSION, '6.0.0-dev', '>=')) +{ + define('STRIP', false); +} +else +{ + @set_magic_quotes_runtime(0); + define('STRIP', (get_magic_quotes_gpc()) ? true : false); +} + +require_once $phpbb_root_path . 'includes/constants.php'; + +// require at least PHPUnit 3.3.0 +require_once 'PHPUnit/Runner/Version.php'; +if (version_compare(PHPUnit_Runner_Version::id(), '3.3.0', '<')) +{ + trigger_error('PHPUnit >= 3.3.0 required'); +} + +if (version_compare(PHPUnit_Runner_Version::id(), '3.5.0', '<')) +{ + require_once 'PHPUnit/Framework.php'; + require_once 'PHPUnit/Extensions/Database/TestCase.php'; +} + +require_once 'test_framework/phpbb_test_case_helpers.php'; +require_once 'test_framework/phpbb_test_case.php'; +require_once 'test_framework/phpbb_database_test_case.php'; diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php new file mode 100644 index 0000000000..a64bae8c57 --- /dev/null +++ b/tests/test_framework/phpbb_database_test_case.php @@ -0,0 +1,376 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_TestCase +{ + private static $already_connected; + + protected $test_case_helpers; + + public function get_test_case_helpers() + { + if (!$this->test_case_helpers) + { + $this->test_case_helpers = new phpbb_test_case_helpers($this); + } + + return $this->test_case_helpers; + } + + public function get_dbms_data($dbms) + { + $available_dbms = array( + 'firebird' => array( + 'SCHEMA' => 'firebird', + 'DELIM' => ';;', + 'PDO' => 'firebird', + ), + 'mysqli' => array( + 'SCHEMA' => 'mysql_41', + 'DELIM' => ';', + 'PDO' => 'mysql', + ), + 'mysql' => array( + 'SCHEMA' => 'mysql', + 'DELIM' => ';', + 'PDO' => 'mysql', + ), + 'mssql' => array( + 'SCHEMA' => 'mssql', + 'DELIM' => 'GO', + 'PDO' => 'odbc', + ), + 'mssql_odbc'=> array( + 'SCHEMA' => 'mssql', + 'DELIM' => 'GO', + 'PDO' => 'odbc', + ), + 'mssqlnative' => array( + 'SCHEMA' => 'mssql', + 'DELIM' => 'GO', + 'PDO' => 'sqlsrv', + ), + 'oracle' => array( + 'SCHEMA' => 'oracle', + 'DELIM' => '/', + 'PDO' => 'oci', + ), + 'postgres' => array( + 'SCHEMA' => 'postgres', + 'DELIM' => ';', + 'PDO' => 'pgsql', + ), + 'sqlite' => array( + 'SCHEMA' => 'sqlite', + 'DELIM' => ';', + 'PDO' => 'sqlite2', + ), + ); + + if (isset($available_dbms[$dbms])) + { + return $available_dbms[$dbms]; + } + else + { + trigger_error('Database unsupported', E_USER_ERROR); + } + } + + public function get_database_config() + { + if (isset($_SERVER['PHPBB_TEST_DBMS'])) + { + return array( + 'dbms' => isset($_SERVER['PHPBB_TEST_DBMS']) ? $_SERVER['PHPBB_TEST_DBMS'] : '', + 'dbhost' => isset($_SERVER['PHPBB_TEST_DBHOST']) ? $_SERVER['PHPBB_TEST_DBHOST'] : '', + 'dbport' => isset($_SERVER['PHPBB_TEST_DBPORT']) ? $_SERVER['PHPBB_TEST_DBPORT'] : '', + 'dbname' => isset($_SERVER['PHPBB_TEST_DBNAME']) ? $_SERVER['PHPBB_TEST_DBNAME'] : '', + 'dbuser' => isset($_SERVER['PHPBB_TEST_DBUSER']) ? $_SERVER['PHPBB_TEST_DBUSER'] : '', + 'dbpasswd' => isset($_SERVER['PHPBB_TEST_DBPASSWD']) ? $_SERVER['PHPBB_TEST_DBPASSWD'] : '', + ); + } + else if (file_exists('test_config.php')) + { + include('test_config.php'); + + return array( + 'dbms' => $dbms, + 'dbhost' => $dbhost, + 'dbport' => $dbport, + 'dbname' => $dbname, + 'dbuser' => $dbuser, + 'dbpasswd' => $dbpasswd, + ); + } + else if (extension_loaded('sqlite') && version_compare(PHPUnit_Runner_Version::id(), '3.4.15', '>=')) + { + // Silently use sqlite + return array( + 'dbms' => 'sqlite', + 'dbhost' => 'phpbb_unit_tests.sqlite2', // filename + 'dbport' => '', + 'dbname' => '', + 'dbuser' => '', + 'dbpasswd' => '', + ); + } + else + { + $this->markTestSkipped('Missing test_config.php: See first error.'); + } + } + + // NOTE: This function is not the same as split_sql_file from functions_install + public function split_sql_file($sql, $dbms) + { + $dbms_data = $this->get_dbms_data($dbms); + + $sql = str_replace("\r" , '', $sql); + $data = preg_split('/' . preg_quote($dbms_data['DELIM'], '/') . '$/m', $sql); + + $data = array_map('trim', $data); + + // The empty case + $end_data = end($data); + + if (empty($end_data)) + { + unset($data[key($data)]); + } + + if ($dbms == 'sqlite') + { + // remove comment lines starting with # - they are not proper sqlite + // syntax and break sqlite2 + foreach ($data as $i => $query) + { + $data[$i] = preg_replace('/^#.*$/m', "\n", $query); + } + } + + return $data; + } + + /** + * Retrieves a list of all tables from the database. + * + * @param PDO $pdo + * @param string $dbms + * @return array(string) + */ + function get_tables($pdo, $dbms) + { + switch ($pdo) + { + case 'mysql': + case 'mysql4': + case 'mysqli': + $sql = 'SHOW TABLES'; + break; + + case 'sqlite': + $sql = 'SELECT name + FROM sqlite_master + WHERE type = "table"'; + break; + + case 'mssql': + case 'mssql_odbc': + case 'mssqlnative': + $sql = "SELECT name + FROM sysobjects + WHERE type='U'"; + break; + + case 'postgres': + $sql = 'SELECT relname + FROM pg_stat_user_tables'; + break; + + case 'firebird': + $sql = 'SELECT rdb$relation_name + FROM rdb$relations + WHERE rdb$view_source is null + AND rdb$system_flag = 0'; + break; + + case 'oracle': + $sql = 'SELECT table_name + FROM USER_TABLES'; + break; + } + + $result = $pdo->query($sql); + + $tables = array(); + while ($row = $result->fetch(PDO::FETCH_NUM)) + { + $tables[] = current($row); + } + + return $tables; + } + + /** + * Returns a PDO connection for the configured database. + * + * @param array $config The database configuration + * @param array $dbms Information on the used DBMS. + * @param bool $use_db Whether the DSN should be tied to a + * particular database making it impossible + * to delete that database. + * @return PDO The PDO database connection. + */ + public function new_pdo($config, $dbms, $use_db) + { + $dsn = $dbms['PDO'] . ':'; + + switch ($dbms['PDO']) + { + case 'sqlite2': + $dsn .= $config['dbhost']; + break; + + case 'sqlsrv': + // prefix the hostname (or DSN) with Server= so using just (local)\SQLExpress + // works for example, further parameters can still be appended using ;x=y + $dsn .= 'Server='; + // no break -> rest like ODBC + case 'odbc': + // for ODBC assume dbhost is a suitable DSN + // e.g. Driver={SQL Server Native Client 10.0};Server=(local)\SQLExpress; + $dsn .= $config['dbhost']; + + if ($use_db) + { + $dsn .= ';Database=' . $config['dbname']; + } + break; + + default: + $dsn .= 'host=' . $config['dbhost']; + + if ($use_db) + { + $dsn .= ';dbname=' . $config['dbname']; + } + break; + } + + $pdo = new PDO($dsn, $config['dbuser'], $config['dbpasswd']);; + + // good for debug + // $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + return $pdo; + } + + private function recreate_db($config, $dbms) + { + switch ($config['dbms']) + { + case 'sqlite': + if (file_exists($config['dbhost'])) + { + unlink($config['dbhost']); + } + break; + + default: + $pdo = $this->new_pdo($config, $dbms, false); + + try + { + $pdo->exec('DROP DATABASE ' . $config['dbname']); + } + catch (PDOException $e) + { + // try to delete all tables if dropping the database was not possible. + foreach ($this->get_tables() as $table) + { + try + { + $pdo->exec('DROP TABLE ' . $table); + } + catch (PDOException $e){} // ignore non-existent tables + } + } + + $pdo->exec('CREATE DATABASE ' . $config['dbname']); + break; + } + } + + private function load_schema($pdo, $config, $dbms) + { + if ($config['dbms'] == 'mysql') + { + $sth = $pdo->query('SELECT VERSION() AS version'); + $row = $sth->fetch(PDO::FETCH_ASSOC); + + if (version_compare($row['version'], '4.1.3', '>=')) + { + $dbms['SCHEMA'] .= '_41'; + } + else + { + $dbms['SCHEMA'] .= '_40'; + } + } + + $sql = $this->split_sql_file(file_get_contents("../phpBB/install/schemas/{$dbms['SCHEMA']}_schema.sql"), $config['dbms']); + + foreach ($sql as $query) + { + $pdo->exec($query); + } + } + + public function getConnection() + { + $config = $this->get_database_config(); + $dbms = $this->get_dbms_data($config['dbms']); + + if (!self::$already_connected) + { + $this->recreate_db($config, $dbms); + } + + $pdo = $this->new_pdo($config, $dbms, true); + + if (!self::$already_connected) + { + $this->load_schema($pdo, $config, $dbms); + + self::$already_connected = true; + } + + return $this->createDefaultDBConnection($pdo, 'testdb'); + } + + public function new_dbal() + { + global $phpbb_root_path, $phpEx; + + $config = $this->get_database_config(); + + require_once '../phpBB/includes/db/' . $config['dbms'] . '.php'; + $dbal = 'dbal_' . $config['dbms']; + $db = new $dbal(); + $db->sql_connect($config['dbhost'], $config['dbuser'], $config['dbpasswd'], $config['dbname'], $config['dbport']); + + return $db; + } + + public function setExpectedTriggerError($errno, $message = '') + { + $this->get_test_case_helpers()->setExpectedTriggerError($errno, $message); + } +} diff --git a/tests/test_framework/phpbb_test_case.php b/tests/test_framework/phpbb_test_case.php new file mode 100644 index 0000000000..fe90d321dc --- /dev/null +++ b/tests/test_framework/phpbb_test_case.php @@ -0,0 +1,28 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +class phpbb_test_case extends PHPUnit_Framework_TestCase +{ + protected $test_case_helpers; + + public function get_test_case_helpers() + { + if (!$this->test_case_helpers) + { + $this->test_case_helpers = new phpbb_test_case_helpers($this); + } + + return $this->test_case_helpers; + } + + public function setExpectedTriggerError($errno, $message = '') + { + $this->get_test_case_helpers()->setExpectedTriggerError($errno, $message); + } +} diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php new file mode 100644 index 0000000000..0acdce32e0 --- /dev/null +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -0,0 +1,44 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +class phpbb_test_case_helpers +{ + protected $expectedTriggerError = false; + + protected $test_case; + + public function __construct($test_case) + { + $this->test_case = $test_case; + } + + public function setExpectedTriggerError($errno, $message = '') + { + $exceptionName = ''; + switch ($errno) + { + case E_NOTICE: + case E_STRICT: + PHPUnit_Framework_Error_Notice::$enabled = true; + $exceptionName = 'PHPUnit_Framework_Error_Notice'; + break; + + case E_WARNING: + PHPUnit_Framework_Error_Warning::$enabled = true; + $exceptionName = 'PHPUnit_Framework_Error_Warning'; + break; + + default: + $exceptionName = 'PHPUnit_Framework_Error'; + break; + } + $this->expectedTriggerError = true; + $this->test_case->setExpectedException($exceptionName, (string) $message, $errno); + } +} diff --git a/tests/text_processing/all_tests.php b/tests/text_processing/all_tests.php new file mode 100644 index 0000000000..5e759c72ee --- /dev/null +++ b/tests/text_processing/all_tests.php @@ -0,0 +1,41 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ + define('PHPUnit_MAIN_METHOD', 'phpbb_text_processing_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'text_processing/make_clickable.php'; + +class phpbb_text_processing_all_tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite('phpBB Text Processing Tools'); + + $suite->addTestSuite('phpbb_text_processing_make_clickable_test'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_text_processing_all_tests::main') +{ + phpbb_text_processing_all_tests::main(); +} + diff --git a/tests/text_processing/make_clickable.php b/tests/text_processing/make_clickable.php new file mode 100644 index 0000000000..a667dd705e --- /dev/null +++ b/tests/text_processing/make_clickable.php @@ -0,0 +1,106 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; + +require_once '../phpBB/includes/functions.php'; +require_once '../phpBB/includes/functions_content.php'; + +class phpbb_text_processing_make_clickable_test extends phpbb_test_case +{ + public static function make_clickable_data() + { + // value => whether it should work + $prefix_texts = array( + '' => true, + "np \n" => true, + 'bp text ' => true, + 'cp text>' => true, + 'ep text.' => array('w' => false), // doesn't work for www. type urls, but for everything else + ); + $suffix_texts = array( + '' => true, + "\n ns" => true, + ' bs text.' => true, + '>cs text' => true, + '"ds text' => true, + '. es text.' => true, + ', fs text.' => true, + ); + + $urls = array( + 'http://example.com' => array('tag' => 'm', 'url' => false, 'text' => false), // false means same as key + 'http://example.com/' => array('tag' => 'm', 'url' => false, 'text' => false), + 'http://example.com/path?query=abc' => array('tag' => 'm', 'url' => false, 'text' => false), + 'http://example.com/1' => array('tag' => 'm', 'url' => false, 'text' => false), + 'http://example.com/some/very/long/path/with/over/55/characters?and=a&long=query&too=1' => array('tag' => 'm', 'url' => false, 'text' => 'http://example.com/some/very/long/path/ ... uery&too=1'), + 'http://localhost' => array('tag' => 'm', 'url' => false, 'text' => false), + 'http://localhost/#abc' => array('tag' => 'm', 'url' => false, 'text' => false), + + 'www.example.com/path/' => array('tag' => 'w', 'url' => 'http://www.example.com/path/', 'text' => false), + 'randomwww.example.com/path/' => false, + + 'http://thisdomain.org' => array('tag' => 'm', 'url' => false, 'text' => false), + 'http://thisdomain.org/' => array('tag' => 'm', 'url' => false, 'text' => false), + 'http://thisdomain.org/1' => array('tag' => 'l', 'url' => false, 'text' => '1'), + 'http://thisdomain.org/path/some?query=abc#test' => array('tag' => 'l', 'url' => false, 'text' => 'path/some?query=abc#test'), + + 'javascript:www.example.com/' => false, + ); + + $test_data = array(); + + // run the test for each combination + foreach ($prefix_texts as $prefix => $prefix_success) + { + foreach ($suffix_texts as $suffix => $suffix_success) + { + foreach ($urls as $url => $url_type) + { + $input = $prefix . $url . $suffix; + // no valid url => no change + $output = $input; + + if ( + ($prefix_success && $suffix_success && is_array($url_type)) && + // handle except syntax for prefix/suffix + (!is_array($prefix_success) || !isset($prefix_success[$url_type['tag']]) || $prefix_success[$url_type['tag']] == true) && + (!is_array($suffix_success) || !isset($suffix_success[$url_type['tag']]) || $suffix_success[$url_type['tag']] == true) + ) + { + // false means it's the same as the url, less typing + $url_type['url'] = ($url_type['url']) ? $url_type['url'] : $url; + $url_type['text'] = ($url_type['text']) ? $url_type['text'] : $url; + + $class = ($url_type['tag'] === 'l') ? 'postlink-local' : 'postlink'; + + // replace the url with the desired output format + $output = $prefix . '<!-- ' . $url_type['tag'] . ' --><a class="' . $class . '" href="' . $url_type['url'] . '">' . $url_type['text'] . '</a><!-- ' . $url_type['tag'] . ' -->' . $suffix; + } + $test_data[] = array($input, $output); + } + } + } + + return $test_data; + } + + /** + * @dataProvider make_clickable_data + */ + public function test_make_clickable($input, $expected) + { + $result = make_clickable($input, 'http://thisdomain.org'); + + $label = 'Making text clickable: ' . $input; + $this->assertEquals($expected, $result, $label); + } + +} + diff --git a/tests/utf/all_tests.php b/tests/utf/all_tests.php new file mode 100644 index 0000000000..0d5d44d695 --- /dev/null +++ b/tests/utf/all_tests.php @@ -0,0 +1,43 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ + define('PHPUnit_MAIN_METHOD', 'phpbb_utf_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'utf/utf8_wordwrap_test.php'; +require_once 'utf/utf8_clean_string_test.php'; + +class phpbb_utf_all_tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite('phpBB Unicode Transformation Format'); + + $suite->addTestSuite('phpbb_utf_utf8_wordwrap_test'); + $suite->addTestSuite('phpbb_utf_utf8_clean_string_test'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_utf_all_tests::main') +{ + phpbb_utf_all_tests::main(); +} + diff --git a/tests/utf/utf8_clean_string_test.php b/tests/utf/utf8_clean_string_test.php new file mode 100644 index 0000000000..870ad76fc4 --- /dev/null +++ b/tests/utf/utf8_clean_string_test.php @@ -0,0 +1,32 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/utf/utf_tools.php'; + +class phpbb_utf_utf8_clean_string_test extends phpbb_test_case +{ + public static function cleanable_strings() + { + return array( + array('MiXed CaSe', 'mixed case', 'Checking case folding'), + array(' many spaces ', 'many spaces', 'Checking whitespace reduction'), + array("we\xC2\xA1rd\xE1\x9A\x80ch\xCE\xB1r\xC2\xADacters", 'weird characters', 'Checking confusables replacement'), + ); + } + + /** + * @dataProvider cleanable_strings + */ + public function test_utf8_clean_string($input, $output, $label) + { + $this->assertEquals($output, utf8_clean_string($input), $label); + } +} + diff --git a/tests/utf/utf8_wordwrap_test.php b/tests/utf/utf8_wordwrap_test.php new file mode 100644 index 0000000000..ef1165a897 --- /dev/null +++ b/tests/utf/utf8_wordwrap_test.php @@ -0,0 +1,84 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/utf/utf_tools.php'; + +class phpbb_utf_utf8_wordwrap_test extends phpbb_test_case +{ + public function test_utf8_wordwrap_ascii() + { + // if the input is all ascii it should work exactly like php's wordwrap + + $text = 'The quick brown fox jumped over the lazy dog.'; + + $php_wordwrap = wordwrap($text, 20); + $phpbb_utf8_wordwrap = utf8_wordwrap($text, 20); + $this->assertEquals($php_wordwrap, $phpbb_utf8_wordwrap, "Checking ASCII standard behaviour with length 20"); + + $php_wordwrap = wordwrap($text, 30, "<br />\n"); + $phpbb_utf8_wordwrap = utf8_wordwrap($text, 30, "<br />\n"); + $this->assertEquals($php_wordwrap, $phpbb_utf8_wordwrap, "Checking ASCII special break string with length 30"); + + $text = 'A very long woooooooooooord.'; + + $php_wordwrap = wordwrap($text, 8, "\n"); + $phpbb_utf8_wordwrap = utf8_wordwrap($text, 8, "\n"); + $this->assertEquals($php_wordwrap, $phpbb_utf8_wordwrap, 'Checking ASCII not cutting long words'); + + $php_wordwrap = wordwrap($text, 8, "\n", true); + $phpbb_utf8_wordwrap = utf8_wordwrap($text, 8, "\n", true); + $this->assertEquals($php_wordwrap, $phpbb_utf8_wordwrap, 'Checking ASCII cutting long words'); + } + + /** + * Helper function that generates meaningless greek text + */ + private function turn_into_greek($string) + { + $greek_chars = array("\xCE\x90", "\xCE\x91", "\xCE\x92", "\xCE\x93", "\xCE\x94", "\xCE\x95", "\xCE\x96", "\xCE\x97", "\xCE\x98", "\xCE\x99"); + + $greek = ''; + for ($i = 0, $n = strlen($string); $i < $n; $i++) + { + // replace each number with the character from the array + if (ctype_digit($string[$i])) + { + $greek .= $greek_chars[(int) $string[$i]]; + } + else + { + $greek .= $string[$i]; + } + } + + return $greek; + } + + public function test_utf8_wordwrap_utf8() + { + $text = "0123456 0123 012345 01234"; + $greek = $this->turn_into_greek($text); + + $expected = $this->turn_into_greek(wordwrap($text, 10)); + $phpbb_utf8_wordwrap = utf8_wordwrap($greek, 10); + $this->assertEquals($expected, $phpbb_utf8_wordwrap, 'Checking UTF-8 standard behaviour with length 10'); + } + + public function test_utf8_wordwrap_utf8_cut() + { + $text = "0123456 0123 012345 01234"; + $greek = $this->turn_into_greek($text); + + $expected = $this->turn_into_greek(wordwrap($text, 5, "\n", true)); + $phpbb_utf8_wordwrap = utf8_wordwrap($greek, 5, "\n", true); + $this->assertEquals($expected, $phpbb_utf8_wordwrap, 'Checking UTF-8 cutting long words'); + } +} + |