diff options
Diffstat (limited to 'tests')
242 files changed, 10368 insertions, 499 deletions
diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.txt index 59197acc0f..cede81d59d 100644 --- a/tests/RUNNING_TESTS.txt +++ b/tests/RUNNING_TESTS.txt @@ -17,45 +17,111 @@ 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 +- ctype (also a PHPUnit dependency) +- dom (PHPUnit dependency) +- json (also a phpBB dependency) + +Some of the functionality in phpBB and/or the test suite uses additional +PHP extensions. If these extensions are not loaded, respective tests +will be skipped: + +- apc (APC cache driver) +- bz2 (compress tests) +- interbase, pdo_firebird (Firebird database driver) +- mysql, pdo_mysql (MySQL database driver) +- mysqli, pdo_mysql (MySQLi database driver) +- pcntl (flock class) +- pdo (any database tests) +- pgsql, pdo_pgsql (PostgreSQL database driver) +- redis (https://github.com/nicolasff/phpredis, Redis cache driver) +- simplexml (any database tests) +- sqlite, pdo_sqlite (SQLite database driver, requires SQLite 2.x support +  in pdo_sqlite) +- zlib (compress tests)  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). +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'; +    $dbms = 'phpbb_db_driver_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: +It is possible to have multiple test_config.php files, for example if you +are testing on multiple databases. You can specify which test_config.php file +to use in the environment as follows: + +    $ PHPBB_TEST_CONFIG=tests/test_config.php phpunit + +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 +Special Database Cases +---------------------- +In order to run tests on some of the databases that we support, it will be +necessary to provide a custom DSN string in test_config.php. This is only +needed for MSSQL 2000+ (PHP module), MSSQL via ODBC, and Firebird when +PDO_Firebird does not work on your system +(https://bugs.php.net/bug.php?id=61183). The variable must be named $custom_dsn. + +Examples: +Firebird using http://www.firebirdsql.org/en/odbc-driver/ +$custom_dsn = "Driver={Firebird/InterBase(r) driver};dbname=$dbhost:$dbname"; + +MSSQL +$custom_dsn = "Driver={SQL Server Native Client 10.0};Server=$dbhost;Database=$dbname"; + +The other fields in test_config.php should be filled out as you would normally +to connect to that database in phpBB. + +Additionally, you will need to be running the DbUnit fork from +https://github.com/phpbb/dbunit/tree/phpbb. + +Redis +----- + +In order to run tests for the Redis cache driver, at least one of Redis host +or port must be specified in test configuration. This can be done via +test_config.php as follows: + +    <?php +    $phpbb_redis_host = 'localhost'; +    $phpbb_redis_port = 6379; + +Or via environment variables as follows: + +    $ PHPBB_TEST_REDIS_HOST=localhost PHPBB_TEST_REDIS_PORT=6379 phpunit +  Running  ======= -Once the prerequisites are installed, run the tests from the project root directory (above phpBB): +Once the prerequisites are installed, run the tests from the project root +directory (above phpBB):      $ phpunit  Slow tests  -------------- +  Certain tests, such as the UTF-8 normalizer or the DNS tests tend to be slow.  Thus these tests are in the `slow` group, which is excluded by default. You can -enable slow tests by copying the phpunit.xml.all file to phpunit.xml. If you only -want the slow tests, run: +enable slow tests by copying the phpunit.xml.all file to phpunit.xml. If you +only want the slow tests, run:      $ phpunit --group slow @@ -63,4 +129,4 @@ More Information  ================  Further information is available on phpbb wiki: -http://wiki.phpbb.com/display/DEV/Unit+Tests +http://wiki.phpbb.com/Unit_Tests diff --git a/tests/bbcode/parser_test.php b/tests/bbcode/parser_test.php new file mode 100644 index 0000000000..d0dcce5bbf --- /dev/null +++ b/tests/bbcode/parser_test.php @@ -0,0 +1,265 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/bbcode.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/message_parser.php'; + +class phpbb_bbcode_parser_test extends PHPUnit_Framework_TestCase +{ +	public function bbcode_firstpass_data() +	{ +		return array( +			// Default bbcodes from in their simplest way +			array( +				'Test default bbcodes: simple bold', +				'[b]bold[/b]', +				'[b:]bold[/b:]', +			), +			array( +				'Test default bbcodes: simple underlined', +				'[u]underlined[/u]', +				'[u:]underlined[/u:]', +			), +			array( +				'Test default bbcodes: simple italic', +				'[i]italic[/i]', +				'[i:]italic[/i:]', +			), +			array( +				'Test default bbcodes: simple color rgb', +				'[color=#FF0000]colored[/color]', +				'[color=#FF0000:]colored[/color:]', +			), +			array( +				'Test default bbcodes: simple color name', +				'[color=red]colored[/color]', +				'[color=red:]colored[/color:]', +			), +			array( +				'Test default bbcodes: simple size', +				'[size=75]smaller[/size]', +				'[size=75:]smaller[/size:]', +			), +			array( +				'Test default bbcodes: simple quote', +				'[quote]quoted[/quote]', +				'[quote:]quoted[/quote:]', +			), +			array( +				'Test default bbcodes: simple quote with username', +				'[quote="username"]quoted[/quote]', +				'[quote="username":]quoted[/quote:]', +			), +			array( +				'Test default bbcodes: simple code', +				'[code]unparsed code[/code]', +				'[code:]unparsed code[/code:]', +			), +			array( +				'Test default bbcodes: simple php code', +				'[code=php]unparsed code[/code]', +				'[code=php:]<span class="syntaxdefault">unparsed code</span>[/code:]', +			), +			array( +				'Test default bbcodes: simple list', +				'[list]no item[/list]', +				'[list:]no item[/list:u:]', +			), +			array( +				'Test default bbcodes: simple list-item only', +				'[*]unparsed', +				'[*]unparsed', +			), +			array( +				'Test default bbcodes: simple list-item', +				'[list][*]item[/list]', +				'[list:][*:]item[/*:m:][/list:u:]', +			), +			array( +				'Test default bbcodes: simple list-item closed', +				'[list][*]item[/*][/list]', +				'[list:][*:]item[/*:][/list:u:]', +			), +			array( +				'Test default bbcodes: simple list-item numbered', +				'[list=1][*]item[/list]', +				'[list=1:][*:]item[/*:m:][/list:o:]', +			), +			array( +				'Test default bbcodes: simple list-item alpha', +				'[list=a][*]item[/list]', +				'[list=a:][*:]item[/*:m:][/list:o:]', +			), +			array( +				'Test default bbcodes: simple list-item roman', +				'[list=i][*]item[/list]', +				'[list=i:][*:]item[/*:m:][/list:o:]', +			), +			array( +				'Test default bbcodes: simple list-item disc', +				'[list=disc][*]item[/list]', +				'[list=disc:][*:]item[/*:m:][/list:u:]', +			), +			array( +				'Test default bbcodes: simple list-item circle', +				'[list=circle][*]item[/list]', +				'[list=circle:][*:]item[/*:m:][/list:u:]', +			), +			array( +				'Test default bbcodes: simple list-item square', +				'[list=square][*]item[/list]', +				'[list=square:][*:]item[/*:m:][/list:u:]', +			), +			array( +				'Test default bbcodes: simple img', +				'[img]https://area51.phpbb.com/images/area51.png[/img]', +				'[img:]https://area51.phpbb.com/images/area51.png[/img:]', +			), +			array( +				'Test default bbcodes: simple url', +				'[url]https://area51.phpbb.com/[/url]', +				'[url:]https://area51.phpbb.com/[/url:]', +			), +			array( +				'Test default bbcodes: simple url with description', +				'[url=https://area51.phpbb.com/]Area51[/url]', +				'[url=https://area51.phpbb.com/:]Area51[/url:]', +			), +			array( +				'Test default bbcodes: simple email', +				'[email]bbcode-test@phpbb.com[/email]', +				'[email:]bbcode-test@phpbb.com[/email:]', +			), +			array( +				'Test default bbcodes: simple email with description', +				'[email=bbcode-test@phpbb.com]Email[/email]', +				'[email=bbcode-test@phpbb.com:]Email[/email:]', +			), +			array( +				'Test default bbcodes: simple attachment', +				'[attachment=0]filename[/attachment]', +				'[attachment=0:]<!-- ia0 -->filename<!-- ia0 -->[/attachment:]', +			), + +			// Special cases for quote which were reported as bugs before +			array( +				'PHPBB3-1401 - correct: parsed', +				'[quote="[test]test"]test [ test[/quote]', +				'[quote="[test]test":]test [ test[/quote:]', +			), +			array( +				'PHPBB3-6117 - correct: parsed', +				'[quote]test[/quote] test ] and [ test [quote]test[/quote]', +				'[quote:]test[/quote:] test ] and [ test [quote:]test[/quote:]', +			), +			array( +				'PHPBB3-6200 - correct: parsed', +				'[quote="["]test[/quote]', +				'[quote="[":]test[/quote:]', +			), +			array( +				'PHPBB3-9364 - quoted: "test[/[/b]quote] test" / non-quoted: "[/quote] test" - also failed if layout distorted', +				'[quote]test[/[/b]quote] test [/quote][/quote] test', +				'[quote:]test[/[/b]quote] test [/quote:][/quote] test', +			), +			array( +				'PHPBB3-8096 - first quote tag parsed, second quote tag unparsed', +				'[quote="a"]a[/quote][quote="a]a[/quote]', +				'[quote="a":]a[/quote:][quote="a]a[/quote]', +			), + +			// Simple bbcodes nesting +			array( +				'Allow textual bbcodes in textual bbcodes', +				'[b]bold [i]bold + italic[/i][/b]', +				'[b:]bold [i:]bold + italic[/i:][/b:]', +			), +			array( +				'Allow textual bbcodes in url with description', +				'[url=https://area51.phpbb.com/]Area51 [i]italic[/i][/url]', +				'[url=https://area51.phpbb.com/:]Area51 [i:]italic[/i:][/url:]', +			), +			array( +				'Allow url with description in textual bbcodes', +				'[i]italic [url=https://area51.phpbb.com/]Area51[/url][/i]', +				'[i:]italic [url=https://area51.phpbb.com/:]Area51[/url:][/i:]', +			), + +			// Nesting bbcodes into quote usernames +			array( +				'Allow textual bbcodes in usernames', +				'[quote="[i]test[/i]"]test[/quote]', +				'[quote="[i:]test[/i:]":]test[/quote:]', +			), +			array( +				'Allow links bbcodes in usernames', +				'[quote="[url=https://area51.phpbb.com/]test[/url]"]test[/quote]', +				'[quote="[url=https://area51.phpbb.com/:]test[/url:]":]test[/quote:]', +			), +			array( +				'Allow img bbcodes in usernames - Username displayed the image', +				'[quote="[img]https://area51.phpbb.com/images/area51.png[/img]"]test[/quote]', +				'[quote="[img:]https://area51.phpbb.com/images/area51.png[/img:]":]test[/quote:]', +			), +			array( +				'Disallow flash bbcodes in usernames - Username displayed as [flash]http://www.phpbb.com/[/flash]', +				'[quote="[flash]http://www.phpbb.com/[/flash]"]test[/quote]', +				'[quote="[flash]http://www.phpbb.com/[/flash]":]test[/quote:]', +			), +			array( +				'Disallow quote bbcodes in usernames - Username displayed as [quote]test[/quote]', +				'[quote="[quote]test[/quote]"]test[/quote]', +				'[quote="[quote]test[/quote]":]test[/quote:]', +			), + +			// Do not parse bbcodes in code boxes +			array( +				'Do not parse textual bbcodes in code', +				'[code]unparsed code [b]bold [i]bold + italic[/i][/b][/code]', +				'[code:]unparsed code [b]bold [i]bold + italic[/i][/b][/code:]', +			), +			array( +				'Do not parse quote bbcodes in code', +				'[code]unparsed code [quote="username"]quoted[/quote][/code]', +				'[code:]unparsed code [quote="username"]quoted[/quote][/code:]', +			), + +			// New user friendly mixed nesting +			array( +				'Textual bbcode nesting into textual bbcode', +				'[b]bold [i]bold + italic[/b] italic[/i]', +				'[b:]bold [i:]bold + italic[/b:] italic[/i:]', +				'Incomplete test case: secondpass parses as [b:]bold [i:]bold + italic[/i:] italic[/b:]', +			), +		); +	} + +	/** +	* @dataProvider bbcode_firstpass_data +	*/ +	public function test_bbcode_firstpass($description, $message, $expected, $incomplete = false) +	{ +		if ($incomplete) +		{ +			$this->markTestIncomplete($incomplete); +		} + +		global $user, $request; +		$user = new phpbb_mock_user; +		$request = new phpbb_mock_request; + +		$bbcode = new bbcode_firstpass(); +		$bbcode->message = $message; +		$bbcode->bbcode_init(false); +		$bbcode->parse_bbcode(); +		$this->assertEquals($expected, $bbcode->message); +	} +} diff --git a/tests/bbcode/url_bbcode_test.php b/tests/bbcode/url_bbcode_test.php index 15bdfc434f..d5df386714 100644 --- a/tests/bbcode/url_bbcode_test.php +++ b/tests/bbcode/url_bbcode_test.php @@ -11,7 +11,6 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';  require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php';  require_once dirname(__FILE__) . '/../../phpBB/includes/bbcode.php';  require_once dirname(__FILE__) . '/../../phpBB/includes/message_parser.php'; -require_once dirname(__FILE__) . '/../mock_user.php';  class phpbb_url_bbcode_test extends phpbb_test_case  { @@ -51,8 +50,9 @@ class phpbb_url_bbcode_test extends phpbb_test_case  	*/  	public function test_url($description, $message, $expected)  	{ -		global $user; +		global $user, $request;  		$user = new phpbb_mock_user; +		$request = new phpbb_mock_request;  		$bbcode = new bbcode_firstpass();  		$bbcode->message = $message; diff --git a/tests/bootstrap.php b/tests/bootstrap.php index d6c5d25bc8..1017e0c72f 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -14,13 +14,17 @@ require_once $phpbb_root_path . 'includes/startup.php';  $table_prefix = 'phpbb_';  require_once $phpbb_root_path . 'includes/constants.php'; +require_once $phpbb_root_path . 'includes/class_loader.' . $phpEx; + +$phpbb_class_loader_mock = new phpbb_class_loader('phpbb_mock_', $phpbb_root_path . '../tests/mock/', ".php"); +$phpbb_class_loader_mock->register(); +$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', $phpbb_root_path . 'ext/', ".php"); +$phpbb_class_loader_ext->register(); +$phpbb_class_loader = new phpbb_class_loader('phpbb_', $phpbb_root_path . 'includes/', ".php"); +$phpbb_class_loader->register();  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';  require_once 'test_framework/phpbb_database_test_connection_manager.php'; - -if (version_compare(PHP_VERSION, '5.3.0-dev', '>=')) -{ -	require_once 'test_framework/phpbb_functional_test_case.php'; -} +require_once 'test_framework/phpbb_functional_test_case.php'; diff --git a/tests/cache/apc_driver_test.php b/tests/cache/apc_driver_test.php new file mode 100644 index 0000000000..3380762878 --- /dev/null +++ b/tests/cache/apc_driver_test.php @@ -0,0 +1,53 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +// Important: apc.enable_cli=1 must be in php.ini. +// http://forums.devshed.com/php-development-5/apc-problem-561290.html +// http://php.net/manual/en/apc.configuration.php + +require_once dirname(__FILE__) . '/common_test_case.php'; + +class phpbb_cache_apc_driver_test extends phpbb_cache_common_test_case +{ +	protected static $config; +	protected $driver; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/config.xml'); +	} + +	static public function setUpBeforeClass() +	{ +		if (!extension_loaded('apc')) +		{ +			self::markTestSkipped('APC extension is not loaded'); +		} + +		$php_ini = new phpbb_php_ini; + +		if (!$php_ini->get_bool('apc.enabled')) +		{ +			self::markTestSkipped('APC is not enabled. Make sure apc.enabled=1 in php.ini'); +		} + +		if (PHP_SAPI == 'cli' && !$php_ini->get_bool('apc.enable_cli')) +		{ +			self::markTestSkipped('APC is not enabled for CLI. Set apc.enable_cli=1 in php.ini'); +		} +	} + +	protected function setUp() +	{ +		parent::setUp(); + +		$this->driver = new phpbb_cache_driver_apc; +		$this->driver->purge(); +	} +} diff --git a/tests/cache/common_test_case.php b/tests/cache/common_test_case.php new file mode 100644 index 0000000000..a5bc2bfda9 --- /dev/null +++ b/tests/cache/common_test_case.php @@ -0,0 +1,98 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +abstract class phpbb_cache_common_test_case extends phpbb_database_test_case +{ +	public function test_get_put_exists() +	{ +		$this->assertFalse($this->driver->_exists('test_key')); +		$this->assertSame(false, $this->driver->get('test_key')); + +		$this->driver->put('test_key', 'test_value'); + +		$this->assertTrue($this->driver->_exists('test_key')); +		$this->assertEquals( +			'test_value', +			$this->driver->get('test_key'), +			'File ACM put and get' +		); +	} + +	public function test_purge() +	{ +		$this->driver->put('test_key', 'test_value'); + +		$this->assertEquals( +			'test_value', +			$this->driver->get('test_key'), +			'File ACM put and get' +		); + +		$this->driver->purge(); + +		$this->assertSame(false, $this->driver->get('test_key')); +	} + +	public function test_destroy() +	{ +		$this->driver->put('first_key', 'first_value'); +		$this->driver->put('second_key', 'second_value'); + +		$this->assertEquals( +			'first_value', +			$this->driver->get('first_key') +		); +		$this->assertEquals( +			'second_value', +			$this->driver->get('second_key') +		); + +		$this->driver->destroy('first_key'); + +		$this->assertFalse($this->driver->_exists('first_key')); +		$this->assertEquals( +			'second_value', +			$this->driver->get('second_key') +		); +	} + +	public function test_cache_sql() +	{ +		global $db, $cache, $phpbb_root_path, $phpEx; +		$config = new phpbb_config(array()); +		$db = $this->new_dbal(); +		$cache = new phpbb_cache_service($this->driver, $config, $db, $phpbb_root_path, $phpEx); + +		$sql = "SELECT * FROM phpbb_config +			WHERE config_name = 'foo'"; + +		$result = $db->sql_query($sql, 300); +		$first_result = $db->sql_fetchrow($result); +		$expected = array('config_name' => 'foo', 'config_value' => '23', 'is_dynamic' => 0); +		$this->assertEquals($expected, $first_result); + +		$sql = 'DELETE FROM phpbb_config'; +		$result = $db->sql_query($sql); + +		$sql = "SELECT * FROM phpbb_config +			WHERE config_name = 'foo'"; +		$result = $db->sql_query($sql, 300); + +		$this->assertEquals($expected, $db->sql_fetchrow($result)); + +		$sql = "SELECT * FROM phpbb_config +			WHERE config_name = 'foo'"; +		$result = $db->sql_query($sql); + +		$no_cache_result = $db->sql_fetchrow($result); +		$this->assertSame(false, $no_cache_result); + +		$db->sql_close(); +	} +} diff --git a/tests/cache/file_driver_test.php b/tests/cache/file_driver_test.php new file mode 100644 index 0000000000..745c6bb081 --- /dev/null +++ b/tests/cache/file_driver_test.php @@ -0,0 +1,69 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/common_test_case.php'; + +class phpbb_cache_file_driver_test extends phpbb_cache_common_test_case +{ +	private $cache_dir; +	protected $driver; + +	public function __construct() +	{ +		$this->cache_dir = dirname(__FILE__) . '/../tmp/cache/'; +	} + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/config.xml'); +	} + +	protected function setUp() +	{ +		parent::setUp(); + +		if (file_exists($this->cache_dir)) +		{ +			// cache directory possibly left after aborted +			// or failed run earlier +			$this->remove_cache_dir(); +		} +		$this->create_cache_dir(); + +		$this->driver = new phpbb_cache_driver_file($this->cache_dir); +	} + +	protected function tearDown() +	{ +		if (file_exists($this->cache_dir)) +		{ +			$this->remove_cache_dir(); +		} + +		parent::tearDown(); +	} + +	private function create_cache_dir() +	{ +		$this->get_test_case_helpers()->makedirs($this->cache_dir); +	} + +	private function remove_cache_dir() +	{ +		$iterator = new DirectoryIterator($this->cache_dir); +		foreach ($iterator as $file) +		{ +			if ($file != '.' && $file != '..') +			{ +				unlink($this->cache_dir . '/' . $file); +			} +		} +		rmdir($this->cache_dir); +	} +} diff --git a/tests/cache/fixtures/config.xml b/tests/cache/fixtures/config.xml new file mode 100644 index 0000000000..9d395b685c --- /dev/null +++ b/tests/cache/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>foo</value> +			<value>23</value> +			<value>0</value> +		</row> +		<row> +			<value>bar</value> +			<value>42</value> +			<value>1</value> +		</row> +	</table> +</dataset> diff --git a/tests/cache/null_driver_test.php b/tests/cache/null_driver_test.php new file mode 100644 index 0000000000..43a0cc806c --- /dev/null +++ b/tests/cache/null_driver_test.php @@ -0,0 +1,75 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_cache_null_driver_test extends phpbb_database_test_case +{ +	protected $driver; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/config.xml'); +	} + +	protected function setUp() +	{ +		parent::setUp(); + +		$this->driver = new phpbb_cache_driver_null; +	} + +	public function test_get_put() +	{ +		$this->assertSame(false, $this->driver->get('key')); + +		$this->driver->put('key', 'value'); + +		// null driver does not cache +		$this->assertSame(false, $this->driver->get('key')); +	} + +	public function test_purge() +	{ +		// does nothing +		$this->driver->purge(); +	} + +	public function test_destroy() +	{ +		// does nothing +		$this->driver->destroy('foo'); +	} + +	public function test_cache_sql() +	{ +		global $db, $cache, $phpbb_root_path, $phpEx; +		$config = new phpbb_config(array()); +		$db = $this->new_dbal(); +		$cache = new phpbb_cache_service($this->driver, $config, $db, $phpbb_root_path, $phpEx); + +		$sql = "SELECT * FROM phpbb_config +			WHERE config_name = 'foo'"; +		$result = $db->sql_query($sql, 300); +		$first_result = $db->sql_fetchrow($result); +		$expected = array('config_name' => 'foo', 'config_value' => '23', 'is_dynamic' => 0); +		$this->assertEquals($expected, $first_result); + +		$sql = 'DELETE FROM phpbb_config'; +		$result = $db->sql_query($sql); + +		// As null cache driver does not actually cache, +		// this should return no results +		$sql = "SELECT * FROM phpbb_config +			WHERE config_name = 'foo'"; +		$result = $db->sql_query($sql, 300); + +		$this->assertSame(false, $db->sql_fetchrow($result)); + +		$db->sql_close(); +	} +} diff --git a/tests/cache/redis_driver_test.php b/tests/cache/redis_driver_test.php new file mode 100644 index 0000000000..1308519a18 --- /dev/null +++ b/tests/cache/redis_driver_test.php @@ -0,0 +1,49 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/common_test_case.php'; + +class phpbb_cache_redis_driver_test extends phpbb_cache_common_test_case +{ +	protected static $config; +	protected $driver; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/config.xml'); +	} + +	static public function setUpBeforeClass() +	{ +		if (!extension_loaded('redis')) +		{ +			self::markTestSkipped('redis extension is not loaded'); +		} + +		$config = phpbb_test_case_helpers::get_test_config(); +		if (isset($config['redis_host']) || isset($config['redis_port'])) +		{ +			$host = isset($config['redis_host']) ? $config['redis_host'] : 'localhost'; +			$port = isset($config['redis_port']) ? $config['redis_port'] : 6379; +			self::$config = array('host' => $host, 'port' => $port); +		} +		else +		{ +			self::markTestSkipped('Test redis host/port is not specified'); +		} +	} + +	protected function setUp() +	{ +		parent::setUp(); + +		$this->driver = new phpbb_cache_driver_redis(self::$config['host'], self::$config['port']); +		$this->driver->purge(); +	} +} diff --git a/tests/class_loader/class_loader_test.php b/tests/class_loader/class_loader_test.php new file mode 100644 index 0000000000..76af4dde37 --- /dev/null +++ b/tests/class_loader/class_loader_test.php @@ -0,0 +1,103 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_class_loader_test extends PHPUnit_Framework_TestCase +{ +	public function setUp() +	{ +		global $phpbb_class_loader; +		$phpbb_class_loader->unregister(); + +		global $phpbb_class_loader_ext; +		$phpbb_class_loader_ext->unregister(); +	} + +	public function tearDown() +	{ +		global $phpbb_class_loader_ext; +		$phpbb_class_loader_ext->register(); + +		global $phpbb_class_loader; +		$phpbb_class_loader->register(); +	} + +	public function test_resolve_path() +	{ +		$prefix = dirname(__FILE__) . '/'; +		$class_loader = new phpbb_class_loader('phpbb_', $prefix . 'includes/'); + +		$prefix .= 'includes/'; + +		$this->assertEquals( +			'', +			$class_loader->resolve_path('phpbb_dir'), +			'Class with same name as a directory is unloadable' +		); + +		$this->assertEquals( +			$prefix . 'class_name.php', +			$class_loader->resolve_path('phpbb_class_name'), +			'Top level class' +		); +		$this->assertEquals( +			$prefix . 'dir/class_name.php', +			$class_loader->resolve_path('phpbb_dir_class_name'), +			'Class in a directory' +		); +		$this->assertEquals( +			$prefix . 'dir/subdir/class_name.php', +			$class_loader->resolve_path('phpbb_dir_subdir_class_name'), +			'Class in a sub-directory' +		); +		$this->assertEquals( +			$prefix . 'dir2/dir2.php', +			$class_loader->resolve_path('phpbb_dir2'), +			'Class with name of dir within dir (short class name)' +		); +	} + +	public function test_resolve_cached() +	{ +		$cache_map = array( +			'class_loader_phpbb_' => array('phpbb_a_cached_name' => 'a/cached_name'), +			'class_loader_phpbb_ext_' => array('phpbb_ext_foo' => 'foo'), +		); +		$cache = new phpbb_mock_cache($cache_map); + +		$prefix = dirname(__FILE__) . '/'; +		$class_loader = new phpbb_class_loader('phpbb_', $prefix . 'includes/', '.php', $cache); +		$class_loader_ext = new phpbb_class_loader('phpbb_ext_', $prefix . 'includes/', '.php', $cache); + +		$prefix .= 'includes/'; + +		$this->assertEquals( +			$prefix . 'dir/class_name.php', +			$class_loader->resolve_path('phpbb_dir_class_name'), +			'Class in a directory' +		); + +		$this->assertFalse($class_loader->resolve_path('phpbb_ext_foo')); +		$this->assertFalse($class_loader_ext->resolve_path('phpbb_a_cached_name')); + +		$this->assertEquals( +			$prefix . 'a/cached_name.php', +			$class_loader->resolve_path('phpbb_a_cached_name'), +			'Cached class found' +		); + +		$this->assertEquals( +			$prefix . 'foo.php', +			$class_loader_ext->resolve_path('phpbb_ext_foo'), +			'Cached class found in alternative loader' +		); + +		$cache_map['class_loader_phpbb_']['phpbb_dir_class_name'] = 'dir/class_name'; +		$cache->check($this, $cache_map); +	} +} diff --git a/tests/class_loader/includes/class_name.php b/tests/class_loader/includes/class_name.php new file mode 100644 index 0000000000..e941173cdd --- /dev/null +++ b/tests/class_loader/includes/class_name.php @@ -0,0 +1,6 @@ +<?php + +class phpbb_class_name +{ +} + diff --git a/tests/class_loader/includes/dir.php b/tests/class_loader/includes/dir.php new file mode 100644 index 0000000000..1c8930d8e7 --- /dev/null +++ b/tests/class_loader/includes/dir.php @@ -0,0 +1,6 @@ +<?php + +class phpbb_dir +{ +} + diff --git a/tests/class_loader/includes/dir/class_name.php b/tests/class_loader/includes/dir/class_name.php new file mode 100644 index 0000000000..0675aa8fc5 --- /dev/null +++ b/tests/class_loader/includes/dir/class_name.php @@ -0,0 +1,6 @@ +<?php + +class phpbb_dir_class_name +{ +} + diff --git a/tests/class_loader/includes/dir/subdir/class_name.php b/tests/class_loader/includes/dir/subdir/class_name.php new file mode 100644 index 0000000000..7321a609cc --- /dev/null +++ b/tests/class_loader/includes/dir/subdir/class_name.php @@ -0,0 +1,6 @@ +<?php + +class phpbb_dir_subdir_class_name +{ +} + diff --git a/tests/class_loader/includes/dir2/dir2.php b/tests/class_loader/includes/dir2/dir2.php new file mode 100644 index 0000000000..01cf4086ff --- /dev/null +++ b/tests/class_loader/includes/dir2/dir2.php @@ -0,0 +1,6 @@ +<?php + +class phpbb_dir2 +{ +} + diff --git a/tests/compress/archive/.gitkeep b/tests/compress/archive/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/compress/archive/.gitkeep diff --git a/tests/compress/compress_test.php b/tests/compress/compress_test.php new file mode 100644 index 0000000000..6623f7ed8a --- /dev/null +++ b/tests/compress/compress_test.php @@ -0,0 +1,184 @@ +<?php +/** + * + * @package testing + * @copyright (c) 2012 phpBB Group + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 + * + */ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_admin.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_compress.php'; + +class phpbb_compress_test extends phpbb_test_case +{ +	const EXTRACT_DIR = '/extract/'; +	const ARCHIVE_DIR = '/archive/'; + +	private $path; + +	protected $filelist = array( +		'1.txt', +		'dir/2.txt', +		'dir/3.txt', +		'dir/subdir/4.txt', +	); + +	protected $conflicts = array( +		'1_1.txt', +		'1_2.txt', +		'dir/2_1.txt', +	); + +	protected function setUp() +	{ +		// Required for compress::add_file +		global $phpbb_root_path; +		$phpbb_root_path = ''; + +		$this->path = dirname(__FILE__) . '/fixtures/'; +	} + +	protected function check_extensions($extensions) +	{ +		foreach ($extensions as $extension) +		{ +			if (!@extension_loaded($extension)) +			{ +				$this->markTestSkipped("$extension extension is not loaded"); +			} +		} +	} + +	protected function tearDown() +	{ +		foreach (array(dirname(__FILE__) . self::EXTRACT_DIR, dirname(__FILE__) . self::ARCHIVE_DIR) as $dir) +		{ +			$this->clear_dir($dir); +		} +	} + +	protected function clear_dir($dir) +	{ +		$iterator = new DirectoryIterator($dir); +		foreach ($iterator as $fileinfo) +		{ +			$name = $fileinfo->getFilename(); +			$path = $fileinfo->getPathname(); + +			if ($name[0] !== '.') +			{ +				if ($fileinfo->isDir()) +				{ +					$this->clear_dir($path); +					rmdir($path); +				} +				else +				{ +					unlink($path); +				} +			} +		} +	} + +	protected function archive_files($compress) +	{ +		$compress->add_file($this->path . '1.txt', $this->path); +		$compress->add_file( +			'tests/compress/fixtures/dir/', +			'tests/compress/fixtures/', +			'', +			// The comma here is not an error, this is a comma-separated list +			'subdir/4.txt,3.txt' +		); +		$compress->add_custom_file($this->path . 'dir/3.txt', 'dir/3.txt'); +		$compress->add_data(file_get_contents($this->path . 'dir/subdir/4.txt'), 'dir/subdir/4.txt'); + +		// Add multiples of the same file to check conflicts are handled +		$compress->add_file($this->path . '1.txt', $this->path); +		$compress->add_file($this->path . '1.txt', $this->path); +		$compress->add_file($this->path . 'dir/2.txt', $this->path); +	} + +	protected function valid_extraction($extra = array()) +	{ +		$filelist = array_merge($this->filelist, $extra); + +		foreach ($filelist as $filename) +		{ +			$path = dirname(__FILE__) . self::EXTRACT_DIR . $filename; +			$this->assertTrue(file_exists($path)); + +			// Check the file's contents is correct +			$contents = explode('_', basename($filename, '.txt')); +			$contents = $contents[0]; +			$this->assertEquals($contents . "\n", file_get_contents($path)); +		} +	} + +	public function tar_archive_list() +	{ +		return array( +			array('archive.tar', '.tar', array()), +			array('archive.tar.gz', '.tar.gz', array('zlib')), +			array('archive.tar.bz2', '.tar.bz2', array('bz2')), +		); +	} + +	/** +	 * @dataProvider tar_archive_list +	 */ +	public function test_extract_tar($filename, $type, $extensions) +	{ +		$this->check_extensions($extensions); +		$compress = new compress_tar('r', $this->path . $filename); +		$compress->extract('tests/compress/' . self::EXTRACT_DIR); +		$this->valid_extraction(); +	} + +	public function test_extract_zip() +	{ +		$compress = new compress_zip('r', $this->path . 'archive.zip'); +		$compress->extract('tests/compress/' . self::EXTRACT_DIR); +		$this->valid_extraction(); +	} + +	/** +	 * @depends test_extract_tar +	 * @dataProvider tar_archive_list +	 */ +	public function test_compress_tar($filename, $type, $extensions) +	{ +		$this->check_extensions($extensions); + +		$tar = dirname(__FILE__) . self::ARCHIVE_DIR . $filename; +		$compress = new compress_tar('w', $tar); +		$this->archive_files($compress); +		$compress->close(); +		$this->assertTrue(file_exists($tar)); + +		$compress->mode = 'r'; +		$compress->open(); +		$compress->extract('tests/compress/' . self::EXTRACT_DIR); +		$this->valid_extraction($this->conflicts); +	} + +	/** +	 * @depends test_extract_zip +	 */ +	public function test_compress_zip() +	{ +		$this->check_extensions(array('zlib')); + +		$zip =  dirname(__FILE__) . self::ARCHIVE_DIR . 'archive.zip'; +		$compress = new compress_zip('w', $zip); +		$this->archive_files($compress); +		$compress->close(); +		$this->assertTrue(file_exists($zip)); + +		$compress = new compress_zip('r', $zip); +		$compress->extract('tests/compress/' . self::EXTRACT_DIR); +		$this->valid_extraction($this->conflicts); +	} +} diff --git a/tests/compress/extract/.gitkeep b/tests/compress/extract/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/compress/extract/.gitkeep diff --git a/tests/compress/fixtures/1.txt b/tests/compress/fixtures/1.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/compress/fixtures/1.txt @@ -0,0 +1 @@ +1 diff --git a/tests/compress/fixtures/archive.tar b/tests/compress/fixtures/archive.tar Binary files differnew file mode 100644 index 0000000000..54ed56084e --- /dev/null +++ b/tests/compress/fixtures/archive.tar diff --git a/tests/compress/fixtures/archive.tar.bz2 b/tests/compress/fixtures/archive.tar.bz2 Binary files differnew file mode 100644 index 0000000000..04c0eccd74 --- /dev/null +++ b/tests/compress/fixtures/archive.tar.bz2 diff --git a/tests/compress/fixtures/archive.tar.gz b/tests/compress/fixtures/archive.tar.gz Binary files differnew file mode 100644 index 0000000000..195e7a060a --- /dev/null +++ b/tests/compress/fixtures/archive.tar.gz diff --git a/tests/compress/fixtures/archive.zip b/tests/compress/fixtures/archive.zip Binary files differnew file mode 100644 index 0000000000..bdb618fc26 --- /dev/null +++ b/tests/compress/fixtures/archive.zip diff --git a/tests/compress/fixtures/dir/2.txt b/tests/compress/fixtures/dir/2.txt new file mode 100644 index 0000000000..0cfbf08886 --- /dev/null +++ b/tests/compress/fixtures/dir/2.txt @@ -0,0 +1 @@ +2 diff --git a/tests/compress/fixtures/dir/3.txt b/tests/compress/fixtures/dir/3.txt new file mode 100644 index 0000000000..00750edc07 --- /dev/null +++ b/tests/compress/fixtures/dir/3.txt @@ -0,0 +1 @@ +3 diff --git a/tests/compress/fixtures/dir/subdir/4.txt b/tests/compress/fixtures/dir/subdir/4.txt new file mode 100644 index 0000000000..b8626c4cff --- /dev/null +++ b/tests/compress/fixtures/dir/subdir/4.txt @@ -0,0 +1 @@ +4 diff --git a/tests/config/config_test.php b/tests/config/config_test.php new file mode 100644 index 0000000000..5845cc4590 --- /dev/null +++ b/tests/config/config_test.php @@ -0,0 +1,120 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_config_test extends phpbb_test_case +{ +	public function test_offset_exists() +	{ +		$config = new phpbb_config(array('foo' => 'bar')); + +		$this->assertTrue(isset($config['foo'])); +		$this->assertFalse(isset($config['foobar'])); +	} + +	public function test_offset_get() +	{ +		$config = new phpbb_config(array('foo' => 'bar')); +		$this->assertEquals('bar', $config['foo']); +	} + +	public function test_offset_get_missing() +	{ +		$config = new phpbb_config(array()); +		$this->assertEquals('', $config['foo']); +	} + +	public function test_offset_set() +	{ +		$config = new phpbb_config(array()); +		$config['foo'] = 'x'; +		$this->assertEquals('x', $config['foo']); +	} + +	public function test_offset_unset_fails() +	{ +		$this->setExpectedTriggerError(E_USER_ERROR); +		$config = new phpbb_config(array('foo' => 'x')); +		unset($config['foo']); +	} + +	public function test_count() +	{ +		$config = new phpbb_config(array('foo' => 'bar')); +		$this->assertEquals(1, count($config)); +	} + +	public function test_iterate() +	{ +		$vars = array('foo' => '23', 'bar' => '42'); +		$config = new phpbb_config($vars); + +		$count = 0; +		foreach ($config as $key => $value) +		{ +			$this->assertTrue(isset($vars[$key])); +			$this->assertEquals($vars[$key], $value); + +			$count++; +		} + +		$this->assertEquals(count($vars), $count); +	} + +	public function test_set_overwrite() +	{ +		$config = new phpbb_config(array('foo' => 'x')); +		$config->set('foo', 'bar'); +		$this->assertEquals('bar', $config['foo']); +	} + +	public function test_set_new() +	{ +		$config = new phpbb_config(array()); +		$config->set('foo', 'bar'); +		$this->assertEquals('bar', $config['foo']); +	} + +	public function test_set_atomic_overwrite() +	{ +		$config = new phpbb_config(array('foo' => 'bar')); +		$this->assertTrue($config->set_atomic('foo', 'bar', '23')); +		$this->assertEquals('23', $config['foo']); +	} + +	public function test_set_atomic_new() +	{ +		$config = new phpbb_config(array()); +		$this->assertTrue($config->set_atomic('foo', false, '23')); +		$this->assertEquals('23', $config['foo']); +	} + +	public function test_set_atomic_failure() +	{ +		$config = new phpbb_config(array('foo' => 'bar')); +		$this->assertFalse($config->set_atomic('foo', 'wrong', '23')); +		$this->assertEquals('bar', $config['foo']); +	} + +	public function test_increment() +	{ +		$config = new phpbb_config(array('foo' => '23')); +		$config->increment('foo', 3); +		$this->assertEquals(26, $config['foo']); +		$config->increment('foo', 1); +		$this->assertEquals(27, $config['foo']); +	} + +	public function test_delete() +	{ +		$config = new phpbb_config(array('foo' => 'bar')); + +		$config->delete('foo'); +		$this->assertFalse(isset($config['foo'])); +	} +} diff --git a/tests/config/db_test.php b/tests/config/db_test.php new file mode 100644 index 0000000000..0b8f73d53a --- /dev/null +++ b/tests/config/db_test.php @@ -0,0 +1,164 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_config_db_test extends phpbb_database_test_case +{ +	private $cache; +	private $db; +	private $config; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/config.xml'); +	} + +	public function setUp() +	{ +		parent::setUp(); + +		$this->cache = new phpbb_mock_cache; +		$this->db = $this->new_dbal(); +		$this->config = new phpbb_config_db($this->db, $this->cache, 'phpbb_config'); +	} + +	public function test_load_config() +	{ +		$this->assertEquals('23', $this->config['foo']); +		$this->assertEquals('42', $this->config['bar']); +	} + +	public function test_load_cached() +	{ +		$cache = new phpbb_mock_cache(array('config' => array('x' => 'y'))); +		$this->config = new phpbb_config_db($this->db, $cache, 'phpbb_config'); + +		$this->assertTrue(!isset($this->config['foo'])); +		$this->assertEquals('42', $this->config['bar']); + +		$this->assertEquals('y', $this->config['x']); +	} + +	public function test_offset_set() +	{ +		$this->config['foo'] = 'x'; // temporary set +		$this->assertEquals('x', $this->config['foo']); + +		$config2 = new phpbb_config_db($this->db, $this->cache, 'phpbb_config'); +		$this->assertEquals('23', $config2['foo']); +	} + +	public function test_set_overwrite() +	{ +		$this->config->set('foo', '17'); +		$this->assertEquals('17', $this->config['foo']); + +		// re-read config and populate cache +		$config2 = new phpbb_config_db($this->db, $this->cache, 'phpbb_config'); +		$this->cache->checkVar($this, 'config', array('foo' => '17')); +	} + +	public function test_set_overwrite_uncached() +	{ +		$this->config->set('bar', '17', false); + +		// re-read config and populate cache +		$config2 = new phpbb_config_db($this->db, $this->cache, 'phpbb_config'); +		$this->cache->checkVar($this, 'config', array('foo' => '23')); +	} + +	public function test_set_new() +	{ +		$this->config->set('foobar', '5'); +		$this->assertEquals('5', $this->config['foobar']); + +		// re-read config and populate cache +		$config2 = new phpbb_config_db($this->db, $this->cache, 'phpbb_config'); +		$this->cache->checkVar($this, 'config', array('foo' => '23', 'foobar' => '5')); +	} + +	public function test_set_new_uncached() +	{ +		$this->config->set('foobar', '5', false); +		$this->assertEquals('5', $this->config['foobar']); + +		// re-read config and populate cache +		$config2 = new phpbb_config_db($this->db, $this->cache, 'phpbb_config'); +		$this->cache->checkVar($this, 'config', array('foo' => '23')); +	} + +	public function test_set_atomic_overwrite() +	{ +		$this->assertTrue($this->config->set_atomic('foo', '23', '17')); +		$this->assertEquals('17', $this->config['foo']); +	} + +	public function test_set_atomic_new() +	{ +		$this->assertTrue($this->config->set_atomic('foobar', false, '5')); +		$this->assertEquals('5', $this->config['foobar']); +	} + +	public function test_set_atomic_failure() +	{ +		$this->assertFalse($this->config->set_atomic('foo', 'wrong', '17')); +		$this->assertEquals('23', $this->config['foo']); +	} + +	public function test_increment() +	{ +		$this->config->increment('foo', 3); +		$this->assertEquals(26, $this->config['foo']); +		$this->config->increment('foo', 1); +		$this->assertEquals(27, $this->config['foo']); +	} + +	public function test_increment_new() +	{ +		$this->config->increment('foobar', 3); +		$this->assertEquals(3, $this->config['foobar']);; +	} + +	public function test_delete() +	{ +		$this->assertTrue(isset($this->config['foo'])); +		$this->config->delete('foo'); +		$this->cache->checkVarUnset($this, 'foo'); +		$this->assertFalse(isset($this->config['foo'])); + +		// re-read config and populate cache +		$cache2 = new phpbb_mock_cache; +		$config2 = new phpbb_config_db($this->db, $cache2, 'phpbb_config'); +		$cache2->checkVarUnset($this, 'foo'); +		$this->assertFalse(isset($config2['foo'])); +	} + +	public function test_delete_write_read_not_cacheable() +	{ +		// bar is dynamic +		$this->assertTrue(isset($this->config['bar'])); +		$this->config->delete('bar'); +		$this->cache->checkVarUnset($this, 'bar'); +		$this->assertFalse(isset($this->config['bar'])); +		 +		$this->config->set('bar', 'new bar', false); +		$this->assertEquals('new bar', $this->config['bar']); +	} + +	public function test_delete_write_read_cacheable() +	{ +		// foo is not dynamic +		$this->assertTrue(isset($this->config['foo'])); +		$this->config->delete('foo'); +		$this->cache->checkVarUnset($this, 'foo'); +		$this->assertFalse(isset($this->config['foo'])); +		 +		$this->config->set('foo', 'new foo', true); +		$this->assertEquals('new foo', $this->config['foo']); +	} +} diff --git a/tests/config/fixtures/config.xml b/tests/config/fixtures/config.xml new file mode 100644 index 0000000000..9d395b685c --- /dev/null +++ b/tests/config/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>foo</value> +			<value>23</value> +			<value>0</value> +		</row> +		<row> +			<value>bar</value> +			<value>42</value> +			<value>1</value> +		</row> +	</table> +</dataset> diff --git a/tests/controller/config/routing.yml b/tests/controller/config/routing.yml new file mode 100644 index 0000000000..175b11f130 --- /dev/null +++ b/tests/controller/config/routing.yml @@ -0,0 +1,3 @@ +core_controller: +    pattern: /core_foo +    defaults: { _controller: core_foo.controller:bar } diff --git a/tests/controller/config/services.yml b/tests/controller/config/services.yml new file mode 100644 index 0000000000..f1bd047489 --- /dev/null +++ b/tests/controller/config/services.yml @@ -0,0 +1,3 @@ +services: +    core_foo.controller: +        class: phpbb_controller_foo diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php new file mode 100644 index 0000000000..198fb3c6dd --- /dev/null +++ b/tests/controller/controller_test.php @@ -0,0 +1,76 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + +class phpbb_controller_test extends phpbb_test_case +{ +	public function setUp() +	{ +		$this->extension_manager = new phpbb_mock_extension_manager( +			dirname(__FILE__) . '/', +			array( +				'foo' => array( +					'ext_name' => 'foo', +					'ext_active' => '1', +					'ext_path' => 'ext/foo/', +				), +			)); +	} + +	public function test_provider() +	{ +		$provider = new phpbb_controller_provider; +		$routes = $provider +			->import_paths_from_finder($this->extension_manager->get_finder()) +			->find('./tests/controller/'); + +		// This will need to be updated if any new routes are defined +		$this->assertEquals(2, sizeof($routes)); +	} + +	public function test_controller_resolver() +	{ +		$container = new ContainerBuilder(); +		// YamlFileLoader only uses one path at a time, so we need to loop +		// through all of the ones we are using. +		foreach (array(__DIR__.'/config', __DIR__.'/ext/foo/config') as $path) +		{ +			$loader = new YamlFileLoader($container, new FileLocator($path)); +			$loader->load('services.yml'); +		} + +		// Autoloading classes within the tests folder does not work +		// so I'll include them manually. +		if (!class_exists('phpbb_ext_foo_controller')) +		{ +			include(__DIR__.'/ext/foo/controller.php'); +		} +		if (!class_exists('phpbb_controller_foo')) +		{ +			include(__DIR__.'/includes/controller/foo.php'); +		} + +		$resolver = new phpbb_controller_resolver(new phpbb_user, $container); +		$symfony_request = new Request(); +		$symfony_request->attributes->set('_controller', 'foo.controller:handle'); + +		$this->assertEquals($resolver->getController($symfony_request), array(new phpbb_ext_foo_controller, 'handle')); + +		$symfony_request = new Request(); +		$symfony_request->attributes->set('_controller', 'core_foo.controller:bar'); + +		$this->assertEquals($resolver->getController($symfony_request), array(new phpbb_controller_foo, 'bar')); +	} +} diff --git a/tests/controller/ext/foo/config/routing.yml b/tests/controller/ext/foo/config/routing.yml new file mode 100644 index 0000000000..4799fec37d --- /dev/null +++ b/tests/controller/ext/foo/config/routing.yml @@ -0,0 +1,3 @@ +controller1: +    pattern: /foo +    defaults: { _controller: foo.controller:handle } diff --git a/tests/controller/ext/foo/config/services.yml b/tests/controller/ext/foo/config/services.yml new file mode 100644 index 0000000000..ce0e18c610 --- /dev/null +++ b/tests/controller/ext/foo/config/services.yml @@ -0,0 +1,3 @@ +services: +    foo.controller: +        class: phpbb_ext_foo_controller diff --git a/tests/controller/ext/foo/controller.php b/tests/controller/ext/foo/controller.php new file mode 100644 index 0000000000..cfc5c20622 --- /dev/null +++ b/tests/controller/ext/foo/controller.php @@ -0,0 +1,16 @@ +<?php + +use Symfony\Component\HttpFoundation\Response; + +class phpbb_ext_foo_controller +{ +	/** +	* Handle method +	* +	* @return null +	*/ +	public function handle() +	{ +		return new Response('Test', 200); +	} +} diff --git a/tests/controller/includes/controller/foo.php b/tests/controller/includes/controller/foo.php new file mode 100644 index 0000000000..04576e16c4 --- /dev/null +++ b/tests/controller/includes/controller/foo.php @@ -0,0 +1,16 @@ +<?php + +use Symfony\Component\HttpFoundation\Response; + +class phpbb_controller_foo +{ +	/** +	* Bar method +	* +	* @return null +	*/ +	public function bar() +	{ +		return new Response('bar()', 200); +	} +} diff --git a/tests/cron/ext/testext/cron/dummy_task.php b/tests/cron/ext/testext/cron/dummy_task.php new file mode 100644 index 0000000000..3e81db1895 --- /dev/null +++ b/tests/cron/ext/testext/cron/dummy_task.php @@ -0,0 +1,28 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_ext_testext_cron_dummy_task extends phpbb_cron_task_base +{ +	static public $was_run = 0; + +	public function get_name() +	{ +		return get_class($this); +	} + +	public function run() +	{ +		self::$was_run++; +	} + +	public function should_run() +	{ +		return true; +	} +} diff --git a/tests/cron/includes/cron/task/core/dummy_task.php b/tests/cron/includes/cron/task/core/dummy_task.php new file mode 100644 index 0000000000..c94455603f --- /dev/null +++ b/tests/cron/includes/cron/task/core/dummy_task.php @@ -0,0 +1,28 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_cron_task_core_dummy_task extends phpbb_cron_task_base +{ +	static public $was_run = 0; + +	public function get_name() +	{ +		return get_class($this); +	} + +	public function run() +	{ +		self::$was_run++; +	} + +	public function should_run() +	{ +		return true; +	} +} diff --git a/tests/cron/includes/cron/task/core/second_dummy_task.php b/tests/cron/includes/cron/task/core/second_dummy_task.php new file mode 100644 index 0000000000..77ef6f70ed --- /dev/null +++ b/tests/cron/includes/cron/task/core/second_dummy_task.php @@ -0,0 +1,28 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_cron_task_core_second_dummy_task extends phpbb_cron_task_base +{ +	static public $was_run = 0; + +	public function get_name() +	{ +		return get_class($this); +	} + +	public function run() +	{ +		self::$was_run++; +	} + +	public function should_run() +	{ +		return true; +	} +} diff --git a/tests/cron/manager_test.php b/tests/cron/manager_test.php new file mode 100644 index 0000000000..3c541be2a6 --- /dev/null +++ b/tests/cron/manager_test.php @@ -0,0 +1,76 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/includes/cron/task/core/dummy_task.php'; +require_once dirname(__FILE__) . '/includes/cron/task/core/second_dummy_task.php'; +require_once dirname(__FILE__) . '/ext/testext/cron/dummy_task.php'; +require_once dirname(__FILE__) . '/tasks/simple_ready.php'; +require_once dirname(__FILE__) . '/tasks/simple_not_runnable.php'; +require_once dirname(__FILE__) . '/tasks/simple_should_not_run.php'; + +class phpbb_cron_manager_test extends PHPUnit_Framework_TestCase +{ +	public function setUp() +	{ +		$this->manager = $this->create_cron_manager(array( +			new phpbb_cron_task_core_dummy_task(), +			new phpbb_cron_task_core_second_dummy_task(), +			new phpbb_ext_testext_cron_dummy_task(), +		)); +		$this->task_name = 'phpbb_cron_task_core_dummy_task'; +	} + +	public function test_manager_finds_shipped_task_by_name() +	{ +		$task = $this->manager->find_task($this->task_name); +		$this->assertInstanceOf('phpbb_cron_task_wrapper', $task); +		$this->assertEquals($this->task_name, $task->get_name()); +	} + +	public function test_manager_finds_all_ready_tasks() +	{ +		$tasks = $this->manager->find_all_ready_tasks(); +		$this->assertEquals(3, sizeof($tasks)); +	} + +	public function test_manager_finds_one_ready_task() +	{ +		$task = $this->manager->find_one_ready_task(); +		$this->assertInstanceOf('phpbb_cron_task_wrapper', $task); +	} + +	public function test_manager_finds_only_ready_tasks() +	{ +		$manager = $this->create_cron_manager(array( +			new phpbb_cron_task_core_simple_ready(), +			new phpbb_cron_task_core_simple_not_runnable(), +			new phpbb_cron_task_core_simple_should_not_run(), +		)); +		$tasks = $manager->find_all_ready_tasks(); +		$task_names = $this->tasks_to_names($tasks); +		$this->assertEquals(array('phpbb_cron_task_core_simple_ready'), $task_names); +	} + +	private function tasks_to_names($tasks) +	{ +		$names = array(); +		foreach ($tasks as $task) +		{ +			$names[] = $task->get_name(); +		} +		return $names; +	} + +	private function create_cron_manager($tasks) +	{ +		global $phpbb_root_path, $phpEx; + +		return new phpbb_cron_manager($tasks, $phpbb_root_path, $phpEx); +	} +} diff --git a/tests/cron/tasks/simple_not_runnable.php b/tests/cron/tasks/simple_not_runnable.php new file mode 100644 index 0000000000..56d484eacd --- /dev/null +++ b/tests/cron/tasks/simple_not_runnable.php @@ -0,0 +1,18 @@ +<?php + +class phpbb_cron_task_core_simple_not_runnable extends phpbb_cron_task_base +{ +	public function get_name() +	{ +		return get_class($this); +	} + +	public function run() +	{ +	} + +	public function is_runnable() +	{ +		return false; +	} +} diff --git a/tests/cron/tasks/simple_ready.php b/tests/cron/tasks/simple_ready.php new file mode 100644 index 0000000000..8aa0507406 --- /dev/null +++ b/tests/cron/tasks/simple_ready.php @@ -0,0 +1,13 @@ +<?php + +class phpbb_cron_task_core_simple_ready extends phpbb_cron_task_base +{ +	public function get_name() +	{ +		return get_class($this); +	} + +	public function run() +	{ +	} +} diff --git a/tests/cron/tasks/simple_should_not_run.php b/tests/cron/tasks/simple_should_not_run.php new file mode 100644 index 0000000000..58f6df2616 --- /dev/null +++ b/tests/cron/tasks/simple_should_not_run.php @@ -0,0 +1,18 @@ +<?php + +class phpbb_cron_task_core_simple_should_not_run extends phpbb_cron_task_base +{ +	public function get_name() +	{ +		return get_class($this); +	} + +	public function run() +	{ +	} + +	public function should_run() +	{ +		return false; +	} +} diff --git a/tests/datetime/from_format_test.php b/tests/datetime/from_format_test.php new file mode 100644 index 0000000000..c28925272e --- /dev/null +++ b/tests/datetime/from_format_test.php @@ -0,0 +1,57 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/session.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/user.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/datetime.php'; +require_once dirname(__FILE__) . '/../mock/lang.php'; + +class phpbb_datetime_from_format_test extends phpbb_test_case +{ +	public function from_format_data() +	{ +		return array( +			array( +				'UTC', +				'Y-m-d', +				'2012-06-08', +			), + +			array( +				'Europe/Berlin', +				'Y-m-d H:i:s', +				'2012-06-08 14:01:02', +			), +		); +	} + +	/** +	* @dataProvider from_format_data() +	*/ +	public function test_from_format($timezone, $format, $expected) +	{ +		global $user; + +		$user = new phpbb_user(); +		$user->timezone = new DateTimeZone($timezone); +		$user->lang['datetime'] = array( +			'TODAY'		=> 'Today', +			'TOMORROW'	=> 'Tomorrow', +			'YESTERDAY'	=> 'Yesterday', +			'AGO'		=> array( +				0		=> 'less than a minute ago', +				1		=> '%d minute ago', +				2		=> '%d minutes ago', +			), +		); + +		$timestamp = $user->get_timestamp_from_format($format, $expected, new DateTimeZone($timezone)); +		$this->assertEquals($expected, $user->format_date($timestamp, $format, true)); +	} +} diff --git a/tests/dbal/auto_increment_test.php b/tests/dbal/auto_increment_test.php new file mode 100644 index 0000000000..e87fc1c6bd --- /dev/null +++ b/tests/dbal/auto_increment_test.php @@ -0,0 +1,100 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/db/db_tools.php'; + +class phpbb_dbal_auto_increment_test extends phpbb_database_test_case +{ +	protected $db; +	protected $tools; +	protected $table_exists; +	protected $table_data; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/config.xml'); +	} + +	protected function setUp() +	{ +		parent::setUp(); + +		$this->db = $this->new_dbal(); +		$this->tools = new phpbb_db_tools($this->db); + +		$this->table_data = array( +			'COLUMNS'		=> array( +				'c_id'				=> array('UINT', NULL, 'auto_increment'), +				'c_uint'				=> array('UINT', 4), +			), +			'PRIMARY_KEY'	=> 'c_id', +		); +		$this->tools->sql_create_table('prefix_table_name', $this->table_data); +		$this->table_exists = true; +	} + +	protected function tearDown() +	{ +		if ($this->table_exists) +		{ +			$this->tools->sql_table_drop('prefix_table_name'); +		} + +		parent::tearDown(); +	} + +	static protected function get_default_values() +	{ +		return array( +			'c_uint' => 0, +		); +	} + +	public function test_auto_increment() +	{ +		$sql = 'DELETE FROM prefix_table_name'; +		$result = $this->db->sql_query($sql); + +		$row1 = array_merge(self::get_default_values(), array( +			'c_uint' => 1, +		)); +		$row2 = array_merge(self::get_default_values(), array( +			'c_uint' => 2, +		)); + +		$sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row1); +		$result = $this->db->sql_query($sql); +		$id1 = $this->db->sql_nextid(); + +		$sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row2); +		$result = $this->db->sql_query($sql); +		$id2 = $this->db->sql_nextid(); + +		$this->assertGreaterThan($id1, $id2, 'Auto increment should increase the id value'); + +		$sql = "SELECT * +			FROM prefix_table_name WHERE c_id = $id1"; +		$result = $this->db->sql_query($sql); +		$row_actual = $this->db->sql_fetchrow($result); +		$this->db->sql_freeresult($result); + +		$row1['c_id'] = $id1; +		$this->assertEquals($row1, $row_actual); + +		$sql = "SELECT * +			FROM prefix_table_name WHERE c_id = $id2"; +		$result = $this->db->sql_query($sql); +		$row_actual = $this->db->sql_fetchrow($result); +		$this->db->sql_freeresult($result); + +		$row2['c_id'] = $id2; +		$this->assertEquals($row2, $row_actual); +	} +} diff --git a/tests/dbal/case_test.php b/tests/dbal/case_test.php new file mode 100644 index 0000000000..57a1729a39 --- /dev/null +++ b/tests/dbal/case_test.php @@ -0,0 +1,69 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_dbal_case_test extends phpbb_database_test_case +{ +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); +	} + +	public function test_case_int() +	{ +		$db = $this->new_dbal(); + +		$sql = 'SELECT ' . $db->sql_case('1 = 1', '1', '2') . ' AS test_num +			FROM phpbb_config'; +		$result = $db->sql_query_limit($sql, 1); + +		$this->assertEquals(1, (int) $db->sql_fetchfield('test_num')); + +		$sql = 'SELECT ' . $db->sql_case('1 = 0', '1', '2') . ' AS test_num +			FROM phpbb_config'; +		$result = $db->sql_query_limit($sql, 1); + +		$this->assertEquals(2, (int) $db->sql_fetchfield('test_num')); +	} + +	public function test_case_string() +	{ +		$db = $this->new_dbal(); + +		$sql = 'SELECT ' . $db->sql_case('1 = 1', "'foo'", "'bar'") . ' AS test_string +			FROM phpbb_config'; +		$result = $db->sql_query_limit($sql, 1); + +		$this->assertEquals('foo', $db->sql_fetchfield('test_string')); + +		$sql = 'SELECT ' . $db->sql_case('1 = 0', "'foo'", "'bar'") . ' AS test_string +			FROM phpbb_config'; +		$result = $db->sql_query_limit($sql, 1); + +		$this->assertEquals('bar', $db->sql_fetchfield('test_string')); +	} + +	public function test_case_column() +	{ +		$db = $this->new_dbal(); + +		$sql = 'SELECT ' . $db->sql_case("config_name = 'config1'", 'config_name', 'config_value') . " AS test_string +			FROM phpbb_config +			WHERE config_name = 'config1'"; +		$result = $db->sql_query_limit($sql, 1); + +		$this->assertEquals('config1', $db->sql_fetchfield('test_string')); + +		$sql = 'SELECT ' . $db->sql_case("config_name = 'config1'", 'config_name', 'config_value') . " AS test_string +			FROM phpbb_config +			WHERE config_value = 'bar'"; +		$result = $db->sql_query_limit($sql, 1); + +		$this->assertEquals('bar', $db->sql_fetchfield('test_string')); +	} +} diff --git a/tests/dbal/concatenate_test.php b/tests/dbal/concatenate_test.php new file mode 100644 index 0000000000..0891fa58a0 --- /dev/null +++ b/tests/dbal/concatenate_test.php @@ -0,0 +1,64 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_dbal_concatenate_test extends phpbb_database_test_case +{ +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); +	} + +	public function test_concatenate_string() +	{ +		$db = $this->new_dbal(); + +		$sql = 'SELECT config_name, ' . $db->sql_concatenate('config_name', "'" . $db->sql_escape('append') . "'") . ' AS string +			FROM phpbb_config'; +		$result = $db->sql_query($sql); + +		$db->sql_return_on_error(false); + +		$this->assertEquals(array( +				array( +					'config_name'	=> 'config1', +					'string'		=> 'config1append', +				), +				array( +					'config_name'	=> 'config2', +					'string'		=> 'config2append', +				), +			), +			$db->sql_fetchrowset($result) +		); +	} + +	public function test_concatenate_statement() +	{ +		$db = $this->new_dbal(); + +		$sql = 'SELECT config_name, ' . $db->sql_concatenate('config_name', 'config_value') . ' AS string +			FROM phpbb_config'; +		$result = $db->sql_query($sql); + +		$db->sql_return_on_error(false); + +		$this->assertEquals(array( +				array( +					'config_name'	=> 'config1', +					'string'		=> 'config1foo', +				), +				array( +					'config_name'	=> 'config2', +					'string'		=> 'config2bar', +				), +			), +			$db->sql_fetchrowset($result) +		); +	} +} diff --git a/tests/dbal/connect_test.php b/tests/dbal/connect_test.php new file mode 100644 index 0000000000..1e352d6b03 --- /dev/null +++ b/tests/dbal/connect_test.php @@ -0,0 +1,41 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_dbal_connect_test extends phpbb_database_test_case +{ +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/../fixtures/empty.xml'); +	} + +	public function test_failing_connect() +	{ +		global $phpbb_root_path, $phpEx; + +		$config = $this->get_database_config(); + +		$db = new $config['dbms'](); + +		// Failure to connect results in a trigger_error call in dbal. +		// phpunit converts triggered errors to exceptions. +		// In particular there should be no fatals here. +		try +		{ +			$db->sql_connect($config['dbhost'], 'phpbbogus', 'phpbbogus', 'phpbbogus', $config['dbport']); +			$this->assertFalse(true); +		} +		catch (Exception $e) +		{ +			// should have a legitimate message +			$this->assertNotEmpty($e->getMessage()); +		} +	} +} diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php index c7ddb88ce8..c20e46011f 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -106,7 +106,7 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case  			'c_bool' => 0,  			'c_vchar' => '',  			'c_vchar_size' => '', -			'c_char_size' => '', +			'c_char_size' => 'abcd',  			'c_xstext' => '',  			'c_stext' => '',  			'c_text' => '', @@ -165,6 +165,11 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case  	*/  	public function test_created_column($column_name, $column_value)  	{ +		if ($column_name === 'c_varbinary' && stripos(get_class($this->db), 'mysql') === false) +		{ +			$this->markTestIncomplete('Binary handling is not implemented properly on non-MySQL DBMSes.'); +		} +  		$row_insert = self::get_default_values();  		$row_insert[$column_name] = $column_value; @@ -189,51 +194,6 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case  		$this->assertEquals($row_expect[$column_name], $row_actual[$column_name], "Column $column_name of type $type should have equal return and input value.");  	} -	public function test_auto_increment() -	{ -		$sql = 'DELETE FROM prefix_table_name'; -		$result = $this->db->sql_query($sql); - -		$row1 = array_merge(self::get_default_values(), array( -			'c_uint' => 1, -			'c_vchar' => '1', // these values are necessary to avoid unique index issues -			'c_vchar_size' => '1', -		)); -		$row2 = array_merge(self::get_default_values(), array( -			'c_uint' => 2, -			'c_vchar' => '2', -			'c_vchar_size' => '2', -		)); - -		$sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row1); -		$result = $this->db->sql_query($sql); -		$id1 = $this->db->sql_nextid(); - -		$sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row2); -		$result = $this->db->sql_query($sql); -		$id2 = $this->db->sql_nextid(); - -		$this->assertGreaterThan($id1, $id2, 'Auto increment should increase the id value'); - -		$sql = "SELECT * -			FROM prefix_table_name WHERE c_id = $id1"; -		$result = $this->db->sql_query($sql); -		$row_actual = $this->db->sql_fetchrow($result); -		$this->db->sql_freeresult($result); - -		$row1['c_id'] = $id1; -		$this->assertEquals($row1, $row_actual); - -		$sql = "SELECT * -			FROM prefix_table_name WHERE c_id = $id2"; -		$result = $this->db->sql_query($sql); -		$row_actual = $this->db->sql_fetchrow($result); -		$this->db->sql_freeresult($result); - -		$row2['c_id'] = $id2; -		$this->assertEquals($row2, $row_actual); -	} -  	public function test_list_columns()  	{  		$this->assertEquals( diff --git a/tests/dbal/fixtures/styles.xml b/tests/dbal/fixtures/styles.xml index 47b384c47f..dcbe39d3b0 100644 --- a/tests/dbal/fixtures/styles.xml +++ b/tests/dbal/fixtures/styles.xml @@ -5,35 +5,39 @@  		<column>style_name</column>  		<column>style_copyright</column>  		<column>style_active</column> -		<column>template_id</column> -		<column>theme_id</column> -		<column>imageset_id</column> +		<column>style_path</column> +		<column>bbcode_bitfield</column> +		<column>style_parent_id</column> +		<column>style_parent_tree</column>  		<row>  			<value>1</value>  			<value>prosilver</value>  			<value>&copy; phpBB Group</value>  			<value>1</value> -			<value>1</value> -			<value>1</value> -			<value>1</value> +			<value>prosilver</value> +			<value>kNg=</value> +			<value>0</value> +			<value></value>  		</row>  		<row>  			<value>2</value>  			<value>prosilver2</value>  			<value>&copy; phpBB Group</value>  			<value>0</value> -			<value>2</value> -			<value>2</value> -			<value>2</value> +			<value>prosilver2</value> +			<value>kNg=</value> +			<value>0</value> +			<value></value>  		</row>  		<row>  			<value>3</value>  			<value>Prosilver1</value>  			<value>&copy; phpBB Group</value>  			<value>0</value> -			<value>3</value> -			<value>3</value> -			<value>3</value> +			<value>prosilver1</value> +			<value>kNg=</value> +			<value>1</value> +			<value>prosilver</value>  		</row>  	</table>  </dataset> diff --git a/tests/dbal/order_lower_test.php b/tests/dbal/order_lower_test.php index b50494d506..84d454742f 100644 --- a/tests/dbal/order_lower_test.php +++ b/tests/dbal/order_lower_test.php @@ -14,7 +14,7 @@ class phpbb_dbal_order_lower_test extends phpbb_database_test_case  		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/styles.xml');  	} -	public function test_cross_join() +	public function test_order_lower()  	{  		$db = $this->new_dbal(); @@ -33,27 +33,30 @@ class phpbb_dbal_order_lower_test extends phpbb_database_test_case  					'style_name'		=> 'prosilver',  					'style_copyright'	=> '© phpBB Group',  					'style_active'		=> 1, -					'template_id'		=> 1, -					'theme_id'			=> 1, -					'imageset_id'		=> 1 +					'style_path'		=> 'prosilver', +					'bbcode_bitfield'	=> 'kNg=', +					'style_parent_id'	=> 0, +					'style_parent_tree'	=> '',  				),  				array(  					'style_id' 			=> 3,  					'style_name'		=> 'Prosilver1',  					'style_copyright'	=> '© phpBB Group',  					'style_active'		=> 0, -					'template_id'		=> 3, -					'theme_id'			=> 3, -					'imageset_id'		=> 3 +					'style_path'		=> 'prosilver1', +					'bbcode_bitfield'	=> 'kNg=', +					'style_parent_id'	=> 1, +					'style_parent_tree'	=> 'prosilver',  				),  				array(  					'style_id' 			=> 2,  					'style_name'		=> 'prosilver2',  					'style_copyright'	=> '© phpBB Group',  					'style_active'		=> 0, -					'template_id'		=> 2, -					'theme_id'			=> 2, -					'imageset_id'		=> 2 +					'style_path'		=> 'prosilver2', +					'bbcode_bitfield'	=> 'kNg=', +					'style_parent_id'	=> 0, +					'style_parent_tree'	=> '',  				)  			),   			$db->sql_fetchrowset($result) diff --git a/tests/dbal/schema_test.php b/tests/dbal/schema_test.php new file mode 100644 index 0000000000..2a332fddba --- /dev/null +++ b/tests/dbal/schema_test.php @@ -0,0 +1,38 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_dbal_schema_test extends phpbb_database_test_case +{ +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); +	} + +	public function test_config_value_multibyte() +	{ +		$db = $this->new_dbal(); + +		$value = str_repeat("\xC3\x84", 255); +		$sql = "INSERT INTO phpbb_config +			(config_name, config_value) +			VALUES ('name', '$value')"; +		$result = $db->sql_query($sql); + +		$sql = "SELECT config_value +			FROM phpbb_config +			WHERE config_name = 'name'"; +		$result = $db->sql_query_limit($sql, 1); +		$row = $db->sql_fetchrow($result); +		$db->sql_freeresult($result); + +		$this->assertEquals($value, $row['config_value']); +	} +} diff --git a/tests/dbal/select_test.php b/tests/dbal/select_test.php index 21b12777dc..c8cfad04e0 100644 --- a/tests/dbal/select_test.php +++ b/tests/dbal/select_test.php @@ -17,7 +17,7 @@ class phpbb_dbal_select_test extends phpbb_database_test_case  		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/three_users.xml');  	} -	public static function return_on_error_select_data() +	public function return_on_error_select_data()  	{  		return array(  			array('phpbb_users', "username_clean = 'bertie'", array(array('username_clean' => 'bertie'))), @@ -44,7 +44,7 @@ class phpbb_dbal_select_test extends phpbb_database_test_case  		$this->assertEquals($expected, $db->sql_fetchrowset($result));  	} -	public static function fetchrow_data() +	public function fetchrow_data()  	{  		return array(  			array('', array(array('username_clean' => 'barfoo'), @@ -95,7 +95,7 @@ class phpbb_dbal_select_test extends phpbb_database_test_case  		$db->sql_freeresult($result);  	} -	public static function fetchfield_data() +	public function fetchfield_data()  	{  		return array(  			array('', array('barfoo', 'foobar', 'bertie')), @@ -125,7 +125,33 @@ class phpbb_dbal_select_test extends phpbb_database_test_case  		$this->assertEquals($expected, $ary);  	} -	public static function query_limit_data() +	static public function fetchfield_seek_data() +	{ +		return array( +			array(1, 'foobar'), +			array(0, 'barfoo'), +			array(2, 'bertie'), +		); +	} + +	/** +	* @dataProvider fetchfield_seek_data +	*/ +	public function test_fetchfield_seek($rownum, $expected) +	{ +		$db = $this->new_dbal(); + +		$result = $db->sql_query('SELECT username_clean +			FROM phpbb_users +			ORDER BY user_id ASC'); + +		$field = $db->sql_fetchfield('username_clean', $rownum, $result); +		$db->sql_freeresult($result); + +		$this->assertEquals($expected, $field); +	} + +	static public function query_limit_data()  	{  		return array(  			array(0, 0, array(array('username_clean' => 'barfoo'), @@ -166,7 +192,7 @@ class phpbb_dbal_select_test extends phpbb_database_test_case  		$this->assertEquals($expected, $ary);  	} -	public static function like_expression_data() +	public function like_expression_data()  	{  		// * = any_char; # = one_char  		return array( @@ -203,7 +229,7 @@ class phpbb_dbal_select_test extends phpbb_database_test_case  		$db->sql_freeresult($result);  	} -	public static function in_set_data() +	public function in_set_data()  	{  		return array(  			array('user_id', 3, false, false, array(array('username_clean' => 'bertie'))), @@ -277,7 +303,7 @@ class phpbb_dbal_select_test extends phpbb_database_test_case  		$db->sql_freeresult($result);  	} -	public static function build_array_data() +	public function build_array_data()  	{  		return array(  			array(array('username_clean' => 'barfoo'), array(array('username_clean' => 'barfoo'))), @@ -349,7 +375,9 @@ class phpbb_dbal_select_test extends phpbb_database_test_case  	{  		$db = $this->new_dbal(); -		$sql = 'SELECT * FROM (SELECT 1) AS TBL WHERE 1 = 0'; +		$sql = 'SELECT user_id +			FROM phpbb_users +			WHERE 1 = 0';  		$result = $db->sql_query($sql);  		$row = $db->sql_fetchrow($result); diff --git a/tests/dbal/write_sequence_test.php b/tests/dbal/write_sequence_test.php new file mode 100644 index 0000000000..f382a971a5 --- /dev/null +++ b/tests/dbal/write_sequence_test.php @@ -0,0 +1,59 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_dbal_write_sequence_test extends phpbb_database_test_case +{ +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/three_users.xml'); +	} + +	static public function write_sequence_data() +	{ +		return array( +			array( +				'ticket/11219', +				4, +			), +		); +	} + +	/** +	* @dataProvider write_sequence_data +	*/ +	public function test_write_sequence($username, $expected) +	{ +		$db = $this->new_dbal(); + +		// dbal uses cache +		global $cache; +		$cache = new phpbb_mock_cache(); + +		$sql = 'INSERT INTO phpbb_users ' . $db->sql_build_array('INSERT', array( +			'username'			=> $username, +			'username_clean'	=> $username, +			'user_permissions'	=> '', +			'user_sig'			=> '', +			'user_occ'			=> '', +			'user_interests'	=> '', +		)); +		$db->sql_query($sql); + +		$this->assertEquals($expected, $db->sql_nextid()); + +		$sql = "SELECT user_id +			FROM phpbb_users +			WHERE username_clean = '" . $db->sql_escape($username) . "'"; +		$result = $db->sql_query_limit($sql, 1); + +		$this->assertEquals($expected, $db->sql_fetchfield('user_id')); +	} +} diff --git a/tests/dbal/write_test.php b/tests/dbal/write_test.php index 596c50a220..987161a831 100644 --- a/tests/dbal/write_test.php +++ b/tests/dbal/write_test.php @@ -16,7 +16,7 @@ class phpbb_dbal_write_test extends phpbb_database_test_case  		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml');  	} -	public static function build_array_insert_data() +	public function build_array_insert_data()  	{  		return array(  			array(array( @@ -104,7 +104,7 @@ class phpbb_dbal_write_test extends phpbb_database_test_case  		$db->sql_freeresult($result);  	} -	public static function update_data() +	public function update_data()  	{  		return array(  			array( diff --git a/tests/di/create_container_test.php b/tests/di/create_container_test.php new file mode 100644 index 0000000000..6de8803df9 --- /dev/null +++ b/tests/di/create_container_test.php @@ -0,0 +1,71 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_container.php'; + +class phpbb_di_container_test extends phpbb_test_case +{ +    public function test_phpbb_create_container() +    { +        $phpbb_root_path = __DIR__ . '/../../phpBB/'; +        $extensions = array( +            new phpbb_di_extension_config(__DIR__ . '/fixtures/config.php'), +            new phpbb_di_extension_core($phpbb_root_path), +        ); +        $container = phpbb_create_container($extensions, $phpbb_root_path, 'php'); + +        $this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerBuilder', $container); +    } + +    public function test_phpbb_create_install_container() +    { +        $phpbb_root_path = __DIR__ . '/../../phpBB/'; +        $extensions = array( +            new phpbb_di_extension_config(__DIR__ . '/fixtures/config.php'), +            new phpbb_di_extension_core($phpbb_root_path), +        ); +        $container = phpbb_create_install_container($phpbb_root_path, 'php'); + +        $this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerBuilder', $container); +        $this->assertTrue($container->isFrozen()); +    } + +    public function test_phpbb_create_compiled_container() +    { +        $phpbb_root_path = __DIR__ . '/../../phpBB/'; +        $extensions = array( +            new phpbb_di_extension_config(__DIR__ . '/fixtures/config.php'), +            new phpbb_di_extension_core($phpbb_root_path), +        ); +        $container = phpbb_create_compiled_container($extensions, array(), $phpbb_root_path, 'php'); + +        $this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerBuilder', $container); +        $this->assertTrue($container->isFrozen()); +    } +} + +class phpbb_db_driver_container_mock extends phpbb_db_driver +{ +    public function sql_connect() +    { +    } + +    public function sql_query() +    { +    } + +    public function sql_fetchrow() +    { +    } + +    public function sql_freeresult() +    { +    } +} diff --git a/tests/di/fixtures/config.php b/tests/di/fixtures/config.php new file mode 100644 index 0000000000..5033d2dc9f --- /dev/null +++ b/tests/di/fixtures/config.php @@ -0,0 +1,11 @@ +<?php +// phpBB 3.1.x auto-generated configuration file +// Do not change anything in this file! +$dbms = 'container_mock'; +$dbhost = '127.0.0.1'; +$dbport = ''; +$dbname = 'phpbb'; +$dbuser = 'root'; +$dbpasswd = ''; +$table_prefix = 'phpbb_'; +$acm_type = 'phpbb_cache_driver_null'; diff --git a/tests/download/http_byte_range_test.php b/tests/download/http_byte_range_test.php new file mode 100644 index 0000000000..23b9169fe3 --- /dev/null +++ b/tests/download/http_byte_range_test.php @@ -0,0 +1,64 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_download.php'; + +class phpbb_download_http_byte_range_test extends phpbb_test_case +{ +	public function test_find_range_request() +	{ +		// Missing 'bytes=' prefix +		$GLOBALS['request'] = new phpbb_mock_request(); +		$GLOBALS['request']->set_header('Range', 'bztes='); +		$this->assertEquals(false, phpbb_find_range_request()); +		unset($GLOBALS['request']); + +		$GLOBALS['request'] = new phpbb_mock_request(); +		$_ENV['HTTP_RANGE'] = 'bztes='; +		$this->assertEquals(false, phpbb_find_range_request()); +		unset($_ENV['HTTP_RANGE']); + +		$GLOBALS['request'] = new phpbb_mock_request(); +		$GLOBALS['request']->set_header('Range', 'bytes=0-0,123-125'); +		$this->assertEquals(array('0-0', '123-125'), phpbb_find_range_request()); +		unset($GLOBALS['request']); +	} + +	/** +	* @dataProvider parse_range_request_data() +	*/ +	public function test_parse_range_request($request_array, $filesize, $expected) +	{ +		$this->assertEquals($expected, phpbb_parse_range_request($request_array, $filesize)); +	} + +	public function parse_range_request_data() +	{ +		return array( +			// Does not read until the end of file. +			array( +				array('3-4'), +				10, +				false, +			), + +			// Valid request, handle second range. +			array( +				array('0-0', '120-125'), +				125, +				array( +					'byte_pos_start'	=> 120, +					'byte_pos_end'		=> 124, +					'bytes_requested'	=> 5, +					'bytes_total'		=> 125, +				) +			), +		); +	} +} diff --git a/tests/event/dispatcher_test.php b/tests/event/dispatcher_test.php new file mode 100644 index 0000000000..9b9203e06a --- /dev/null +++ b/tests/event/dispatcher_test.php @@ -0,0 +1,29 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_event_dispatcher_test extends phpbb_test_case +{ +    public function test_trigger_event() +    { +        $dispatcher = new phpbb_event_dispatcher(new phpbb_mock_container_builder()); + +        $dispatcher->addListener('core.test_event', function (phpbb_event_data $event) { +            $event['foo'] = $event['foo'] . '2'; +            $event['bar'] = $event['bar'] . '2'; +        }); + +        $foo = 'foo'; +        $bar = 'bar'; + +        $vars = array('foo', 'bar'); +        $result = $dispatcher->trigger_event('core.test_event', compact($vars)); + +        $this->assertSame(array('foo' => 'foo2', 'bar' => 'bar2'), $result); +    } +} diff --git a/tests/extension/acp.php b/tests/extension/acp.php new file mode 100644 index 0000000000..790df77c0d --- /dev/null +++ b/tests/extension/acp.php @@ -0,0 +1,205 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class acp_test extends phpbb_functional_test_case +{ +	static private $copied_files = array(); +	static private $helper; + +	/** +	* This should only be called once before the tests are run. +	* This is used to copy the extensions to the phpBB install +	*/ +	static public function setUpBeforeClass() +	{ +		global $phpbb_root_path; + +		parent::setUpBeforeClass(); + +		self::$helper = new phpbb_test_case_helpers(self); + +		// First, move any extensions setup on the board to a temp directory +		self::$copied_files = self::$helper->copy_dir($phpbb_root_path . 'ext/', $phpbb_root_path . 'store/temp_ext/'); + +		// Then empty the ext/ directory on the board (for accurate test cases) +		self::$helper->empty_dir($phpbb_root_path . 'ext/'); + +		// Copy our ext/ files from the test case to the board +		self::$copied_files = array_merge(self::$copied_files, self::$helper->copy_dir(dirname(__FILE__) . '/ext/', $phpbb_root_path . 'ext/')); +	} + +	public function setUp() +	{ +		parent::setUp(); + +		$this->get_db(); + +		// Clear the phpbb_ext table +		$this->db->sql_query('DELETE FROM phpbb_ext'); + +		// Insert our base data +		$insert_rows = array( +			array( +				'ext_name'		=> 'foo', +				'ext_active'	=> true, +				'ext_state'		=> 'b:0;', +			), +			array( +				'ext_name'		=> 'vendor/moo', +				'ext_active'	=> false, +				'ext_state'		=> 'b:0;', +			), + +			// do not exist +			array( +				'ext_name'		=> 'test2', +				'ext_active'	=> true, +				'ext_state'		=> 'b:0;', +			), +			array( +				'ext_name'		=> 'test3', +				'ext_active'	=> false, +				'ext_state'		=> 'b:0;', +			), +		); +		$this->db->sql_multi_insert('phpbb_ext', $insert_rows); + +		$this->login(); +		$this->admin_login(); + +		$this->add_lang('acp/extensions'); +	} + +	/** +	* This should only be called once after the tests are run. +	* This is used to remove the files copied to the phpBB install +	*/ +	static public function tearDownAfterClass() +	{ +		global $phpbb_root_path; + +		// Copy back the board installed extensions from the temp directory +		self::$helper->copy_dir($phpbb_root_path . 'store/temp_ext/', $phpbb_root_path . 'ext/'); + +		self::$copied_files[] = $phpbb_root_path . 'store/temp_ext/'; + +		// Remove all of the files we copied around (from board ext -> temp_ext, from test ext -> board ext) +		self::$helper->remove_files(self::$copied_files); +	} + +	public function test_list() +	{ +        $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid); + +        $this->assertCount(1, $crawler->filter('.ext_enabled')); +        $this->assertCount(4, $crawler->filter('.ext_disabled')); + +        $this->assertContains('phpBB Foo Extension', $crawler->filter('.ext_enabled')->eq(0)->text()); +        $this->assertContainsLang('PURGE', $crawler->filter('.ext_enabled')->eq(0)->text()); + +        $this->assertContains('The "test2" extension is not valid.', $crawler->filter('.ext_disabled')->eq(0)->text()); + +        $this->assertContains('The "test3" extension is not valid.', $crawler->filter('.ext_disabled')->eq(1)->text()); + +        $this->assertContains('phpBB Moo Extension', $crawler->filter('.ext_disabled')->eq(2)->text()); +        $this->assertContainsLang('DETAILS', $crawler->filter('.ext_disabled')->eq(2)->text()); +        $this->assertContainsLang('ENABLE', $crawler->filter('.ext_disabled')->eq(2)->text()); +        $this->assertContainsLang('PURGE', $crawler->filter('.ext_disabled')->eq(2)->text()); + +        $this->assertContains('The "bar" extension is not valid.', $crawler->filter('.ext_disabled')->eq(3)->text()); +	} + +	public function test_details() +	{ +        $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=foo&sid=' . $this->sid); + +        $validation = array( +        	'DISPLAY_NAME'		=> 'phpBB Foo Extension', +        	'CLEAN_NAME'		=> 'foo/example', +        	'DESCRIPTION'		=> 'An example/sample extension to be used for testing purposes in phpBB Development.', +        	'VERSION'	  		=> '1.0.0', +        	'TIME'				=> '2012-02-15 01:01:01', +        	'LICENCE'			=> 'GPL-2.0', +        	'PHPBB_VERSION'		=> '3.1.0-dev', +        	'PHP_VERSION'		=> '>=5.3', +        	'AUTHOR_NAME'		=> 'Nathan Guse', +        	'AUTHOR_EMAIL'		=> 'email@phpbb.com', +        	'AUTHOR_HOMEPAGE'	=> 'http://lithiumstudios.org', +        	'AUTHOR_ROLE'		=> 'N/A', +        ); + +        for ($i = 0; $i < $crawler->filter('dl')->count(); $i++) +        { +        	$text = $crawler->filter('dl')->eq($i)->text(); + +        	$match = false; + +        	foreach ($validation as $language_key => $expected) +        	{ +        		if (strpos($text, $this->lang($language_key)) === 0) +        		{ +        			$match = true; + +        			$this->assertContains($expected, $text); +				} +			} + +			if (!$match) +			{ +				$this->fail('Unexpected field: "' . $text . '"'); +			} +		} +	} + +	public function test_enable_pre() +	{ +		// Foo is already enabled (redirect to list) +        $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=foo&sid=' . $this->sid); +        $this->assertContainsLang('EXTENSION_NAME', $crawler->filter('html')->text()); +        $this->assertContainsLang('EXTENSION_OPTIONS', $crawler->filter('html')->text()); +        $this->assertContainsLang('EXTENSION_ACTIONS', $crawler->filter('html')->text()); + +        $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); +        $this->assertContainsLang('ENABLE_CONFIRM', $crawler->filter('html')->text()); +	} + +	public function test_disable_pre() +	{ +        // Moo is not enabled (redirect to list) +        $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); +        $this->assertContainsLang('EXTENSION_NAME', $crawler->filter('html')->text()); +        $this->assertContainsLang('EXTENSION_OPTIONS', $crawler->filter('html')->text()); +        $this->assertContainsLang('EXTENSION_ACTIONS', $crawler->filter('html')->text()); + +        $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=foo&sid=' . $this->sid); +        $this->assertContainsLang('DISABLE_CONFIRM', $crawler->filter('html')->text()); +	} + +	public function test_purge_pre() +	{ +        // test2 is not available (error) +        $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge_pre&ext_name=test2&sid=' . $this->sid); +        $this->assertContains('The required file does not exist', $crawler->filter('html')->text()); + +        $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge_pre&ext_name=foo&sid=' . $this->sid); +        $this->assertContainsLang('PURGE_CONFIRM', $crawler->filter('html')->text()); +	} + +	public function test_actions() +	{ +        $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable&ext_name=vendor%2Fmoo&sid=' . $this->sid); +        $this->assertContainsLang('ENABLE_SUCCESS', $crawler->filter('html')->text()); + +        $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable&ext_name=vendor%2Fmoo&sid=' . $this->sid); +        $this->assertContainsLang('DISABLE_SUCCESS', $crawler->filter('html')->text()); + +        $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge&ext_name=vendor%2Fmoo&sid=' . $this->sid); +        $this->assertContainsLang('PURGE_SUCCESS', $crawler->filter('html')->text()); +	} +}
\ No newline at end of file diff --git a/tests/extension/ext/bar/ext.php b/tests/extension/ext/bar/ext.php new file mode 100644 index 0000000000..5585edf9ac --- /dev/null +++ b/tests/extension/ext/bar/ext.php @@ -0,0 +1,24 @@ +<?php + +class phpbb_ext_bar_ext extends phpbb_extension_base +{ +	static public $state; + +	public function enable_step($old_state) +	{ +		// run 4 steps, then quit +		if ($old_state === 4) +		{ +			return false; +		} + +		if ($old_state === false) +		{ +			$old_state = 0; +		} + +		self::$state = ++$old_state; + +		return self::$state; +	} +} diff --git a/tests/extension/ext/bar/my/hidden_class.php b/tests/extension/ext/bar/my/hidden_class.php new file mode 100644 index 0000000000..0261d7c59a --- /dev/null +++ b/tests/extension/ext/bar/my/hidden_class.php @@ -0,0 +1,5 @@ +<?php + +class phpbb_ext_bar_my_hidden_class +{ +} diff --git a/tests/extension/ext/foo/a_class.php b/tests/extension/ext/foo/a_class.php new file mode 100644 index 0000000000..b7be1ad654 --- /dev/null +++ b/tests/extension/ext/foo/a_class.php @@ -0,0 +1,5 @@ +<?php + +class phpbb_ext_foo_a_class +{ +} diff --git a/tests/extension/ext/foo/b_class.php b/tests/extension/ext/foo/b_class.php new file mode 100644 index 0000000000..4645266122 --- /dev/null +++ b/tests/extension/ext/foo/b_class.php @@ -0,0 +1,5 @@ +<?php + +class phpbb_ext_foo_b_class +{ +} diff --git a/tests/extension/ext/foo/composer.json b/tests/extension/ext/foo/composer.json new file mode 100644 index 0000000000..744f7be625 --- /dev/null +++ b/tests/extension/ext/foo/composer.json @@ -0,0 +1,22 @@ +{ +	"name": "foo/example", +	"type": "phpbb3-extension", +	"description": "An example/sample extension to be used for testing purposes in phpBB Development.", +	"version": "1.0.0", +	"time": "2012-02-15 01:01:01", +	"licence": "GPL-2.0", +	"authors": [{ +			"name": "Nathan Guse", +			"username": "EXreaction", +			"email": "email@phpbb.com", +			"homepage": "http://lithiumstudios.org", +			"role": "N/A" +		}], +	"require": { +		"php": ">=5.3", +		"phpbb": "3.1.0-dev" +	}, +	"extra": { +		"display-name": "phpBB Foo Extension" +	} +} diff --git a/tests/extension/ext/foo/ext.php b/tests/extension/ext/foo/ext.php new file mode 100644 index 0000000000..60b3ad1f16 --- /dev/null +++ b/tests/extension/ext/foo/ext.php @@ -0,0 +1,13 @@ +<?php + +class phpbb_ext_foo_ext extends phpbb_extension_base +{ +	static public $disabled; + +	public function disable_step($old_state) +	{ +		self::$disabled = true; + +		return false; +	} +} diff --git a/tests/extension/ext/foo/sub/type/alternative.php b/tests/extension/ext/foo/sub/type/alternative.php new file mode 100644 index 0000000000..2ea7353f4b --- /dev/null +++ b/tests/extension/ext/foo/sub/type/alternative.php @@ -0,0 +1,5 @@ +<?php + +class phpbb_ext_foo_sub_type_alternative +{ +} diff --git a/tests/extension/ext/foo/type/alternative.php b/tests/extension/ext/foo/type/alternative.php new file mode 100644 index 0000000000..404b66b965 --- /dev/null +++ b/tests/extension/ext/foo/type/alternative.php @@ -0,0 +1,5 @@ +<?php + +class phpbb_ext_foo_type_alternative +{ +} diff --git a/tests/extension/ext/foo/type/dummy/empty.txt b/tests/extension/ext/foo/type/dummy/empty.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/extension/ext/foo/type/dummy/empty.txt diff --git a/tests/extension/ext/foo/typewrong/error.php b/tests/extension/ext/foo/typewrong/error.php new file mode 100644 index 0000000000..ba22cfae9a --- /dev/null +++ b/tests/extension/ext/foo/typewrong/error.php @@ -0,0 +1,5 @@ +<?php + +class phpbb_ext_foo_typewrong_error +{ +} diff --git a/tests/extension/ext/vendor/moo/composer.json b/tests/extension/ext/vendor/moo/composer.json new file mode 100644 index 0000000000..c91a5e027b --- /dev/null +++ b/tests/extension/ext/vendor/moo/composer.json @@ -0,0 +1,22 @@ +{ +	"name": "moo/example", +	"type": "phpbb3-extension", +	"description": "An example/sample extension to be used for testing purposes in phpBB Development.", +	"version": "1.0.0", +	"time": "2012-02-15 01:01:01", +	"licence": "GNU GPL v2", +	"authors": [{ +			"name": "Nathan Guse", +			"username": "EXreaction", +			"email": "email@phpbb.com", +			"homepage": "http://lithiumstudios.org", +			"role": "N/A" +		}], +	"require": { +		"php": ">=5.3", +		"phpbb": "3.1.0-dev" +	}, +	"extra": { +		"display-name": "phpBB Moo Extension" +	} +} diff --git a/tests/extension/ext/vendor/moo/ext.php b/tests/extension/ext/vendor/moo/ext.php new file mode 100644 index 0000000000..e0ac1a22cc --- /dev/null +++ b/tests/extension/ext/vendor/moo/ext.php @@ -0,0 +1,13 @@ +<?php + +class phpbb_ext_vendor_moo_ext extends phpbb_extension_base +{ +	static public $purged; + +	public function purge_step($old_state) +	{ +		self::$purged = true; + +		return false; +	} +} diff --git a/tests/extension/ext/vendor/moo/feature_class.php b/tests/extension/ext/vendor/moo/feature_class.php new file mode 100644 index 0000000000..c3bcc4451c --- /dev/null +++ b/tests/extension/ext/vendor/moo/feature_class.php @@ -0,0 +1,5 @@ +<?php + +class phpbb_ext_vendor_moo_feature_class +{ +} diff --git a/tests/extension/finder_test.php b/tests/extension/finder_test.php new file mode 100644 index 0000000000..622f404786 --- /dev/null +++ b/tests/extension/finder_test.php @@ -0,0 +1,203 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_extension_finder_test extends phpbb_test_case +{ +	protected $extension_manager; +	protected $finder; + +	public function setUp() +	{ +		$this->extension_manager = new phpbb_mock_extension_manager( +			dirname(__FILE__) . '/', +			array( +				'foo' => array( +					'ext_name' => 'foo', +					'ext_active' => '1', +					'ext_path' => 'ext/foo/', +				), +				'bar' => array( +					'ext_name' => 'bar', +					'ext_active' => '1', +					'ext_path' => 'ext/bar/', +				), +			)); + +		$this->finder = $this->extension_manager->get_finder(); +	} + +	public function test_suffix_get_classes() +	{ +		$classes = $this->finder +			->core_path('includes/default/') +			->extension_suffix('_class') +			->get_classes(); + +		sort($classes); +		$this->assertEquals( +			array( +				'phpbb_default_implementation', +				'phpbb_ext_bar_my_hidden_class', +				'phpbb_ext_foo_a_class', +				'phpbb_ext_foo_b_class', +			), +			$classes +		); +	} + +	public function test_get_directories() +	{ +		$dirs = $this->finder +			->directory('/type') +			->get_directories(); + +		sort($dirs); +		$this->assertEquals(array( +			dirname(__FILE__) . '/ext/foo/type/', +		), $dirs); +	} + +	public function test_prefix_get_directories() +	{ +		$dirs = $this->finder +            ->prefix('t') +			->get_directories(); + +		sort($dirs); +		$this->assertEquals(array( +			dirname(__FILE__) . '/ext/foo/sub/type/', +			dirname(__FILE__) . '/ext/foo/type/', +			dirname(__FILE__) . '/ext/foo/typewrong/', +		), $dirs); +	} + +	public function test_prefix_get_classes() +	{ +		$classes = $this->finder +			->core_path('includes/default/') +			->extension_prefix('hidden_') +			->get_classes(); + +		sort($classes); +		$this->assertEquals( +			array( +				'phpbb_default_implementation', +				'phpbb_ext_bar_my_hidden_class', +			), +			$classes +		); +	} + +	public function test_directory_get_classes() +	{ +		$classes = $this->finder +			->core_path('includes/default/') +			->extension_directory('type') +			->get_classes(); + +		sort($classes); +		$this->assertEquals( +			array( +				'phpbb_default_implementation', +				'phpbb_ext_foo_sub_type_alternative', +				'phpbb_ext_foo_type_alternative', +			), +			$classes +		); +	} + +	public function test_absolute_directory_get_classes() +	{ +		$classes = $this->finder +			->directory('/type/') +			->get_classes(); + +		sort($classes); +		$this->assertEquals( +			array( +				'phpbb_ext_foo_type_alternative', +			), +			$classes +		); +	} + +	public function test_sub_directory_get_classes() +	{ +		$classes = $this->finder +			->directory('/sub/type') +			->get_classes(); + +		sort($classes); +		$this->assertEquals( +			array( +				'phpbb_ext_foo_sub_type_alternative', +			), +			$classes +		); +	} + +	public function test_get_classes_create_cache() +	{ +		$cache = new phpbb_mock_cache; +		$finder = new phpbb_extension_finder($this->extension_manager, dirname(__FILE__) . '/', $cache, '.php', '_custom_cache_name'); +		$files = $finder->suffix('_class.php')->get_files(); + +		$expected_files = array( +			'ext/bar/my/hidden_class.php' => 'bar', +			'ext/foo/a_class.php' => 'foo', +			'ext/foo/b_class.php' => 'foo', +		); + +		$query = array( +			'core_path' => false, +			'core_suffix' => '_class.php', +			'core_prefix' => false, +			'core_directory' => false, +			'extension_suffix' => '_class.php', +			'extension_prefix' => false, +			'extension_directory' => false, +			'is_dir' => false, +		); + +		$cache->checkAssociativeVar($this, '_custom_cache_name', array( +			md5(serialize($query)) => $expected_files, +		), false); +	} + +	public function test_cached_get_files() +	{ +		$query = array( +			'core_path' => 'includes/foo', +			'core_suffix' => false, +			'core_prefix' => false, +			'core_directory' => 'bar', +			'extension_suffix' => false, +			'extension_prefix' => false, +			'extension_directory' => false, +			'is_dir' => false, +		); + +		$finder = new phpbb_extension_finder($this->extension_manager, dirname(__FILE__) . '/', new phpbb_mock_cache(array( +			'_ext_finder' => array( +				md5(serialize($query)) => array('file_name' => 'extension'), +			), +		))); + +		$classes = $finder +			->core_path($query['core_path']) +			->core_directory($query['core_directory']) +			->get_files(); + +		sort($classes); +		$this->assertEquals( +			array(dirname(__FILE__) . '/file_name'), +			$classes +		); +	} +} diff --git a/tests/extension/fixtures/extensions.xml b/tests/extension/fixtures/extensions.xml new file mode 100644 index 0000000000..6eb6fd11a5 --- /dev/null +++ b/tests/extension/fixtures/extensions.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> +	<table name="phpbb_ext"> +		<column>ext_name</column> +		<column>ext_active</column> +		<column>ext_state</column> +		<row> +			<value>foo</value> +			<value>1</value> +			<value></value> +		</row> +		<row> +			<value>vendor/moo</value> +			<value>0</value> +			<value></value> +		</row> +	</table> +</dataset> diff --git a/tests/extension/includes/default/implementation.php b/tests/extension/includes/default/implementation.php new file mode 100644 index 0000000000..91d5f8aa2f --- /dev/null +++ b/tests/extension/includes/default/implementation.php @@ -0,0 +1,5 @@ +<?php + +class phpbb_default_impl_class implements phpbb_default_interface +{ +} diff --git a/tests/extension/manager_test.php b/tests/extension/manager_test.php new file mode 100644 index 0000000000..5cde5bccdb --- /dev/null +++ b/tests/extension/manager_test.php @@ -0,0 +1,103 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/ext/bar/ext.php'; +require_once dirname(__FILE__) . '/ext/foo/ext.php'; +require_once dirname(__FILE__) . '/ext/vendor/moo/ext.php'; + +class phpbb_extension_manager_test extends phpbb_database_test_case +{ +	protected $extension_manager; +	protected $class_loader; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/extensions.xml'); +	} + +	protected function setUp() +	{ +		parent::setUp(); + +		$this->extension_manager = new phpbb_extension_manager( +			$this->new_dbal(), +			new phpbb_config(array()), +			'phpbb_ext', +			dirname(__FILE__) . '/', +			'.php', +			new phpbb_mock_cache +		); +	} + +	public function test_available() +	{ +		$this->assertEquals(array('bar', 'foo', 'vendor/moo'), array_keys($this->extension_manager->all_available())); +	} + +	public function test_enabled() +	{ +		$this->assertEquals(array('foo'), array_keys($this->extension_manager->all_enabled())); +	} + +	public function test_configured() +	{ +		$this->assertEquals(array('foo', 'vendor/moo'), array_keys($this->extension_manager->all_configured())); +	} + +	public function test_enable() +	{ +		phpbb_ext_bar_ext::$state = 0; + +		$this->assertEquals(array('foo'), array_keys($this->extension_manager->all_enabled())); +		$this->extension_manager->enable('bar'); +		$this->assertEquals(array('bar', 'foo'), array_keys($this->extension_manager->all_enabled())); +		$this->assertEquals(array('bar', 'foo', 'vendor/moo'), array_keys($this->extension_manager->all_configured())); + +		$this->assertEquals(4, phpbb_ext_bar_ext::$state); +	} + +	public function test_disable() +	{ +		phpbb_ext_foo_ext::$disabled = false; + +		$this->assertEquals(array('foo'), array_keys($this->extension_manager->all_enabled())); +		$this->extension_manager->disable('foo'); +		$this->assertEquals(array(), array_keys($this->extension_manager->all_enabled())); +		$this->assertEquals(array('foo', 'vendor/moo'), array_keys($this->extension_manager->all_configured())); + +		$this->assertTrue(phpbb_ext_foo_ext::$disabled); +	} + +	public function test_purge() +	{ +		phpbb_ext_vendor_moo_ext::$purged = false; + +		$this->assertEquals(array('foo'), array_keys($this->extension_manager->all_enabled())); +		$this->assertEquals(array('foo', 'vendor/moo'), array_keys($this->extension_manager->all_configured())); +		$this->extension_manager->purge('vendor/moo'); +		$this->assertEquals(array('foo'), array_keys($this->extension_manager->all_enabled())); +		$this->assertEquals(array('foo'), array_keys($this->extension_manager->all_configured())); + +		$this->assertTrue(phpbb_ext_vendor_moo_ext::$purged); +	} + +	public function test_enabled_no_cache() +	{ +		$extension_manager = new phpbb_extension_manager( +			$this->new_dbal(), +			new phpbb_config(array()), +			'phpbb_ext', +			dirname(__FILE__) . '/', +			'.php' +		); + +		$this->assertEquals(array('foo'), array_keys($extension_manager->all_enabled())); +	} + +} diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php new file mode 100644 index 0000000000..ce7be0dea5 --- /dev/null +++ b/tests/extension/metadata_manager_test.php @@ -0,0 +1,431 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class metadata_manager_test extends phpbb_database_test_case +{ +	protected $class_loader; +	protected $extension_manager; + +	protected $cache; +	protected $config; +	protected $db; +	protected $phpbb_root_path; +	protected $phpEx; +	protected $template; +	protected $user; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/extensions.xml'); +	} + +	protected function setUp() +	{ +		parent::setUp(); + +		$this->cache = new phpbb_mock_cache(); +		$this->config = new phpbb_config(array( +			'version'		=> '3.1.0', +		)); +		$this->db = $this->new_dbal(); +		$this->phpbb_root_path = dirname(__FILE__) . '/'; +		$this->phpEx = '.php'; +		$this->user = new phpbb_user(); + +		$this->template = new phpbb_template( +			$this->phpbb_root_path, +			$this->phpEx, +			$this->config, +			$this->user, +			new phpbb_style_resource_locator(), +			new phpbb_template_context() +		); + +		$this->extension_manager = new phpbb_extension_manager( +			$this->db, +			$this->config, +			'phpbb_ext', +			$this->phpbb_root_path, +			$this->phpEx, +			$this->cache +		); +	} + +	// Should fail from missing composer.json +	public function test_bar() +	{ +		$ext_name = 'bar'; + +		$manager = $this->get_metadata_manager($ext_name); + +		try +		{ +			$manager->get_metadata(); +		} +		catch(phpbb_extension_exception $e){} + +		$this->assertEquals((string) $e, 'The required file does not exist: ' . $this->phpbb_root_path . $this->extension_manager->get_extension_path($ext_name) . 'composer.json'); +	} + +	// Should be the same as a direct json_decode of the composer.json file +	public function test_foo() +	{ +		$ext_name = 'foo'; + +		$manager = $this->get_metadata_manager($ext_name); + +		try +		{ +			$metadata = $manager->get_metadata(); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->fail($e); +		} + +		$json = json_decode(file_get_contents($this->phpbb_root_path . 'ext/foo/composer.json'), true); + +		$this->assertEquals($metadata, $json); +	} + +	public function test_validator_non_existant() +	{ +		$ext_name = 'validator'; + +		$manager = $this->get_metadata_manager($ext_name); + +		// Non-existant data +		try +		{ +			$manager->validate('name'); + +			$this->fail('Exception not triggered'); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->assertEquals((string) $e, 'Required meta field \'name\' has not been set.'); +		} + +		try +		{ +			$manager->validate('type'); + +			$this->fail('Exception not triggered'); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->assertEquals((string) $e, 'Required meta field \'type\' has not been set.'); +		} + +		try +		{ +			$manager->validate('licence'); + +			$this->fail('Exception not triggered'); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->assertEquals((string) $e, 'Required meta field \'licence\' has not been set.'); +		} + +		try +		{ +			$manager->validate('version'); + +			$this->fail('Exception not triggered'); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->assertEquals((string) $e, 'Required meta field \'version\' has not been set.'); +		} + +		try +		{ +			$manager->validate_authors(); + +			$this->fail('Exception not triggered'); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->assertEquals((string) $e, 'Required meta field \'authors\' has not been set.'); +		} + +		$manager->merge_metadata(array( +			'authors'	=> array( +				array(), +			), +		)); + +		try +		{ +			$manager->validate_authors(); + +			$this->fail('Exception not triggered'); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->assertEquals((string) $e, 'Required meta field \'author name\' has not been set.'); +		} +	} + + +	public function test_validator_invalid() +	{ +		$ext_name = 'validator'; + +		$manager = $this->get_metadata_manager($ext_name); + +		// Invalid data +		$manager->set_metadata(array( +			'name'		=> 'asdf', +			'type'		=> 'asdf', +			'licence'	=> '', +			'version'	=> '', +		)); + +		try +		{ +			$manager->validate('name'); + +			$this->fail('Exception not triggered'); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->assertEquals((string) $e, 'Meta field \'name\' is invalid.'); +		} + +		try +		{ +			$manager->validate('type'); + +			$this->fail('Exception not triggered'); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->assertEquals((string) $e, 'Meta field \'type\' is invalid.'); +		} + +		try +		{ +			$manager->validate('licence'); + +			$this->fail('Exception not triggered'); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->assertEquals((string) $e, 'Meta field \'licence\' is invalid.'); +		} + +		try +		{ +			$manager->validate('version'); + +			$this->fail('Exception not triggered'); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->assertEquals((string) $e, 'Meta field \'version\' is invalid.'); +		} +	} + +	public function test_validator_valid() +	{ +		$ext_name = 'validator'; + +		$manager = $this->get_metadata_manager($ext_name); + +		// Valid data +		$manager->set_metadata(array( +			'name'		=> 'test/foo', +			'type'		=> 'phpbb3-extension', +			'licence'	=> 'GPL v2', +			'version'	=> '1.0.0', +		)); + +		try +		{ +			$this->assertEquals(true, $manager->validate('enable')); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->fail($e); +		} +	} + + +	public function test_validator_requirements() +	{ +		$ext_name = 'validator'; + +		$manager = $this->get_metadata_manager($ext_name); +		// Too high of requirements +		$manager->merge_metadata(array( +			'require'		=> array( +				'php'		=> '10.0.0', +				'phpbb'		=> '3.2.0', // config is set to 3.1.0 +			), +		)); + +		try +		{ +			$this->assertEquals(false, $manager->validate_require_php()); +			$this->assertEquals(false, $manager->validate_require_phpbb()); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->fail($e); +		} + + +		// Too high of requirements +		$manager->merge_metadata(array( +			'require'		=> array( +				'php'		=> '5.3.0', +				'phpbb'		=> '3.1.0-beta', // config is set to 3.1.0 +			), +		)); + +		try +		{ +			$this->assertEquals(true, $manager->validate_require_php()); +			$this->assertEquals(true, $manager->validate_require_phpbb()); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->fail($e); +		} + + +		// Too high of requirements +		$manager->merge_metadata(array( +			'require'		=> array( +				'php'		=> '>' . phpversion(), +				'phpbb'		=> '>3.1.0', // config is set to 3.1.0 +			), +		)); + +		try +		{ +			$this->assertEquals(false, $manager->validate_require_php()); +			$this->assertEquals(false, $manager->validate_require_phpbb()); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->fail($e); +		} + + +		// Too high of current install +		$manager->merge_metadata(array( +			'require'		=> array( +				'php'		=> '<' . phpversion(), +				'phpbb'		=> '<3.1.0', // config is set to 3.1.0 +			), +		)); + +		try +		{ +			$this->assertEquals(false, $manager->validate_require_php()); +			$this->assertEquals(false, $manager->validate_require_phpbb()); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->fail($e); +		} + + +		// Matching requirements +		$manager->merge_metadata(array( +			'require'		=> array( +				'php'		=> phpversion(), +				'phpbb'		=> '3.1.0', // config is set to 3.1.0 +			), +		)); + +		try +		{ +			$this->assertEquals(true, $manager->validate_require_php()); +			$this->assertEquals(true, $manager->validate_require_phpbb()); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->fail($e); +		} + + +		// Matching requirements +		$manager->merge_metadata(array( +			'require'		=> array( +				'php'		=> '>=' . phpversion(), +				'phpbb'		=> '>=3.1.0', // config is set to 3.1.0 +			), +		)); + +		try +		{ +			$this->assertEquals(true, $manager->validate_require_php()); +			$this->assertEquals(true, $manager->validate_require_phpbb()); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->fail($e); +		} + + +		// Matching requirements +		$manager->merge_metadata(array( +			'require'		=> array( +				'php'		=> '<=' . phpversion(), +				'phpbb'		=> '<=3.1.0', // config is set to 3.1.0 +			), +		)); + +		try +		{ +			$this->assertEquals(true, $manager->validate_require_php()); +			$this->assertEquals(true, $manager->validate_require_phpbb()); +		} +		catch(phpbb_extension_exception $e) +		{ +			$this->fail($e); +		} +	} + +	/** +	* Get an instance of the metadata manager +	* +	* @param string $ext_name +	* @return phpbb_extension_metadata_manager_test +	*/ +	private function get_metadata_manager($ext_name) +	{ +		return new phpbb_extension_metadata_manager_test( +			$ext_name, +			$this->db, +			$this->extension_manager, +			$this->phpbb_root_path, +			$this->phpEx, +			$this->template, +			$this->config +		); +	} +} + +class phpbb_extension_metadata_manager_test extends phpbb_extension_metadata_manager +{ +	public function set_metadata($metadata) +	{ +		$this->metadata = $metadata; +	} + +	public function merge_metadata($metadata) +	{ +		$this->metadata = array_merge($this->metadata, $metadata); +	} +}
\ No newline at end of file diff --git a/tests/fixtures/empty.xml b/tests/fixtures/empty.xml new file mode 100644 index 0000000000..195e30e38d --- /dev/null +++ b/tests/fixtures/empty.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> +	<table name="phpbb_sessions"> +		<column>session_id</column> +		<column>session_user_id</column> +		<column>session_ip</column> +		<column>session_browser</column> +	</table> +</dataset> diff --git a/tests/functional/acp_permissions_test.php b/tests/functional/acp_permissions_test.php new file mode 100644 index 0000000000..f7fd44fc89 --- /dev/null +++ b/tests/functional/acp_permissions_test.php @@ -0,0 +1,128 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_acp_permissions_test extends phpbb_functional_test_case +{ +	public function setUp() +	{ +		parent::setUp(); + +		$this->login(); +		$this->admin_login(); +		$this->add_lang('acp/permissions'); +	} + +	public function test_permissions_tab() +	{ +		// Permissions tab +		// XXX hardcoded id +		$crawler = $this->request('GET', 'adm/index.php?i=16&sid=' . $this->sid); +		$this->assert_response_success(); +		// these language strings are html +		$this->assertContains($this->lang('ACP_PERMISSIONS_EXPLAIN'), $this->client->getResponse()->getContent()); +	} + +	public function test_select_user() +	{ +		// User permissions +		$crawler = $this->request('GET', 'adm/index.php?i=acp_permissions&icat=16&mode=setting_user_global&sid=' . $this->sid); +		$this->assert_response_success(); +		$this->assertContains($this->lang('ACP_USERS_PERMISSIONS_EXPLAIN'), $this->client->getResponse()->getContent()); + +		// Select admin +		$form = $crawler->selectButton($this->lang('SUBMIT'))->form(); +		$data = array('username[0]' => 'admin'); +		$form->setValues($data); +		$crawler = $this->client->submit($form); +		$this->assert_response_success(); +		$this->assertContains($this->lang('ACL_SET'), $crawler->filter('h1')->eq(1)->text()); +	} + +	public function permissions_data() +	{ +		return array( +			// description +			// permission type +			// permission name +			// mode +			// object name +			// object id +			array( +				'user permission', +				'u_', +				'u_hideonline', +				'setting_user_global', +				'user_id', +				2, +			), +			array( +				'moderator permission', +				'm_', +				'm_ban', +				'setting_mod_global', +				'group_id', +				4, +			), +			/* Admin does not work yet, probably because founder can do everything +			array( +				'admin permission', +				'a_', +				'a_forum', +				'setting_admin_global', +				'group_id', +				5, +			), +			*/ +		); +	} + +	/** +	* @dataProvider permissions_data +	*/ +	public function test_change_permission($description, $permission_type, $permission, $mode, $object_name, $object_id) +	{ +		// Get the form +		$crawler = $this->request('GET', "adm/index.php?i=acp_permissions&icat=16&mode=$mode&${object_name}[0]=$object_id&type=$permission_type&sid=" . $this->sid); +		$this->assert_response_success(); +		$this->assertContains($this->lang('ACL_SET'), $crawler->filter('h1')->eq(1)->text()); + +		// XXX globals for phpbb_auth, refactor it later +		global $db, $cache; +		$db = $this->get_db(); +		$cache = new phpbb_mock_null_cache; + +		$auth = new phpbb_auth; +		// XXX hardcoded id +		$user_data = $auth->obtain_user_data(2); +		$auth->acl($user_data); +		$this->assertEquals(1, $auth->acl_get($permission)); + +		// Set u_hideonline to never +		$form = $crawler->selectButton($this->lang('APPLY_PERMISSIONS'))->form(); +		// initially it should be a yes +		$values = $form->getValues(); +		$this->assertEquals(1, $values["setting[$object_id][0][$permission]"]); +		// set to never +		$data = array("setting[$object_id][0][$permission]" => '0'); +		$form->setValues($data); +		$crawler = $this->client->submit($form); +		$this->assert_response_success(); +		$this->assertContains($this->lang('AUTH_UPDATED'), $crawler->text()); + +		// check acl again +		$auth = new phpbb_auth; +		// XXX hardcoded id +		$user_data = $auth->obtain_user_data(2); +		$auth->acl($user_data); +		$this->assertEquals(0, $auth->acl_get($permission)); +	} +} diff --git a/tests/functional/auth_test.php b/tests/functional/auth_test.php new file mode 100644 index 0000000000..f92a4a2210 --- /dev/null +++ b/tests/functional/auth_test.php @@ -0,0 +1,63 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_auth_test extends phpbb_functional_test_case +{ +	public function test_login() +	{ +		$this->login(); + +		// check for logout link +		$crawler = $this->request('GET', 'index.php'); +		$this->assert_response_success(); +		$this->assertContains($this->lang('LOGOUT_USER', 'admin'), $crawler->filter('.navbar')->text()); +	} + +	public function test_login_other() +	{ +		$this->create_user('anothertestuser'); +		$this->login('anothertestuser'); +		$crawler = $this->request('GET', 'index.php'); +		$this->assert_response_success(); +		$this->assertContains('anothertestuser', $crawler->filter('.icon-logout')->text()); +	} + +	/** +	* @depends test_login +	*/ +	public function test_logout() +	{ +		$this->login(); +		$this->add_lang('ucp'); + +		// logout +		$crawler = $this->request('GET', 'ucp.php?sid=' . $this->sid . '&mode=logout'); +		$this->assert_response_success(); +		$this->assertContains($this->lang('LOGOUT_REDIRECT'), $crawler->filter('#message')->text()); + +		// look for a register link, which should be visible only when logged out +		$crawler = $this->request('GET', 'index.php'); +		$this->assert_response_success(); +		$this->assertContains($this->lang('REGISTER'), $crawler->filter('.navbar')->text()); +	} + +	public function test_acp_login() +	{ +		$this->login(); +		$this->admin_login(); + +		// check that we are logged in +		$crawler = $this->request('GET', 'adm/index.php?sid=' . $this->sid); +		$this->assert_response_success(); +		$this->assertContains($this->lang('ADMIN_PANEL'), $crawler->filter('h1')->text()); +	} +} diff --git a/tests/functional/browse_test.php b/tests/functional/browse_test.php index 723cf93232..b5748059c6 100644 --- a/tests/functional/browse_test.php +++ b/tests/functional/browse_test.php @@ -15,12 +15,21 @@ class phpbb_functional_browse_test extends phpbb_functional_test_case  	public function test_index()  	{  		$crawler = $this->request('GET', 'index.php'); +		$this->assert_response_success();  		$this->assertGreaterThan(0, $crawler->filter('.topiclist')->count());  	}  	public function test_viewforum()  	{  		$crawler = $this->request('GET', 'viewforum.php?f=2'); +		$this->assert_response_success();  		$this->assertGreaterThan(0, $crawler->filter('.topiclist')->count());  	} + +	public function test_viewtopic() +	{ +		$crawler = $this->request('GET', 'viewtopic.php?t=1'); +		$this->assert_response_success(); +		$this->assertGreaterThan(0, $crawler->filter('.postbody')->count()); +	}  } diff --git a/tests/functional/extension_controller_test.php b/tests/functional/extension_controller_test.php new file mode 100644 index 0000000000..f28b321942 --- /dev/null +++ b/tests/functional/extension_controller_test.php @@ -0,0 +1,151 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_extension_controller_test extends phpbb_functional_test_case +{ +	protected $phpbb_extension_manager; + +	static protected $fixtures = array( +		'foo/bar/config/routing.yml', +		'foo/bar/config/services.yml', +		'foo/bar/controller/controller.php', +		'foo/bar/styles/prosilver/template/foo_bar_body.html', +	); + +	/** +	* This should only be called once before the tests are run. +	* This is used to copy the fixtures to the phpBB install +	*/ +	static public function setUpBeforeClass() +	{ +		global $phpbb_root_path; +		parent::setUpBeforeClass(); + +		$directories = array( +			$phpbb_root_path . 'ext/foo/bar/', +			$phpbb_root_path . 'ext/foo/bar/config/', +			$phpbb_root_path . 'ext/foo/bar/controller/', +			$phpbb_root_path . 'ext/foo/bar/styles/prosilver/template', +		); + +		foreach ($directories as $dir) +		{ +			if (!is_dir($dir)) +			{ +				mkdir($dir, 0777, true); +			} +		} + +		foreach (self::$fixtures as $fixture) +		{ +			copy( +				"tests/functional/fixtures/ext/$fixture", +				"{$phpbb_root_path}ext/$fixture"); +		} +	} + +	/** +	* This should only be called once after the tests are run. +	* This is used to remove the fixtures from the phpBB install +	*/ +	static public function tearDownAfterClass() +	{ +		global $phpbb_root_path; + +		foreach (self::$fixtures as $fixture) +		{ +			unlink("{$phpbb_root_path}ext/$fixture"); +		} + +		rmdir("{$phpbb_root_path}ext/foo/bar/config"); +		rmdir("{$phpbb_root_path}ext/foo/bar/controller"); +		rmdir("{$phpbb_root_path}ext/foo/bar/styles/prosilver/template"); +		rmdir("{$phpbb_root_path}ext/foo/bar/styles/prosilver"); +		rmdir("{$phpbb_root_path}ext/foo/bar/styles"); +		rmdir("{$phpbb_root_path}ext/foo/bar"); +		rmdir("{$phpbb_root_path}ext/foo"); +	} + +	public function setUp() +	{ +		parent::setUp(); + +		$this->phpbb_extension_manager = $this->get_extension_manager(); + +		$this->purge_cache(); +	} + +	/** +	* Check a controller for extension foo/bar. +	*/ +	public function test_foo_bar() +	{ +		$this->phpbb_extension_manager->enable('foo/bar'); +		$crawler = $this->request('GET', 'app.php?controller=foo/bar'); +		$this->assert_response_success(); +		$this->assertContains("foo/bar controller handle() method", $crawler->filter('body')->text()); +		$this->phpbb_extension_manager->purge('foo/bar'); +	} + +	/** +	* Check the output of a controller using the template system +	*/ +	public function test_controller_with_template() +	{ +		$this->phpbb_extension_manager->enable('foo/bar'); +		$crawler = $this->request('GET', 'app.php?controller=foo/template'); +		$this->assert_response_success(); +		$this->assertContains("I am a variable", $crawler->filter('#content')->text()); +		$this->phpbb_extension_manager->purge('foo/bar'); +	} + +	/** +	* Check the error produced by calling a controller without a required +	* argument. +	*/ +	public function test_missing_argument() +	{ +		$this->phpbb_extension_manager->enable('foo/bar'); +		$crawler = $this->request('GET', 'app.php?controller=foo/baz'); +		$this->assertEquals(500, $this->client->getResponse()->getStatus()); +		$this->assertContains('Missing value for argument #1: test in class phpbb_ext_foo_bar_controller:baz', $crawler->filter('body')->text()); +		$this->phpbb_extension_manager->purge('foo/bar'); +	} + +	/** +	* Check the status code resulting from an exception thrown by a controller +	*/ +	public function test_exception_should_result_in_500_status_code() +	{ +		$this->phpbb_extension_manager->enable('foo/bar'); +		$crawler = $this->request('GET', 'app.php?controller=foo/exception'); +		$this->assertEquals(500, $this->client->getResponse()->getStatus()); +		$this->assertContains('Exception thrown from foo/exception route', $crawler->filter('body')->text()); +		$this->phpbb_extension_manager->purge('foo/bar'); +	} + +	/** +	* Check the error produced by extension at ./ext/does/not/exist. +	* +	* If an extension is disabled, its routes are not loaded. Because we +	* are not looking for a controller based on a specified extension, +	* we don't know the difference between a route in a disabled +	* extension and a route that is not defined anyway; it is the same +	* error message. +	*/ +	public function test_error_ext_disabled_or_404() +	{ +		$crawler = $this->request('GET', 'app.php?controller=does/not/exist'); +		$this->assertEquals(404, $this->client->getResponse()->getStatus()); +		$this->assertContains('No route found for "GET /does/not/exist"', $crawler->filter('body')->text()); +	} +} diff --git a/tests/functional/fileupload_form_test.php b/tests/functional/fileupload_form_test.php new file mode 100644 index 0000000000..b663c89e95 --- /dev/null +++ b/tests/functional/fileupload_form_test.php @@ -0,0 +1,74 @@ +<?php +/** + * + * @package testing + * @copyright (c) 2012 phpBB Group + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 + * + */ + +/** + * @group functional + */ +class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case +{ +	private $path; + +	public function setUp() +	{ +		parent::setUp(); +		$this->path = __DIR__ . '/fixtures/files/'; +		$this->add_lang('posting'); +		$this->login(); +	} + +	private function upload_file($filename, $mimetype) +	{ +		$file = array( +			'tmp_name' => $this->path . $filename, +			'name' => $filename, +			'type' => $mimetype, +			'size' => filesize($this->path . $filename), +			'error' => UPLOAD_ERR_OK, +		); + +		$crawler = $this->client->request( +			'POST', +			'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid, +			array('add_file' => $this->lang('ADD_FILE')), +			array('fileupload' => $file) +		); + +		return $crawler; +	} + +	public function test_empty_file() +	{ +		$this->markTestIncomplete('Test fails intermittently.'); +		$crawler = $this->upload_file('empty.png', 'image/png'); +		$this->assertEquals($this->lang('ATTACHED_IMAGE_NOT_IMAGE'), $this->assert_filter($crawler, 'div#message p')->text()); +	} + +	public function test_invalid_extension() +	{ +		$crawler = $this->upload_file('illegal-extension.bif', 'application/octet-stream'); +		$this->assertEquals($this->lang('DISALLOWED_EXTENSION', 'bif'), $crawler->filter('p.error')->text()); +	} + +	public function test_too_large() +	{ +		$this->markTestIncomplete('Functional tests use an admin account which ignores maximum upload size.'); +		$crawler = $this->upload_file('too-large.png', 'image/png'); +		$this->assertEquals($this->lang('WRONG_FILESIZE', '256', 'KiB'), $crawler->filter('p.error')->text()); +	} + +	public function test_valid_file() +	{ +		$this->markTestIncomplete('Test fails intermittently.'); +		$crawler = $this->upload_file('valid.jpg', 'image/jpeg'); +		$this->assert_response_success(); +		// ensure there was no error message rendered +		$this->assertNotContains('<h2>' . $this->lang('INFORMATION') . '</h2>', $this->client->getResponse()->getContent()); +		$this->assertContains($this->lang('POSTED_ATTACHMENTS'), $crawler->filter('#postform h3')->eq(1)->text()); +	} +} diff --git a/tests/functional/fileupload_remote_test.php b/tests/functional/fileupload_remote_test.php new file mode 100644 index 0000000000..0deb79acf6 --- /dev/null +++ b/tests/functional/fileupload_remote_test.php @@ -0,0 +1,72 @@ +<?php +/** + * + * @package testing + * @copyright (c) 2012 phpBB Group + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 + * + */ + +/** + * @group functional + */ +class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case +{ +	public function setUp() +	{ +		parent::setUp(); +		// Only doing this within the functional framework because we need a +		// URL + +		// Global $config required by unique_id +		// Global $user required by fileupload::remote_upload +		global $config, $user; + +		if (!is_array($config)) +		{ +			$config = array(); +		} + +		$config['rand_seed'] = ''; +		$config['rand_seed_last_update'] = time() + 600; + +		$user = new phpbb_mock_user(); +		$user->lang = new phpbb_mock_lang(); +	} + +	public function tearDown() +	{ +		global $config, $user; +		$user = null; +		$config = array(); +	} + +	public function test_invalid_extension() +	{ +		$upload = new fileupload('', array('jpg'), 100); +		$file = $upload->remote_upload('http://example.com/image.gif'); +		$this->assertEquals('URL_INVALID', $file->error[0]); +	} + +	public function test_non_existant() +	{ +		$upload = new fileupload('', array('jpg'), 100); +		$file = $upload->remote_upload('http://example.com/image.jpg'); +		$this->assertEquals('EMPTY_REMOTE_DATA', $file->error[0]); +	} + +	public function test_successful_upload() +	{ +		$upload = new fileupload('', array('gif'), 1000); +		$file = $upload->remote_upload($this->root_url . 'styles/prosilver/theme/images/forum_read.gif'); +		$this->assertEquals(0, sizeof($file->error)); +		$this->assertTrue(file_exists($file->filename)); +	} + +	public function test_too_large() +	{ +		$upload = new fileupload('', array('gif'), 100); +		$file = $upload->remote_upload($this->root_url . 'styles/prosilver/theme/images/forum_read.gif'); +		$this->assertEquals('WRONG_FILESIZE', $file->error[0]); +	} +} diff --git a/tests/functional/fixtures/ext/foo/bar/config/routing.yml b/tests/functional/fixtures/ext/foo/bar/config/routing.yml new file mode 100644 index 0000000000..09a30a8c67 --- /dev/null +++ b/tests/functional/fixtures/ext/foo/bar/config/routing.yml @@ -0,0 +1,15 @@ +foo_bar_controller: +    pattern: /foo/bar +    defaults: { _controller: foo_bar.controller:handle } + +foo_baz_controller: +    pattern: /foo/baz +    defaults: { _controller: foo_bar.controller:baz } + +foo_template_controller: +    pattern: /foo/template +    defaults: { _controller: foo_bar.controller:template } + +foo_exception_controller: +    pattern: /foo/exception +    defaults: { _controller: foo_bar.controller:exception } diff --git a/tests/functional/fixtures/ext/foo/bar/config/services.yml b/tests/functional/fixtures/ext/foo/bar/config/services.yml new file mode 100644 index 0000000000..33ced55af9 --- /dev/null +++ b/tests/functional/fixtures/ext/foo/bar/config/services.yml @@ -0,0 +1,6 @@ +services: +    foo_bar.controller: +        class: phpbb_ext_foo_bar_controller +        arguments: +            - @controller.helper +            - @template diff --git a/tests/functional/fixtures/ext/foo/bar/controller/controller.php b/tests/functional/fixtures/ext/foo/bar/controller/controller.php new file mode 100644 index 0000000000..5a91b5f681 --- /dev/null +++ b/tests/functional/fixtures/ext/foo/bar/controller/controller.php @@ -0,0 +1,35 @@ +<?php +use Symfony\Component\HttpFoundation\Response; + +class phpbb_ext_foo_bar_controller +{ +	protected $template; + +	public function __construct(phpbb_controller_helper $helper, phpbb_template $template) +	{ +		$this->template = $template; +		$this->helper = $helper; +	} + +	public function handle() +	{ +		return new Response('foo/bar controller handle() method', 200); +	} + +	public function baz($test) +	{ +		return new Response('Value of "test" URL argument is: ' . $test); +	} + +	public function template() +	{ +		$this->template->assign_var('A_VARIABLE', 'I am a variable'); + +		return $this->helper->render('foo_bar_body.html'); +	} + +	public function exception() +	{ +		throw new phpbb_controller_exception('Exception thrown from foo/exception route'); +	} +} diff --git a/tests/functional/fixtures/ext/foo/bar/ext.php b/tests/functional/fixtures/ext/foo/bar/ext.php new file mode 100644 index 0000000000..74359d51ab --- /dev/null +++ b/tests/functional/fixtures/ext/foo/bar/ext.php @@ -0,0 +1,6 @@ +<?php + +class phpbb_ext_foo_bar_ext extends phpbb_extension_base +{ + +} diff --git a/tests/functional/fixtures/ext/foo/bar/styles/prosilver/template/foo_bar_body.html b/tests/functional/fixtures/ext/foo/bar/styles/prosilver/template/foo_bar_body.html new file mode 100644 index 0000000000..8fb6994d3d --- /dev/null +++ b/tests/functional/fixtures/ext/foo/bar/styles/prosilver/template/foo_bar_body.html @@ -0,0 +1,3 @@ +<!-- INCLUDE overall_header.html --> +<div id="content">{A_VARIABLE}</div> +<!-- INCLUDE overall_footer.html --> diff --git a/tests/functional/fixtures/files/empty.png b/tests/functional/fixtures/files/empty.png new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/functional/fixtures/files/empty.png diff --git a/tests/functional/fixtures/files/illegal-extension.bif b/tests/functional/fixtures/files/illegal-extension.bif Binary files differnew file mode 100644 index 0000000000..3cd5038e38 --- /dev/null +++ b/tests/functional/fixtures/files/illegal-extension.bif diff --git a/tests/functional/fixtures/files/too-large.png b/tests/functional/fixtures/files/too-large.png Binary files differnew file mode 100644 index 0000000000..ed4b0abd80 --- /dev/null +++ b/tests/functional/fixtures/files/too-large.png diff --git a/tests/functional/fixtures/files/valid.jpg b/tests/functional/fixtures/files/valid.jpg Binary files differnew file mode 100644 index 0000000000..95a87ddbdf --- /dev/null +++ b/tests/functional/fixtures/files/valid.jpg diff --git a/tests/functional/lang_test.php b/tests/functional/lang_test.php new file mode 100644 index 0000000000..053806a431 --- /dev/null +++ b/tests/functional/lang_test.php @@ -0,0 +1,45 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_lang_test extends phpbb_functional_test_case +{ +	public function test_lang() +	{ +		// Test a language string present in the common language file +		$this->assertEquals('Board index', $this->lang('FORUM_INDEX')); +	} + +	/** +	* @expectedException RuntimeException +	*/ +	public function test_lang_missing() +	{ +		$this->assertEquals('Your account has now been activated. Thank you for registering.', $this->lang('ACCOUNT_ACTIVE')); +	} + +	public function test_add_lang() +	{ +		$this->add_lang('ucp'); + +		// Test a language string present only in the UCP language file +		$this->assertEquals('Your account has now been activated. Thank you for registering.', $this->lang('ACCOUNT_ACTIVE')); +	} + +	public function test_add_langs() +	{ +		$this->add_lang(array('groups', 'memberlist')); + +		// Test a language string from each UCP and memberlist +		$this->assertEquals('The selected group is already your default group.', $this->lang('ALREADY_DEFAULT_GROUP')); +		$this->assertEquals('Profile', $this->lang('ABOUT_USER')); +	} +} diff --git a/tests/functional/memberlist_test.php b/tests/functional/memberlist_test.php new file mode 100644 index 0000000000..879bee2f0e --- /dev/null +++ b/tests/functional/memberlist_test.php @@ -0,0 +1,43 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_memberlist_test extends phpbb_functional_test_case +{ +	public function test_memberlist() +	{ +		$this->create_user('memberlist-test-user'); +		// logs in as admin +		$this->login(); +		$crawler = $this->request('GET', 'memberlist.php?sid=' . $this->sid); +		$this->assert_response_success(); +		$this->assertContains('memberlist-test-user', $crawler->text()); + +		// restrict by first character +		$crawler = $this->request('GET', 'memberlist.php?first_char=m&sid=' . $this->sid); +		$this->assert_response_success(); +		$this->assertContains('memberlist-test-user', $crawler->text()); + +		// make sure results for wrong character are not returned +		$crawler = $this->request('GET', 'memberlist.php?first_char=a&sid=' . $this->sid); +		$this->assert_response_success(); +		$this->assertNotContains('memberlist-test-user', $crawler->text()); +	} + +	public function test_viewprofile() +	{ +		$this->login(); +		// XXX hardcoded user id +		$crawler = $this->request('GET', 'memberlist.php?mode=viewprofile&u=2&sid=' . $this->sid); +		$this->assert_response_success(); +		$this->assertContains('admin', $crawler->filter('h2')->text()); +	} +} diff --git a/tests/functional/posting_test.php b/tests/functional/posting_test.php new file mode 100644 index 0000000000..d05207edf0 --- /dev/null +++ b/tests/functional/posting_test.php @@ -0,0 +1,139 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_posting_test extends phpbb_functional_test_case +{ +	public function test_post_new_topic() +	{ +		$this->login(); + +		// Test creating topic +		$post = $this->create_topic(2, 'Test Topic 1', 'This is a test topic posted by the testing framework.'); + +		$crawler = $this->request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}"); +		$this->assertContains('This is a test topic posted by the testing framework.', $crawler->filter('html')->text()); + +		// Test creating a reply +		$post2 = $this->create_post(2, $post['topic_id'], 'Re: Test Topic 1', 'This is a test post posted by the testing framework.'); + +		$crawler = $this->request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); +		$this->assertContains('This is a test post posted by the testing framework.', $crawler->filter('html')->text()); + +		// Test quoting a message +		$crawler = $this->request('GET', "posting.php?mode=quote&f=2&t={$post2['topic_id']}&p={$post2['post_id']}&sid={$this->sid}"); +		$this->assert_response_success(); +		$this->assertContains('This is a test post posted by the testing framework.', $crawler->filter('html')->text()); +	} + +	/** +	* Creates a topic +	*  +	* Be sure to login before creating +	*  +	* @param int $forum_id +	* @param string $subject +	* @param string $message +	* @param array $additional_form_data Any additional form data to be sent in the request +	* @return array post_id, topic_id +	*/ +	public function create_topic($forum_id, $subject, $message, $additional_form_data = array()) +	{ +		$posting_url = "posting.php?mode=post&f={$forum_id}&sid={$this->sid}"; + +		$form_data = array_merge(array( +			'subject'		=> $subject, +			'message'		=> $message, +			'post'			=> true, +		), $additional_form_data); + +		return $this->submit_post($posting_url, 'POST_TOPIC', $form_data); +	} + +	/** +	* Creates a post +	*  +	* Be sure to login before creating +	*  +	* @param int $forum_id +	* @param string $subject +	* @param string $message +	* @param array $additional_form_data Any additional form data to be sent in the request +	* @return array post_id, topic_id +	*/ +	public function create_post($forum_id, $topic_id, $subject, $message, $additional_form_data = array()) +	{ +		$posting_url = "posting.php?mode=reply&f={$forum_id}&t={$topic_id}&sid={$this->sid}"; + +		$form_data = array_merge(array( +			'subject'		=> $subject, +			'message'		=> $message, +			'post'			=> true, +		), $additional_form_data); + +		return $this->submit_post($posting_url, 'POST_REPLY', $form_data); +	} +	 +	/** +	* Helper for submitting posts +	*  +	* @param string $posting_url +	* @param string $posting_contains +	* @param array $form_data +	* @return array post_id, topic_id +	*/ +	protected function submit_post($posting_url, $posting_contains, $form_data) +	{ +		$this->add_lang('posting'); + +		$crawler = $this->request('GET', $posting_url); +		$this->assert_response_success(); +		$this->assertContains($this->lang($posting_contains), $crawler->filter('html')->text()); + +		$hidden_fields = array( +			$crawler->filter('[type="hidden"]')->each(function ($node, $i) { +				return array('name' => $node->getAttribute('name'), 'value' => $node->getAttribute('value')); +			}), +		); + +		foreach ($hidden_fields as $fields) +		{ +			foreach($fields as $field) +			{ +				$form_data[$field['name']] = $field['value']; +			} +		} + +		// Bypass time restriction that said that if the lastclick time (i.e. time when the form was opened) +		// is not at least 2 seconds before submission, cancel the form +		$form_data['lastclick'] = 0; + +		// I use a request because the form submission method does not allow you to send data that is not +		// contained in one of the actual form fields that the browser sees (i.e. it ignores "hidden" inputs) +		// Instead, I send it as a request with the submit button "post" set to true. +		$crawler = $this->client->request('POST', $posting_url, $form_data); +		$this->assert_response_success(); +		$this->assertContains($this->lang('POST_STORED'), $crawler->filter('html')->text()); + +		$url = $crawler->selectLink($this->lang('VIEW_MESSAGE', '', ''))->link()->getUri(); +		 +		$matches = $topic_id = $post_id = false; +		preg_match_all('#&t=([0-9]+)(&p=([0-9]+))?#', $url, $matches); +		 +		$topic_id = (int) (isset($matches[1][0])) ? $matches[1][0] : 0; +		$post_id = (int) (isset($matches[3][0])) ? $matches[3][0] : 0; + +		return array( +			'topic_id'	=> $topic_id, +			'post_id'	=> $post_id, +		); +	} +} diff --git a/tests/functions/build_hidden_fields_for_query_params_test.php b/tests/functions/build_hidden_fields_for_query_params_test.php new file mode 100644 index 0000000000..ef2f5744d3 --- /dev/null +++ b/tests/functions/build_hidden_fields_for_query_params_test.php @@ -0,0 +1,71 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_build_hidden_fields_for_query_params_test extends phpbb_test_case +{ +	public function build_hidden_fields_for_query_params_test_data() +	{ +		return array( +			// get +			// post +			// exclude +			// expected +			array( +				array('foo' => 'bar'), +				array(), +				array(), +				"<input type='hidden' name=\"foo\" value=\"bar\" />", +			), +			array( +				array('foo' => 'bar', 'a' => 'b'), +				array(), +				array(), +				"<input type='hidden' name=\"foo\" value=\"bar\" /><input type='hidden' name=\"a\" value=\"b\" />", +			), +			array( +				array('a' => 'quote"', 'b' => '<less>'), +				array(), +				array(), +				"<input type='hidden' name=\"a\" value='quote\"' /><input type='hidden' name=\"b\" value=\"<less>\" />", +			), +			array( +				array('a' => "quotes'\""), +				array(), +				array(), +				"<input type='hidden' name=\"a\" value=\"quotes'"\" />", +			), +			array( +				array('foo' => 'bar', 'a' => 'b'), +				array('a' => 'c'), +				array(), +				"<input type='hidden' name=\"foo\" value=\"bar\" />", +			), +			// strict equality check +			array( +				array('foo' => 'bar', 'a' => '0'), +				array('a' => ''), +				array(), +				"<input type='hidden' name=\"foo\" value=\"bar\" />", +			), +		); +	} + +	/** +	* @dataProvider build_hidden_fields_for_query_params_test_data +	*/ +	public function test_build_hidden_fields_for_query_params($get, $post, $exclude, $expected) +	{ +		$request = new phpbb_mock_request($get, $post); +		$result = phpbb_build_hidden_fields_for_query_params($request, $exclude); + +		$this->assertEquals($expected, $result); +	} +} diff --git a/tests/functions/clean_path_test.php b/tests/functions/clean_path_test.php new file mode 100644 index 0000000000..bcbe9838d9 --- /dev/null +++ b/tests/functions/clean_path_test.php @@ -0,0 +1,44 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_clean_path_test extends phpbb_test_case +{ +	public function clean_path_test_data() +	{ +		return array( +			array('foo', 'foo'), +			array('foo/bar', 'foo/bar'), +			array('foo/bar/', 'foo/bar/'), +			array('foo/./bar', 'foo/bar'), +			array('foo/./././bar', 'foo/bar'), +			array('foo/bar/.', 'foo/bar'), +			array('./foo/bar', './foo/bar'), +			array('../foo/bar', '../foo/bar'), +			array('one/two/three', 'one/two/three'), +			array('one/two/../three', 'one/three'), +			array('one/../two/three', 'two/three'), +			array('one/two/..', 'one'), +			array('one/two/../', 'one/'), +			array('one/two/../three/../four', 'one/four'), +			array('one/two/three/../../four', 'one/four'), +		); +	} + +	/** +	* @dataProvider clean_path_test_data +	*/ +	public function test_clean_path($input, $expected) +	{ +		$output = phpbb_clean_path($input); + +		$this->assertEquals($expected, $output); +	} +} diff --git a/tests/functions/convert_30_dbms_to_31_test.php b/tests/functions/convert_30_dbms_to_31_test.php new file mode 100644 index 0000000000..d08bf87f15 --- /dev/null +++ b/tests/functions/convert_30_dbms_to_31_test.php @@ -0,0 +1,40 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_convert_30_dbms_to_31_test extends phpbb_test_case +{ +	public function convert_30_dbms_to_31_data() +	{ +		return array( +			array('firebird'), +			array('mssql'), +			array('mssql_odbc'), +			array('mssqlnative'), +			array('mysql'), +			array('mysqli'), +			array('oracle'), +			array('postgres'), +			array('sqlite'), +		); +	} + +	/** +	* @dataProvider convert_30_dbms_to_31_data +	*/ +	public function test_convert_30_dbms_to_31($input) +	{ +		$expected = "phpbb_db_driver_$input"; + +		$output = phpbb_convert_30_dbms_to_31($input); + +		$this->assertEquals($expected, $output); +	} +} diff --git a/tests/functions/get_formatted_filesize_test.php b/tests/functions/get_formatted_filesize_test.php new file mode 100644 index 0000000000..96ea2be132 --- /dev/null +++ b/tests/functions/get_formatted_filesize_test.php @@ -0,0 +1,71 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_get_formatted_filesize_test extends phpbb_test_case +{ +	public function get_formatted_filesize_test_data() +	{ +		return array( +			// exact powers of 2 +			array(1, '1 BYTES'), +			array(1024, '1 KIB'), +			array(1048576, '1 MIB'), +			array(1073741824, '1 GIB'), +			array(1099511627776, '1 TIB'), + +			// exact powers of 10 +			array(1000, '1000 BYTES'), +			array(1000000, '976.56 KIB'), +			array(1000000000, '953.67 MIB'), +			array(1000000000000, '931.32 GIB'), +			array(100000000000000, '90.95 TIB'), + +			array(0, '0 BYTES'), +			array(2, '2 BYTES'), + +			array(1023, '1023 BYTES'), +			array(1025, '1 KIB'), +			array(1048575, '1024 KIB'), + +			// String values +			// exact powers of 2 +			array('1', '1 BYTES'), +			array('1024', '1 KIB'), +			array('1048576', '1 MIB'), +			array('1073741824', '1 GIB'), +			array('1099511627776', '1 TIB'), + +			// exact powers of 10 +			array('1000', '1000 BYTES'), +			array('1000000', '976.56 KIB'), +			array('1000000000', '953.67 MIB'), +			array('1000000000000', '931.32 GIB'), +			array('100000000000000', '90.95 TIB'), + +			array('0', '0 BYTES'), +			array('2', '2 BYTES'), + +			array('1023', '1023 BYTES'), +			array('1025', '1 KIB'), +			array('1048575', '1024 KIB'), +		); +	} + +	/** +	* @dataProvider get_formatted_filesize_test_data +	*/ +	public function test_get_formatted_filesize($input, $expected) +	{ +		$output = get_formatted_filesize($input); + +		$this->assertEquals($expected, $output); +	} +} diff --git a/tests/functions/quoteattr_test.php b/tests/functions/quoteattr_test.php new file mode 100644 index 0000000000..9d2a7d470e --- /dev/null +++ b/tests/functions/quoteattr_test.php @@ -0,0 +1,44 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_quoteattr_test extends phpbb_test_case +{ +	public function quoteattr_test_data() +	{ +		return array( +			array('foo', null, '"foo"'), +			array('', null, '""'), +			array(' ', null, '" "'), +			array('<a>', null, '"<a>"'), +			array('&', null, '"&amp;"'), +			array('"hello"', null, "'\"hello\"'"), +			array("'hello'", null, "\"'hello'\""), +			array("\"'", null, "\""'\""), +			array("a\nb", null, '"a
b"'), +			array("a\r\nb", null, '"a
b"'), +			array("a\tb", null, '"a	b"'), +			array('a b', null, '"a b"'), +			array('"a<b"', null, "'\"a<b\"'"), +			array('foo', array('f' => 'z'), '"zoo"'), +			array('<a>', array('a' => '&'), '"<&>"'), +		); +	} + +	/** +	* @dataProvider quoteattr_test_data +	*/ +	public function test_quoteattr($input, $entities, $expected) +	{ +		$output = phpbb_quoteattr($input, $entities); + +		$this->assertEquals($expected, $output); +	} +} diff --git a/tests/functions_acp/build_cfg_template_test.php b/tests/functions_acp/build_cfg_template_test.php new file mode 100644 index 0000000000..bf5330fd88 --- /dev/null +++ b/tests/functions_acp/build_cfg_template_test.php @@ -0,0 +1,196 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php'; + +class phpbb_functions_acp_build_cfg_template_test extends phpbb_test_case +{ +	public function build_cfg_template_text_data() +	{ +		return array( +			array( +				array('text', 20, 255), +				'key_name', +				array('config_key_name'	=> '1'), +				'config_key_name', +				array(), +				'<input id="key_name" type="text" size="20" maxlength="255" name="config[config_key_name]" value="1" />', +			), +			array( +				array('password', 20, 128), +				'key_name', +				array('config_key_name'	=> '2'), +				'config_key_name', +				array(), +				'<input id="key_name" type="password" size="20" maxlength="128" name="config[config_key_name]" value="2" autocomplete="off" />', +			), +			array( +				array('text', 0, 255), +				'key_name', +				array('config_key_name'	=> '3'), +				'config_key_name', +				array(), +				'<input id="key_name" type="text" maxlength="255" name="config[config_key_name]" value="3" />', +			), +		); +	} + +	/** +	* @dataProvider build_cfg_template_text_data +	*/ +	public function test_build_cfg_template_text($tpl_type, $key, $new, $config_key, $vars, $expected) +	{ +		global $user, $phpbb_dispatcher; + +		$phpbb_dispatcher = new phpbb_mock_event_dispatcher(); +		$user->lang = new phpbb_mock_lang(); + +		$this->assertEquals($expected, build_cfg_template($tpl_type, $key, $new, $config_key, $vars)); +	} + +	public function build_cfg_template_dimension_data() +	{ +		return array( +			array( +				array('dimension', 20, 255), +				'key_name', +				array('config_key_name_width' => 10, 'config_key_name_height' => 20), +				'config_key_name', +				array(), +				'<input id="key_name" type="text" size="20" maxlength="255" name="config[config_key_name_width]" value="10" /> x <input type="text" size="20" maxlength="255" name="config[config_key_name_height]" value="20" />', +			), +			array( +				array('dimension', 0, 255), +				'key_name', +				array('config_key_name_width' => 10, 'config_key_name_height' => 20), +				'config_key_name', +				array(), +				'<input id="key_name" type="text" maxlength="255" name="config[config_key_name_width]" value="10" /> x <input type="text" maxlength="255" name="config[config_key_name_height]" value="20" />', +			), +		); +	} + +	/** +	* @dataProvider build_cfg_template_dimension_data +	*/ +	public function test_build_cfg_template_dimension($tpl_type, $key, $new, $config_key, $vars, $expected) +	{ +		global $user, $phpbb_dispatcher; + +		$phpbb_dispatcher = new phpbb_mock_event_dispatcher(); +		$user->lang = new phpbb_mock_lang(); + +		$this->assertEquals($expected, build_cfg_template($tpl_type, $key, $new, $config_key, $vars)); +	} + +	public function build_cfg_template_textarea_data() +	{ +		return array( +			array( +				array('textarea', 5, 30), +				'key_name', +				array('config_key_name' => 'phpBB'), +				'config_key_name', +				array(), +				'<textarea id="key_name" name="config[config_key_name]" rows="5" cols="30">phpBB</textarea>', +			), +		); +	} + +	/** +	* @dataProvider build_cfg_template_textarea_data +	*/ +	public function test_build_cfg_template_textarea($tpl_type, $key, $new, $config_key, $vars, $expected) +	{ +		global $user, $phpbb_dispatcher; + +		$phpbb_dispatcher = new phpbb_mock_event_dispatcher(); +		$user->lang = new phpbb_mock_lang(); + +		$this->assertEquals($expected, build_cfg_template($tpl_type, $key, $new, $config_key, $vars)); +	} + +	public function build_cfg_template_radio_data() +	{ +		return array( +			array( +				array('radio', 'enabled_disabled'), +				'key_name', +				array('config_key_name'	=> '0'), +				'config_key_name', +				array(), +				'<label><input type="radio" id="key_name" name="config[config_key_name]" value="1" class="radio" /> ENABLED</label><label><input type="radio" name="config[config_key_name]" value="0" checked="checked" class="radio" /> DISABLED</label>', +			), +			array( +				array('radio', 'enabled_disabled'), +				'key_name', +				array('config_key_name'	=> '1'), +				'config_key_name', +				array(), +				'<label><input type="radio" id="key_name" name="config[config_key_name]" value="1" checked="checked" class="radio" /> ENABLED</label><label><input type="radio" name="config[config_key_name]" value="0" class="radio" /> DISABLED</label>', +			), +			array( +				array('radio', 'yes_no'), +				'key_name', +				array('config_key_name'	=> '0'), +				'config_key_name', +				array(), +				'<label><input type="radio" id="key_name" name="config[config_key_name]" value="1" class="radio" /> YES</label><label><input type="radio" name="config[config_key_name]" value="0" checked="checked" class="radio" /> NO</label>', +			), +			array( +				array('radio', 'yes_no'), +				'key_name', +				array('config_key_name'	=> '1'), +				'config_key_name', +				array(), +				'<label><input type="radio" id="key_name" name="config[config_key_name]" value="1" checked="checked" class="radio" /> YES</label><label><input type="radio" name="config[config_key_name]" value="0" class="radio" /> NO</label>', +			), +		); +	} + +	/** +	* @dataProvider build_cfg_template_radio_data +	*/ +	public function test_build_cfg_template_radio($tpl_type, $key, $new, $config_key, $vars, $expected) +	{ +		global $user, $phpbb_dispatcher; + +		$phpbb_dispatcher = new phpbb_mock_event_dispatcher(); +		$user->lang = new phpbb_mock_lang(); + +		$this->assertEquals($expected, build_cfg_template($tpl_type, $key, $new, $config_key, $vars)); +	} + +	public function build_cfg_template_append_data() +	{ +		return array( +			array( +				array('textarea', 5, 30), +				'key_name', +				array('config_key_name' => 'phpBB'), +				'config_key_name', +				array('append' => 'Bertie is cool!'), +				'<textarea id="key_name" name="config[config_key_name]" rows="5" cols="30">phpBB</textarea>Bertie is cool!', +			), +		); +	} + +	/** +	* @dataProvider build_cfg_template_append_data +	*/ +	public function test_build_cfg_template_append($tpl_type, $key, $new, $config_key, $vars, $expected) +	{ +		global $user, $phpbb_dispatcher; + +		$phpbb_dispatcher = new phpbb_mock_event_dispatcher(); +		$user->lang = new phpbb_mock_lang(); + +		$this->assertEquals($expected, build_cfg_template($tpl_type, $key, $new, $config_key, $vars)); +	} +} diff --git a/tests/functions_acp/build_select_test.php b/tests/functions_acp/build_select_test.php new file mode 100644 index 0000000000..aca49b7655 --- /dev/null +++ b/tests/functions_acp/build_select_test.php @@ -0,0 +1,55 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php'; + +class phpbb_functions_acp_built_select_test extends phpbb_test_case +{ +	public function build_select_data() +	{ +		return array( +			array( +				array( +					'test'		=> 'TEST', +					'second'	=> 'SEC_OPTION', +				), +				false, +				'<option value="test">TEST</option><option value="second">SEC_OPTION</option>', +			), +			array( +				array( +					'test'		=> 'TEST', +					'second'	=> 'SEC_OPTION', +				), +				'test', +				'<option value="test" selected="selected">TEST</option><option value="second">SEC_OPTION</option>', +			), +			array( +				array( +					'test'		=> 'TEST', +					'second'	=> 'SEC_OPTION', +				), +				'second', +				'<option value="test">TEST</option><option value="second" selected="selected">SEC_OPTION</option>', +			), +		); +	} + +	/** +	* @dataProvider build_select_data +	*/ +	public function test_build_select($option_ary, $option_default, $expected) +	{ +		global $user; + +		$user->lang = new phpbb_mock_lang(); + +		$this->assertEquals($expected, build_select($option_ary, $option_default)); +	} +} diff --git a/tests/functions_acp/h_radio_test.php b/tests/functions_acp/h_radio_test.php new file mode 100644 index 0000000000..a61f2e8975 --- /dev/null +++ b/tests/functions_acp/h_radio_test.php @@ -0,0 +1,120 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php'; + +class phpbb_functions_acp_h_radio_test extends phpbb_test_case +{ +	public function h_radio_data() +	{ +		return array( +			array( +				'test_name', +				array( +					'test'		=> 'TEST', +					'second'	=> 'SEC_OPTION', +				), +				false, +				false, +				false, +				'<label><input type="radio" name="test_name" value="test" class="radio" /> TEST</label><label><input type="radio" name="test_name" value="second" class="radio" /> SEC_OPTION</label>', +			), +			array( +				'test_name', +				array( +					'test'		=> 'TEST', +					'second'	=> 'SEC_OPTION', +				), +				'test', +				false, +				false, +				'<label><input type="radio" name="test_name" value="test" checked="checked" class="radio" /> TEST</label><label><input type="radio" name="test_name" value="second" class="radio" /> SEC_OPTION</label>', +			), +			array( +				'test_name', +				array( +					'test'		=> 'TEST', +					'second'	=> 'SEC_OPTION', +				), +				false, +				'test_id', +				false, +				'<label><input type="radio" name="test_name" id="test_id" value="test" class="radio" /> TEST</label><label><input type="radio" name="test_name" value="second" class="radio" /> SEC_OPTION</label>', +			), +			array( +				'test_name', +				array( +					'test'		=> 'TEST', +					'second'	=> 'SEC_OPTION', +				), +				'test', +				'test_id', +				false, +				'<label><input type="radio" name="test_name" id="test_id" value="test" checked="checked" class="radio" /> TEST</label><label><input type="radio" name="test_name" value="second" class="radio" /> SEC_OPTION</label>', +			), + +			array( +				'test_name', +				array( +					'test'		=> 'TEST', +					'second'	=> 'SEC_OPTION', +				), +				false, +				false, +				'k', +				'<label><input type="radio" name="test_name" value="test" accesskey="k" class="radio" /> TEST</label><label><input type="radio" name="test_name" value="second" accesskey="k" class="radio" /> SEC_OPTION</label>', +			), +			array( +				'test_name', +				array( +					'test'		=> 'TEST', +					'second'	=> 'SEC_OPTION', +				), +				'test', +				false, +				'k', +				'<label><input type="radio" name="test_name" value="test" checked="checked" accesskey="k" class="radio" /> TEST</label><label><input type="radio" name="test_name" value="second" accesskey="k" class="radio" /> SEC_OPTION</label>', +			), +			array( +				'test_name', +				array( +					'test'		=> 'TEST', +					'second'	=> 'SEC_OPTION', +				), +				false, +				'test_id', +				'k', +				'<label><input type="radio" name="test_name" id="test_id" value="test" accesskey="k" class="radio" /> TEST</label><label><input type="radio" name="test_name" value="second" accesskey="k" class="radio" /> SEC_OPTION</label>', +			), +			array( +				'test_name', +				array( +					'test'		=> 'TEST', +					'second'	=> 'SEC_OPTION', +				), +				'test', +				'test_id', +				'k', +				'<label><input type="radio" name="test_name" id="test_id" value="test" checked="checked" accesskey="k" class="radio" /> TEST</label><label><input type="radio" name="test_name" value="second" accesskey="k" class="radio" /> SEC_OPTION</label>', +			), +		); +	} + +	/** +	* @dataProvider h_radio_data +	*/ +	public function test_h_radio($name, $input_ary, $input_default, $id, $key, $expected) +	{ +		global $user; + +		$user->lang = new phpbb_mock_lang(); + +		$this->assertEquals($expected, h_radio($name, $input_ary, $input_default, $id, $key)); +	} +} diff --git a/tests/functions_acp/validate_config_vars_test.php b/tests/functions_acp/validate_config_vars_test.php new file mode 100644 index 0000000000..7cd7fa3892 --- /dev/null +++ b/tests/functions_acp/validate_config_vars_test.php @@ -0,0 +1,158 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php'; + +class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case +{ +	/** +	* Data sets that don't throw an error. +	*/ +	public function validate_config_vars_fit_data() +	{ +		return array( +			array( +				array( +					'test_bool'				=> array('lang' => 'TEST_BOOL',			'validate' => 'bool'), +					'test_string'			=> array('lang' => 'TEST_STRING',		'validate' => 'string'), +					'test_string'			=> array('lang' => 'TEST_STRING',		'validate' => 'string'), +					'test_string_128'		=> array('lang' => 'TEST_STRING_128',	'validate' => 'string:128'), +					'test_string_128'		=> array('lang' => 'TEST_STRING_128',	'validate' => 'string:128'), +					'test_string_32_64'		=> array('lang' => 'TEST_STRING_32_64',	'validate' => 'string:32:64'), +					'test_string_32_64'		=> array('lang' => 'TEST_STRING_32_64',	'validate' => 'string:32:64'), +					'test_int'				=> array('lang' => 'TEST_INT',			'validate' => 'int'), +					'test_int_32'			=> array('lang' => 'TEST_INT',			'validate' => 'int:32'), +					'test_int_32_64'		=> array('lang' => 'TEST_INT',			'validate' => 'int:32:64'), +					'test_lang'				=> array('lang' => 'TEST_LANG',			'validate' => 'lang'), +					/* +					'test_sp'				=> array('lang' => 'TEST_SP',			'validate' => 'script_path'), +					'test_rpath'			=> array('lang' => 'TEST_RPATH',		'validate' => 'rpath'), +					'test_rwpath'			=> array('lang' => 'TEST_RWPATH',		'validate' => 'rwpath'), +					'test_path'				=> array('lang' => 'TEST_PATH',			'validate' => 'path'), +					'test_wpath'			=> array('lang' => 'TEST_WPATH',		'validate' => 'wpath'), +					*/ +				), +				array( +					'test_bool'			=> true, +					'test_string'		=> str_repeat('a', 255), +					'test_string'		=> str_repeat("\xC3\x84", 255), +					'test_string_128'	=> str_repeat('a', 128), +					'test_string_128'	=> str_repeat("\xC3\x84", 128), +					'test_string_32_64'	=> str_repeat('a', 48), +					'test_string_32_64'	=> str_repeat("\xC3\x84", 48), +					'test_int'			=> 128, +					'test_int_32'		=> 32, +					'test_int_32_64'	=> 48, +					'test_lang'			=> 'en', +				), +			), +		); +	} + +	/** +	* @dataProvider validate_config_vars_fit_data +	*/ +	public function test_validate_config_vars_fit($test_data, $cfg_array) +	{ +		global $user; + +		$user->lang = new phpbb_mock_lang(); + +		$phpbb_error = array(); +		validate_config_vars($test_data, $cfg_array, $phpbb_error); + +		$this->assertEquals(array(), $phpbb_error); +	} + +	/** +	* Data sets that throw the error. +	*/ +	public function validate_config_vars_error_data() +	{ +		return array( +			array( +				array('test_string_32_64'		=> array('lang' => 'TEST_STRING_32_64',	'validate' => 'string:32:64')), +				array('test_string_32_64'	=> str_repeat('a', 20)), +				array('SETTING_TOO_SHORT'), +			), +			array( +				array('test_string_32_64'		=> array('lang' => 'TEST_STRING_32_64',	'validate' => 'string:32:64')), +				array('test_string_32_64'	=> str_repeat("\xC3\x84", 20)), +				array('SETTING_TOO_SHORT'), +			), +			array( +				array('test_string'		=> array('lang' => 'TEST_STRING',	'validate' => 'string')), +				array('test_string'		=> str_repeat('a', 256)), +				array('SETTING_TOO_LONG'), +			), +			array( +				array('test_string'		=> array('lang' => 'TEST_STRING',	'validate' => 'string')), +				array('test_string'		=> str_repeat("\xC3\x84", 256)), +				array('SETTING_TOO_LONG'), +			), +			array( +				array('test_string_32_64'	=> array('lang' => 'TEST_STRING_32_64',	'validate' => 'string:32:64')), +				array('test_string_32_64'	=> str_repeat('a', 65)), +				array('SETTING_TOO_LONG'), +			), +			array( +				array('test_string_32_64'	=> array('lang' => 'TEST_STRING_32_64',	'validate' => 'string:32:64')), +				array('test_string_32_64'	=> str_repeat("\xC3\x84", 65)), +				array('SETTING_TOO_LONG'), +			), + +			array( +				array('test_int_32'		=> array('lang' => 'TEST_INT',			'validate' => 'int:32')), +				array('test_int_32'		=> 31), +				array('SETTING_TOO_LOW'), +			), +			array( +				array('test_int_32_64'	=> array('lang' => 'TEST_INT',			'validate' => 'int:32:64')), +				array('test_int_32_64'	=> 31), +				array('SETTING_TOO_LOW'), +			), +			array( +				array('test_int_32_64'	=> array('lang' => 'TEST_INT',			'validate' => 'int:32:64')), +				array('test_int_32_64'	=> 65), +				array('SETTING_TOO_BIG'), +			), +			array( +				array( +					'test_int_min'	=> array('lang' => 'TEST_INT_MIN',		'validate' => 'int:32:64'), +					'test_int_max'	=> array('lang' => 'TEST_INT_MAX',		'validate' => 'int:32:64'), +				), +				array( +					'test_int_min'	=> 52, +					'test_int_max'	=> 48, +				), +				array('SETTING_TOO_LOW'), +			), +			array( +				array('test_lang'		=> array('lang' => 'TEST_LANG',			'validate' => 'lang')), +				array('test_lang'		=> 'this_is_no_language'), +				array('WRONG_DATA_LANG'), +			), +		); +	} + +	/** +	* @dataProvider validate_config_vars_error_data +	*/ +	public function test_validate_config_vars_error($test_data, $cfg_array, $expected) +	{ +		global $user; + +		$user->lang = new phpbb_mock_lang(); + +		$phpbb_error = array(); +		validate_config_vars($test_data, $cfg_array, $phpbb_error); + +		$this->assertEquals($expected, $phpbb_error); +	} +} diff --git a/tests/functions_acp/validate_range_test.php b/tests/functions_acp/validate_range_test.php new file mode 100644 index 0000000000..8606158251 --- /dev/null +++ b/tests/functions_acp/validate_range_test.php @@ -0,0 +1,170 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php'; + +class phpbb_functions_acp_validate_range_test extends phpbb_test_case +{ +	/** +	* Data sets that don't throw an error. +	*/ +	public function validate_range_data_fit() +	{ +		return array( +			array(array(array('column_type' => 'BOOL', 'lang' => 'TEST', 'value' => 0))), +			array(array(array('column_type' => 'BOOL', 'lang' => 'TEST', 'value' => 1))), + +			array(array(array('column_type' => 'USINT', 'lang' => 'TEST', 'value' => 0))), +			array(array(array('column_type' => 'USINT', 'lang' => 'TEST', 'value' => 65535))), +			array(array(array('column_type' => 'USINT:32:128', 'lang' => 'TEST', 'value' => 35))), + +			array(array(array('column_type' => 'UINT', 'lang' => 'TEST', 'value' => 0))), +			array(array(array('column_type' => 'UINT', 'lang' => 'TEST', 'value' => (int) 0x7fffffff))), +			array(array(array('column_type' => 'UINT:32:128', 'lang' => 'TEST', 'value' => 35))), + +			array(array(array('column_type' => 'INT', 'lang' => 'TEST', 'value' => (int) -2147483648))), +			array(array(array('column_type' => 'INT', 'lang' => 'TEST', 'value' => (int) 0x7fffffff))), +			array(array(array('column_type' => 'INT:-32:128', 'lang' => 'TEST', 'value' => -28))), +			array(array(array('column_type' => 'INT:-32:128', 'lang' => 'TEST', 'value' => 35))), + +			array(array(array('column_type' => 'TINT', 'lang' => 'TEST', 'value' => -128))), +			array(array(array('column_type' => 'TINT', 'lang' => 'TEST', 'value' => 127))), +			array(array(array('column_type' => 'TINT:-32:64', 'lang' => 'TEST', 'value' => -16))), +			array(array(array('column_type' => 'TINT:-32:64', 'lang' => 'TEST', 'value' => 16))), + +			array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => ''))), +			array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => str_repeat('a', 255)))), +			array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => str_repeat("\xC3\x84", 255)))), +			array(array(array('column_type' => 'VCHAR:128', 'lang' => 'TEST', 'value' => str_repeat('a', 128)))), +			array(array(array('column_type' => 'VCHAR:128', 'lang' => 'TEST', 'value' => str_repeat("\xC3\x84", 128)))), +		); +	} + +	/** +	* @dataProvider validate_range_data_fit +	*/ +	public function test_validate_range_fit($test_data) +	{ +		global $user; + +		$user->lang = new phpbb_mock_lang(); + +		$phpbb_error = array(); +		validate_range($test_data, $phpbb_error); + +		$this->assertEquals(array(), $phpbb_error); +	} + +	/** +	* Data sets that throw the SETTING_TOO_LOW-error. +	*/ +	public function validate_range_data_too_low() +	{ +		return array( +			array(array(array('column_type' => 'BOOL', 'lang' => 'TEST', 'value' => -1))), + +			array(array(array('column_type' => 'USINT', 'lang' => 'TEST', 'value' => -1))), +			array(array(array('column_type' => 'USINT:32:128', 'lang' => 'TEST', 'value' => 31))), + +			array(array(array('column_type' => 'UINT', 'lang' => 'TEST', 'value' => -1))), +			array(array(array('column_type' => 'UINT:32:128', 'lang' => 'TEST', 'value' => 31))), + +			array(array(array('column_type' => 'INT', 'lang' => 'TEST', 'value' => ((int) -2147483648) - 1))), +			array(array(array('column_type' => 'INT:32:128', 'lang' => 'TEST', 'value' => 31))), +			array(array(array('column_type' => 'INT:-32:128', 'lang' => 'TEST', 'value' => -33))), + +			array(array(array('column_type' => 'TINT', 'lang' => 'TEST', 'value' => -129))), +			array(array(array('column_type' => 'TINT:32:64', 'lang' => 'TEST', 'value' => 31))), +			array(array(array('column_type' => 'TINT:-32:64', 'lang' => 'TEST', 'value' => -33))), +		); +	} + +	/** +	* @dataProvider validate_range_data_too_low +	*/ +	public function test_validate_range_too_low($test_data) +	{ +		global $user; + +		$user->lang = new phpbb_mock_lang(); + +		$phpbb_error = array(); +		validate_range($test_data, $phpbb_error); + +		$this->assertEquals(array('SETTING_TOO_LOW'), $phpbb_error); +	} + +	/** +	* Data sets that throw the SETTING_TOO_BIG-error. +	*/ +	public function validate_range_data_too_big() +	{ +		return array( +			array(array(array('column_type' => 'BOOL', 'lang' => 'TEST', 'value' => 2))), + +			array(array(array('column_type' => 'USINT', 'lang' => 'TEST', 'value' => 65536))), +			array(array(array('column_type' => 'USINT:32:128', 'lang' => 'TEST', 'value' => 129))), + +			array(array(array('column_type' => 'UINT', 'lang' => 'TEST', 'value' => ((int) 0x7fffffff) + 1))), +			array(array(array('column_type' => 'UINT:32:128', 'lang' => 'TEST', 'value' => 129))), + +			array(array(array('column_type' => 'INT', 'lang' => 'TEST', 'value' => ((int) 0x7fffffff) + 1))), +			array(array(array('column_type' => 'INT:-32:-16', 'lang' => 'TEST', 'value' => -15))), +			array(array(array('column_type' => 'INT:-32:128', 'lang' => 'TEST', 'value' => 129))), + +			array(array(array('column_type' => 'TINT', 'lang' => 'TEST', 'value' => 128))), +			array(array(array('column_type' => 'TINT:-32:-16', 'lang' => 'TEST', 'value' => -15))), +			array(array(array('column_type' => 'TINT:-32:64', 'lang' => 'TEST', 'value' => 65))), +		); +	} + +	/** +	* @dataProvider validate_range_data_too_big +	*/ +	public function test_validate_range_too_big($test_data) +	{ +		global $user; + +		$user->lang = new phpbb_mock_lang(); + +		$phpbb_error = array(); +		validate_range($test_data, $phpbb_error); + +		$this->assertEquals(array('SETTING_TOO_BIG'), $phpbb_error); +	} + +	/** +	* Data sets that throw the SETTING_TOO_LONG-error. +	*/ +	public function validate_range_data_too_long() +	{ +		return array( +			array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => str_repeat('a', 256)))), +			array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => str_repeat("\xC3\x84", 256)))), +			array(array(array('column_type' => 'VCHAR:128', 'lang' => 'TEST', 'value' => str_repeat('a', 129)))), +			array(array(array('column_type' => 'VCHAR:128', 'lang' => 'TEST', 'value' => str_repeat("\xC3\x84", 129)))), +		); +	} + +	/** +	* @dataProvider validate_range_data_too_long +	*/ +	public function test_validate_range_too_long($test_data) +	{ +		global $user; + +		$user->lang = new phpbb_mock_lang(); + +		$phpbb_error = array(); +		validate_range($test_data, $phpbb_error); + +		$this->assertEquals(array('SETTING_TOO_LONG'), $phpbb_error); +	} +} diff --git a/tests/functions_database_helper/fixtures/bookmarks_duplicates.xml b/tests/functions_database_helper/fixtures/bookmarks_duplicates.xml new file mode 100644 index 0000000000..d49f76b073 --- /dev/null +++ b/tests/functions_database_helper/fixtures/bookmarks_duplicates.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> +	<table name="phpbb_bookmarks"> +		<column>user_id</column> +		<column>topic_id</column> + +		<!-- one entry for this topic --> +		<row> +			<value>1</value> +			<value>1</value> +		</row> + +		<!-- non-conflicting entries --> +		<row> +			<value>2</value> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +			<value>3</value> +		</row> + +		<!-- conflicting entries --> +		<row> +			<value>1</value> +			<value>4</value> +		</row> +		<row> +			<value>1</value> +			<value>5</value> +		</row> + +		<!-- conflicting and non-conflicting entries --> +		<row> +			<value>1</value> +			<value>6</value> +		</row> +		<row> +			<value>1</value> +			<value>7</value> +		</row> +		<row> +			<value>2</value> +			<value>6</value> +		</row> +	</table> +</dataset> diff --git a/tests/functions_database_helper/fixtures/topics_watch_duplicates.xml b/tests/functions_database_helper/fixtures/topics_watch_duplicates.xml new file mode 100644 index 0000000000..c387bb737a --- /dev/null +++ b/tests/functions_database_helper/fixtures/topics_watch_duplicates.xml @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> +	<table name="phpbb_topics_watch"> +		<column>user_id</column> +		<column>topic_id</column> +		<column>notify_status</column> + +		<!-- one entry for this topic --> +		<row> +			<value>1</value> +			<value>1</value> +			<value>1</value> +		</row> + +		<!-- non-conflicting entries --> +		<row> +			<value>1</value> +			<value>2</value> +			<value>1</value> +		</row> +		<row> +			<value>2</value> +			<value>3</value> +			<value>0</value> +		</row> + +		<!-- conflicting entries, same notify status --> +		<row> +			<value>1</value> +			<value>4</value> +			<value>1</value> +		</row> +		<row> +			<value>1</value> +			<value>5</value> +			<value>1</value> +		</row> + +		<!-- conflicting entries, notify status 0 into 1 --> +		<row> +			<value>1</value> +			<value>6</value> +			<value>0</value> +		</row> +		<row> +			<value>1</value> +			<value>7</value> +			<value>1</value> +		</row> + +		<!-- conflicting entries, notify status 1 into 0 --> +		<row> +			<value>1</value> +			<value>8</value> +			<value>1</value> +		</row> +		<row> +			<value>1</value> +			<value>9</value> +			<value>0</value> +		</row> + +		<!-- conflicting and non-conflicting entries --> +		<row> +			<value>1</value> +			<value>10</value> +			<value>0</value> +		</row> +		<row> +			<value>1</value> +			<value>11</value> +			<value>1</value> +		</row> +		<row> +			<value>2</value> +			<value>10</value> +			<value>1</value> +		</row> +	</table> +</dataset> diff --git a/tests/functions_database_helper/update_rows_avoiding_duplicates_notify_status_test.php b/tests/functions_database_helper/update_rows_avoiding_duplicates_notify_status_test.php new file mode 100644 index 0000000000..d4881daf7e --- /dev/null +++ b/tests/functions_database_helper/update_rows_avoiding_duplicates_notify_status_test.php @@ -0,0 +1,101 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_database_helper.php'; + +class phpbb_update_rows_avoiding_duplicates_notify_status_test extends phpbb_database_test_case +{ +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/topics_watch_duplicates.xml'); +	} + +	public static function fixture_data() +	{ +		return array( +			// description +			// from array +			// to value +			// expected count with to value post update +			// expected notify_status values +			array( +				'trivial', +				array(1), +				1000, +				1, +				1, +			), +			array( +				'no conflict', +				array(2), +				3, +				2, +				1, +			), +			array( +				'conflict, same notify status', +				array(4), +				5, +				1, +				1, +			), +			array( +				'conflict, notify status 0 into 1', +				array(6), +				7, +				1, +				0, +			), +			array( +				'conflict, notify status 1 into 0', +				array(8), +				9, +				1, +				0, +			), +			array( +				'conflict and no conflict', +				array(10), +				11, +				2, +				0, +			), +		); +	} + +	/** +	* @dataProvider fixture_data +	*/ +	public function test_update($description, $from, $to, $expected_result_count, $expected_notify_status) +	{ +		$db = $this->new_dbal(); + +		phpbb_update_rows_avoiding_duplicates_notify_status($db, TOPICS_WATCH_TABLE, 'topic_id', $from, $to); + +		$sql = 'SELECT COUNT(*) AS remaining_rows +			FROM ' . TOPICS_WATCH_TABLE . ' +			WHERE topic_id = ' . (int) $to; +		$result = $db->sql_query($sql); +		$result_count = $db->sql_fetchfield('remaining_rows'); +		$db->sql_freeresult($result); + +		$this->assertEquals($expected_result_count, $result_count); + +		// user id of 1 is the user being updated +		$sql = 'SELECT notify_status +			FROM ' . TOPICS_WATCH_TABLE . ' +			WHERE topic_id = ' . (int) $to . ' +			AND user_id = 1'; +		$result = $db->sql_query($sql); +		$notify_status = $db->sql_fetchfield('notify_status'); +		$db->sql_freeresult($result); + +		$this->assertEquals($expected_notify_status, $notify_status); +	} +} diff --git a/tests/functions_database_helper/update_rows_avoiding_duplicates_test.php b/tests/functions_database_helper/update_rows_avoiding_duplicates_test.php new file mode 100644 index 0000000000..2f01d29d15 --- /dev/null +++ b/tests/functions_database_helper/update_rows_avoiding_duplicates_test.php @@ -0,0 +1,71 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_database_helper.php'; + +class phpbb_update_rows_avoiding_duplicates_test extends phpbb_database_test_case +{ +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/bookmarks_duplicates.xml'); +	} + +	public static function fixture_data() +	{ +		return array( +			// description +			// from array +			// to value +			// expected count with to value post update +			array( +				'trivial', +				array(1), +				10, +				1, +			), +			array( +				'no conflict', +				array(2), +				3, +				2, +			), +			array( +				'conflict', +				array(4), +				5, +				1, +			), +			array( +				'conflict and no conflict', +				array(6), +				7, +				2, +			), +		); +	} + +	/** +	* @dataProvider fixture_data +	*/ +	public function test_update($description, $from, $to, $expected_result_count) +	{ +		$db = $this->new_dbal(); + +		phpbb_update_rows_avoiding_duplicates($db, BOOKMARKS_TABLE, 'topic_id', $from, $to); + +		$sql = 'SELECT COUNT(*) AS remaining_rows +			FROM ' . BOOKMARKS_TABLE . ' +			WHERE topic_id = ' . (int) $to; +		$result = $db->sql_query($sql); +		$result_count = $db->sql_fetchfield('remaining_rows'); +		$db->sql_freeresult($result); + +		$this->assertEquals($expected_result_count, $result_count); +	} +} diff --git a/tests/group_positions/fixtures/group_positions.xml b/tests/group_positions/fixtures/group_positions.xml new file mode 100644 index 0000000000..00ea18fe4f --- /dev/null +++ b/tests/group_positions/fixtures/group_positions.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> +	<table name="phpbb_groups"> +		<column>group_id</column> +		<column>group_teampage</column> +		<column>group_legend</column> +		<column>group_desc</column> +		<row> +			<value>1</value> +			<value>0</value> +			<value>0</value> +			<value></value> +		</row> +		<row> +			<value>2</value> +			<value>1</value> +			<value>0</value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value>2</value> +			<value>1</value> +			<value></value> +		</row> +	</table> +</dataset> diff --git a/tests/group_positions/group_positions_test.php b/tests/group_positions/group_positions_test.php new file mode 100644 index 0000000000..c17e25511b --- /dev/null +++ b/tests/group_positions/group_positions_test.php @@ -0,0 +1,287 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + + +class phpbb_group_positions_test extends phpbb_database_test_case +{ +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/group_positions.xml'); +	} + +	public function get_group_value_data() +	{ +		return array( +			array('teampage', 1, 0), +			array('teampage', 2, 1), +			array('legend', 1, 0), +			array('legend', 3, 1), +		); +	} + +	/** +	* @dataProvider get_group_value_data +	*/ +	public function test_get_group_value($field, $group_id, $expected) +	{ +		global $db; + +		$db = $this->new_dbal(); + +		$test_class = new phpbb_group_positions($db, $field); +		$this->assertEquals($expected, $test_class->get_group_value($group_id)); +	} + +	public function get_group_count_data() +	{ +		return array( +			array('teampage', 2), +			array('legend', 1), +		); +	} + +	/** +	* @dataProvider get_group_count_data +	*/ +	public function test_get_group_count($field, $expected) +	{ +		global $db; + +		$db = $this->new_dbal(); + +		$test_class = new phpbb_group_positions($db, $field); +		$this->assertEquals($expected, $test_class->get_group_count()); +	} + +	public function add_group_data() +	{ +		return array( +			array('teampage', 1, array( +				array('group_id' => 1, 'group_teampage' => 3, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +			array('teampage', 2, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +		); +	} + +	/** +	* @dataProvider add_group_data +	*/ +	public function test_add_group($field, $group_id, $expected) +	{ +		global $db; + +		$db = $this->new_dbal(); +		$test_class = new phpbb_group_positions($db, $field); +		$test_class->add_group($group_id); + +		$result = $db->sql_query('SELECT group_id, group_teampage, group_legend +			FROM ' . GROUPS_TABLE . ' +			ORDER BY group_id ASC'); + +		$this->assertEquals($expected, $db->sql_fetchrowset($result)); +	} + +	public function delete_group_data() +	{ +		return array( +			array('teampage', 1, false, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +			array('teampage', 2, false, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 1, 'group_legend' => 1), +			)), +			array('teampage', 3, false, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 0, 'group_legend' => 1), +			)), +			array('teampage', 1, true, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +			array('teampage', 2, true, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 1, 'group_legend' => 1), +			)), +			array('teampage', 3, true, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +		); +	} + +	/** +	* @dataProvider delete_group_data +	*/ +	public function test_delete_group($field, $group_id, $skip_group, $expected) +	{ +		global $db; + +		$db = $this->new_dbal(); +		$test_class = new phpbb_group_positions($db, $field); +		$test_class->delete_group($group_id, $skip_group); + +		$result = $db->sql_query('SELECT group_id, group_teampage, group_legend +			FROM ' . GROUPS_TABLE . ' +			ORDER BY group_id ASC'); + +		$this->assertEquals($expected, $db->sql_fetchrowset($result)); +	} + +	public function move_up_data() +	{ +		return array( +			array('teampage', 1, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +			array('teampage', 2, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +			array('teampage', 3, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 2, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 1, 'group_legend' => 1), +			)), +		); +	} + +	/** +	* @dataProvider move_up_data +	*/ +	public function test_move_up($field, $group_id, $expected) +	{ +		global $db; + +		$db = $this->new_dbal(); +		$test_class = new phpbb_group_positions($db, $field); +		$test_class->move_up($group_id); + +		$result = $db->sql_query('SELECT group_id, group_teampage, group_legend +			FROM ' . GROUPS_TABLE . ' +			ORDER BY group_id ASC'); + +		$this->assertEquals($expected, $db->sql_fetchrowset($result)); +	} + +	public function move_down_data() +	{ +		return array( +			array('teampage', 1, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +			array('teampage', 2, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 2, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 1, 'group_legend' => 1), +			)), +			array('teampage', 3, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +		); +	} + +	/** +	* @dataProvider move_down_data +	*/ +	public function test_move_down($field, $group_id, $expected) +	{ +		global $db; + +		$db = $this->new_dbal(); +		$test_class = new phpbb_group_positions($db, $field); +		$test_class->move_down($group_id); + +		$result = $db->sql_query('SELECT group_id, group_teampage, group_legend +			FROM ' . GROUPS_TABLE . ' +			ORDER BY group_id ASC'); + +		$this->assertEquals($expected, $db->sql_fetchrowset($result)); +	} + +	public function move_data() +	{ +		return array( +			array('teampage', 1, 1, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +			array('teampage', 1, -1, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +			array('teampage', 3, 3, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 2, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 1, 'group_legend' => 1), +			)), +			array('teampage', 2, 0, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +			array('teampage', 2, -1, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 2, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 1, 'group_legend' => 1), +			)), +			array('teampage', 2, -3, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 2, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 1, 'group_legend' => 1), +			)), +			array('teampage', 3, -1, array( +				array('group_id' => 1, 'group_teampage' => 0, 'group_legend' => 0), +				array('group_id' => 2, 'group_teampage' => 1, 'group_legend' => 0), +				array('group_id' => 3, 'group_teampage' => 2, 'group_legend' => 1), +			)), +		); +	} + +	/** +	* @dataProvider move_data +	*/ +	public function test_move($field, $group_id, $increment, $expected) +	{ +		global $db; + +		$db = $this->new_dbal(); +		$test_class = new phpbb_group_positions($db, $field); +		$test_class->move($group_id, $increment); + +		$result = $db->sql_query('SELECT group_id, group_teampage, group_legend +			FROM ' . GROUPS_TABLE . ' +			ORDER BY group_id ASC'); + +		$this->assertEquals($expected, $db->sql_fetchrowset($result)); +	} +} + diff --git a/tests/lint_test.php b/tests/lint_test.php new file mode 100644 index 0000000000..905067072d --- /dev/null +++ b/tests/lint_test.php @@ -0,0 +1,74 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_lint_test extends phpbb_test_case +{ +	static protected $exclude; + +	static public function setUpBeforeClass() +	{ +		$output = array(); +		$status = 1; +		exec('(php -v) 2>&1', $output, $status); +		if ($status) +		{ +			$output = implode("\n", $output); +			self::markTestSkipped("php is not in PATH or broken: $output"); +		} + +		self::$exclude = array( +			// PHP Fatal error:  Cannot declare class Container because the name is already in use in /var/www/projects/phpbb3/tests/../phpBB/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php on line 20 +			// https://gist.github.com/e003913ffd493da63cbc +			dirname(__FILE__) . '/../phpBB/vendor', +		); +	} + +	public function test_lint() +	{ +		if (version_compare(PHP_VERSION, '5.3.0', '<')) +		{ +			$this->markTestSkipped('phpBB uses PHP 5.3 syntax in some files, linting on PHP < 5.3 will fail'); +		} + +		$root = dirname(__FILE__) . '/..'; +		$this->check($root); +	} + +	protected function check($root) +	{ +		$dh = opendir($root); +		while (($filename = readdir($dh)) !== false) +		{ +			if ($filename == '.' || $filename == '..' || $filename == 'git') +			{ +				continue; +			} +			$path = $root . '/' . $filename; +			// skip symlinks to avoid infinite loops +			if (is_link($path)) +			{ +				continue; +			} +			if (is_dir($path) && !in_array($path, self::$exclude)) +			{ +				$this->check($path); +			} +			else if (substr($filename, strlen($filename)-4) == '.php') +			{ +				// assume php binary is called php and it is in PATH +				$cmd = '(php -l ' . escapeshellarg($path) . ') 2>&1'; +				$output = array(); +				$status = 1; +				exec($cmd, $output, $status); +				$output = implode("\n", $output); +				$this->assertEquals(0, $status, "php -l failed for $path:\n$output"); +			} +		} +	} +} diff --git a/tests/lock/db_test.php b/tests/lock/db_test.php new file mode 100644 index 0000000000..f7b1557a0c --- /dev/null +++ b/tests/lock/db_test.php @@ -0,0 +1,83 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_lock_db_test extends phpbb_database_test_case +{ +	private $db; +	private $config; +	private $lock; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); +	} + +	public function setUp() +	{ +		global $db, $config; + +		$db = $this->db = $this->new_dbal(); +		$config = $this->config = new phpbb_config(array('rand_seed' => '', 'rand_seed_last_update' => '0')); +		set_config(null, null, null, $this->config); +		$this->lock = new phpbb_lock_db('test_lock', $this->config, $this->db); +	} + +	public function test_new_lock() +	{ +		$this->assertTrue($this->lock->acquire()); +		$this->assertTrue(isset($this->config['test_lock']), 'Lock was created'); + +		$lock2 = new phpbb_lock_db('test_lock', $this->config, $this->db); +		$this->assertFalse($lock2->acquire()); + +		$this->lock->release(); +		$this->assertEquals('0', $this->config['test_lock'], 'Lock was released'); +	} + +	public function test_expire_lock() +	{ +		$lock = new phpbb_lock_db('foo_lock', $this->config, $this->db); +		$this->assertTrue($lock->acquire()); +	} + +	public function test_double_lock() +	{ +		$this->assertTrue($this->lock->acquire()); +		$this->assertTrue(isset($this->config['test_lock']), 'Lock was created'); + +		$value = $this->config['test_lock']; + +		$this->assertFalse($this->lock->acquire()); +		$this->assertEquals($value, $this->config['test_lock'], 'Second lock failed'); + +		$this->lock->release(); +		$this->assertEquals('0', $this->config['test_lock'], 'Lock was released'); +	} + +	public function test_double_unlock() +	{ +		$this->assertTrue($this->lock->acquire()); +		$this->assertFalse(empty($this->config['test_lock']), 'First lock is acquired'); + +		$this->lock->release(); +		$this->assertEquals('0', $this->config['test_lock'], 'First lock is released'); + +		$lock2 = new phpbb_lock_db('test_lock', $this->config, $this->db); +		$this->assertTrue($lock2->acquire()); +		$this->assertFalse(empty($this->config['test_lock']), 'Second lock is acquired'); + +		$this->lock->release(); +		$this->assertFalse(empty($this->config['test_lock']), 'Double release of first lock is ignored'); + +		$lock2->release(); +		$this->assertEquals('0', $this->config['test_lock'], 'Second lock is released'); +	} +} diff --git a/tests/lock/fixtures/config.xml b/tests/lock/fixtures/config.xml new file mode 100644 index 0000000000..f36c8b929a --- /dev/null +++ b/tests/lock/fixtures/config.xml @@ -0,0 +1,13 @@ +<?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>foo_lock</value> +			<value>1 abcd</value> +			<value>1</value> +		</row> +	</table> +</dataset> diff --git a/tests/lock/flock_test.php b/tests/lock/flock_test.php new file mode 100644 index 0000000000..1edc96b3a4 --- /dev/null +++ b/tests/lock/flock_test.php @@ -0,0 +1,109 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_lock_flock_test extends phpbb_test_case +{ +	public function test_lock() +	{ +		$path = __DIR__ . '/../tmp/precious'; + +		$lock = new phpbb_lock_flock($path); +		$ok = $lock->acquire(); +		$this->assertTrue($ok); +		$lock->release(); +	} + +	public function test_consecutive_locking() +	{ +		$path = __DIR__ . '/../tmp/precious'; + +		$lock = new phpbb_lock_flock($path); +		$ok = $lock->acquire(); +		$this->assertTrue($ok); +		$lock->release(); + +		$ok = $lock->acquire(); +		$this->assertTrue($ok); +		$lock->release(); + +		$ok = $lock->acquire(); +		$this->assertTrue($ok); +		$lock->release(); +	} + +	/* This hangs the process. +	public function test_concurrent_locking_fail() +	{ +		$path = __DIR__ . '/../tmp/precious'; + +		$lock1 = new phpbb_lock_flock($path); +		$ok = $lock1->acquire(); +		$this->assertTrue($ok); + +		$lock2 = new phpbb_lock_flock($path); +		$ok = $lock2->acquire(); +		$this->assertFalse($ok); + +		$lock->release(); +		$ok = $lock2->acquire(); +		$this->assertTrue($ok); +	} +	*/ + +	public function test_concurrent_locking() +	{ +		if (!function_exists('pcntl_fork')) +		{ +			$this->markTestSkipped('pcntl extension and pcntl_fork are required for this test'); +		} + +		$path = __DIR__ . '/../tmp/precious'; + +		$pid = pcntl_fork(); +		if ($pid) +		{ +			// parent +			// wait 0.5 s, acquire the lock, note how long it took +			sleep(1); + +			$lock = new phpbb_lock_flock($path); +			$start = time(); +			$ok = $lock->acquire(); +			$delta = time() - $start; +			$this->assertTrue($ok); +			$this->assertGreaterThan(0.5, $delta, 'First lock acquired too soon'); + +			$lock->release(); + +			// acquire again, this should be instantaneous +			$start = time(); +			$ok = $lock->acquire(); +			$delta = time() - $start; +			$this->assertTrue($ok); +			$this->assertLessThan(0.1, $delta, 'Second lock not acquired instantaneously'); + +			// reap the child +			$status = null; +			pcntl_waitpid($pid, $status); +		} +		else +		{ +			// child +			// immediately acquire the lock and sleep for 2 s +			$lock = new phpbb_lock_flock($path); +			$ok = $lock->acquire(); +			$this->assertTrue($ok); +			sleep(2); +			$lock->release(); + +			// and go away silently +			pcntl_exec('/usr/bin/env', array('true')); +		} +	} +} diff --git a/tests/mock/cache.php b/tests/mock/cache.php index 650545c3d6..71af3037f5 100644 --- a/tests/mock/cache.php +++ b/tests/mock/cache.php @@ -2,21 +2,18 @@  /**  *  * @package testing -* @copyright (c) 2008 phpBB Group +* @copyright (c) 2011 phpBB Group  * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2  *  */ -class phpbb_mock_cache +class phpbb_mock_cache implements phpbb_cache_driver_interface  { +	protected $data; +  	public function __construct($data = array())  	{  		$this->data = $data; - -		if (!isset($this->data['_bots'])) -		{ -			$this->data['_bots'] = array(); -		}  	}  	public function get($var_name) @@ -35,14 +32,6 @@ class phpbb_mock_cache  	}  	/** -	* Obtain active bots -	*/ -	public function obtain_bots() -	{ -		return $this->data['_bots']; -	} -	 -	/**  	 * Obtain list of word censors. We don't need to parse them here,  	 * that is tested elsewhere.  	 */ @@ -64,17 +53,32 @@ class phpbb_mock_cache  		);  	} -	public function set_bots($bots) +	public function checkVar(PHPUnit_Framework_Assert $test, $var_name, $data)  	{ -		$this->data['_bots'] = $bots; +		$test->assertTrue(isset($this->data[$var_name])); +		$test->assertEquals($data, $this->data[$var_name]);  	} -	public function checkVar(PHPUnit_Framework_Assert $test, $var_name, $data) +	public function checkAssociativeVar(PHPUnit_Framework_Assert $test, $var_name, $data, $sort = true)  	{  		$test->assertTrue(isset($this->data[$var_name])); + +		if ($sort) +		{ +			foreach ($this->data[$var_name] as &$content) +			{ +				sort($content); +			} +		} +  		$test->assertEquals($data, $this->data[$var_name]);  	} +	public function checkVarUnset(PHPUnit_Framework_Assert $test, $var_name) +	{ +		$test->assertFalse(isset($this->data[$var_name])); +	} +  	public function check(PHPUnit_Framework_Assert $test, $data, $ignore_db_info = true)  	{  		$cache_data = $this->data; @@ -91,5 +95,58 @@ class phpbb_mock_cache  		$test->assertEquals($data, $cache_data);  	} -} +	function load() +	{ +	} +	function unload() +	{ +	} +	function save() +	{ +	} +	function tidy() +	{ +	} +	function purge() +	{ +	} +	function destroy($var_name, $table = '') +	{ +		unset($this->data[$var_name]); +	} +	public function _exists($var_name) +	{ +	} +	public function sql_load($query) +	{ +	} + +	/** +	* {@inheritDoc} +	*/ +	public function sql_save(phpbb_db_driver $db, $query, $query_result, $ttl) +	{ +		return $query_result; +	} +	public function sql_exists($query_id) +	{ +	} +	public function sql_fetchrow($query_id) +	{ +	} +	public function sql_fetchfield($query_id, $field) +	{ +	} +	public function sql_rowseek($rownum, $query_id) +	{ +	} +	public function sql_freeresult($query_id) +	{ +	} + +	public function obtain_bots() +	{ +		return isset($this->data['_bots']) ? $this->data['_bots'] : array(); +	} +} diff --git a/tests/mock/container_builder.php b/tests/mock/container_builder.php new file mode 100644 index 0000000000..8a81dd72d1 --- /dev/null +++ b/tests/mock/container_builder.php @@ -0,0 +1,160 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ScopeInterface; + +class phpbb_mock_container_builder implements ContainerInterface +{ +	/** +	* Sets a service. +	* +	* @param string $id      The service identifier +	* @param object $service The service instance +	* @param string $scope   The scope of the service +	* +	* @api +	*/ +	public function set($id, $service, $scope = self::SCOPE_CONTAINER) +	{ +	} + +	/** +	* Gets a service. +	* +	* @param string $id              The service identifier +	* @param int    $invalidBehavior The behavior when the service does not exist +	* +	* @return object The associated service +	* +	* @throws InvalidArgumentException if the service is not defined +	* @throws ServiceCircularReferenceException When a circular reference is detected +	* @throws ServiceNotFoundException When the service is not defined +	* +	* @see Reference +	* +	* @api +	*/ +	public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) +	{ +	} + +	/** +	* Returns true if the given service is defined. +	* +	* @param string $id The service identifier +	* +	* @return Boolean true if the service is defined, false otherwise +	* +	* @api +	*/ +	public function has($id) +	{ +	} + +	/** +	* Gets a parameter. +	* +	* @param string $name The parameter name +	* +	* @return mixed  The parameter value +	* +	* @throws InvalidArgumentException if the parameter is not defined +	* +	* @api +	*/ +	public function getParameter($name) +	{ +	} + +	/** +	* Checks if a parameter exists. +	* +	* @param string $name The parameter name +	* +	* @return Boolean The presence of parameter in container +	* +	* @api +	*/ +	public function hasParameter($name) +	{ +	} + +	/** +	* Sets a parameter. +	* +	* @param string $name  The parameter name +	* @param mixed  $value The parameter value +	* +	* @api +	*/ +	public function setParameter($name, $value) +	{ +	} + +	/** +	* Enters the given scope +	* +	* @param string $name +	* +	* @api +	*/ +	public function enterScope($name) +	{ +	} + +	/** +	* Leaves the current scope, and re-enters the parent scope +	* +	* @param string $name +	* +	* @api +	*/ +	public function leaveScope($name) +	{ +	} + +	/** +	* Adds a scope to the container +	* +	* @param ScopeInterface $scope +	* +	* @api +	*/ +	public function addScope(ScopeInterface $scope) +	{ +	} + +	/** +	* Whether this container has the given scope +	* +	* @param string $name +	* +	* @return Boolean +	* +	* @api +	*/ +	public function hasScope($name) +	{ +	} + +	/** +	* Determines whether the given scope is currently active. +	* +	* It does however not check if the scope actually exists. +	* +	* @param string $name +	* +	* @return Boolean +	* +	* @api +	*/ +	public function isScopeActive($name) +	{ +	} +} diff --git a/tests/mock/event_dispatcher.php b/tests/mock/event_dispatcher.php new file mode 100644 index 0000000000..8887b16163 --- /dev/null +++ b/tests/mock/event_dispatcher.php @@ -0,0 +1,16 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_mock_event_dispatcher +{ +	public function trigger_event($eventName, $data) +	{ +		return array(); +	} +} diff --git a/tests/mock/extension_manager.php b/tests/mock/extension_manager.php new file mode 100644 index 0000000000..fdda4cbadc --- /dev/null +++ b/tests/mock/extension_manager.php @@ -0,0 +1,18 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_mock_extension_manager extends phpbb_extension_manager +{ +	public function __construct($phpbb_root_path, $extensions = array()) +	{ +		$this->phpbb_root_path = $phpbb_root_path; +		$this->php_ext = '.php'; +		$this->extensions = $extensions; +	} +} diff --git a/tests/mock/filespec.php b/tests/mock/filespec.php new file mode 100644 index 0000000000..9d2a5c84de --- /dev/null +++ b/tests/mock/filespec.php @@ -0,0 +1,32 @@ +<?php +/** + * + * @package testing + * @copyright (c) 2012 phpBB Group + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 + * + */ + +/** + * Mock filespec class with some basic values to help with testing the + * fileupload class + */ +class phpbb_mock_filespec +{ +	public $filesize; +	public $realname; +	public $extension; +	public $width; +	public $height; +	public $error = array(); + +	public function check_content($disallowed_content) +	{ +		return true; +	} + +	public function get($property) +	{ +		return $this->$property; +	} +} diff --git a/tests/mock/filesystem_extension_manager.php b/tests/mock/filesystem_extension_manager.php new file mode 100644 index 0000000000..c5a51bbb3f --- /dev/null +++ b/tests/mock/filesystem_extension_manager.php @@ -0,0 +1,32 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_mock_filesystem_extension_manager extends phpbb_mock_extension_manager +{ +	public function __construct($phpbb_root_path) +	{ +		$extensions = array(); +		$iterator = new DirectoryIterator($phpbb_root_path . 'ext/'); +		foreach ($iterator as $fileinfo) +		{ +			if ($fileinfo->isDir() && substr($fileinfo->getFilename(), 0, 1) != '.') +			{ +				$name = $fileinfo->getFilename(); +				$extension = array( +					'ext_name' => $name, +					'ext_active' => true, +					'ext_path' => 'ext/' . $name . '/', +				); +				$extensions[$name] = $extension; +			} +		} +		ksort($extensions); +		parent::__construct($phpbb_root_path, $extensions); +	} +} diff --git a/tests/mock/fileupload.php b/tests/mock/fileupload.php new file mode 100644 index 0000000000..cbcbf4a6ab --- /dev/null +++ b/tests/mock/fileupload.php @@ -0,0 +1,23 @@ +<?php +/** + * + * @package testing + * @copyright (c) 2012 phpBB Group + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 + * + */ + +/** + * Mock fileupload class with some basic values to help with testing the + * filespec class + */ +class phpbb_mock_fileupload +{ +	public $max_filesize = 100; +	public $error_prefix = ''; + +	public function valid_dimensions($filespec) +	{ +		return true; +	} +} diff --git a/tests/mock/lang.php b/tests/mock/lang.php new file mode 100644 index 0000000000..781b3d060e --- /dev/null +++ b/tests/mock/lang.php @@ -0,0 +1,33 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* phpbb_mock_lang +* mock a user with some language-keys specified +*/ +class phpbb_mock_lang implements ArrayAccess +{ +	public function offsetExists($offset) +	{ +		return true; +	} + +	public function offsetGet($offset) +	{ +		return $offset; +	} + +	public function offsetSet($offset, $value) +	{ +	} + +	public function offsetUnset($offset) +	{ +	} +} diff --git a/tests/mock/null_cache.php b/tests/mock/null_cache.php new file mode 100644 index 0000000000..7bd33b441b --- /dev/null +++ b/tests/mock/null_cache.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_mock_null_cache +{ +	public function __construct() +	{ +	} + +	public function get($var_name) +	{ +		return false; +	} + +	public function put($var_name, $var, $ttl = 0) +	{ +	} + +	public function destroy($var_name, $table = '') +	{ +	} + +	public function obtain_bots() +	{ +		return array(); +	} + +	public function obtain_word_list() +	{ +		return array(); +	} + +	public function set_bots($bots) +	{ +	} + +	public function sql_exists($query_id) +	{ +		return false; +	} +} diff --git a/tests/mock/request.php b/tests/mock/request.php new file mode 100644 index 0000000000..2a272fc03b --- /dev/null +++ b/tests/mock/request.php @@ -0,0 +1,89 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_mock_request implements phpbb_request_interface +{ +	protected $data; + +	public function __construct($get = array(), $post = array(), $cookie = array(), $server = array(), $request = false, $files = array()) +	{ +		$this->data[phpbb_request_interface::GET] = $get; +		$this->data[phpbb_request_interface::POST] = $post; +		$this->data[phpbb_request_interface::COOKIE] = $cookie; +		$this->data[phpbb_request_interface::REQUEST] = ($request === false) ? $post + $get : $request; +		$this->data[phpbb_request_interface::SERVER] = $server; +		$this->data[phpbb_request_interface::FILES] = $files; +	} + +	public function overwrite($var_name, $value, $super_global = phpbb_request_interface::REQUEST) +	{ +		$this->data[$super_global][$var_name] = $value; +	} + +	public function variable($var_name, $default, $multibyte = false, $super_global = phpbb_request_interface::REQUEST) +	{ +		return isset($this->data[$super_global][$var_name]) ? $this->data[$super_global][$var_name] : $default; +	} + +	public function server($var_name, $default = '') +	{ +		$super_global = phpbb_request_interface::SERVER; +		return isset($this->data[$super_global][$var_name]) ? $this->data[$super_global][$var_name] : $default; +	} + +	public function header($header_name, $default = '') +	{ +		$var_name = 'HTTP_' . str_replace('-', '_', strtoupper($header_name)); +		return $this->server($var_name, $default); +	} + +	public function file($form_name) +	{ +		$super_global = phpbb_request_interface::FILES; +		return isset($this->data[$super_global][$form_name]) ? $this->data[$super_global][$form_name] : array(); +	} + +	public function is_set_post($name) +	{ +		return $this->is_set($name, phpbb_request_interface::POST); +	} + +	public function is_set($var, $super_global = phpbb_request_interface::REQUEST) +	{ +		return isset($this->data[$super_global][$var]); +	} + +	public function is_ajax() +	{ +		return false; +	} + +	public function is_secure() +	{ +		return false; +	} + +	public function variable_names($super_global = phpbb_request_interface::REQUEST) +	{ +		return array_keys($this->data[$super_global]); +	} + +	/* custom methods */ + +	public function set_header($header_name, $value) +	{ +		$var_name = 'HTTP_' . str_replace('-', '_', strtoupper($header_name)); +		$this->data[phpbb_request_interface::SERVER][$var_name] = $value; +	} + +	public function merge($super_global = phpbb_request_interface::REQUEST, $values) +	{ +		$this->data[$super_global] = array_merge($this->data[$super_global], $values); +	} +} diff --git a/tests/mock/session_testable.php b/tests/mock/session_testable.php index 70a58fb6cc..56ff8c8b32 100644 --- a/tests/mock/session_testable.php +++ b/tests/mock/session_testable.php @@ -8,7 +8,6 @@  */  require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; -require_once dirname(__FILE__) . '/../../phpBB/includes/session.php';  /**  * Extends the session class to overwrite the setting of cookies. @@ -17,7 +16,7 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/session.php';  * test it without warnings about sent headers. This class only stores cookie  * data for later verification.  */ -class phpbb_mock_session_testable extends session +class phpbb_mock_session_testable extends phpbb_session  {  	private $_cookies = array(); diff --git a/tests/mock_user.php b/tests/mock/user.php index ec14ce430e..ec14ce430e 100644 --- a/tests/mock_user.php +++ b/tests/mock/user.php diff --git a/tests/network/inet_ntop_pton_test.php b/tests/network/inet_ntop_pton_test.php new file mode 100644 index 0000000000..a59c2103bd --- /dev/null +++ b/tests/network/inet_ntop_pton_test.php @@ -0,0 +1,54 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_network_inet_ntop_pton_test extends phpbb_test_case +{ +	public function data_provider() +	{ +		return array( +			array('127.0.0.1',						'7f000001'), +			array('192.232.131.223',				'c0e883df'), +			array('13.1.68.3',						'0d014403'), +			array('129.144.52.38',					'81903426'), + +			array('2001:280:0:10::5',				'20010280000000100000000000000005'), +			array('fe80::200:4cff:fefe:172f',		'fe8000000000000002004cfffefe172f'), + +			array('::',								'00000000000000000000000000000000'), +			array('::1',							'00000000000000000000000000000001'), +			array('1::',							'00010000000000000000000000000000'), + +			array('1:1:0:0:1::',					'00010001000000000001000000000000'), + +			array('0:2:3:4:5:6:7:8',				'00000002000300040005000600070008'), +			array('1:2:0:4:5:6:7:8',				'00010002000000040005000600070008'), +			array('1:2:3:4:5:6:7:0',				'00010002000300040005000600070000'), + +			array('2001:0:0:1::1',					'20010000000000010000000000000001'), +		); +	} + +	/** +	* @dataProvider data_provider +	*/ +	public function test_inet_ntop($address, $hex) +	{ +		$this->assertEquals($address, phpbb_inet_ntop(pack('H*', $hex))); +	} + +	/** +	* @dataProvider data_provider +	*/ +	public function test_inet_pton($address, $hex) +	{ +		$this->assertEquals($hex, bin2hex(phpbb_inet_pton($address))); +	} +} diff --git a/tests/network/ip_normalise_test.php b/tests/network/ip_normalise_test.php new file mode 100644 index 0000000000..28059f376a --- /dev/null +++ b/tests/network/ip_normalise_test.php @@ -0,0 +1,64 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_network_ip_normalise_test extends phpbb_test_case +{ +	public function data_provider() +	{ +		return array( +			// From: A Recommendation for IPv6 Address Text Representation +			// http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-07 + +			// Section 4: A Recommendation for IPv6 Text Representation +			// Section 4.1: Handling Leading Zeros in a 16 Bit Field +			array('2001:0db8::0001', '2001:db8::1'), + +			// Section 4.2: "::" Usage +			// Section 4.2.1: Shorten As Much As Possible +			array('2001:db8::0:1', '2001:db8::1'), + +			// Section 4.2.2: Handling One 16 Bit 0 Field +			array('2001:db8::1:1:1:1:1', '2001:db8:0:1:1:1:1:1'), + +			// Section 4.2.3: Choice in Placement of "::" +			array('2001:db8:0:0:1:0:0:1', '2001:db8::1:0:0:1'), + +			// Section 4.3: Lower Case +			array('2001:DB8::1', '2001:db8::1'), + +			// Section 5: Text Representation of Special Addresses +			// We want to show IPv4-mapped addresses as plain IPv4 addresses, though. +			array('::ffff:192.168.0.1',			'192.168.0.1'), +			array('0000::0000:ffff:c000:0280',	'192.0.2.128'), + +			// IPv6 addresses with the last 32-bit written in dotted-quad notation +			// should be converted to hex-only IPv6 addresses. +			array('2001:db8::192.0.2.128', '2001:db8::c000:280'), + +			// Any string not passing the IPv4 or IPv6 regular expression +			// is supposed to result in false being returned. +			// Valid and invalid IP addresses are tested in  +			// tests/regex/ipv4.php and tests/regex/ipv6.php. +			array('', false), +			array('192.168.1.256', false), +			array('::ffff:192.168.255.256', false), +			array('::1111:2222:3333:4444:5555:6666::', false), +		); +	} + +	/** +	* @dataProvider data_provider +	*/ +	public function test_ip_normalise($ip_address, $expected) +	{ +		$this->assertEquals($expected, phpbb_ip_normalise($ip_address)); +	} +} diff --git a/tests/privmsgs/delete_user_pms_test.php b/tests/privmsgs/delete_user_pms_test.php new file mode 100644 index 0000000000..f705825262 --- /dev/null +++ b/tests/privmsgs/delete_user_pms_test.php @@ -0,0 +1,102 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_privmsgs.php'; + +class phpbb_privmsgs_delete_user_pms_test extends phpbb_database_test_case +{ +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/delete_user_pms.xml'); +	} + +	static public function delete_user_pms_data() +	{ +		return array( +		//	array( +		//		(user we delete), +		//		array(remaining privmsgs ids), +		//		array(remaining privmsgs_to), +		//	), +			array( +				2, +				array( +					array('msg_id' => 1), +				), +				array( +					array('msg_id' => 1, 'user_id' => 3), +				), +			), +			array( +				3, +				array( +					array('msg_id' => 1), +					array('msg_id' => 2), +					array('msg_id' => 3), +					array('msg_id' => 5), +				), +				array( +					array('msg_id' => 1, 'user_id' => 2), +					array('msg_id' => 1, 'user_id' => 4), +					array('msg_id' => 2, 'user_id' => 2), +					array('msg_id' => 2, 'user_id' => 4), +					array('msg_id' => 3, 'user_id' => 2), +					array('msg_id' => 5, 'user_id' => 2), +					array('msg_id' => 5, 'user_id' => 4), +				), +			), +			array( +				5, +				array( +					array('msg_id' => 1), +					array('msg_id' => 2), +					array('msg_id' => 3), +					array('msg_id' => 4), +					array('msg_id' => 5), +				), +				array( +					array('msg_id' => 1, 'user_id' => 2), +					array('msg_id' => 1, 'user_id' => 3), +					array('msg_id' => 1, 'user_id' => 4), +					array('msg_id' => 2, 'user_id' => 2), +					array('msg_id' => 2, 'user_id' => 4), +					array('msg_id' => 3, 'user_id' => 2), +					array('msg_id' => 4, 'user_id' => 3), +					array('msg_id' => 5, 'user_id' => 2), +					array('msg_id' => 5, 'user_id' => 3), +					array('msg_id' => 5, 'user_id' => 4), +				), +			), +		); +	} + +	/** +	* @dataProvider delete_user_pms_data +	*/ +	public function test_delete_user_pms($delete_user, $remaining_privmsgs, $remaining_privmsgs_to) +	{ +		global $db; + +		$db = $this->new_dbal(); + +		phpbb_delete_user_pms($delete_user); + +		$sql = 'SELECT msg_id +			FROM ' . PRIVMSGS_TABLE; +		$result = $db->sql_query($sql); + +		$this->assertEquals($remaining_privmsgs, $db->sql_fetchrowset($result)); + +		$sql = 'SELECT msg_id, user_id +			FROM ' . PRIVMSGS_TO_TABLE; +		$result = $db->sql_query($sql); + +		$this->assertEquals($remaining_privmsgs_to, $db->sql_fetchrowset($result)); +	} +} diff --git a/tests/privmsgs/fixtures/delete_user_pms.xml b/tests/privmsgs/fixtures/delete_user_pms.xml new file mode 100644 index 0000000000..9a86501b7a --- /dev/null +++ b/tests/privmsgs/fixtures/delete_user_pms.xml @@ -0,0 +1,215 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> +	<table name="phpbb_users"> +		<column>user_id</column> +		<column>username</column> +		<column>username_clean</column> +		<column>user_new_privmsg</column> +		<column>user_unread_privmsg</column> +		<column>user_permissions</column> +		<column>user_sig</column> +		<column>user_occ</column> +		<column>user_interests</column> +		<row> +			<value>2</value> +			<value>sender</value> +			<value>sender</value> +			<value>0</value> +			<value>0</value> +			<value></value> +			<value></value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value>pm in inbox</value> +			<value>pm in inbox</value> +			<value>0</value> +			<value>0</value> +			<value></value> +			<value></value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>4</value> +			<value>pm in no box</value> +			<value>pm in no box</value> +			<value>2</value> +			<value>2</value> +			<value></value> +			<value></value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>5</value> +			<value>no pms</value> +			<value>no pms</value> +			<value>0</value> +			<value>0</value> +			<value></value> +			<value></value> +			<value></value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_privmsgs"> +		<column>msg_id</column> +		<column>root_level</column> +		<column>author_id</column> +		<column>message_subject</column> +		<column>message_text</column> +		<column>to_address</column> +		<column>bcc_address</column> +		<row> +			<value>1</value> +			<value>0</value> +			<value>2</value> +			<value>#1</value> +			<value> +				2 - outbox +				3 - inbox +				4 - nobox +			</value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>2</value> +			<value>0</value> +			<value>2</value> +			<value>#2</value> +			<value> +				2 - outbox +				4 - nobox +			</value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value>0</value> +			<value>2</value> +			<value>#3</value> +			<value> +				2 - outbox +			</value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>4</value> +			<value>0</value> +			<value>2</value> +			<value>#4</value> +			<value> +				3 - nobox +			</value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>5</value> +			<value>0</value> +			<value>2</value> +			<value>#5</value> +			<value> +				2 - outbox +				3 - nobox +				4 - nobox +			</value> +			<value></value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_privmsgs_to"> +		<column>msg_id</column> +		<column>user_id</column> +		<column>author_id</column> +		<column>pm_new</column> +		<column>pm_unread</column> +		<column>folder_id</column> +		<row> +			<value>1</value> +			<value>2</value> +			<value>2</value> +			<value>0</value> +			<value>0</value> +			<value>-2</value> +		</row> +		<row> +			<value>1</value> +			<value>3</value> +			<value>2</value> +			<value>0</value> +			<value>0</value> +			<value>0</value> +		</row> +		<row> +			<value>1</value> +			<value>4</value> +			<value>2</value> +			<value>0</value> +			<value>0</value> +			<value>-3</value> +		</row> +		<row> +			<value>2</value> +			<value>2</value> +			<value>2</value> +			<value>0</value> +			<value>0</value> +			<value>-2</value> +		</row> +		<row> +			<value>2</value> +			<value>4</value> +			<value>2</value> +			<value>0</value> +			<value>0</value> +			<value>-3</value> +		</row> +		<row> +			<value>3</value> +			<value>2</value> +			<value>2</value> +			<value>0</value> +			<value>0</value> +			<value>-2</value> +		</row> +		<row> +			<value>4</value> +			<value>3</value> +			<value>2</value> +			<value>0</value> +			<value>0</value> +			<value>-3</value> +		</row> +		<row> +			<value>5</value> +			<value>2</value> +			<value>2</value> +			<value>0</value> +			<value>0</value> +			<value>-2</value> +		</row> +		<row> +			<value>5</value> +			<value>3</value> +			<value>2</value> +			<value>0</value> +			<value>0</value> +			<value>-3</value> +		</row> +		<row> +			<value>5</value> +			<value>4</value> +			<value>2</value> +			<value>0</value> +			<value>0</value> +			<value>-3</value> +		</row> +	</table> +</dataset> diff --git a/tests/regex/email_test.php b/tests/regex/email_test.php index 17f93259c3..b4ea5b23aa 100644 --- a/tests/regex/email_test.php +++ b/tests/regex/email_test.php @@ -28,6 +28,8 @@ class phpbb_regex_email_test extends phpbb_test_case  			array('alice_foo@bar.phpbb.com'),  			array('alice+tag@foo.phpbb.com'),  			array('alice&tag@foo.phpbb.com'), +			array('alice@phpbb.australia'), +			array('alice@phpbb.topZlevelZdomainZnamesZcanZbeZupZtoZsixtyZthreeZcharactersZlong'),  			//array('"John Doe"@example.com'),  			//array('Alice@[192.168.2.1]'),		// IPv4 @@ -96,6 +98,7 @@ class phpbb_regex_email_test extends phpbb_test_case  			array('! "#$%(),/;<>[]`|@invalidCharsInLocal.org'),  			array('invalidCharsInDomain@! "#$%(),/;<>_[]`|.org'),  			array('local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org'), +			array('alice@phpbb.topZlevelZdomainZnamesZcanZbeZupZtoZsixtyZthreeZcharactersZlongZ'),  		);  	} diff --git a/tests/request/deactivated_super_global_test.php b/tests/request/deactivated_super_global_test.php new file mode 100644 index 0000000000..2e19928a5a --- /dev/null +++ b/tests/request/deactivated_super_global_test.php @@ -0,0 +1,22 @@ +<?php +/** +* +* @package testing +* @version $Id$ +* @copyright (c) 2009 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_deactivated_super_global_test extends phpbb_test_case +{ +	/** +	* Checks that on write access the correct error is thrown +	*/ +	public function test_write_triggers_error() +	{ +		$this->setExpectedTriggerError(E_USER_ERROR); +		$obj = new phpbb_request_deactivated_super_global($this->getMock('phpbb_request_interface'), 'obj', phpbb_request_interface::POST); +		$obj->offsetSet(0, 0); +	} +} diff --git a/tests/request/request_test.php b/tests/request/request_test.php new file mode 100644 index 0000000000..52c21abd2a --- /dev/null +++ b/tests/request/request_test.php @@ -0,0 +1,168 @@ +<?php +/** +* +* @package testing +* @version $Id$ +* @copyright (c) 2009 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_request_test extends phpbb_test_case +{ +	private $type_cast_helper; +	private $request; + +	protected function setUp() +	{ +		// populate super globals +		$_POST['test'] = 1; +		$_GET['test'] = 2; +		$_COOKIE['test'] = 3; +		$_REQUEST['test'] = 3; +		$_GET['unset'] = ''; +		$_FILES['test'] = array( +			'name' => 'file', +			'tmp_name' => 'tmp', +			'size' => 256, +			'type' => 'application/octet-stream', +			'error' => UPLOAD_ERR_OK, +		); + +		$_SERVER['HTTP_HOST'] = 'example.com'; +		$_SERVER['HTTP_ACCEPT'] = 'application/json'; +		$_SERVER['HTTP_SOMEVAR'] = '<value>'; + +		$this->type_cast_helper = $this->getMock('phpbb_request_type_cast_helper_interface'); +		$this->request = new phpbb_request($this->type_cast_helper); +	} + +	public function test_toggle_super_globals() +	{ +		$this->assertTrue($this->request->super_globals_disabled(), 'Superglobals were not disabled'); + +		$this->request->enable_super_globals(); + +		$this->assertFalse($this->request->super_globals_disabled(), 'Superglobals were not enabled'); + +		$this->assertEquals(1, $_POST['test'], 'Checking $_POST after enable_super_globals'); +		$this->assertEquals(2, $_GET['test'], 'Checking $_GET after enable_super_globals'); +		$this->assertEquals(3, $_COOKIE['test'], 'Checking $_COOKIE after enable_super_globals'); +		$this->assertEquals(3, $_REQUEST['test'], 'Checking $_REQUEST after enable_super_globals'); +		$this->assertEquals(256, $_FILES['test']['size']); + +		$_POST['x'] = 2; +		$this->assertEquals($_POST, $GLOBALS['_POST'], 'Checking whether $_POST can still be accessed via $GLOBALS[\'_POST\']'); +	} + +	public function test_server() +	{ +		$this->assertEquals('example.com', $this->request->server('HTTP_HOST')); +	} + +	public function test_server_escaping() +	{ +		$this->type_cast_helper +			->expects($this->once()) +			->method('recursive_set_var') +			->with( +				$this->anything(), +				'', +				true +			); + +		$this->request->server('HTTP_SOMEVAR'); +	} + +	public function test_header() +	{ +		$this->assertEquals('application/json', $this->request->header('Accept')); +	} + +	public function test_header_escaping() +	{ +		$this->type_cast_helper +			->expects($this->once()) +			->method('recursive_set_var') +			->with( +				$this->anything(), +				'', +				true +			); + +		$this->request->header('SOMEVAR'); +	} + +	public function test_file() +	{ +		$file = $this->request->file('test'); +		$this->assertEquals('file', $file['name']); +		$this->assertEquals('tmp', $file['tmp_name']); +		$this->assertEquals(256, $file['size']); +		$this->assertEquals('application/octet-stream', $file['type']); +		$this->assertEquals(UPLOAD_ERR_OK, $file['error']); +	} + +	public function test_file_not_exists() +	{ +		$file = $this->request->file('404'); +		$this->assertTrue(is_array($file)); +		$this->assertTrue(empty($file)); +	} + +	/** +	* Checks that directly accessing $_POST will trigger +	* an error. +	*/ +	public function test_disable_post_super_global() +	{ +		$this->setExpectedTriggerError(E_USER_ERROR); +		$_POST['test'] = 3; +	} + +	public function test_is_set_post() +	{ +		$this->assertTrue($this->request->is_set_post('test')); +		$this->assertFalse($this->request->is_set_post('unset')); +	} + +	public function test_is_ajax_without_ajax() +	{ +		$this->assertFalse($this->request->is_ajax()); +	} + +	public function test_is_ajax_with_ajax() +	{ +		$this->request->enable_super_globals(); +		$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'; +		$this->request = new phpbb_request($this->type_cast_helper); + +		$this->assertTrue($this->request->is_ajax()); +	} + +	public function test_is_secure() +	{ +		$this->assertFalse($this->request->is_secure()); + +		$this->request->enable_super_globals(); +		$_SERVER['HTTPS'] = 'on'; +		$this->request = new phpbb_request($this->type_cast_helper); + +		$this->assertTrue($this->request->is_secure()); +	} + +	public function test_variable_names() +	{ +		$expected = array('test', 'unset'); +		$result = $this->request->variable_names(); +		$this->assertEquals($expected, $result); +	} + +	/** +	* Makes sure super globals work properly after these tests +	*/ +	protected function tearDown() +	{ +		$this->request->enable_super_globals(); +	} +} diff --git a/tests/request/request_var_test.php b/tests/request/request_var_test.php index 8e609c00af..0e85d4694b 100644 --- a/tests/request/request_var_test.php +++ b/tests/request/request_var_test.php @@ -10,9 +10,18 @@  require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';  require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; -class phpbb_request_request_var_test extends phpbb_test_case +class phpbb_request_var_test extends phpbb_test_case  {  	/** +	* Makes sure request_var has its standard behaviour. +	*/ +	protected function setUp() +	{ +		parent::setUp(); +		request_var(false, false, false, false, false); +	} + +	/**  	* @dataProvider request_variables  	*/  	public function test_post($variable_value, $default, $multibyte, $expected) @@ -73,7 +82,48 @@ class phpbb_request_request_var_test extends phpbb_test_case  		unset($_GET[$var], $_POST[$var], $_REQUEST[$var], $_COOKIE[$var]);  	} -	public static function request_variables() +	/** +	* @dataProvider deep_access +	* Only possible with 3.1.x (later) +	*/ +	public function test_deep_multi_dim_array_access($path, $default, $expected) +	{ +		$this->unset_variables('var'); + +		// cannot set $_REQUEST directly because in phpbb_request implementation +		// $_REQUEST = $_POST + $_GET +		$_POST['var'] = array( +			0 => array( +				'b' => array( +					true => array( +						5 => 'c', +						6 => 'd', +					), +				), +			), +			2 => array( +				3 => array( +					false => 5, +				), +			), +		); + +		$result = request_var($path, $default); +		$this->assertEquals($expected, $result, 'Testing deep access to multidimensional input arrays: ' . $path); +	} + +	public function deep_access() +	{ +		return array( +			// array(path, default, expected result) +			array(array('var', 0, 'b', true, 5), '', 'c'), +			array(array('var', 0, 'b', true, 6), '', 'd'), +			array(array('var', 2, 3, false), 0, 5), +			array(array('var', 0, 'b', true), array(0 => ''), array(5 => 'c', 6 => 'd')), +		); +	} + +	public function request_variables()  	{  		return array(  			// strings @@ -173,6 +223,50 @@ class phpbb_request_request_var_test extends phpbb_test_case  					'abc' => array()  				)  			), +			array( +				// input: +				array( +					0 => array(0 => array(3, '4', 'ab'), 1 => array()), +					1 => array(array(3, 4)), +				), +				// default: +				array(0 => array(0 => array(0))), +				false, +				// expected: +				array( +					0 => array(0 => array(3, 4, 0), 1 => array()), +					1 => array(array(3, 4)) +				) +			), +			array( +				// input: +				array( +					'ü' => array(array('c' => 'd')), +					'ä' => array(4 => array('a' => 2, 'ö' => 3)), +				), +				// default: +				array('' => array(0 => array('' => 0))), +				false, +				// expected: +				array( +					'??' => array(4 => array('a' => 2, '??' => 3)), +				) +			), +			array( +				// input: +				array( +					'ü' => array(array('c' => 'd')), +					'ä' => array(4 => array('a' => 2, 'ö' => 3)), +				), +				// default: +				array('' => array(0 => array('' => 0))), +				true, +				// expected: +				array( +					'ü' => array(array('c' => 0)), +					'ä' => array(4 => array('a' => 2, 'ö' => 3)), +				) +			),  		);  	} diff --git a/tests/request/type_cast_helper_test.php b/tests/request/type_cast_helper_test.php new file mode 100644 index 0000000000..f41db005af --- /dev/null +++ b/tests/request/type_cast_helper_test.php @@ -0,0 +1,71 @@ +<?php +/** +* +* @package testing +* @version $Id$ +* @copyright (c) 2009 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; + +class phpbb_type_cast_helper_test extends phpbb_test_case +{ +	private $type_cast_helper; + +	protected function setUp() +	{ +		$this->type_cast_helper = new phpbb_request_type_cast_helper(); +	} + +	public function test_addslashes_recursively() +	{ +		$data = array('some"string' => array('that"' => 'really"', 'needs"' => '"escaping')); +		$expected = array('some\\"string' => array('that\\"' => 'really\\"', 'needs\\"' => '\\"escaping')); + +		$this->type_cast_helper->addslashes_recursively($data); + +		$this->assertEquals($expected, $data); +	} + +	public function test_simple_recursive_set_var() +	{ +		$data = 'eviL<3'; +		$expected = 'eviL<3'; + +		$this->type_cast_helper->recursive_set_var($data, '', true); + +		$this->assertEquals($expected, $data); +	} + +	public function test_nested_recursive_set_var() +	{ +		$data = array('eviL<3'); +		$expected = array('eviL<3'); + +		$this->type_cast_helper->recursive_set_var($data, array(0 => ''), true); + +		$this->assertEquals($expected, $data); +	} + +	public function test_simple_untrimmed_recursive_set_var() +	{ +		$data = " eviL<3\t\t"; +		$expected = " eviL<3\t\t"; + +		$this->type_cast_helper->recursive_set_var($data, '', true, false); + +		$this->assertEquals($expected, $data); +	} + +	public function test_nested_untrimmed_recursive_set_var() +	{ +		$data = array(" eviL<3\t\t"); +		$expected = array(" eviL<3\t\t"); + +		$this->type_cast_helper->recursive_set_var($data, array(0 => ''), true, false); + +		$this->assertEquals($expected, $data); +	} +} diff --git a/tests/search/common_test_case.php b/tests/search/common_test_case.php new file mode 100644 index 0000000000..dd04f7048c --- /dev/null +++ b/tests/search/common_test_case.php @@ -0,0 +1,106 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../test_framework/phpbb_search_test_case.php'; + +abstract class phpbb_search_common_test_case extends phpbb_search_test_case +{ +	public function keywords() +	{ +		return array( +			// keywords +			// terms +			// ok +			// split words +			// common words +			array( +				'fooo', +				'all', +				true, +				array('fooo'), +				array(), +			), +			array( +				'fooo baar', +				'all', +				true, +				array('fooo', 'baar'), +				array(), +			), +			// leading, trailing and multiple spaces +			array( +				'      fooo    baar   ', +				'all', +				true, +				array('fooo', 'baar'), +				array(), +			), +			// words too short +			array( +				'f', +				'all', +				false, +				null, +				// short words count as "common" words +				array('f'), +			), +			array( +				'f o o', +				'all', +				false, +				null, +				array('f', 'o', 'o'), +			), +			array( +				'f -o -o', +				'all', +				false, +				null, +				array('f', '-o', '-o'), +			), +			array( +				'fooo -baar', +				'all', +				true, +				array('-baar', 'fooo'), +				array(), +			), +			// all negative +			array( +				'-fooo', +				'all', +				true, +				array('-fooo'), +				array(), +			), +			array( +				'-fooo -baar', +				'all', +				true, +				array('-fooo', '-baar'), +				array(), +			), +		); +	} + +	/** +	* @dataProvider keywords +	*/ +	public function test_split_keywords($keywords, $terms, $ok, $split_words, $common) +	{ +		$rv = $this->search->split_keywords($keywords, $terms); +		$this->assertEquals($ok, $rv); +		if ($ok) +		{ +			// only check criteria if the search is going to be performed +			$this->assert_array_content_equals($split_words, $this->search->get_split_words()); +		} +		$this->assert_array_content_equals($common, $this->search->get_common_words()); +	} +} diff --git a/tests/search/fixtures/posts.xml b/tests/search/fixtures/posts.xml new file mode 100644 index 0000000000..7b249ee303 --- /dev/null +++ b/tests/search/fixtures/posts.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> +	<table name="phpbb_posts"> +		<column>post_username</column> +		<column>post_subject</column> +		<column>post_text</column> +		<row> +			<value>foo</value> +			<value>foo</value> +			<value>foo</value> +		</row> +		<row> +			<value>bar</value> +			<value>bar</value> +			<value>bar</value> +		</row> +		<row> +			<value>commonword</value> +			<value>commonword</value> +			<value>commonword</value> +		</row> +	</table> +	<table name="phpbb_search_wordlist"> +		<column>word_id</column> +		<column>word_text</column> +		<column>word_common</column> +		<row> +			<value>1</value> +			<value>foo</value> +			<value>0</value> +		</row> +		<row> +			<value>2</value> +			<value>bar</value> +			<value>0</value> +		</row> +		<row> +			<value>3</value> +			<value>commonword</value> +			<value>1</value> +		</row> +	</table> +</dataset> diff --git a/tests/search/mysql_test.php b/tests/search/mysql_test.php new file mode 100644 index 0000000000..3ad15bd806 --- /dev/null +++ b/tests/search/mysql_test.php @@ -0,0 +1,40 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/common_test_case.php'; + +class phpbb_search_mysql_test extends phpbb_search_common_test_case +{ +	protected $db; +	protected $search; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/../fixtures/empty.xml'); +	} + +	protected function setUp() +	{ +		global $phpbb_root_path, $phpEx, $config, $user, $cache; + +		parent::setUp(); + +		// dbal uses cache +		$cache = new phpbb_mock_cache(); + +		//  set config values +		$config['fulltext_mysql_min_word_len'] = 4; +		$config['fulltext_mysql_max_word_len'] = 254; + +		$this->db = $this->new_dbal(); +		$error = null; +		$class = self::get_search_wrapper('phpbb_search_fulltext_mysql'); +		$this->search = new $class($error, $phpbb_root_path, $phpEx, null, $config, $this->db, $user); +	} +} diff --git a/tests/search/native_test.php b/tests/search/native_test.php new file mode 100644 index 0000000000..4a2c210013 --- /dev/null +++ b/tests/search/native_test.php @@ -0,0 +1,158 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../test_framework/phpbb_search_test_case.php'; + +class phpbb_search_native_test extends phpbb_search_test_case +{ +	protected $db; +	protected $search; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/posts.xml'); +	} + +	protected function setUp() +	{ +		global $phpbb_root_path, $phpEx, $config, $user, $cache; + +		parent::setUp(); + +		// dbal uses cache +		$cache = new phpbb_mock_cache(); + +		$this->db = $this->new_dbal(); +		$error = null; +		$class = self::get_search_wrapper('phpbb_search_fulltext_native'); +		$this->search = new $class($error, $phpbb_root_path, $phpEx, null, $config, $this->db, $user); +	} + +	public function keywords() +	{ +		return array( +			// keywords +			// terms +			// ok +			// must contain ids +			// must not contain ids +			// common words +			array( +				'foo', +				'all', +				true, +				array(1), +				array(), +				array(), +			), +			array( +				'foo bar', +				'all', +				true, +				array(1, 2), +				array(), +				array(), +			), +			// leading, trailing and multiple spaces +			array( +				'      foo    bar   ', +				'all', +				true, +				array(1, 2), +				array(), +				array(), +			), +			// words too short +			array( +				'f', +				'all', +				false, +				null, +				null, +				// short words count as "common" words +				array('f'), +			), +			array( +				'f o o', +				'all', +				false, +				null, +				null, +				array('f', 'o', 'o'), +			), +			array( +				'f -o -o', +				'all', +				false, +				null, +				null, +				array('f', 'o', 'o'), +			), +			array( +				'foo -bar', +				'all', +				true, +				array(1), +				array(2), +				array(), +			), +			// all negative +			array( +				'-foo', +				'all', +				false, +				null, +				null, +				array(), +			), +			array( +				'-foo -bar', +				'all', +				false, +				null, +				null, +				array(), +			), +			// all common +			array( +				'commonword', +				'all', +				false, +				null, +				null, +				array('commonword'), +			), +			// some common +			array( +				'commonword foo', +				'all', +				true, +				array(1), +				array(), +				array('commonword'), +			), +		); +	} + +	/** +	* @dataProvider keywords +	*/ +	public function test_split_keywords($keywords, $terms, $ok, $must_contain, $must_not_contain, $common) +	{ +		$rv = $this->search->split_keywords($keywords, $terms); +		$this->assertEquals($ok, $rv); +		if ($ok) +		{ +			// only check criteria if the search is going to be performed +			$this->assert_array_content_equals($must_contain, $this->search->get_must_contain_ids()); +			$this->assert_array_content_equals($must_not_contain, $this->search->get_must_not_contain_ids()); +		} +		$this->assert_array_content_equals($common, $this->search->get_common_words()); +	} +} diff --git a/tests/search/postgres_test.php b/tests/search/postgres_test.php new file mode 100644 index 0000000000..923af6f854 --- /dev/null +++ b/tests/search/postgres_test.php @@ -0,0 +1,40 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/common_test_case.php'; + +class phpbb_search_postgres_test extends phpbb_search_common_test_case +{ +	protected $db; +	protected $search; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/../fixtures/empty.xml'); +	} + +	protected function setUp() +	{ +		global $phpbb_root_path, $phpEx, $config, $user, $cache; + +		parent::setUp(); + +		// dbal uses cache +		$cache = new phpbb_mock_cache(); + +		//  set config values +		$config['fulltext_postgres_min_word_len'] = 4; +		$config['fulltext_postgres_max_word_len'] = 254; + +		$this->db = $this->new_dbal(); +		$error = null; +		$class = self::get_search_wrapper('phpbb_search_fulltext_postgres'); +		$this->search = new $class($error, $phpbb_root_path, $phpEx, null, $config, $this->db, $user); +	} +} diff --git a/tests/security/base.php b/tests/security/base.php index 2658798237..08878ad60d 100644 --- a/tests/security/base.php +++ b/tests/security/base.php @@ -14,20 +14,20 @@ abstract class phpbb_security_test_base extends phpbb_test_case  	*/  	protected function setUp()  	{ -		global $user, $phpbb_root_path; +		global $user, $phpbb_root_path, $request;  		// 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'; +		$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 @@ -36,14 +36,16 @@ abstract class phpbb_security_test_base extends phpbb_test_case  		[SCRIPT_FILENAME] => /var/www/tests/index.php  */ +		$request = new phpbb_mock_request(array(), array(), array(), $server); +  		// Set no user and trick a bit to circumvent errors -		$user = new user(); +		$user = new phpbb_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); +		$user->browser				= $server['HTTP_USER_AGENT']; +		$user->referer				= ''; +		$user->forwarded_for		= ''; +		$user->host					= $server['HTTP_HOST']; +		$user->page = phpbb_session::extract_current_page($phpbb_root_path);  	}  	protected function tearDown() diff --git a/tests/security/extract_current_page_test.php b/tests/security/extract_current_page_test.php index 4911f7b452..d77cbbcaf3 100644 --- a/tests/security/extract_current_page_test.php +++ b/tests/security/extract_current_page_test.php @@ -10,11 +10,10 @@  require_once dirname(__FILE__) . '/base.php';  require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; -require_once dirname(__FILE__) . '/../../phpBB/includes/session.php';  class phpbb_security_extract_current_page_test extends phpbb_security_test_base  { -	public static function security_variables() +	public 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'), @@ -27,10 +26,14 @@ class phpbb_security_extract_current_page_test extends phpbb_security_test_base  	*/  	public function test_query_string_php_self($url, $query_string, $expected)  	{ -		$_SERVER['PHP_SELF'] = $url; -		$_SERVER['QUERY_STRING'] = $query_string; +		global $request; -		$result = session::extract_current_page('./'); +		$request->merge(phpbb_request_interface::SERVER, array( +			'PHP_SELF'	=> $url, +			'QUERY_STRING'	=> $query_string, +		)); + +		$result = phpbb_session::extract_current_page('./');  		$label = 'Running extract_current_page on ' . $query_string . ' with PHP_SELF filled.';  		$this->assertEquals($expected, $result['query_string'], $label); @@ -41,10 +44,14 @@ class phpbb_security_extract_current_page_test extends phpbb_security_test_base  	*/  	public function test_query_string_request_uri($url, $query_string, $expected)  	{ -		$_SERVER['REQUEST_URI'] = $url . '?' . $query_string; -		$_SERVER['QUERY_STRING'] = $query_string; +		global $request; + +		$request->merge(phpbb_request_interface::SERVER, array( +			'PHP_SELF'	=> $url, +			'QUERY_STRING'	=> $query_string, +		)); -		$result = session::extract_current_page('./'); +		$result = phpbb_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_test.php b/tests/security/redirect_test.php index 4848a938c6..1325466137 100644 --- a/tests/security/redirect_test.php +++ b/tests/security/redirect_test.php @@ -10,11 +10,10 @@  require_once dirname(__FILE__) . '/base.php';  require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; -require_once dirname(__FILE__) . '/../../phpBB/includes/session.php';  class phpbb_security_redirect_test extends phpbb_security_test_base  { -	public static function provider() +	public function provider()  	{  		// array(Input -> redirect(), expected triggered error (else false), expected returned result url (else false))  		return array( @@ -30,7 +29,7 @@ class phpbb_security_redirect_test extends phpbb_security_test_base  	protected function setUp()  	{  		parent::setUp(); -		 +  		$GLOBALS['config'] = array(  			'force_server_vars'	=> '0',  		); @@ -57,4 +56,3 @@ class phpbb_security_redirect_test extends phpbb_security_test_base  		}  	}  } - diff --git a/tests/session/append_sid_test.php b/tests/session/append_sid_test.php index 88f6f0718e..b9e9ac1aa9 100644 --- a/tests/session/append_sid_test.php +++ b/tests/session/append_sid_test.php @@ -1,51 +1,54 @@ -<?php
 -/**
 -*
 -* @package testing
 -* @copyright (c) 2011 phpBB Group
 -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
 -*
 -*/
 -
 -require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
 -
 -class phpbb_session_append_sid_test extends phpbb_test_case
 -{
 -
 -	public function append_sid_data()
 -	{
 -		return array(
 -			array('viewtopic.php?t=1&f=2', false, true, false, 'viewtopic.php?t=1&f=2', 'parameters in url-argument'),
 -			array('viewtopic.php', 't=1&f=2', true, false, 'viewtopic.php?t=1&f=2', 'parameters in params-argument using amp'),
 -			array('viewtopic.php', 't=1&f=2', false, false, 'viewtopic.php?t=1&f=2', 'parameters in params-argument using &'),
 -			array('viewtopic.php', array('t' => 1, 'f' => 2), true, false, 'viewtopic.php?t=1&f=2', 'parameters in params-argument as array'),
 -
 -			// Custom sid parameter
 -			array('viewtopic.php', 't=1&f=2', true, 'custom-sid', 'viewtopic.php?t=1&f=2&sid=custom-sid', 'using session_id'),
 -
 -			// Testing anchors
 -			array('viewtopic.php?t=1&f=2#anchor', false, true, false, 'viewtopic.php?t=1&f=2#anchor', 'anchor in url-argument'),
 -			array('viewtopic.php', 't=1&f=2#anchor', true, false, 'viewtopic.php?t=1&f=2#anchor', 'anchor in params-argument'),
 -			array('viewtopic.php', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'viewtopic.php?t=1&f=2#anchor', 'anchor in params-argument (array)'),
 -
 -			// Anchors and custom sid
 -			array('viewtopic.php?t=1&f=2#anchor', false, true, 'custom-sid', 'viewtopic.php?t=1&f=2&sid=custom-sid#anchor', 'anchor in url-argument using session_id'),
 -			array('viewtopic.php', 't=1&f=2#anchor', true, 'custom-sid', 'viewtopic.php?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument using session_id'),
 -			array('viewtopic.php', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'viewtopic.php?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'),
 -
 -			// Empty parameters should not append the ?
 -			array('viewtopic.php', false, true, false, 'viewtopic.php', 'no params using bool false'),
 -			array('viewtopic.php', '', true, false, 'viewtopic.php', 'no params using empty string'),
 -			array('viewtopic.php', array(), true, false, 'viewtopic.php', 'no params using empty array'),
 -		);
 -	}
 -
 -	/**
 -	* @dataProvider append_sid_data
 -	*/
 -	public function test_append_sid($url, $params, $is_amp, $session_id, $expected, $description)
 -	{
 -		$this->assertEquals($expected, append_sid($url, $params, $is_amp, $session_id));
 -	}
 -}
 -
 +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_session_append_sid_test extends phpbb_test_case +{ + +	public function append_sid_data() +	{ +		return array( +			array('viewtopic.php?t=1&f=2', false, true, false, 'viewtopic.php?t=1&f=2', 'parameters in url-argument'), +			array('viewtopic.php', 't=1&f=2', true, false, 'viewtopic.php?t=1&f=2', 'parameters in params-argument using amp'), +			array('viewtopic.php', 't=1&f=2', false, false, 'viewtopic.php?t=1&f=2', 'parameters in params-argument using &'), +			array('viewtopic.php', array('t' => 1, 'f' => 2), true, false, 'viewtopic.php?t=1&f=2', 'parameters in params-argument as array'), + +			// Custom sid parameter +			array('viewtopic.php', 't=1&f=2', true, 'custom-sid', 'viewtopic.php?t=1&f=2&sid=custom-sid', 'using session_id'), + +			// Testing anchors +			array('viewtopic.php?t=1&f=2#anchor', false, true, false, 'viewtopic.php?t=1&f=2#anchor', 'anchor in url-argument'), +			array('viewtopic.php', 't=1&f=2#anchor', true, false, 'viewtopic.php?t=1&f=2#anchor', 'anchor in params-argument'), +			array('viewtopic.php', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'viewtopic.php?t=1&f=2#anchor', 'anchor in params-argument (array)'), + +			// Anchors and custom sid +			array('viewtopic.php?t=1&f=2#anchor', false, true, 'custom-sid', 'viewtopic.php?t=1&f=2&sid=custom-sid#anchor', 'anchor in url-argument using session_id'), +			array('viewtopic.php', 't=1&f=2#anchor', true, 'custom-sid', 'viewtopic.php?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument using session_id'), +			array('viewtopic.php', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'viewtopic.php?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + +			// Empty parameters should not append the ? +			array('viewtopic.php', false, true, false, 'viewtopic.php', 'no params using bool false'), +			array('viewtopic.php', '', true, false, 'viewtopic.php', 'no params using empty string'), +			array('viewtopic.php', array(), true, false, 'viewtopic.php', 'no params using empty array'), +		); +	} + +	/** +	* @dataProvider append_sid_data +	*/ +	public function test_append_sid($url, $params, $is_amp, $session_id, $expected, $description) +	{ +		global $phpbb_dispatcher; + +		$phpbb_dispatcher = new phpbb_mock_event_dispatcher; +		$this->assertEquals($expected, append_sid($url, $params, $is_amp, $session_id)); +	} +} + diff --git a/tests/session/continue_test.php b/tests/session/continue_test.php index c4f7f8d75b..ad78d92299 100644 --- a/tests/session/continue_test.php +++ b/tests/session/continue_test.php @@ -7,7 +7,6 @@  *  */ -require_once dirname(__FILE__) . '/../mock/cache.php';  require_once dirname(__FILE__) . '/testable_factory.php';  class phpbb_session_continue_test extends phpbb_database_test_case diff --git a/tests/session/init_test.php b/tests/session/init_test.php index 2ce6c4a4ac..830de34ed0 100644 --- a/tests/session/init_test.php +++ b/tests/session/init_test.php @@ -7,7 +7,6 @@  *  */ -require_once dirname(__FILE__) . '/../mock/cache.php';  require_once dirname(__FILE__) . '/testable_factory.php';  class phpbb_session_init_test extends phpbb_database_test_case diff --git a/tests/session/testable_factory.php b/tests/session/testable_factory.php index 00f79738ef..1e2b194ece 100644 --- a/tests/session/testable_factory.php +++ b/tests/session/testable_factory.php @@ -7,8 +7,6 @@  *  */ -require_once dirname(__FILE__) . '/../mock/session_testable.php'; -  /**  * This class exists to setup an instance of phpbb's session class for testing.  * @@ -24,6 +22,7 @@ class phpbb_session_testable_factory  	protected $config;  	protected $cache; +	protected $request;  	/**  	* Initialises the factory with a set of default config and cache values. @@ -60,23 +59,30 @@ class phpbb_session_testable_factory  	/**  	* Retrieve the configured session class instance  	* -	* @param dbal $dbal The database connection to use for session data +	* @param phpbb_db_driver $dbal The database connection to use for session data  	* @return phpbb_mock_session_testable A session instance  	*/ -	public function get_session(dbal $dbal) +	public function get_session(phpbb_db_driver $dbal)  	{  		// set up all the global variables used by session -		global $SID, $_SID, $db, $config, $cache; +		global $SID, $_SID, $db, $config, $cache, $request; + +		$request = $this->request = new phpbb_mock_request( +			array(), +			array(), +			$this->cookies, +			$this->server_data +		); +		request_var(null, null, null, null, $request); + +		$config = $this->config = new phpbb_config($this->get_config_data()); +		set_config(null, null, null, $config); -		$config = $this->config = $this->get_config_data();  		$db = $dbal;  		$cache = $this->cache = new phpbb_mock_cache($this->get_cache_data());  		$SID = $_SID = null; -		$_COOKIE = $this->cookies; -		$_SERVER = $this->server_data; -  		$session = new phpbb_mock_session_testable;  		return $session;  	} diff --git a/tests/template/datasets/event_inheritance/ext/kappa/styles/all/template/test.html b/tests/template/datasets/event_inheritance/ext/kappa/styles/all/template/test.html new file mode 100644 index 0000000000..3eb906a09e --- /dev/null +++ b/tests/template/datasets/event_inheritance/ext/kappa/styles/all/template/test.html @@ -0,0 +1 @@ +Kappa test event in all diff --git a/tests/template/datasets/event_inheritance/ext/kappa/styles/silver/template/test.html b/tests/template/datasets/event_inheritance/ext/kappa/styles/silver/template/test.html new file mode 100644 index 0000000000..3b65d80a6d --- /dev/null +++ b/tests/template/datasets/event_inheritance/ext/kappa/styles/silver/template/test.html @@ -0,0 +1 @@ +Kappa test event in silver diff --git a/tests/template/datasets/event_inheritance/ext/kappa/styles/silver_inherit/template/test.html b/tests/template/datasets/event_inheritance/ext/kappa/styles/silver_inherit/template/test.html new file mode 100644 index 0000000000..26826d59e3 --- /dev/null +++ b/tests/template/datasets/event_inheritance/ext/kappa/styles/silver_inherit/template/test.html @@ -0,0 +1 @@ +Kappa test event in silver_inherit diff --git a/tests/template/datasets/event_inheritance/ext/omega/styles/all/template/test.html b/tests/template/datasets/event_inheritance/ext/omega/styles/all/template/test.html new file mode 100644 index 0000000000..003d193dc3 --- /dev/null +++ b/tests/template/datasets/event_inheritance/ext/omega/styles/all/template/test.html @@ -0,0 +1 @@ +Omega test event in all diff --git a/tests/template/datasets/event_inheritance/ext/omega/styles/silver/template/test.html b/tests/template/datasets/event_inheritance/ext/omega/styles/silver/template/test.html new file mode 100644 index 0000000000..6bf06f5457 --- /dev/null +++ b/tests/template/datasets/event_inheritance/ext/omega/styles/silver/template/test.html @@ -0,0 +1 @@ +Omega test event in silver diff --git a/tests/template/datasets/event_inheritance/ext/omega/styles/silver/template/two.html b/tests/template/datasets/event_inheritance/ext/omega/styles/silver/template/two.html new file mode 100644 index 0000000000..7f8058f4e4 --- /dev/null +++ b/tests/template/datasets/event_inheritance/ext/omega/styles/silver/template/two.html @@ -0,0 +1 @@ +two in silver in omega diff --git a/tests/template/datasets/event_inheritance/ext/zeta/styles/all/template/test.html b/tests/template/datasets/event_inheritance/ext/zeta/styles/all/template/test.html new file mode 100644 index 0000000000..5fc7e5ac12 --- /dev/null +++ b/tests/template/datasets/event_inheritance/ext/zeta/styles/all/template/test.html @@ -0,0 +1 @@ +Zeta test event in all diff --git a/tests/template/datasets/event_inheritance/styles/silver/template/event_test.html b/tests/template/datasets/event_inheritance/styles/silver/template/event_test.html new file mode 100644 index 0000000000..4d78dddb12 --- /dev/null +++ b/tests/template/datasets/event_inheritance/styles/silver/template/event_test.html @@ -0,0 +1 @@ +<!-- EVENT test --> diff --git a/tests/template/datasets/event_inheritance/styles/silver/template/event_two.html b/tests/template/datasets/event_inheritance/styles/silver/template/event_two.html new file mode 100644 index 0000000000..fe46be3782 --- /dev/null +++ b/tests/template/datasets/event_inheritance/styles/silver/template/event_two.html @@ -0,0 +1 @@ +<!-- EVENT two --> diff --git a/tests/template/datasets/event_inheritance/styles/silver_inherit/template/event_test.html b/tests/template/datasets/event_inheritance/styles/silver_inherit/template/event_test.html new file mode 100644 index 0000000000..4d78dddb12 --- /dev/null +++ b/tests/template/datasets/event_inheritance/styles/silver_inherit/template/event_test.html @@ -0,0 +1 @@ +<!-- EVENT test --> diff --git a/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/universal.html b/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/universal.html new file mode 100644 index 0000000000..f2c5762ade --- /dev/null +++ b/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/universal.html @@ -0,0 +1 @@ +Universal in trivial extension. diff --git a/tests/template/datasets/ext_trivial/ext/trivial/styles/silver/template/simple.html b/tests/template/datasets/ext_trivial/ext/trivial/styles/silver/template/simple.html new file mode 100644 index 0000000000..fe32a1ed3f --- /dev/null +++ b/tests/template/datasets/ext_trivial/ext/trivial/styles/silver/template/simple.html @@ -0,0 +1 @@ +Simple in trivial extension. diff --git a/tests/template/datasets/ext_trivial/styles/silver/template/event_simple.html b/tests/template/datasets/ext_trivial/styles/silver/template/event_simple.html new file mode 100644 index 0000000000..604c1acdce --- /dev/null +++ b/tests/template/datasets/ext_trivial/styles/silver/template/event_simple.html @@ -0,0 +1 @@ +<!-- EVENT simple --> diff --git a/tests/template/datasets/ext_trivial/styles/silver/template/event_universal.html b/tests/template/datasets/ext_trivial/styles/silver/template/event_universal.html new file mode 100644 index 0000000000..15425cacc3 --- /dev/null +++ b/tests/template/datasets/ext_trivial/styles/silver/template/event_universal.html @@ -0,0 +1 @@ +<!-- EVENT universal --> diff --git a/tests/template/includephp_test.php b/tests/template/includephp_test.php new file mode 100644 index 0000000000..f1012b6939 --- /dev/null +++ b/tests/template/includephp_test.php @@ -0,0 +1,59 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/template_test_case.php'; + +class phpbb_template_includephp_test extends phpbb_template_template_test_case +{ +	public function test_includephp_relative() +	{ +		$this->setup_engine(array('tpl_allow_php' => true)); + +		$cache_file = $this->template->cachepath . 'includephp_relative.html.php'; + +		$this->run_template('includephp_relative.html', array(), array(), array(), "Path is relative to board root.\ntesting included php", $cache_file); + +		$this->template->set_filenames(array('test' => 'includephp_relative.html')); +		$this->assertEquals("Path is relative to board root.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP"); +	} + +	public function test_includephp_variables() +	{ +		$this->setup_engine(array('tpl_allow_php' => true)); + +		$cache_file = $this->template->cachepath . 'includephp_variables.html.php'; + +		$this->run_template('includephp_variables.html', array('TEMPLATES' => 'templates'), array(), array(), "Path includes variables.\ntesting included php", $cache_file); + +		$this->template->set_filenames(array('test' => 'includephp_variables.html')); +		$this->assertEquals("Path includes variables.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP"); +	} + +	public function test_includephp_absolute() +	{ +		$path_to_php = dirname(__FILE__) . '/templates/_dummy_include.php.inc'; +		$this->assertTrue(phpbb_is_absolute($path_to_php)); +		$template_text = "Path is absolute.\n<!-- INCLUDEPHP $path_to_php -->"; + +		$cache_dir = dirname($this->template->cachepath) . '/'; +		$fp = fopen($cache_dir . 'includephp_absolute.html', 'w'); +		fputs($fp, $template_text); +		fclose($fp); + +		$this->setup_engine(array('tpl_allow_php' => true)); + +		$this->style->set_custom_style('tests', $cache_dir, array(), ''); +		$cache_file = $this->template->cachepath . 'includephp_absolute.html.php'; + +		$this->run_template('includephp_absolute.html', array(), array(), array(), "Path is absolute.\ntesting included php", $cache_file); + +		$this->template->set_filenames(array('test' => 'includephp_absolute.html')); +		$this->assertEquals("Path is absolute.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP"); +	} +} diff --git a/tests/template/invalid_constructs_test.php b/tests/template/invalid_constructs_test.php new file mode 100644 index 0000000000..19d192b8b6 --- /dev/null +++ b/tests/template/invalid_constructs_test.php @@ -0,0 +1,87 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/template_test_case.php'; + +class phpbb_template_invalid_constructs_test extends phpbb_template_template_test_case +{ +	public function template_data() +	{ +		return array( +			array( +				'Unknown tag', +				'invalid/unknown_tag.html', +				array(), +				array(), +				array(), +				'invalid/output/unknown_tag.html', +			), +			/* +			* Produces a parse error which is fatal, therefore +			* destroying the test suite. +			array( +				'ENDIF without IF', +				'invalid/endif_without_if.html', +				array(), +				array(), +				array(), +				'invalid/output/endif_without_if.html', +			), +			*/ +		); +	} + +	public function template_data_error() +	{ +		return array( +			array( +				'Include a nonexistent file', +				'invalid/include_nonexistent_file.html', +				array(), +				array(), +				array(), +				E_USER_ERROR, +				'invalid/output/include_nonexistent_file.html', +			), +		); +	} + +	/** +	* @dataProvider template_data +	*/ +	public function test_template($description, $file, $vars, $block_vars, $destroy, $expected) +	{ +		$cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; + +		$this->assertFileNotExists($cache_file); + +		$expected = file_get_contents(dirname(__FILE__) . '/templates/' . $expected); +		// apparently the template engine does not put +		// the trailing newline into compiled templates +		$expected = trim($expected); +		$this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); +	} + +	/** +	* @dataProvider template_data_error +	*/ +	public function test_template_error($description, $file, $vars, $block_vars, $destroy, $error, $expected) +	{ +		$cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; + +		$this->assertFileNotExists($cache_file); + +		$expected = file_get_contents(dirname(__FILE__) . '/templates/' . $expected); +		// apparently the template engine does not put +		// the trailing newline into compiled templates +		$expected = trim($expected); +		$this->setExpectedTriggerError($error, $expected); +		$this->run_template($file, $vars, $block_vars, $destroy, '', $cache_file); +	} +} diff --git a/tests/template/parent_templates/parent_and_child.html b/tests/template/parent_templates/parent_and_child.html new file mode 100644 index 0000000000..71984b48ad --- /dev/null +++ b/tests/template/parent_templates/parent_and_child.html @@ -0,0 +1 @@ +Parent template. diff --git a/tests/template/parent_templates/parent_and_child.js b/tests/template/parent_templates/parent_and_child.js new file mode 100644 index 0000000000..6d9bb163bf --- /dev/null +++ b/tests/template/parent_templates/parent_and_child.js @@ -0,0 +1 @@ +// JavaScript file in a parent style. diff --git a/tests/template/parent_templates/parent_only.html b/tests/template/parent_templates/parent_only.html new file mode 100644 index 0000000000..8cfb90eca2 --- /dev/null +++ b/tests/template/parent_templates/parent_only.html @@ -0,0 +1 @@ +Only in parent. diff --git a/tests/template/parent_templates/parent_only.js b/tests/template/parent_templates/parent_only.js new file mode 100644 index 0000000000..9c3007d83f --- /dev/null +++ b/tests/template/parent_templates/parent_only.js @@ -0,0 +1 @@ +// JavaScript file only in parent style. diff --git a/tests/template/renderer_eval_test.php b/tests/template/renderer_eval_test.php new file mode 100644 index 0000000000..7ebb8b9bda --- /dev/null +++ b/tests/template/renderer_eval_test.php @@ -0,0 +1,31 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_renderer_eval_test extends phpbb_test_case +{ +	public function test_eval() +	{ +		$compiled_code = '<a href="<?php echo \'Test\'; ?>">'; +		$valid_code = '<a href="Test">'; +		$context = new phpbb_template_context(); +		$template = new phpbb_template_renderer_eval($compiled_code, NULL); +		ob_start(); +		try +		{ +			$template->render($context, array()); +		} +		catch (Exception $exception) +		{ +			ob_end_clean(); +			throw $exception; +		} +		$output = ob_get_clean(); +		$this->assertEquals($valid_code, $output); +	} +} diff --git a/tests/template/subdir/includephp_from_subdir_test.php b/tests/template/subdir/includephp_from_subdir_test.php new file mode 100644 index 0000000000..517cb85a30 --- /dev/null +++ b/tests/template/subdir/includephp_from_subdir_test.php @@ -0,0 +1,29 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../template_test_case.php'; + +class phpbb_template_subdir_includephp_from_subdir_test extends phpbb_template_template_test_case +{ +	// Exact copy of test_includephp_relatve from ../includephp_test.php. +	// Verifies that relative php inclusion works when including script +	// (and thus current working directory) is in a subdirectory of +	// board root. +	public function test_includephp_relative() +	{ +		$this->setup_engine(array('tpl_allow_php' => true)); + +		$cache_file = $this->template->cachepath . 'includephp_relative.html.php'; + +		$this->run_template('includephp_relative.html', array(), array(), array(), "Path is relative to board root.\ntesting included php", $cache_file); + +		$this->template->set_filenames(array('test' => 'includephp_relative.html')); +		$this->assertEquals("Path is relative to board root.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP"); +	} +} diff --git a/tests/template/template_compile_test.php b/tests/template/template_compile_test.php new file mode 100644 index 0000000000..7393fc1747 --- /dev/null +++ b/tests/template/template_compile_test.php @@ -0,0 +1,31 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_template_template_compile_test extends phpbb_test_case +{ +	private $template_compile; +	private $template_path; + +	protected function setUp() +	{ +		$this->template_compile = new phpbb_template_compile(false, null, $this->style_resource_locator, ''); +		$this->template_path = dirname(__FILE__) . '/templates'; +	} + +	public function test_in_phpbb() +	{ +		$output = $this->template_compile->compile_file($this->template_path . '/trivial.html'); +		$this->assertTrue(strlen($output) > 0); +		$statements = explode(';', $output); +		$first_statement = $statements[0]; +		$this->assertTrue(!!preg_match('#if.*defined.*IN_PHPBB.*exit#', $first_statement)); +	} +} diff --git a/tests/template/template_events_test.php b/tests/template/template_events_test.php new file mode 100644 index 0000000000..6cea9b92e3 --- /dev/null +++ b/tests/template/template_events_test.php @@ -0,0 +1,118 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/template_test_case.php'; + +class phpbb_template_template_events_test extends phpbb_template_template_test_case +{ +	public function template_data() +	{ +		return array( +			/* +			array( +				'', // file +				'', // dataset +				array(), // style names +				array(), // vars +				array(), // block vars +				array(), // destroy +				'', // expected result +			), +			*/ +			array( +				'Simple template event', +				'ext_trivial', +				array(), +				'event_simple.html', +				array(), +				array(), +				array(), +				"Simple in trivial extension.", +			), +			array( +				'Universal template event ("all" style)', +				'ext_trivial', +				array(), +				'event_universal.html', +				array(), +				array(), +				array(), +				"Universal in trivial extension.", +			), +			array( +				'Template event with inheritance - parent', +				'event_inheritance', +				array('silver'), +				'event_test.html', +				array(), +				array(), +				array(), +'Kappa test event in all +Omega test event in all +Zeta test event in all +Kappa test event in silver +Omega test event in silver', +			), +			array( +				'Template event with inheritance - child', +				'event_inheritance', +				array('silver_inherit', 'silver'), +				'event_test.html', +				array(), +				array(), +				array(), +'Kappa test event in all +Omega test event in all +Zeta test event in all +Kappa test event in silver_inherit', +			), +			array( +				'Definition in parent style', +				'event_inheritance', +				array('silver_inherit', 'silver'), +				'event_two.html', +				array(), +				array(), +				array(), +'two in silver in omega', +			), +		); +	} + +	/** +	* @dataProvider template_data +	*/ +	public function test_event($desc, $dataset, $style_names, $file, array $vars, array $block_vars, array $destroy, $expected) +	{ +		// Reset the engine state +		$this->setup_engine_for_events($dataset, $style_names); + +		// Run test +		$cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; +		$this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); +	} + +	protected function setup_engine_for_events($dataset, $style_names, array $new_config = array()) +	{ +		global $phpbb_root_path, $phpEx, $user; + +		$defaults = $this->config_defaults(); +		$config = new phpbb_config(array_merge($defaults, $new_config)); + +		$this->template_path = dirname(__FILE__) . "/datasets/$dataset/styles/silver/template"; +		$this->style_resource_locator = new phpbb_style_resource_locator(); +		$this->extension_manager = new phpbb_mock_filesystem_extension_manager( +			dirname(__FILE__) . "/datasets/$dataset/" +		); +		$this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context, $this->extension_manager); +		$this->style_provider = new phpbb_style_path_provider(); +		$this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template); +		$this->style->set_custom_style('silver', array($this->template_path), $style_names, ''); +	} +} diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php new file mode 100644 index 0000000000..22b020208b --- /dev/null +++ b/tests/template/template_includejs_test.php @@ -0,0 +1,33 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/template_test_case_with_tree.php'; + +class phpbb_template_template_includejs_test extends phpbb_template_template_test_case_with_tree +{ +	public function test_includejs_compilation() +	{ +		// Reset the engine state +		$this->setup_engine(array('assets_version' => 1)); + +		// Prepare correct result +		$scripts = array( +			'<script src="' . $this->test_path . '/templates/parent_and_child.js?assets_version=1"></script>', +			'<script src="' . $this->test_path . '/parent_templates/parent_only.js?assets_version=1"></script>', +			'<script src="' . $this->test_path . '/templates/child_only.js?assets_version=1"></script>', +			'<script src="' . $this->test_path . '/templates/subdir/parent_only.js?assets_version=1"></script>', +			'<script src="' . $this->test_path . '/templates/subdir/subsubdir/parent_only.js?assets_version=1"></script>', +			'<script src="' . $this->test_path . '/templates/subdir/parent_only.js?assets_version=1"></script>', +		); + +		// Run test +		$cache_file = $this->template->cachepath . 'includejs.html.php'; +		$this->run_template('includejs.html', array('PARENT' => 'parent_only.js', 'SUBDIR' => 'subdir', 'EXT' => 'js'), array(), array(), implode('', $scripts), $cache_file); +	} +} diff --git a/tests/template/template_inheritance_test.php b/tests/template/template_inheritance_test.php new file mode 100644 index 0000000000..febfed9ef0 --- /dev/null +++ b/tests/template/template_inheritance_test.php @@ -0,0 +1,64 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/template_test_case_with_tree.php'; + +class phpbb_template_template_inheritance_test extends phpbb_template_template_test_case_with_tree +{ +	/** +	 * @todo put test data into templates/xyz.test +	 */ +	public function template_data() +	{ +		return array( +			// First element of the array is test name - keep them distinct +			array( +				'simple inheritance - only parent template exists', +				'parent_only.html', +				array(), +				array(), +				array(), +				"Only in parent.", +			), +			array( +				'simple inheritance - only child template exists', +				'child_only.html', +				array(), +				array(), +				array(), +				"Only in child.", +			), +			array( +				'simple inheritance - both parent and child templates exist', +				'parent_and_child.html', +				array(), +				array(), +				array(), +				"Child template.", +			), +		); +	} + +	/** +	* @dataProvider template_data +	*/ +	public function test_template($name, $file, array $vars, array $block_vars, array $destroy, $expected) +	{ +		$cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; + +		$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); +	} +} diff --git a/tests/template/template_locate_test.php b/tests/template/template_locate_test.php new file mode 100644 index 0000000000..851dcae8ea --- /dev/null +++ b/tests/template/template_locate_test.php @@ -0,0 +1,68 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/template_test_case_with_tree.php'; + +class phpbb_template_template_locate_test extends phpbb_template_template_test_case_with_tree +{ +	public function template_data() +	{ +		return array( +			// First element of the array is test name - keep them distinct +			array( +				'simple inheritance - only parent template exists', +				$this->test_path . '/parent_templates/parent_only.html', +				'parent_only.html', +				false, +				true, +			), +			array( +				'simple inheritance - only child template exists', +				$this->test_path . '/templates/child_only.html', +				'child_only.html', +				false, +				true, +			), +			array( +				'simple inheritance - both parent and child templates exist', +				$this->test_path . '/templates/parent_and_child.html', +				'parent_and_child.html', +				false, +				true, +			), +			array( +				'find first template - only child template exists in main style', +				'child_only.html', +				array('parent_only.html', 'child_only.html'), +				false, +				false, +			), +			array( +				'find first template - both templates exist in main style', +				'parent_and_child.html', +				array('parent_and_child.html', 'child_only.html'), +				false, +				false, +			), +		); +	} + +	/** +	* @dataProvider template_data +	*/ +	public function test_template($name, $expected, $files, $return_default, $return_full_path) +	{ +		// Reset the engine state +		$this->setup_engine(); + +		// Locate template +		$result = $this->style_resource_locator->get_first_template_location($files, $return_default, $return_full_path); +		$this->assertSame($expected, $result); +	} +} diff --git a/tests/template/template_test.php b/tests/template/template_test.php index aaee7bb4a0..f43157775a 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -8,93 +8,14 @@  */  require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; -require_once dirname(__FILE__) . '/../../phpBB/includes/template.php'; +require_once dirname(__FILE__) . '/template_test_case.php'; -class phpbb_template_template_test extends phpbb_test_case +class phpbb_template_template_test extends phpbb_template_template_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(); - -		$template_cache_dir = dirname($this->template->cachepath); -		if (!is_writable($template_cache_dir)) -		{ -			$this->markTestSkipped("Template cache directory ({$template_cache_dir}) 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() +	public function template_data()  	{  		return array(  			/* @@ -111,7 +32,7 @@ class phpbb_template_template_test extends phpbb_test_case  				array(),  				array(),  				array(), -				"pass\npass\n<!-- DUMMY var -->", +				"pass\npass\npass\n<!-- DUMMY var -->",  			),  			array(  				'variable.html', @@ -125,14 +46,14 @@ class phpbb_template_template_test extends phpbb_test_case  				array(),  				array(),  				array(), -				'0', +				'03',  			),  			array(  				'if.html',  				array('S_VALUE' => true),  				array(),  				array(), -				"1\n0", +				'1',  			),  			array(  				'if.html', @@ -181,22 +102,22 @@ class phpbb_template_template_test extends phpbb_test_case  				array(),  				array('loop' => array(array('VARIABLE' => 'x'))),  				array(), -				"first\n0\nx\nset\nlast", -			),/* no nested top level loops +				"first\n0 - a\nx - b\nset\nlast", +			),  			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", +				"first\n0 - a\nx - b\nset\n1 - a\ny - b\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", -			),*/ +				"first\n0 - a\nx - b\nset\n1 - a\ny - b\nset\nlast\n0 - c\n1 - c\nlast inner\ninner loop", +			),  			array(  				'loop_advanced.html',  				array(), @@ -209,14 +130,23 @@ class phpbb_template_template_test extends phpbb_test_case  				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", +				"xyz\nabc\nabc\nbar\nbar\nabc",  			),  			array(  				'expressions.html',  				array(),  				array(),  				array(), -				trim(str_repeat("pass", 39)), +				trim(str_repeat("pass\n", 10) . "\n" +					. str_repeat("pass\n", 4) . "\n" +					. str_repeat("pass\n", 2) . "\n" +					. str_repeat("pass\n", 6) . "\n" +					. str_repeat("pass\n", 2) . "\n" +					. str_repeat("pass\n", 6) . "\n" +					. str_repeat("pass\n", 2) . "\n" +					. str_repeat("pass\n", 2) . "\n" +					. str_repeat("pass\n", 3) . "\n" +					. str_repeat("pass\n", 2) . "\n"),  			),  			array(  				'php.html', @@ -233,12 +163,58 @@ class phpbb_template_template_test extends phpbb_test_case  				'value',  			),  			array( +				'include_define.html', +				array('VARIABLE' => 'value'), +				array(), +				array(), +				'value', +			), +			array( +				'include_loop.html', +				array(), +				array('loop' => array(array('NESTED_FILE' => 'include_loop1.html')), 'loop.inner' => array(array('NESTED_FILE' => 'include_loop1.html'), array('NESTED_FILE' => 'include_loop2.html'), array('NESTED_FILE' => 'include_loop3.html'))), +				array(), +				"1\n_1\n_02\n_3", +			), +			array( +				'include_variable.html', +				array('FILE' => 'variable.html', 'VARIABLE' => 'value'), +				array(), +				array(), +				'value', +			), +			array( +				'include_variables.html', +				array('SUBDIR' => 'subdir', '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 +			), +			/* Currently fail on develop: +			http://tracker.phpbb.com/browse/PHPBB3-11323 +			array( +				'include_define_variable.html', +				array('VARIABLE' => 'variable.html'), +				array(), +				array(), +				'variable.html', +			), +			array( +				'include_loop_define.html', +				array('VARIABLE' => 'value'), +				array('loop' => array(array('NESTED_FILE' => 'variable.html'))), +				array(), +				'value', +			), +			*/ +			/* no top level nested loops  			array(  				'loop_vars.html',  				array(), @@ -247,26 +223,75 @@ class phpbb_template_template_test extends phpbb_test_case  				"first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast",  			),*/  			array( +				// Just like a regular loop but the name begins +				// with an underscore +				'loop_underscore.html', +				array(), +				array(), +				array(), +				"noloop\nnoloop", +			), +			array(  				'lang.html',  				array(),  				array(),  				array(), -				"{ VARIABLE }\n{ VARIABLE }", +				"{ VARIABLE }\n{ 1_VARIABLE }\n{ VARIABLE }\n{ 1_VARIABLE }",  			),  			array(  				'lang.html', -				array('L_VARIABLE' => "Value'"), +				array('L_VARIABLE' => "Value'", 'L_1_VARIABLE' => "1 O'Clock"),  				array(),  				array(), -				"Value'\nValue\'", +				"Value'\n1 O'Clock\nValue\'\n1 O\'Clock",  			),  			array(  				'lang.html', -				array('LA_VARIABLE' => "Value'"), +				array('LA_VARIABLE' => "Value'", 'LA_1_VARIABLE' => "1 O'Clock"), +				array(), +				array(), +				"{ VARIABLE }\n{ 1_VARIABLE }\nValue'\n1 O'Clock", +			), +			array( +				'loop_nested_multilevel_ref.html', +				array(), +				array(), +				array(), +				"top-level content", +			), +			array( +				'loop_nested_multilevel_ref.html', +				array(), +				array('outer' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'outer.inner' => array(array('VARIABLE' => 'z'), array('VARIABLE' => 'zz'))), +				array(), +				// I don't completely understand this output, hopefully it's correct +				"top-level content\nouter x\nouter y\ninner z\nfirst row\n\ninner zz", +			), +			array( +				'loop_nested_deep_multilevel_ref.html', +				array(), +				array('outer' => array(array()), 'outer.middle' => array(array()), 'outer.middle.inner' => array(array('VARIABLE' => 'z'), array('VARIABLE' => 'zz'))), +				array(), +				// I don't completely understand this output, hopefully it's correct +				"top-level content\nouter\nmiddle\ninner z\nfirst row of 2 in inner\n\ninner zz", +			), +			array( +				'loop_size.html',  				array(), +				array('loop' => array(array()), 'empty_loop' => array()),  				array(), -				"{ VARIABLE }\nValue'", +				"nonexistent = 0\n! nonexistent\n\nempty = 0\n! empty\nloop\n\nin loop",  			), +			/* Does not pass with the current implementation. +			array( +				'loop_reuse.html', +				array(), +				array('one' => array(array('VAR' => 'a'), array('VAR' => 'b')), 'one.one' => array(array('VAR' => 'c'), array('VAR' => 'd'))), +				array(), +				// Not entirely sure what should be outputted but the current output of "a" is most certainly wrong +				"a\nb\nc\nd", +			), +			*/  		);  	} @@ -277,7 +302,7 @@ class phpbb_template_template_test extends phpbb_test_case  		$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); +		$expecting = sprintf('style resource locator: File for handle test does not exist. Could not find: %s', $this->test_path . '/templates/' . $filename);  		$this->setExpectedTriggerError(E_USER_ERROR, $expecting);  		$this->display('test'); @@ -285,7 +310,7 @@ class phpbb_template_template_test extends phpbb_test_case  	public function test_empty_file()  	{ -		$expecting = 'template->set_filenames: Empty filename specified for test'; +		$expecting = 'style resource locator: set_filenames: Empty filename specified for test';  		$this->setExpectedTriggerError(E_USER_ERROR, $expecting);  		$this->template->set_filenames(array('test' => '')); @@ -293,52 +318,12 @@ class phpbb_template_template_test extends phpbb_test_case  	public function test_invalid_handle()  	{ -		$expecting = 'template->_tpl_load(): No file specified for handle test'; +		$expecting = '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  	*/ @@ -380,46 +365,61 @@ class phpbb_template_template_test extends phpbb_test_case  			$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() +	public function test_append_var_without_assign_var()  	{ -		$GLOBALS['config']['tpl_allow_php'] = true; +		$this->template->set_filenames(array( +			'append_var'	=> 'variable.html' +		)); -		$cache_file = $this->template->cachepath . 'php.html.php'; +		$items = array('This ', 'is ', 'a ', 'test'); +		$expecting = implode('', $items); +		 +		foreach ($items as $word) +		{ +			$this->template->append_var('VARIABLE', $word); +		} -		$this->assertFileNotExists($cache_file); +		$this->assertEquals($expecting, $this->display('append_var')); +	} -		$this->run_template('php.html', array(), array(), array(), 'test', $cache_file); +	public function test_append_var_with_assign_var() +	{ +		$this->template->set_filenames(array( +			'append_var'	=> 'variable.html' +		)); -		$GLOBALS['config']['tpl_allow_php'] = false; +		$start = 'This '; +		$items = array('is ', 'a ', 'test'); +		$expecting = $start . implode('', $items); +		 +		$this->template->assign_var('VARIABLE', $start); +		foreach ($items as $word) +		{ +			$this->template->append_var('VARIABLE', $word); +		} + +		$this->assertEquals($expecting, $this->display('append_var'));  	} -	public function test_includephp() +	public function test_php()  	{ -		$GLOBALS['config']['tpl_allow_php'] = true; +		$this->setup_engine(array('tpl_allow_php' => true)); -		$cache_file = $this->template->cachepath . 'includephp.html.php'; - -		$this->run_template('includephp.html', array(), array(), array(), 'testing included php', $cache_file); +		$cache_file = $this->template->cachepath . 'php.html.php'; -		$this->template->set_filenames(array('test' => 'includephp.html')); -		$this->assertEquals('testing included php', $this->display('test'), "Testing INCLUDEPHP"); +		$this->assertFileNotExists($cache_file); -		$GLOBALS['config']['tpl_allow_php'] = false; +		$this->run_template('php.html', array(), array(), array(), 'test', $cache_file);  	} -	public static function alter_block_array_data() +	public function alter_block_array_data()  	{  		return array(  			array( @@ -527,5 +527,5 @@ EOT  		$this->template->alter_block_array($alter_block, $vararray, $key, $mode);  		$this->assertEquals($expect, $this->display('test'), $description);  	} -} +} diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php new file mode 100644 index 0000000000..3c997cb00e --- /dev/null +++ b/tests/template/template_test_case.php @@ -0,0 +1,144 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_template_template_test_case extends phpbb_test_case +{ +	protected $style; +	protected $template; +	protected $template_path; +	protected $style_resource_locator; +	protected $style_provider; + +	protected $test_path = 'tests/template'; + +	// Keep the contents of the cache for debugging? +	const PRESERVE_CACHE = true; + +	protected function display($handle) +	{ +		ob_start(); + +		try +		{ +			$this->assertTrue($this->template->display($handle, false)); +		} +		catch (Exception $exception) +		{ +			// reset output buffering even when an error occured +			// PHPUnit turns trigger_error into exceptions as well +			ob_end_clean(); +			throw $exception; +		} + +		$result = self::trim_template_result(ob_get_clean()); + +		return $result; +	} + +	protected static function trim_template_result($result) +	{ +		return str_replace("\n\n", "\n", implode("\n", array_map('trim', explode("\n", trim($result))))); +	} + +	protected function config_defaults() +	{ +		$defaults = array( +			'load_tplcompile'	=> true, +			'tpl_allow_php'		=> false, +		); +		return $defaults; +	} + +	protected function setup_engine(array $new_config = array()) +	{ +		global $phpbb_root_path, $phpEx, $user; + +		$defaults = $this->config_defaults(); +		$config = new phpbb_config(array_merge($defaults, $new_config)); + +		$this->template_path = $this->test_path . '/templates'; +		$this->style_resource_locator = new phpbb_style_resource_locator(); +		$this->style_provider = new phpbb_style_path_provider(); +		$this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context()); +		$this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template); +		$this->style->set_custom_style('tests', $this->template_path, array(), ''); +	} + +	protected function setUp() +	{ +		// Test the engine can be used +		$this->setup_engine(); + +		$template_cache_dir = dirname($this->template->cachepath); +		if (!is_writable($template_cache_dir)) +		{ +			$this->markTestSkipped("Template cache directory ({$template_cache_dir}) is not writable."); +		} + +		foreach (glob($this->template->cachepath . '*') as $file) +		{ +			unlink($file); +		} + +		$this->setup_engine(); +	} + +	protected function tearDown() +	{ +		if (is_object($this->template)) +		{ +			foreach (glob($this->template->cachepath . '*') as $file) +			{ +				unlink($file); +			} +		} +	} + +	protected 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. +		// When testing eval path the cache file may not exist. +		if (self::PRESERVE_CACHE && file_exists($cache_file)) +		{ +			copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file)); +		} +	} +} diff --git a/tests/template/template_test_case_with_tree.php b/tests/template/template_test_case_with_tree.php new file mode 100644 index 0000000000..7585be5728 --- /dev/null +++ b/tests/template/template_test_case_with_tree.php @@ -0,0 +1,29 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/template_test_case.php'; + +class phpbb_template_template_test_case_with_tree extends phpbb_template_template_test_case +{ +	protected function setup_engine(array $new_config = array()) +	{ +		global $phpbb_root_path, $phpEx, $user; + +		$defaults = $this->config_defaults(); +		$config = new phpbb_config(array_merge($defaults, $new_config)); + +		$this->template_path = $this->test_path . '/templates'; +		$this->parent_template_path = $this->test_path . '/parent_templates'; +		$this->style_resource_locator = new phpbb_style_resource_locator(); +		$this->style_provider = new phpbb_style_path_provider(); +		$this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context()); +		$this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template); +		$this->style->set_custom_style('tests', array($this->template_path, $this->parent_template_path), array(), ''); +	} +} diff --git a/tests/template/templates/basic.html b/tests/template/templates/basic.html index c1dd690260..e5c6f280fb 100644 --- a/tests/template/templates/basic.html +++ b/tests/template/templates/basic.html @@ -16,5 +16,8 @@ fail  <!-- BEGINELSE -->  pass  <!-- END empty --> +<!-- IF not S_EMPTY --> +pass +<!-- ENDIF -->  <!-- DUMMY var --> diff --git a/tests/template/templates/child_only.html b/tests/template/templates/child_only.html new file mode 100644 index 0000000000..6121fef5c5 --- /dev/null +++ b/tests/template/templates/child_only.html @@ -0,0 +1 @@ +Only in child. diff --git a/tests/template/templates/child_only.js b/tests/template/templates/child_only.js new file mode 100644 index 0000000000..542b26526c --- /dev/null +++ b/tests/template/templates/child_only.js @@ -0,0 +1 @@ +// JavaScript file only in a child style. diff --git a/tests/template/templates/define.html b/tests/template/templates/define.html index 82237d21a3..4459fffbe0 100644 --- a/tests/template/templates/define.html +++ b/tests/template/templates/define.html @@ -2,6 +2,9 @@  {$VALUE}  <!-- DEFINE $VALUE = 'abc' -->  {$VALUE} +<!-- INCLUDE define_include.html --> +{$INCLUDED_VALUE} +{$VALUE}  <!-- UNDEFINE $VALUE -->  {$VALUE}  <!-- DEFINE $VALUE --> diff --git a/tests/template/templates/define_include.html b/tests/template/templates/define_include.html new file mode 100644 index 0000000000..9c470c296a --- /dev/null +++ b/tests/template/templates/define_include.html @@ -0,0 +1,3 @@ +{$VALUE} +<!-- DEFINE $INCLUDED_VALUE = 'bar' --> +{$INCLUDED_VALUE} diff --git a/tests/template/templates/events.html b/tests/template/templates/events.html new file mode 100644 index 0000000000..c44a7469e7 --- /dev/null +++ b/tests/template/templates/events.html @@ -0,0 +1,4 @@ +<!-- EVENT child_only --> +<!-- EVENT parent_only --> +<!-- EVENT parent_and_child --> +<!-- EVENT random_event --> diff --git a/tests/template/templates/expressions.html b/tests/template/templates/expressions.html index c40d967dab..e1283f165f 100644 --- a/tests/template/templates/expressions.html +++ b/tests/template/templates/expressions.html @@ -1,86 +1,57 @@  <!-- 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 index c502e52f51..eed431019e 100644 --- a/tests/template/templates/if.html +++ b/tests/template/templates/if.html @@ -3,9 +3,9 @@  <!-- ELSEIF S_OTHER_VALUE -->  2  <!-- ELSE --> -0 +03  <!-- ENDIF --> -<!-- IF (S_VALUE > S_OTHER_VALUE) --> -0 +<!-- IF S_VALUE and S_OTHER_VALUE and (S_VALUE > S_OTHER_VALUE) --> +04  <!-- ENDIF --> diff --git a/tests/template/templates/include_define.html b/tests/template/templates/include_define.html new file mode 100644 index 0000000000..2419c8cba1 --- /dev/null +++ b/tests/template/templates/include_define.html @@ -0,0 +1,2 @@ +<!-- DEFINE $DEF = 'variable.html' --> +<!-- INCLUDE {$DEF} --> diff --git a/tests/template/templates/include_define_variable.html b/tests/template/templates/include_define_variable.html new file mode 100644 index 0000000000..aff9b574c2 --- /dev/null +++ b/tests/template/templates/include_define_variable.html @@ -0,0 +1,2 @@ +<!-- DEFINE $DEF = '{VARIABLE}' --> +<!-- INCLUDE {$DEF} --> diff --git a/tests/template/templates/include_loop.html b/tests/template/templates/include_loop.html new file mode 100644 index 0000000000..d5c3d9bc82 --- /dev/null +++ b/tests/template/templates/include_loop.html @@ -0,0 +1,4 @@ +<!-- BEGIN loop --> +<!-- INCLUDE {loop.NESTED_FILE} --> +<!-- BEGIN inner -->_<!-- INCLUDE {inner.NESTED_FILE} --><!-- END inner --> +<!-- END loop --> diff --git a/tests/template/templates/include_loop1.html b/tests/template/templates/include_loop1.html new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/template/templates/include_loop1.html @@ -0,0 +1 @@ +1 diff --git a/tests/template/templates/include_loop2.html b/tests/template/templates/include_loop2.html new file mode 100644 index 0000000000..9e22bcb8e3 --- /dev/null +++ b/tests/template/templates/include_loop2.html @@ -0,0 +1 @@ +02 diff --git a/tests/template/templates/include_loop3.html b/tests/template/templates/include_loop3.html new file mode 100644 index 0000000000..00750edc07 --- /dev/null +++ b/tests/template/templates/include_loop3.html @@ -0,0 +1 @@ +3 diff --git a/tests/template/templates/include_loop_define.html b/tests/template/templates/include_loop_define.html new file mode 100644 index 0000000000..f539b21396 --- /dev/null +++ b/tests/template/templates/include_loop_define.html @@ -0,0 +1,4 @@ +<!-- BEGIN loop --> +<!-- DEFINE $DEF = '{loop.NESTED_FILE}' --> +<!-- INCLUDE {$DEF} --> +<!-- END loop --> diff --git a/tests/template/templates/include_variable.html b/tests/template/templates/include_variable.html new file mode 100644 index 0000000000..b907e0b44f --- /dev/null +++ b/tests/template/templates/include_variable.html @@ -0,0 +1 @@ +<!-- INCLUDE {FILE} --> diff --git a/tests/template/templates/include_variables.html b/tests/template/templates/include_variables.html new file mode 100644 index 0000000000..8371a061b5 --- /dev/null +++ b/tests/template/templates/include_variables.html @@ -0,0 +1 @@ +<!-- INCLUDE {SUBDIR}/variable.html --> diff --git a/tests/template/templates/includejs.html b/tests/template/templates/includejs.html new file mode 100644 index 0000000000..ef73700eeb --- /dev/null +++ b/tests/template/templates/includejs.html @@ -0,0 +1,8 @@ +<!-- INCLUDEJS parent_and_child.js --> +<!-- INCLUDEJS {PARENT} --> +<!-- DEFINE $TEST = 'child_only.js' --> +<!-- INCLUDEJS {$TEST} --> +<!-- INCLUDEJS subdir/{PARENT} --> +<!-- INCLUDEJS {SUBDIR}/subsubdir/{PARENT} --> +<!-- INCLUDEJS {SUBDIR}/parent_only.{EXT} --> +{SCRIPTS} diff --git a/tests/template/templates/includephp.html b/tests/template/templates/includephp_relative.html index 70ebdac0d0..297c9efcb0 100644 --- a/tests/template/templates/includephp.html +++ b/tests/template/templates/includephp_relative.html @@ -1 +1,2 @@ +Path is relative to board root.  <!-- INCLUDEPHP ../tests/template/templates/_dummy_include.php.inc --> diff --git a/tests/template/templates/includephp_variables.html b/tests/template/templates/includephp_variables.html new file mode 100644 index 0000000000..6106efc86a --- /dev/null +++ b/tests/template/templates/includephp_variables.html @@ -0,0 +1,2 @@ +Path includes variables. +<!-- INCLUDEPHP ../tests/template/{TEMPLATES}/_dummy_include.php.inc --> diff --git a/tests/template/templates/invalid/endif_without_if.html b/tests/template/templates/invalid/endif_without_if.html new file mode 100644 index 0000000000..e371ffd150 --- /dev/null +++ b/tests/template/templates/invalid/endif_without_if.html @@ -0,0 +1 @@ +<!-- ENDIF --> diff --git a/tests/template/templates/invalid/include_nonexistent_file.html b/tests/template/templates/invalid/include_nonexistent_file.html new file mode 100644 index 0000000000..617d2fdaaa --- /dev/null +++ b/tests/template/templates/invalid/include_nonexistent_file.html @@ -0,0 +1 @@ +<!-- INCLUDE nonexistent.html --> diff --git a/tests/template/templates/invalid/output/endif_without_if.html b/tests/template/templates/invalid/output/endif_without_if.html new file mode 100644 index 0000000000..5f2239c964 --- /dev/null +++ b/tests/template/templates/invalid/output/endif_without_if.html @@ -0,0 +1 @@ +Parse error (fatal, destroys php runtime). diff --git a/tests/template/templates/invalid/output/include_nonexistent_file.html b/tests/template/templates/invalid/output/include_nonexistent_file.html new file mode 100644 index 0000000000..8a118d2713 --- /dev/null +++ b/tests/template/templates/invalid/output/include_nonexistent_file.html @@ -0,0 +1 @@ +style resource locator: File for handle nonexistent.html does not exist. Could not find: diff --git a/tests/template/templates/invalid/output/unknown_tag.html b/tests/template/templates/invalid/output/unknown_tag.html new file mode 100644 index 0000000000..1489e5e31a --- /dev/null +++ b/tests/template/templates/invalid/output/unknown_tag.html @@ -0,0 +1 @@ +<!-- UNKNOWNTAG variable.html --> diff --git a/tests/template/templates/invalid/unknown_tag.html b/tests/template/templates/invalid/unknown_tag.html new file mode 100644 index 0000000000..1489e5e31a --- /dev/null +++ b/tests/template/templates/invalid/unknown_tag.html @@ -0,0 +1 @@ +<!-- UNKNOWNTAG variable.html --> diff --git a/tests/template/templates/lang.html b/tests/template/templates/lang.html index 2b5ea1cafe..3eecc298cb 100644 --- a/tests/template/templates/lang.html +++ b/tests/template/templates/lang.html @@ -1,3 +1,5 @@  {L_VARIABLE} +{L_1_VARIABLE}  {LA_VARIABLE} +{LA_1_VARIABLE} diff --git a/tests/template/templates/loop_expressions.html b/tests/template/templates/loop_expressions.html new file mode 100644 index 0000000000..6bff53f388 --- /dev/null +++ b/tests/template/templates/loop_expressions.html @@ -0,0 +1,11 @@ +<!-- BEGIN loop --> + +<!-- IF loop.S_ROW_NUM is even by 4 -->on<!-- ELSE -->off<!-- ENDIF --> + +<!-- END loop --> + +<!-- BEGIN loop --> + +<!-- IF loop.S_ROW_NUM is odd by 3 -->on<!-- ELSE -->off<!-- ENDIF --> + +<!-- END loop --> diff --git a/tests/template/templates/loop_nested.html b/tests/template/templates/loop_nested.html index 9b251cd453..45b1ef85d4 100644 --- a/tests/template/templates/loop_nested.html +++ b/tests/template/templates/loop_nested.html @@ -1,8 +1,6 @@  <!-- BEGIN outer -->  	outer - {outer.S_ROW_COUNT}<!-- IF outer.VARIABLE --> - {outer.VARIABLE}<!-- ENDIF --> -  	<!-- BEGIN middle -->  		middle - {middle.S_ROW_COUNT}<!-- IF middle.VARIABLE --> - {middle.VARIABLE}<!-- ENDIF --> -  	<!-- END middle -->  <!-- END outer --> diff --git a/tests/template/templates/loop_nested_deep_multilevel_ref.html b/tests/template/templates/loop_nested_deep_multilevel_ref.html new file mode 100644 index 0000000000..bcc2a7c07b --- /dev/null +++ b/tests/template/templates/loop_nested_deep_multilevel_ref.html @@ -0,0 +1,13 @@ +top-level content +<!-- BEGIN outer --> +	outer +	<!-- BEGIN middle --> +		{outer.middle.S_BLOCK_NAME} +		<!-- BEGIN inner --> +			inner {inner.VARIABLE} +			<!-- IF outer.middle.inner.S_FIRST_ROW --> +				first row of {outer.middle.inner.S_NUM_ROWS} in {middle.inner.S_BLOCK_NAME} +			<!-- ENDIF --> +		<!-- END inner --> +	<!-- END middle --> +<!-- END outer --> diff --git a/tests/template/templates/loop_nested_multilevel_ref.html b/tests/template/templates/loop_nested_multilevel_ref.html new file mode 100644 index 0000000000..f2f1c746ed --- /dev/null +++ b/tests/template/templates/loop_nested_multilevel_ref.html @@ -0,0 +1,10 @@ +top-level content +<!-- BEGIN outer --> +	outer {outer.VARIABLE} +	<!-- BEGIN inner --> +		inner {inner.VARIABLE} +		<!-- IF outer.inner.S_FIRST_ROW --> +			first row +		<!-- ENDIF --> +	<!-- END inner --> +<!-- END outer --> diff --git a/tests/template/templates/loop_reuse.html b/tests/template/templates/loop_reuse.html new file mode 100644 index 0000000000..bd0354ae6f --- /dev/null +++ b/tests/template/templates/loop_reuse.html @@ -0,0 +1,6 @@ +<!-- BEGIN one --> +	{one.VAR} +	<!-- BEGIN one --> +		{one.one.VAR} +	<!-- END one --> +<!-- END one --> diff --git a/tests/template/templates/loop_size.html b/tests/template/templates/loop_size.html new file mode 100644 index 0000000000..f1938441df --- /dev/null +++ b/tests/template/templates/loop_size.html @@ -0,0 +1,39 @@ +<!-- IF .nonexistent_loop --> +	nonexistent +<!-- ENDIF --> + +<!-- IF .nonexistent_loop == 0 --> +	nonexistent = 0 +<!-- ENDIF --> + +<!-- IF ! .nonexistent_loop --> +	! nonexistent +<!-- ENDIF --> + +<!-- IF .empty_loop --> +	empty +<!-- ENDIF --> + +<!-- IF .empty_loop == 0 --> +	empty = 0 +<!-- ENDIF --> + +<!-- IF ! .empty_loop --> +	! empty +<!-- ENDIF --> + +<!-- IF .loop --> +	loop +<!-- ENDIF --> + +<!-- IF .loop == 0 --> +	loop = 0 +<!-- ENDIF --> + +<!-- IF ! .loop --> +	! loop +<!-- ENDIF --> + +<!-- BEGIN loop --> +	in loop +<!-- END --> diff --git a/tests/template/templates/loop_underscore.html b/tests/template/templates/loop_underscore.html new file mode 100644 index 0000000000..dafce5dea6 --- /dev/null +++ b/tests/template/templates/loop_underscore.html @@ -0,0 +1,21 @@ +<!-- BEGIN _underscore_loop --> +loop +<!-- BEGINELSE --> +noloop +<!-- END loop --> + +<!-- IF ._underscore_loop --> +loop +<!-- ELSE --> +noloop +<!-- ENDIF --> + +<!-- IF ._underscore_loop == 2 --> +loop +<!-- ENDIF --> + +<!-- BEGIN _underscore_loop --> +<!-- BEGIN !block --> +loop#{loop.S_ROW_COUNT}-block#{block.S_ROW_COUNT} +<!-- END !block --> +<!-- END _underscore_loop --> diff --git a/tests/template/templates/loop_vars.html b/tests/template/templates/loop_vars.html index 4f02fd2e6c..d94a0ae0f7 100644 --- a/tests/template/templates/loop_vars.html +++ b/tests/template/templates/loop_vars.html @@ -1,21 +1,14 @@  <!-- BEGIN loop -->  <!-- IF loop.S_FIRST_ROW -->first<!-- ENDIF --> - -{loop.S_ROW_COUNT} - -{loop.VARIABLE} - +{loop.S_ROW_NUM} - a +{loop.VARIABLE} - b  <!-- IF loop.VARIABLE -->set<!-- ENDIF --> -  <!-- IF loop.S_LAST_ROW -->  last  <!-- ENDIF -->  <!-- BEGIN inner --> - -{inner.S_ROW_COUNT} - +{inner.S_ROW_NUM} - c  <!-- 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/parent_and_child.html b/tests/template/templates/parent_and_child.html new file mode 100644 index 0000000000..16223d91e7 --- /dev/null +++ b/tests/template/templates/parent_and_child.html @@ -0,0 +1 @@ +Child template. diff --git a/tests/template/templates/parent_and_child.js b/tests/template/templates/parent_and_child.js new file mode 100644 index 0000000000..d544d94d83 --- /dev/null +++ b/tests/template/templates/parent_and_child.js @@ -0,0 +1 @@ +// JavaScript file in a child style. diff --git a/tests/template/templates/subdir/parent_only.js b/tests/template/templates/subdir/parent_only.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/template/templates/subdir/parent_only.js diff --git a/tests/template/templates/subdir/subsubdir/parent_only.js b/tests/template/templates/subdir/subsubdir/parent_only.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/template/templates/subdir/subsubdir/parent_only.js diff --git a/tests/template/templates/subdir/variable.html b/tests/template/templates/subdir/variable.html new file mode 100644 index 0000000000..f68f91597c --- /dev/null +++ b/tests/template/templates/subdir/variable.html @@ -0,0 +1 @@ +{VARIABLE} diff --git a/tests/template/templates/trivial.html b/tests/template/templates/trivial.html new file mode 100644 index 0000000000..3a1c1c5324 --- /dev/null +++ b/tests/template/templates/trivial.html @@ -0,0 +1 @@ +This is a trivial template. diff --git a/tests/test_framework/phpbb_database_connection_odbc_pdo_wrapper.php b/tests/test_framework/phpbb_database_connection_odbc_pdo_wrapper.php new file mode 100644 index 0000000000..ec59fa3886 --- /dev/null +++ b/tests/test_framework/phpbb_database_connection_odbc_pdo_wrapper.php @@ -0,0 +1,37 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +if (!class_exists('PDO')) +{ +	return; +} + +/** +* Used for passing in information about the PDO driver +* since the PDO class reveals nothing about the DSN that +* the user provided. +* +* This is used in the custom PHPUnit ODBC driver +*/ +class phpbb_database_connection_odbc_pdo_wrapper extends PDO +{ +	// Name of the driver being used (i.e. mssql, firebird) +	public $driver = ''; + +	// Version number of driver since PDO::getAttribute(PDO::ATTR_CLIENT_VERSION) is pretty useless for this +	public $version = 0; + +	function __construct($dbms, $version, $dsn, $user, $pass) +	{ +		$this->driver = $dbms; +		$this->version = (double) $version; + +		parent::__construct($dsn, $user, $pass); +	} +} diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index e742b543b0..72bce2e38a 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -13,6 +13,8 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test  	protected $test_case_helpers; +	protected $fixture_xml_data; +  	public function __construct($name = NULL, array $data = array(), $dataName = '')  	{  		parent::__construct($name, $data, $dataName); @@ -28,6 +30,44 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test  		);  	} +	protected function setUp() +	{ +		parent::setUp(); + +		// Resynchronise tables if a fixture was loaded +		if (isset($this->fixture_xml_data)) +		{ +			$config = $this->get_database_config(); +			$manager = $this->create_connection_manager($config); +			$manager->connect(); +			$manager->post_setup_synchronisation($this->fixture_xml_data); +		} +	} + +	public function createXMLDataSet($path) +	{ +		$db_config = $this->get_database_config(); + +		// Firebird requires table and column names to be uppercase +		if ($db_config['dbms'] == 'phpbb_db_driver_firebird') +		{ +			$xml_data = file_get_contents($path); +			$xml_data = preg_replace_callback('/(?:(<table name="))([a-z_]+)(?:(">))/', 'phpbb_database_test_case::to_upper', $xml_data); +			$xml_data = preg_replace_callback('/(?:(<column>))([a-z_]+)(?:(<\/column>))/', 'phpbb_database_test_case::to_upper', $xml_data); + +			$new_fixture = tmpfile(); +			fwrite($new_fixture, $xml_data); +			fseek($new_fixture, 0); + +			$meta_data = stream_get_meta_data($new_fixture); +			$path = $meta_data['uri']; +		} + +		$this->fixture_xml_data = parent::createXMLDataSet($path); + +		return $this->fixture_xml_data; +	} +  	public function get_test_case_helpers()  	{  		if (!$this->test_case_helpers) @@ -78,9 +118,7 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test  		$config = $this->get_database_config(); -		require_once dirname(__FILE__) . '/../../phpBB/includes/db/' . $config['dbms'] . '.php'; -		$dbal = 'dbal_' . $config['dbms']; -		$db = new $dbal(); +		$db = new $config['dbms']();  		$db->sql_connect($config['dbhost'], $config['dbuser'], $config['dbpasswd'], $config['dbname'], $config['dbport']);  		return $db; @@ -106,4 +144,33 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test  	{  		return new phpbb_database_test_connection_manager($config);  	} + +	/** +	* Converts a match in the middle of a string to uppercase. +	* This is necessary for transforming the fixture information for Firebird tests +	* +	* @param $matches The array of matches from a regular expression +	* +	* @return string The string with the specified match converted to uppercase +	*/ +	static public function to_upper($matches) +	{ +		return $matches[1] . strtoupper($matches[2]) . $matches[3]; +	} + +	public function assert_array_content_equals($one, $two) +	{ +		// http://stackoverflow.com/questions/3838288/phpunit-assert-two-arrays-are-equal-but-order-of-elements-not-important +		// but one array_diff is not enough! +		if (sizeof(array_diff($one, $two)) || sizeof(array_diff($two, $one))) +		{ +			// get a nice error message +			$this->assertEquals($one, $two); +		} +		else +		{ +			// increase assertion count +			$this->assertTrue(true); +		} +	}  } diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index c734c90a1a..03097a10a0 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -8,6 +8,7 @@  */  require_once dirname(__FILE__) . '/../../phpBB/includes/functions_install.php'; +require_once dirname(__FILE__) . '/phpbb_database_connection_odbc_pdo_wrapper.php';  class phpbb_database_test_connection_manager  { @@ -62,6 +63,13 @@ class phpbb_database_test_connection_manager  				// e.g. Driver={SQL Server Native Client 10.0};Server=(local)\SQLExpress;  				$dsn .= $this->config['dbhost']; +				// Primarily for MSSQL Native/Azure as ODBC needs it in $dbhost, attached to the Server param +				if ($this->config['dbport']) +				{ +					$port_delimiter = (defined('PHP_OS') && substr(PHP_OS, 0, 3) === 'WIN') ? ',' : ':'; +					$dsn .= $port_delimiter . $this->config['dbport']; +				} +  				if ($use_db)  				{  					$dsn .= ';Database=' . $this->config['dbname']; @@ -80,12 +88,52 @@ class phpbb_database_test_connection_manager  				{  					$dsn .= ';dbname=' . $this->config['dbname'];  				} +				else if ($this->dbms['PDO'] == 'pgsql') +				{ +					// Postgres always connects to a +					// database. If the database is not +					// specified here, but the username +					// is specified, then connection +					// will be to the database named +					// as the username. +					// +					// For greater compatibility, connect +					// instead to postgres database which +					// should always exist: +					// http://www.postgresql.org/docs/9.0/static/manage-ag-templatedbs.html +					$dsn .= ';dbname=postgres'; +				}  			break;  		} +		// These require different connection strings on the phpBB side than they do in PDO +		// so you must provide a DSN string for ODBC separately +		if (!empty($this->config['custom_dsn']) && ($this->config['dbms'] == 'phpbb_db_driver_mssql' || $this->config['dbms'] == 'phpbb_db_driver_firebird')) +		{ +			$dsn = 'odbc:' . $this->config['custom_dsn']; +		} +  		try  		{ -			$this->pdo = new PDO($dsn, $this->config['dbuser'], $this->config['dbpasswd']); +			switch ($this->config['dbms']) +			{ +				case 'phpbb_db_driver_mssql': +				case 'phpbb_db_driver_mssql_odbc': +					$this->pdo = new phpbb_database_connection_odbc_pdo_wrapper('mssql', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']); +				break; + +				case 'phpbb_db_driver_firebird': +					if (!empty($this->config['custom_dsn'])) +					{ +						$this->pdo = new phpbb_database_connection_odbc_pdo_wrapper('firebird', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']); +						break; +					} +					// Fall through if they're using the firebird PDO driver and not the generic ODBC driver + +				default: +					$this->pdo = new PDO($dsn, $this->config['dbuser'], $this->config['dbpasswd']); +				break; +			}  		}  		catch (PDOException $e)  		{ @@ -93,8 +141,7 @@ class phpbb_database_test_connection_manager  			throw new Exception("Unable do connect to $cleaned_dsn using PDO with error: {$e->getMessage()}");  		} -		// good for debug -		// $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +		$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  	}  	/** @@ -118,11 +165,25 @@ class phpbb_database_test_connection_manager  	{  		switch ($this->config['dbms'])  		{ -			case 'sqlite': -				if (file_exists($this->config['dbhost'])) +			case 'phpbb_db_driver_sqlite': +			case 'phpbb_db_driver_firebird': +				$this->connect(); +				// Drop all of the tables +				foreach ($this->get_tables() as $table)  				{ -					unlink($this->config['dbhost']); +					$this->pdo->exec('DROP TABLE ' . $table);  				} +				$this->purge_extras(); +			break; + +			case 'phpbb_db_driver_oracle': +				$this->connect(); +				// Drop all of the tables +				foreach ($this->get_tables() as $table) +				{ +					$this->pdo->exec('DROP TABLE ' . $table . ' CASCADE CONSTRAINTS'); +				} +				$this->purge_extras();  			break;  			default: @@ -131,6 +192,15 @@ class phpbb_database_test_connection_manager  				try  				{  					$this->pdo->exec('DROP DATABASE ' . $this->config['dbname']); + +					try +					{ +						$this->pdo->exec('CREATE DATABASE ' . $this->config['dbname']); +					} +					catch (PDOException $e) +					{ +						throw new Exception("Unable to re-create database: {$e->getMessage()}"); +					}  				}  				catch (PDOException $e)  				{ @@ -139,9 +209,8 @@ class phpbb_database_test_connection_manager  					{  						$this->pdo->exec('DROP TABLE ' . $table);  					} +					$this->purge_extras();  				} - -				$this->pdo->exec('CREATE DATABASE ' . $this->config['dbname']);  			 break;  		}  	} @@ -157,39 +226,38 @@ class phpbb_database_test_connection_manager  		switch ($this->config['dbms'])  		{ -			case 'mysql': -			case 'mysql4': -			case 'mysqli': +			case 'phpbb_db_driver_mysql': +			case 'phpbb_db_driver_mysqli':  				$sql = 'SHOW TABLES';  			break; -			case 'sqlite': +			case 'phpbb_db_driver_sqlite':  				$sql = 'SELECT name  					FROM sqlite_master  					WHERE type = "table"';  			break; -			case 'mssql': -			case 'mssql_odbc': -			case 'mssqlnative': +			case 'phpbb_db_driver_mssql': +			case 'phpbb_db_driver_mssql_odbc': +			case 'phpbb_db_driver_mssqlnative':  				$sql = "SELECT name  					FROM sysobjects  					WHERE type='U'";  			break; -			case 'postgres': +			case 'phpbb_db_driver_postgres':  				$sql = 'SELECT relname  					FROM pg_stat_user_tables';  			break; -			case 'firebird': +			case 'phpbb_db_driver_firebird':  				$sql = 'SELECT rdb$relation_name  					FROM rdb$relations  					WHERE rdb$view_source is null  						AND rdb$system_flag = 0';  			break; -			case 'oracle': +			case 'phpbb_db_driver_oracle':  				$sql = 'SELECT table_name  					FROM USER_TABLES';  			break; @@ -224,8 +292,8 @@ class phpbb_database_test_connection_manager  	protected function load_schema_from_file($directory)  	{  		$schema = $this->dbms['SCHEMA']; -		 -		if ($this->config['dbms'] == 'mysql') + +		if ($this->config['dbms'] == 'phpbb_db_driver_mysql')  		{  			$sth = $this->pdo->query('SELECT VERSION() AS version');  			$row = $sth->fetch(PDO::FETCH_ASSOC); @@ -243,8 +311,8 @@ class phpbb_database_test_connection_manager  		$filename = $directory . $schema . '_schema.sql';  		$queries = file_get_contents($filename); -		$sql = remove_comments($queries); -		 +		$sql = phpbb_remove_comments($queries); +  		$sql = split_sql_file($sql, $this->dbms['DELIM']);  		foreach ($sql as $query) @@ -259,47 +327,47 @@ class phpbb_database_test_connection_manager  	protected function get_dbms_data($dbms)  	{  		$available_dbms = array( -			'firebird'	=> array( +			'phpbb_db_driver_firebird'	=> array(  				'SCHEMA'		=> 'firebird',  				'DELIM'			=> ';;',  				'PDO'			=> 'firebird',  			), -			'mysqli'	=> array( +			'phpbb_db_driver_mysqli'	=> array(  				'SCHEMA'		=> 'mysql_41',  				'DELIM'			=> ';',  				'PDO'			=> 'mysql',  			), -			'mysql'		=> array( +			'phpbb_db_driver_mysql'		=> array(  				'SCHEMA'		=> 'mysql',  				'DELIM'			=> ';',  				'PDO'			=> 'mysql',  			), -			'mssql'		=> array( +			'phpbb_db_driver_mssql'		=> array(  				'SCHEMA'		=> 'mssql',  				'DELIM'			=> 'GO',  				'PDO'			=> 'odbc',  			), -			'mssql_odbc'=>	array( +			'phpbb_db_driver_mssql_odbc'=>	array(  				'SCHEMA'		=> 'mssql',  				'DELIM'			=> 'GO',  				'PDO'			=> 'odbc',  			), -			'mssqlnative'		=> array( +			'phpbb_db_driver_mssqlnative'		=> array(  				'SCHEMA'		=> 'mssql',  				'DELIM'			=> 'GO',  				'PDO'			=> 'sqlsrv',  			), -			'oracle'	=>	array( +			'phpbb_db_driver_oracle'	=>	array(  				'SCHEMA'		=> 'oracle',  				'DELIM'			=> '/',  				'PDO'			=> 'oci',  			), -			'postgres' => array( +			'phpbb_db_driver_postgres' => array(  				'SCHEMA'		=> 'postgres',  				'DELIM'			=> ';',  				'PDO'			=> 'pgsql',  			), -			'sqlite'		=> array( +			'phpbb_db_driver_sqlite'		=> array(  				'SCHEMA'		=> 'sqlite',  				'DELIM'			=> ';',  				'PDO'			=> 'sqlite2', @@ -317,4 +385,151 @@ class phpbb_database_test_connection_manager  			throw new Exception($message);  		}  	} + +	/** +	* Removes extra objects from a database. This is for cases where dropping the database fails. +	*/ +	public function purge_extras() +	{ +		$this->ensure_connected(__METHOD__); +		$queries = array(); + +		switch ($this->config['dbms']) +		{ +			case 'phpbb_db_driver_firebird': +				$sql = 'SELECT RDB$GENERATOR_NAME +					FROM RDB$GENERATORS +					WHERE RDB$SYSTEM_FLAG = 0'; +				$result = $this->pdo->query($sql); + +				while ($row = $result->fetch(PDO::FETCH_NUM)) +				{ +					$queries[] = 'DROP GENERATOR ' . current($row); +				} +			break; + +			case 'phpbb_db_driver_oracle': +				$sql = 'SELECT sequence_name +					FROM USER_SEQUENCES'; +				$result = $this->pdo->query($sql); + +				while ($row = $result->fetch(PDO::FETCH_NUM)) +				{ +					$queries[] = 'DROP SEQUENCE ' . current($row); +				} +			break; +		} + +		foreach ($queries as $query) +		{ +			$this->pdo->exec($query); +		} +	} + +	/** +	* Performs synchronisations on the database after a fixture has been loaded +	* +	* @param	PHPUnit_Extensions_Database_DataSet_XmlDataSet	$xml_data_set		Information about the tables contained within the loaded fixture +	* +	* @return null +	*/ +	public function post_setup_synchronisation($xml_data_set) +	{ +		$this->ensure_connected(__METHOD__); +		$queries = array(); + +		// Get escaped versions of the table names used in the fixture +		$table_names = array_map(array($this->pdo, 'PDO::quote'), $xml_data_set->getTableNames()); + +		switch ($this->config['dbms']) +		{ +			case 'phpbb_db_driver_oracle': +				// Get all of the information about the sequences +				$sql = "SELECT t.table_name, tc.column_name, d.referenced_name as sequence_name, s.increment_by, s.min_value +					FROM USER_TRIGGERS t +					JOIN USER_DEPENDENCIES d ON (d.name = t.trigger_name) +					JOIN USER_TRIGGER_COLS tc ON (tc.trigger_name = t.trigger_name) +					JOIN USER_SEQUENCES s ON (s.sequence_name = d.referenced_name) +					WHERE d.referenced_type = 'SEQUENCE' +						AND d.type = 'TRIGGER' +						AND t.table_name IN (" . implode(', ', array_map('strtoupper', $table_names)) . ')'; + +				$result = $this->pdo->query($sql); + +				while ($row = $result->fetch(PDO::FETCH_ASSOC)) +				{ +					// Get the current max value of the table +					$sql = "SELECT MAX({$row['COLUMN_NAME']}) AS max FROM {$row['TABLE_NAME']}"; +					$max_result = $this->pdo->query($sql); +					$max_row = $max_result->fetch(PDO::FETCH_ASSOC); + +					if (!$max_row) +					{ +						continue; +					} + +					$max_val = (int) $max_row['MAX']; +					$max_val++; + +					/** +					* This is not the "proper" way, but the proper way does not allow you to completely reset +					* tables with no rows since you have to select the next value to make the change go into effect. +					* You would have to go past the minimum value to set it correctly, but that's illegal. +					* Since we have no objects attached to our sequencers (triggers aren't attached), this works fine. +					*/ +					$queries[] = 'DROP SEQUENCE ' . $row['SEQUENCE_NAME']; +					$queries[] = "CREATE SEQUENCE {$row['SEQUENCE_NAME']}  +									MINVALUE {$row['MIN_VALUE']}  +									INCREMENT BY {$row['INCREMENT_BY']}  +									START WITH $max_val"; +				} +			break; + +			case 'phpbb_db_driver_postgres': +				// Get the sequences attached to the tables +				$sql = 'SELECT column_name, table_name FROM information_schema.columns +					WHERE table_name IN (' . implode(', ', $table_names) . ") +						AND strpos(column_default, '_seq''::regclass') > 0"; +				$result = $this->pdo->query($sql); + +				$setval_queries = array(); +				while ($row = $result->fetch(PDO::FETCH_ASSOC)) +				{ +					// Get the columns used in the fixture for this table +					$column_names = $xml_data_set->getTableMetaData($row['table_name'])->getColumns(); + +					// Skip sequences that weren't specified in the fixture +					if (!in_array($row['column_name'], $column_names)) +					{ +						continue; +					} + +					// Get the old value if it exists, or use 1 if it doesn't +					$sql = "SELECT COALESCE((SELECT MAX({$row['column_name']}) + 1 FROM {$row['table_name']}), 1) AS val"; +					$result_max = $this->pdo->query($sql); +					$row_max = $result_max->fetch(PDO::FETCH_ASSOC); + +					if ($row_max) +					{ +						$seq_name = $this->pdo->quote($row['table_name'] . '_seq'); +						$max_val = (int) $row_max['val']; + +						// The last parameter is false so that the system doesn't increment it again +						$setval_queries[] = "SETVAL($seq_name, $max_val, false)"; +					} +				} + +				// Combine all of the SETVALs into one query +				if (sizeof($setval_queries)) +				{ +					$queries[] = 'SELECT ' . implode(', ', $setval_queries); +				} +			break; +		} + +		foreach ($queries as $query) +		{ +			$this->pdo->exec($query); +		} +	}  } diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index b5e6f7e377..e346223a4b 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -6,6 +6,7 @@  * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2  *  */ +use Symfony\Component\BrowserKit\CookieJar;  require_once __DIR__ . '/../../phpBB/includes/functions_install.php'; @@ -14,28 +15,66 @@ class phpbb_functional_test_case extends phpbb_test_case  	protected $client;  	protected $root_url; +	protected $cache = null; +	protected $db = null; +	protected $extension_manager = null; + +	/** +	* Session ID for current test's session (each test makes its own) +	* @var string +	*/ +	protected $sid; + +	/** +	* Language array used by phpBB +	* @var array +	*/ +	protected $lang = array(); +  	static protected $config = array();  	static protected $already_installed = false;  	static public function setUpBeforeClass()  	{ -		if (!extension_loaded('phar')) +		parent::setUpBeforeClass(); + +		self::$config = phpbb_test_case_helpers::get_test_config(); + +		// Important: this is used both for installation and by +		// test cases for querying the tables. +		// Therefore table prefix must be set before a board is +		// installed, and also before each test case is run. +		self::$config['table_prefix'] = 'phpbb_'; + +		if (!isset(self::$config['phpbb_functional_url']))  		{ -			self::markTestSkipped('phar extension is not loaded'); +			self::markTestSkipped('phpbb_functional_url was not set in test_config and wasn\'t set as PHPBB_FUNCTIONAL_URL environment variable either.');  		} -		require_once 'phar://' . __DIR__ . '/../../vendor/goutte.phar'; +		if (!self::$already_installed) +		{ +			self::install_board(); +			self::$already_installed = true; +		}  	}  	public function setUp()  	{ -		if (!isset(self::$config['phpbb_functional_url'])) -		{ -			$this->markTestSkipped('phpbb_functional_url was not set in test_config and wasn\'t set as PHPBB_FUNCTIONAL_URL environment variable either.'); -		} +		parent::setUp(); + +		$this->bootstrap(); -		$this->client = new Goutte\Client(); +		$this->cookieJar = new CookieJar; +		$this->client = new Goutte\Client(array(), null, $this->cookieJar); +		// Reset the curl handle because it is 0 at this point and not a valid +		// resource +		$this->client->getClient()->getCurlMulti()->reset(true);  		$this->root_url = self::$config['phpbb_functional_url']; +		// Clear the language array so that things +		// that were added in other tests are gone +		$this->lang = array(); +		$this->add_lang('common'); +		$this->purge_cache();  	}  	public function request($method, $path) @@ -57,28 +96,64 @@ class phpbb_functional_test_case extends phpbb_test_case  		$this->backupStaticAttributesBlacklist += array(  			'phpbb_functional_test_case' => array('config', 'already_installed'),  		); +	} -		if (!static::$already_installed) +	protected function get_db() +	{ +		global $phpbb_root_path, $phpEx; +		// so we don't reopen an open connection +		if (!($this->db instanceof phpbb_db_driver))  		{ -			$this->install_board(); -			$this->bootstrap(); -			static::$already_installed = true; +			$dbms = self::$config['dbms']; +			$this->db = new $dbms(); +			$this->db->sql_connect(self::$config['dbhost'], self::$config['dbuser'], self::$config['dbpasswd'], self::$config['dbname'], self::$config['dbport']);  		} +		return $this->db;  	} -	protected function install_board() +	protected function get_cache_driver()  	{ -		global $phpbb_root_path, $phpEx; +		if (!$this->cache) +		{ +			$this->cache = new phpbb_cache_driver_file; +		} -		self::$config = phpbb_test_case_helpers::get_test_config(); +		return $this->cache; +	} -		if (!isset(self::$config['phpbb_functional_url'])) +	protected function purge_cache() +	{ +		$cache = $this->get_cache_driver(); + +		$cache->purge(); +		$cache->unload(); +		$cache->load(); +	} + +	protected function get_extension_manager() +	{ +		global $phpbb_root_path, $phpEx; + +		if (!$this->extension_manager)  		{ -			return; +			$this->extension_manager = new phpbb_extension_manager( +				$this->get_db(), +				new phpbb_config(array()), +				self::$config['table_prefix'] . 'ext', +				$phpbb_root_path, +				".$phpEx", +				$this->get_cache_driver() +			);  		} -		self::$config['table_prefix'] = 'phpbb_'; -		$this->recreate_database(self::$config); +		return $this->extension_manager; +	} + +	static protected function install_board() +	{ +		global $phpbb_root_path, $phpEx; + +		self::recreate_database(self::$config);  		if (file_exists($phpbb_root_path . "config.$phpEx"))  		{ @@ -123,21 +198,30 @@ class phpbb_functional_test_case extends phpbb_test_case  		));  		// end data -		$content = $this->do_request('install'); -		$this->assertContains('Welcome to Installation', $content); - -		$this->do_request('create_table', $data); - -		file_put_contents($phpbb_root_path . "config.$phpEx", phpbb_create_config_file_data($data, self::$config['dbms'], array(), true)); - -		$this->do_request('config_file', $data); - +		$content = self::do_request('install'); +		self::assertNotSame(false, $content); +		self::assertContains('Welcome to Installation', $content); + +		// Installer uses 3.0-style dbms name +		$data['dbms'] = str_replace('phpbb_db_driver_', '', $data['dbms']); +		$content = self::do_request('create_table', $data); +		self::assertNotSame(false, $content); +		self::assertContains('The database tables used by phpBB', $content); +		// 3.0 or 3.1 +		self::assertContains('have been created and populated with some initial data.', $content); + +		$content = self::do_request('config_file', $data); +		self::assertNotSame(false, $content); +		self::assertContains('Configuration file', $content); +		file_put_contents($phpbb_root_path . "config.$phpEx", phpbb_create_config_file_data($data, self::$config['dbms'], true, true)); + +		$content = self::do_request('final', $data); +		self::assertNotSame(false, $content); +		self::assertContains('You have successfully installed', $content);  		copy($phpbb_root_path . "config.$phpEx", $phpbb_root_path . "config_test.$phpEx"); - -		$this->do_request('final', $data);  	} -	private function do_request($sub, $post_data = null) +	static private function do_request($sub, $post_data = null)  	{  		$context = null; @@ -156,9 +240,214 @@ class phpbb_functional_test_case extends phpbb_test_case  		return file_get_contents(self::$config['phpbb_functional_url'] . 'install/index.php?mode=install&sub=' . $sub, false, $context);  	} -	private function recreate_database($config) +	static private function recreate_database($config)  	{  		$db_conn_mgr = new phpbb_database_test_connection_manager($config);  		$db_conn_mgr->recreate_db();  	} + +	/** +	* Creates a new user with limited permissions +	* +	* @param string $username Also doubles up as the user's password +	* @return int ID of created user +	*/ +	protected function create_user($username) +	{ +		// Required by unique_id +		global $config; + +		$config = new phpbb_config(array()); +		$config['rand_seed'] = ''; +		$config['rand_seed_last_update'] = time() + 600; + +		// Required by user_add +		global $db, $cache, $phpbb_dispatcher, $phpbb_container; +		$db = $this->get_db(); +		if (!function_exists('phpbb_mock_null_cache')) +		{ +			require_once(__DIR__ . '/../mock/null_cache.php'); +		} +		$cache = new phpbb_mock_null_cache; + +		$cache_driver = new phpbb_cache_driver_null(); +		$phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); +		$phpbb_container +			->expects($this->any()) +			->method('get') +			->with('cache.driver') +			->will($this->returnValue($cache_driver)); + +		if (!function_exists('utf_clean_string')) +		{ +			require_once(__DIR__ . '/../../phpBB/includes/utf/utf_tools.php'); +		} +		if (!function_exists('user_add')) +		{ +			require_once(__DIR__ . '/../../phpBB/includes/functions_user.php'); +		} +		set_config(null, null, null, $config); +		set_config_count(null, null, null, $config); +		$phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + +		$user_row = array( +			'username' => $username, +			'group_id' => 2, +			'user_email' => 'nobody@example.com', +			'user_type' => 0, +			'user_lang' => 'en', +			'user_timezone' => 0, +			'user_dateformat' => '', +			'user_password' => phpbb_hash($username), +		); +		return user_add($user_row); +	} + +	protected function login($username = 'admin') +	{ +		$this->add_lang('ucp'); + +		$crawler = $this->request('GET', 'ucp.php'); +		$this->assertContains($this->lang('LOGIN_EXPLAIN_UCP'), $crawler->filter('html')->text()); + +		$form = $crawler->selectButton($this->lang('LOGIN'))->form(); +		$crawler = $this->client->submit($form, array('username' => $username, 'password' => $username)); +		$this->assert_response_success(); +		$this->assertContains($this->lang('LOGIN_REDIRECT'), $crawler->filter('html')->text()); + +		$cookies = $this->cookieJar->all(); + +		// The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie +		foreach ($cookies as $cookie); +		{ +			if (substr($cookie->getName(), -4) == '_sid') +			{ +				$this->sid = $cookie->getValue(); +			} +		} +	} + +	/** +	* Login to the ACP +	* You must run login() before calling this. +	*/ +	protected function admin_login($username = 'admin') +	{ +		$this->add_lang('acp/common'); + +		// Requires login first! +		if (empty($this->sid)) +		{ +			$this->fail('$this->sid is empty. Make sure you call login() before admin_login()'); +			return; +		} + +		$crawler = $this->request('GET', 'adm/index.php?sid=' . $this->sid); +		$this->assertContains($this->lang('LOGIN_ADMIN_CONFIRM'), $crawler->filter('html')->text()); + +		$form = $crawler->selectButton($this->lang('LOGIN'))->form(); + +		foreach ($form->getValues() as $field => $value) +		{ +			if (strpos($field, 'password_') === 0) +			{ +				$crawler = $this->client->submit($form, array('username' => $username, $field => $username)); +				$this->assert_response_success(); +				$this->assertContains($this->lang('LOGIN_ADMIN_SUCCESS'), $crawler->filter('html')->text()); + +				$cookies = $this->cookieJar->all(); + +				// The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie +				foreach ($cookies as $cookie); +				{ +					if (substr($cookie->getName(), -4) == '_sid') +					{ +						$this->sid = $cookie->getValue(); +					} +				} + +				break; +			} +		} +	} + +	protected function add_lang($lang_file) +	{ +		if (is_array($lang_file)) +		{ +			foreach ($lang_file as $file) +			{ +				$this->add_lang($file); +			} +		} + +		$lang_path = __DIR__ . "/../../phpBB/language/en/$lang_file.php"; + +		$lang = array(); + +		if (file_exists($lang_path)) +		{ +			include($lang_path); +		} + +		$this->lang = array_merge($this->lang, $lang); +	} + +	protected function lang() +	{ +		$args = func_get_args(); +		$key = $args[0]; + +		if (empty($this->lang[$key])) +		{ +			throw new RuntimeException('Language key "' . $key . '" could not be found.'); +		} + +		$args[0] = $this->lang[$key]; + +		return call_user_func_array('sprintf', $args); +	} + +	/** +	 * assertContains for language strings +	 * +	 * @param string $needle Search string +	 * @param string $haystack Search this +	 * @param string $message Optional failure message +	 */ +	public function assertContainsLang($needle, $haystack, $message = null) +	{ +		$this->assertContains(html_entity_decode($this->lang($needle), ENT_QUOTES), $haystack, $message); +	} + +	/** +	* Heuristic function to check that the response is success. +	* +	* When php decides to die with a fatal error, it still sends 200 OK +	* status code. This assertion tries to catch that. +	* +	* @return null +	*/ +	public function assert_response_success() +	{ +		$this->assertEquals(200, $this->client->getResponse()->getStatus()); +		$content = $this->client->getResponse()->getContent(); +		$this->assertNotContains('Fatal error:', $content); +	} + +	public function assert_filter($crawler, $expr, $msg = null) +	{ +		$nodes = $crawler->filter($expr); +		if ($msg) +		{ +			$msg .= "\n"; +		} +		else +		{ +			$msg = ''; +		} +		$msg .= "`$expr` not found in DOM."; +		$this->assertGreaterThan(0, count($nodes), $msg); +		return $nodes; +	}  } diff --git a/tests/test_framework/phpbb_search_test_case.php b/tests/test_framework/phpbb_search_test_case.php new file mode 100644 index 0000000000..418d352c17 --- /dev/null +++ b/tests/test_framework/phpbb_search_test_case.php @@ -0,0 +1,29 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +abstract class phpbb_search_test_case extends phpbb_database_test_case +{ +	static protected function get_search_wrapper($class) +	{ +		$wrapped = $class . '_wrapper'; +		if (!class_exists($wrapped)) +		{ +			$code = " +class $wrapped extends $class +{ +	public function get_must_contain_ids() { return \$this->must_contain_ids; } +	public function get_must_not_contain_ids() { return \$this->must_not_contain_ids; } +	public function get_split_words() { return \$this->split_words; } +} +			"; +			eval($code); +		} +		return $wrapped; +	} +} diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index b46c36efaa..20ae384f21 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -42,6 +42,11 @@ class phpbb_test_case_helpers  		$this->test_case->setExpectedException($exceptionName, (string) $message, $errno);  	} +	public function makedirs($path) +	{ +		mkdir($path, 0777, true); +	} +  	static public function get_test_config()  	{  		$config = array(); @@ -49,7 +54,7 @@ class phpbb_test_case_helpers  		if (extension_loaded('sqlite') && version_compare(PHPUnit_Runner_Version::id(), '3.4.15', '>='))  		{  			$config = array_merge($config, array( -				'dbms'		=> 'sqlite', +				'dbms'		=> 'phpbb_db_driver_sqlite',  				'dbhost'	=> dirname(__FILE__) . '/../phpbb_unit_tests.sqlite2', // filename  				'dbport'	=> '',  				'dbname'	=> '', @@ -58,34 +63,65 @@ class phpbb_test_case_helpers  			));  		} -		if (file_exists(dirname(__FILE__) . '/../test_config.php')) +		if (isset($_SERVER['PHPBB_TEST_CONFIG'])) +		{ +			// Could be an absolute path +			$test_config = $_SERVER['PHPBB_TEST_CONFIG']; +		} +		else  		{ -			include(dirname(__FILE__) . '/../test_config.php'); +			$test_config = dirname(__FILE__) . '/../test_config.php'; +		} + +		if (file_exists($test_config)) +		{ +			include($test_config); + +			if (!function_exists('phpbb_convert_30_dbms_to_31')) +			{ +				require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +			}  			$config = array_merge($config, array( -				'dbms'		=> $dbms, +				'dbms'		=> phpbb_convert_30_dbms_to_31($dbms),  				'dbhost'	=> $dbhost,  				'dbport'	=> $dbport,  				'dbname'	=> $dbname,  				'dbuser'	=> $dbuser,  				'dbpasswd'	=> $dbpasswd, +				'custom_dsn'	=> isset($custom_dsn) ? $custom_dsn : '',  			));  			if (isset($phpbb_functional_url))  			{  				$config['phpbb_functional_url'] = $phpbb_functional_url;  			} + +			if (isset($phpbb_redis_host)) +			{ +				$config['redis_host'] = $phpbb_redis_host; +			} +			if (isset($phpbb_redis_port)) +			{ +				$config['redis_port'] = $phpbb_redis_port; +			}  		}  		if (isset($_SERVER['PHPBB_TEST_DBMS']))  		{ +			if (!function_exists('phpbb_convert_30_dbms_to_31')) +			{ +				require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +			} +  			$config = array_merge($config, array( -				'dbms'		=> isset($_SERVER['PHPBB_TEST_DBMS']) ? $_SERVER['PHPBB_TEST_DBMS'] : '', +				'dbms'		=> isset($_SERVER['PHPBB_TEST_DBMS']) ? phpbb_convert_30_dbms_to_31($_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'] : '' +				'dbpasswd'	=> isset($_SERVER['PHPBB_TEST_DBPASSWD']) ? $_SERVER['PHPBB_TEST_DBPASSWD'] : '', +				'custom_dsn'	=> isset($_SERVER['PHPBB_TEST_CUSTOM_DSN']) ? $_SERVER['PHPBB_TEST_CUSTOM_DSN'] : '',  			));  		} @@ -96,6 +132,124 @@ class phpbb_test_case_helpers  			));  		} +		if (isset($_SERVER['PHPBB_TEST_REDIS_HOST'])) +		{ +			$config['redis_host'] = $_SERVER['PHPBB_TEST_REDIS_HOST']; +		} + +		if (isset($_SERVER['PHPBB_TEST_REDIS_PORT'])) +		{ +			$config['redis_port'] = $_SERVER['PHPBB_TEST_REDIS_PORT']; +		} +  		return $config;  	} + +	/** +	* Recursive directory copying function +	* +	* @param string $source +	* @param string $dest +	* @return array list of files copied +	*/ +	public function copy_dir($source, $dest) +	{ +		$source = (substr($source, -1) == '/') ? $source : $source . '/'; +		$dest = (substr($dest, -1) == '/') ? $dest : $dest . '/'; + +		$copied_files = array(); + +		if (!is_dir($dest)) +		{ +			$this->makedirs($dest); +		} + +		$files = scandir($source); +		foreach ($files as $file) +		{ +			if ($file == '.' || $file == '..') +			{ +				continue; +			} + +			if (is_dir($source . $file)) +			{ +				$created_dir = false; +				if (!is_dir($dest . $file)) +				{ +					$created_dir = true; +					$this->makedirs($dest . $file); +				} + +				$copied_files = array_merge($copied_files, self::copy_dir($source . $file, $dest . $file)); + +				if ($created_dir) +				{ +					$copied_files[] = $dest . $file; +				} +			} +			else +			{ +				if (!file_exists($dest . $file)) +				{ +					copy($source . $file, $dest . $file); + +					$copied_files[] = $dest . $file; +				} +			} +		} + +		return $copied_files; +	} + +	/** +	* Remove files/directories that are listed in an array +	* Designed for use with $this->copy_dir() +	* +	* @param array $file_list +	*/ +	public function remove_files($file_list) +	{ +		foreach ($file_list as $file) +		{ +			if (is_dir($file)) +			{ +				rmdir($file); +			} +			else +			{ +				unlink($file); +			} +		} +	} + +	/** +	* Empty directory (remove any subdirectories/files below) +	* +	* @param array $file_list +	*/ +	public function empty_dir($path) +	{ +		$path = (substr($path, -1) == '/') ? $path : $path . '/'; + +		$files = scandir($path); +		foreach ($files as $file) +		{ +			if ($file == '.' || $file == '..') +			{ +				continue; +			} + +			if (is_dir($path . $file)) +			{ +				$this->empty_dir($path . $file); + +				rmdir($path . $file); +			} +			else +			{ +				unlink($path . $file); +			} +		} +	}  } diff --git a/tests/text_processing/censor_text_test.php b/tests/text_processing/censor_text_test.php index 8fcdb7ef85..043d8eb27d 100644 --- a/tests/text_processing/censor_text_test.php +++ b/tests/text_processing/censor_text_test.php @@ -9,8 +9,6 @@  require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';  require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; -require_once dirname(__FILE__) . '/../mock_user.php'; -require_once dirname(__FILE__) . '/../mock/cache.php';  class phpbb_text_processing_censor_text_test extends phpbb_test_case  { @@ -19,7 +17,7 @@ class phpbb_text_processing_censor_text_test extends phpbb_test_case  		global $cache, $user;  		$cache = new phpbb_mock_cache;  		$user = new phpbb_mock_user; -		 +  		$user->optionset('viewcensors', false);  		return array( @@ -61,7 +59,7 @@ class phpbb_text_processing_censor_text_test extends phpbb_test_case  			array('badword1 badword2 badword3 badword4', 'replacement1 replacement2 replacement3 replacement4'),  			array('badword1 badword2 badword3 badword4d', 'replacement1 replacement2 replacement3 badword4d'),  			array('abadword1 badword2 badword3 badword4', 'replacement1 replacement2 replacement3 replacement4'), -			 +  			array("new\nline\ntest", "new\nline\ntest"),  			array("tab\ttest\t", "tab\ttest\t"),  			array('öäü', 'öäü'), diff --git a/tests/text_processing/make_clickable_test.php b/tests/text_processing/make_clickable_test.php index 8697907311..d94fac2ae4 100644 --- a/tests/text_processing/make_clickable_test.php +++ b/tests/text_processing/make_clickable_test.php @@ -12,7 +12,7 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php';  class phpbb_text_processing_make_clickable_test extends phpbb_test_case  { -	public static function make_clickable_data() +	public function make_clickable_data()  	{  		// value => whether it should work  		$prefix_texts = array( diff --git a/tests/upload/filespec_test.php b/tests/upload/filespec_test.php new file mode 100644 index 0000000000..87cd00197f --- /dev/null +++ b/tests/upload/filespec_test.php @@ -0,0 +1,274 @@ +<?php +/** + * + * @package testing + * @copyright (c) 2012 phpBB Group + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 + * + */ + +require_once __DIR__ . '/../../phpBB/includes/functions.php'; +require_once __DIR__ . '/../../phpBB/includes/utf/utf_tools.php'; +require_once __DIR__ . '/../../phpBB/includes/functions_upload.php'; + +class phpbb_filespec_test extends phpbb_test_case +{ +	const TEST_COUNT = 100; +	const PREFIX = 'phpbb_'; +	const MAX_STR_LEN = 50; +	const UPLOAD_MAX_FILESIZE = 1000; + +	private $config; +	public $path; + +	protected function setUp() +	{ +		// Global $config required by unique_id +		// Global $user required by filespec::additional_checks and +		// filespec::move_file +		global $config, $user; + +		if (!is_array($config)) +		{ +			$config = array(); +		} + +		$config['rand_seed'] = ''; +		$config['rand_seed_last_update'] = time() + 600; +		// This config value is normally pulled from the database which is set +		// to this value at install time. +		// See: phpBB/install/schemas/schema_data.sql +		$config['mime_triggers'] = 'body|head|html|img|plaintext|a href|pre|script|table|title'; + +		$user = new phpbb_mock_user(); +		$user->lang = new phpbb_mock_lang(); + +		$this->config = &$config; +		$this->path = __DIR__ . '/fixture/'; + +		// Create copies of the files for use in testing move_file +		$iterator = new DirectoryIterator($this->path); +		foreach ($iterator as $fileinfo) +		{ +			if ($fileinfo->isDot() || $fileinfo->isDir()) +			{ +				continue; +			} + +			copy($fileinfo->getPathname(), $this->path . 'copies/' . $fileinfo->getFilename() . '_copy'); +			if ($fileinfo->getFilename() === 'txt') +			{ +				copy($fileinfo->getPathname(), $this->path . 'copies/' . $fileinfo->getFilename() . '_copy_2'); +			} +		} +	} + +	private function get_filespec($override = array()) +	{ +		// Initialise a blank filespec object for use with trivial methods +		$upload_ary = array( +			'name' => '', +			'type' => '', +			'size' => '', +			'tmp_name' => '', +			'error' => '', +		); + +		return new filespec(array_merge($upload_ary, $override), null); +	} + +	protected function tearDown() +	{ +		global $user; +		$this->config = array(); +		$user = null; + +		$iterator = new DirectoryIterator($this->path . 'copies'); +		foreach ($iterator as $fileinfo) +		{ +			$name = $fileinfo->getFilename(); +			if ($name[0] !== '.') +			{ +				unlink($fileinfo->getPathname()); +			} +		} +	} + +	public function additional_checks_variables() +	{ +		// False here just indicates the file is too large and fails the +		// filespec::additional_checks method because of it. All other code +		// paths in that method are covered elsewhere. +		return array( +			array('gif', true), +			array('jpg', false), +			array('png', true), +			array('tif', false), +			array('txt', false), +		); +	} + +	/** +	 * @dataProvider additional_checks_variables +	 */ +	public function test_additional_checks($filename, $expected) +	{ +		$upload = new phpbb_mock_fileupload(); +		$filespec = $this->get_filespec(); +		$filespec->upload = $upload; +		$filespec->file_moved = true; +		$filespec->filesize = $filespec->get_filesize($this->path . $filename); + +		$this->assertEquals($expected, $filespec->additional_checks()); +	} + +	public function check_content_variables() +	{ +		// False here indicates that a file is non-binary and contains +		// disallowed content that makes IE report the mimetype incorrectly. +		return array( +			array('gif', true), +			array('jpg', true), +			array('png', true), +			array('tif', true), +			array('txt', false), +		); +	} + +	/** +	 * @dataProvider check_content_variables +	 */ +	public function test_check_content($filename, $expected) +	{ +		$disallowed_content = explode('|', $this->config['mime_triggers']); +		$filespec = $this->get_filespec(array('tmp_name' => $this->path . $filename)); +		$this->assertEquals($expected, $filespec->check_content($disallowed_content)); +	} + +	public function clean_filename_variables() +	{ +		$chunks = str_split('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\'\\" /:*?<>|[];(){},#+=-_`', 8); +		return array( +			array($chunks[0] . $chunks[7]), +			array($chunks[1] . $chunks[8]), +			array($chunks[2] . $chunks[9]), +			array($chunks[3] . $chunks[4]), +			array($chunks[5] . $chunks[6]), +		); +	} + +	/** +	 * @dataProvider clean_filename_variables +	 */ +	public function test_clean_filename_real($filename) +	{ +		$bad_chars = array("'", "\\", ' ', '/', ':', '*', '?', '"', '<', '>', '|'); +		$filespec = $this->get_filespec(array('name' => $filename)); +		$filespec->clean_filename('real', self::PREFIX); +		$name = $filespec->realname; + +		$this->assertEquals(0, preg_match('/%(\w{2})/', $name)); +		foreach ($bad_chars as $char) +		{ +			$this->assertFalse(strpos($name, $char)); +		} +	} + +	public function test_clean_filename_unique() +	{ +		$filenames = array(); +		for ($tests = 0; $tests < self::TEST_COUNT; $tests++) +		{ +			$filespec = $this->get_filespec(); +			$filespec->clean_filename('unique', self::PREFIX); +			$name = $filespec->realname; +			 +			$this->assertEquals(strlen($name), 32 + strlen(self::PREFIX)); +			$this->assertRegExp('#^[A-Za-z0-9]+$#', substr($name, strlen(self::PREFIX))); +			$this->assertFalse(isset($filenames[$name])); +			$filenames[$name] = true; +		} +	} + +	public function get_extension_variables() +	{ +		return array( +			array('file.png', 'png'), +			array('file.phpbb.gif', 'gif'), +			array('file..', ''), +			array('.file..jpg.webp', 'webp'), +		); +	} + +	/** +	 * @dataProvider get_extension_variables +	 */ +	public function test_get_extension($filename, $expected) +	{ +		$this->assertEquals($expected, filespec::get_extension($filename)); +	} + +	public function is_image_variables() +	{ +		return array( +			array('gif', 'image/gif', true), +			array('jpg', 'image/jpg', true), +			array('png', 'image/png', true), +			array('tif', 'image/tif', true), +			array('txt', 'text/plain', false), +		); +	} + +	/** +	 * @dataProvider is_image_variables +	 */ +	public function test_is_image($filename, $mimetype, $expected) +	{ +		$filespec = $this->get_filespec(array('tmp_name' => $this->path . $filename, 'type' => $mimetype)); +		$this->assertEquals($expected, $filespec->is_image()); +	} + +	public function move_file_variables() +	{ +		return array( +			array('gif_copy', 'gif_moved', 'image/gif', 'gif', false, true), +			array('non_existant', 'still_non_existant', 'text/plain', 'txt', 'GENERAL_UPLOAD_ERROR', false), +			array('txt_copy', 'txt_as_img', 'image/jpg', 'txt', false, true), +			array('txt_copy_2', 'txt_moved', 'text/plain', 'txt', false, true), +			array('jpg_copy', 'jpg_moved', 'image/png', 'jpg', false, true), +			array('png_copy', 'png_moved', 'image/png', 'jpg', 'IMAGE_FILETYPE_MISMATCH', true), +		); +	} + +	/** +	 * @dataProvider move_file_variables +	 */ +	public function test_move_file($tmp_name, $realname, $mime_type, $extension, $error, $expected) +	{ +		// Global $phpbb_root_path and $phpEx are required by phpbb_chmod +		global $phpbb_root_path, $phpEx; +		$phpbb_root_path = ''; +		$phpEx = 'php'; + +		$upload = new phpbb_mock_fileupload(); +		$upload->max_filesize = self::UPLOAD_MAX_FILESIZE; + +		$filespec = $this->get_filespec(array( +			'tmp_name' => $this->path . 'copies/' . $tmp_name, +			'name' => $realname, +			'type' => $mime_type, +		)); +		$filespec->extension = $extension; +		$filespec->upload = $upload; +		$filespec->local = true; + +		$this->assertEquals($expected, $filespec->move_file($this->path . 'copies')); +		$this->assertEquals($filespec->file_moved, file_exists($this->path . 'copies/' . $realname)); +		if ($error) +		{ +			$this->assertEquals($error, $filespec->error[0]); +		} + +		$phpEx = ''; +	} +} diff --git a/tests/upload/fileupload_test.php b/tests/upload/fileupload_test.php new file mode 100644 index 0000000000..1665c493be --- /dev/null +++ b/tests/upload/fileupload_test.php @@ -0,0 +1,119 @@ +<?php +/** + * + * @package testing + * @copyright (c) 2012 phpBB Group + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 + * + */ + +require_once __DIR__ . '/../../phpBB/includes/functions.php'; +require_once __DIR__ . '/../../phpBB/includes/utf/utf_tools.php'; +require_once __DIR__ . '/../../phpBB/includes/functions_upload.php'; + +class phpbb_fileupload_test extends phpbb_test_case +{ +	private $path; + +	protected function setUp() +	{ +		// Global $config required by unique_id +		// Global $user required by several functions dealing with translations +		// Global $request required by form_upload, local_upload and is_valid +		global $config, $user, $request; + +		if (!is_array($config)) +		{ +			$config = array(); +		} + +		$config['rand_seed'] = ''; +		$config['rand_seed_last_update'] = time() + 600; + +		$user = new phpbb_mock_user(); +		$user->lang = new phpbb_mock_lang(); + +		$request = new phpbb_mock_request(); + +		$this->path = __DIR__ . '/fixture/'; +	} + +	private function gen_valid_filespec() +	{ +		$filespec = new phpbb_mock_filespec(); +		$filespec->filesize = 1; +		$filespec->extension = 'jpg'; +		$filespec->realname = 'valid'; +		$filespec->width = 2; +		$filespec->height = 2; + +		return $filespec; +	} + +	protected function tearDown() +	{ +		// Clear globals +		global $config, $user; +		$config = array(); +		$user = null; +	} + +	public function test_common_checks_invalid_extension() +	{ +		$upload = new fileupload('', array('png'), 100); +		$file = $this->gen_valid_filespec(); +		$upload->common_checks($file); +		$this->assertEquals('DISALLOWED_EXTENSION', $file->error[0]); +	} + +	public function test_common_checks_invalid_filename() +	{ +		$upload = new fileupload('', array('jpg'), 100); +		$file = $this->gen_valid_filespec(); +		$file->realname = 'invalid?'; +		$upload->common_checks($file); +		$this->assertEquals('INVALID_FILENAME', $file->error[0]); +	} + +	public function test_common_checks_too_large() +	{ +		$upload = new fileupload('', array('jpg'), 100); +		$file = $this->gen_valid_filespec(); +		$file->filesize = 1000; +		$upload->common_checks($file); +		$this->assertEquals('WRONG_FILESIZE', $file->error[0]); +	} + +	public function test_common_checks_valid_file() +	{ +		$upload = new fileupload('', array('jpg'), 1000); +		$file = $this->gen_valid_filespec(); +		$upload->common_checks($file); +		$this->assertEquals(0, sizeof($file->error)); +	} + +	public function test_local_upload() +	{ +		$upload = new fileupload('', array('jpg'), 1000); + +		copy($this->path . 'jpg', $this->path . 'jpg.jpg'); +		$file = $upload->local_upload($this->path . 'jpg.jpg'); +		$this->assertEquals(0, sizeof($file->error)); +		unlink($this->path . 'jpg.jpg'); +	} + +	public function test_valid_dimensions() +	{ +		$upload = new fileupload('', false, false, 1, 1, 100, 100); + +		$file1 = $this->gen_valid_filespec(); +		$file2 = $this->gen_valid_filespec(); +		$file2->height = 101; +		$file3 = $this->gen_valid_filespec(); +		$file3->width = 0; + +		$this->assertTrue($upload->valid_dimensions($file1)); +		$this->assertFalse($upload->valid_dimensions($file2)); +		$this->assertFalse($upload->valid_dimensions($file3)); +	} +} diff --git a/tests/upload/fixture/copies/.gitkeep b/tests/upload/fixture/copies/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/upload/fixture/copies/.gitkeep diff --git a/tests/upload/fixture/gif b/tests/upload/fixture/gif Binary files differnew file mode 100644 index 0000000000..b636f4b8df --- /dev/null +++ b/tests/upload/fixture/gif diff --git a/tests/upload/fixture/jpg b/tests/upload/fixture/jpg Binary files differnew file mode 100644 index 0000000000..3cd5038e38 --- /dev/null +++ b/tests/upload/fixture/jpg diff --git a/tests/upload/fixture/png b/tests/upload/fixture/png Binary files differnew file mode 100644 index 0000000000..5514ad40e9 --- /dev/null +++ b/tests/upload/fixture/png diff --git a/tests/upload/fixture/tif b/tests/upload/fixture/tif Binary files differnew file mode 100644 index 0000000000..248b50f9cb --- /dev/null +++ b/tests/upload/fixture/tif diff --git a/tests/upload/fixture/txt b/tests/upload/fixture/txt new file mode 100644 index 0000000000..a78c858f5c --- /dev/null +++ b/tests/upload/fixture/txt @@ -0,0 +1,2 @@ +<HTML>mime trigger</HTML> +The HTML tags should remain uppercase so that case-insensitivity can be checked. diff --git a/tests/user/lang_test.php b/tests/user/lang_test.php index d33f430955..d7ff451a70 100644 --- a/tests/user/lang_test.php +++ b/tests/user/lang_test.php @@ -7,13 +7,11 @@  *  */ -require_once dirname(__FILE__) . '/../../phpBB/includes/session.php'; -  class phpbb_user_lang_test extends phpbb_test_case  {  	public function test_user_lang_sprintf()  	{ -		$user = new user; +		$user = new phpbb_user;  		$user->lang = array(  			'FOO'		=> 'BAR',  			'BARZ'		=> 'PENG', @@ -26,6 +24,26 @@ class phpbb_user_lang_test extends phpbb_test_case  				1		=> '1 post',		// 1  				2		=> '%d posts',		// 2+  			), +			'ARRY_NO_ZERO'	=> array( +				1		=> '1 post',		// 1 +				2		=> '%d posts',		// 0, 2+ +			), +			'ARRY_MISSING'	=> array( +				1		=> '%d post',		// 1 +				//Missing second plural +			), +			'ARRY_FLOAT'	=> array( +				1		=> '1 post',		// 1.x +				2		=> '%1$.1f posts',	// 0.x, 2+.x +			), +			'ARRY_EMPTY'	=> array( +			), +			'dateformat'	=> array( +				'AGO'	=> array( +					1	=> '%d second', +					2	=> '%d seconds', +				), +			),  		);  		// No param @@ -51,8 +69,45 @@ class phpbb_user_lang_test extends phpbb_test_case  		$this->assertEquals($user->lang('ARRY', 2), '2 posts');  		$this->assertEquals($user->lang('ARRY', 123), '123 posts'); -		// Bug PHPBB3-9949 +		// Empty array returns the language key +		$this->assertEquals($user->lang('ARRY_EMPTY', 123), 'ARRY_EMPTY'); + +		// No 0 key defined +		$this->assertEquals($user->lang('ARRY_NO_ZERO', 0), '0 posts'); +		$this->assertEquals($user->lang('ARRY_NO_ZERO', 1), '1 post'); +		$this->assertEquals($user->lang('ARRY_NO_ZERO', 2), '2 posts'); + +		// Array with missing keys +		$this->assertEquals($user->lang('ARRY_MISSING', 2), '2 post'); + +		// Floats as array key +		$this->assertEquals($user->lang('ARRY_FLOAT', 1.3), '1 post'); +		$this->assertEquals($user->lang('ARRY_FLOAT', 2.0), '2.0 posts'); +		$this->assertEquals($user->lang('ARRY_FLOAT', 2.51), '2.5 posts'); + +		// Use sub key, if first paramenter is an array +		$this->assertEquals($user->lang(array('dateformat', 'AGO'), 2), '2 seconds'); + +		// ticket PHPBB3-9949 - use first int to determinate the plural-form to use  		$this->assertEquals($user->lang('ARRY', 1, 2), '1 post');  		$this->assertEquals($user->lang('ARRY', 1, 's', 2), '1 post'); + +		// ticket PHPBB3-10345 - different plural rules, not just 0/1/2+ +		$user = new phpbb_user; +		$user->lang = array( +			'PLURAL_RULE'		=> 13, +			'ARRY'		=> array( +				0		=> '%d is 0',						// 0 +				1		=> '%d is 1',						// 1 +				2		=> '%d ends with 01-10',			// ending with 01-10 +				3		=> '%d ends with 11-19',			// ending with 11-19 +				4		=> '%d is part of the last rule',	// everything else +			), +		); +		$this->assertEquals($user->lang('ARRY', 0), '0 is 0'); +		$this->assertEquals($user->lang('ARRY', 1), '1 is 1'); +		$this->assertEquals($user->lang('ARRY', 103), '103 ends with 01-10'); +		$this->assertEquals($user->lang('ARRY', 15), '15 ends with 11-19'); +		$this->assertEquals($user->lang('ARRY', 300), '300 is part of the last rule');  	}  } diff --git a/tests/utf/utf8_clean_string_test.php b/tests/utf/utf8_clean_string_test.php index 70bd549d5b..ae11e00fbd 100644 --- a/tests/utf/utf8_clean_string_test.php +++ b/tests/utf/utf8_clean_string_test.php @@ -11,7 +11,7 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php';  class phpbb_utf_utf8_clean_string_test extends phpbb_test_case  { -	public static function cleanable_strings() +	public function cleanable_strings()  	{  		return array(  			array('MiXed CaSe', 'mixed case', 'Checking case folding'), diff --git a/tests/wrapper/phpbb_php_ini_fake.php b/tests/wrapper/phpbb_php_ini_fake.php new file mode 100644 index 0000000000..49bc5936e5 --- /dev/null +++ b/tests/wrapper/phpbb_php_ini_fake.php @@ -0,0 +1,16 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_php_ini_fake extends phpbb_php_ini +{ +	function get($varname) +	{ +		return $varname; +	} +} diff --git a/tests/wrapper/phpbb_php_ini_test.php b/tests/wrapper/phpbb_php_ini_test.php new file mode 100644 index 0000000000..8e08d5c204 --- /dev/null +++ b/tests/wrapper/phpbb_php_ini_test.php @@ -0,0 +1,86 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/phpbb_php_ini_fake.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_wrapper_phpbb_php_ini_test extends phpbb_test_case +{ +	protected $php_ini; + +	public function setUp() +	{ +		$this->php_ini = new phpbb_php_ini_fake; +	} + +	public function test_get_string() +	{ +		$this->assertSame(false, $this->php_ini->get_string(false)); +		$this->assertSame('phpbb', $this->php_ini->get_string(' phpbb ')); +	} + +	public function test_get_bool() +	{ +		$this->assertSame(true, $this->php_ini->get_bool('ON')); +		$this->assertSame(true, $this->php_ini->get_bool('on')); +		$this->assertSame(true, $this->php_ini->get_bool('1')); + +		$this->assertSame(false, $this->php_ini->get_bool('OFF')); +		$this->assertSame(false, $this->php_ini->get_bool('off')); +		$this->assertSame(false, $this->php_ini->get_bool('0')); +		$this->assertSame(false, $this->php_ini->get_bool('')); +	} + +	public function test_get_int() +	{ +		$this->assertSame(1234, $this->php_ini->get_int('1234')); +		$this->assertSame(-12345, $this->php_ini->get_int('-12345')); +		$this->assertSame(false, $this->php_ini->get_int('phpBB')); +	} + +	public function test_get_float() +	{ +		$this->assertSame(1234.0, $this->php_ini->get_float('1234')); +		$this->assertSame(-12345.0, $this->php_ini->get_float('-12345')); +		$this->assertSame(false, $this->php_ini->get_float('phpBB')); +	} + +	public function test_get_bytes_invalid() +	{ +		$this->assertSame(false, $this->php_ini->get_bytes(false)); +		$this->assertSame(false, $this->php_ini->get_bytes('phpBB')); +		$this->assertSame(false, $this->php_ini->get_bytes('k')); +		$this->assertSame(false, $this->php_ini->get_bytes('-k')); +		$this->assertSame(false, $this->php_ini->get_bytes('M')); +		$this->assertSame(false, $this->php_ini->get_bytes('-M')); +	} + +	/** +	* @dataProvider get_bytes_data +	*/ +	public function test_get_bytes($expected, $value) +	{ +		$actual = $this->php_ini->get_bytes($value); + +		$this->assertTrue(is_float($actual) || is_int($actual)); +		$this->assertEquals($expected, $actual); +	} + +	static public function get_bytes_data() +	{ +		return array( +			array(32 * pow(2, 20),		'32m'), +			array(- 32 * pow(2, 20),	'-32m'), +			array(8 * pow(2, 30),		'8G'), +			array(- 8 * pow(2, 30),		'-8G'), +			array(1234,					'1234'), +			array(-12345,				'-12345'), +		); +	} +}  | 
