diff options
| author | Maat <maat-pub@mageia.biz> | 2020-05-09 01:15:08 +0200 | 
|---|---|---|
| committer | Maat <maat-pub@mageia.biz> | 2020-05-09 01:15:08 +0200 | 
| commit | 6985226b17e8a0ef0a720bf1d12fe0c216e13dab (patch) | |
| tree | 116d2565ac02c40abe0548863c6badf8ec3e1d1e /tests/functional | |
| parent | 8ea437e30605e0f66b5220bf904a61d7c1d11ddd (diff) | |
| parent | 8d00784dfe2c8bcb10843ff70b4cfa998d703285 (diff) | |
| download | forums-master.tar forums-master.tar.gz forums-master.tar.bz2 forums-master.tar.xz forums-master.zip | |
Diffstat (limited to 'tests/functional')
22 files changed, 640 insertions, 68 deletions
| diff --git a/tests/functional/acp_bbcodes_test.php b/tests/functional/acp_bbcodes_test.php index 58681dfa07..cc6397fdfd 100644 --- a/tests/functional/acp_bbcodes_test.php +++ b/tests/functional/acp_bbcodes_test.php @@ -43,4 +43,44 @@ class phpbb_functional_acp_bbcodes_test extends phpbb_functional_test_case  		$this->assertContains('<div>c</div>', $html);  		$this->assertContains('<div>d</div>', $html);  	} + +	/** +	* @dataProvider get_bbcode_error_tests +	*/ +	public function test_bbcode_error($match, $tpl, $error) +	{ +		$this->login(); +		$this->admin_login(); + +		$crawler = self::request('GET', 'adm/index.php?i=acp_bbcodes&sid=' . $this->sid . '&mode=bbcodes&action=add'); +		$form = $crawler->selectButton('Submit')->form([ +			'bbcode_match' => $match, +			'bbcode_tpl'   => $tpl +		]); +		$crawler = self::submit($form); + +		$text = $crawler->filter('.errorbox')->text(); +		$this->assertStringContainsString($error, $text); +	} + +	public function get_bbcode_error_tests() +	{ +		return [ +			[ +				'XXX', +				'', +				'BBCode is constructed in an invalid form' +			], +			[ +				'[x]{TEXT}[/x]', +				'<xsl:invalid', +				'template is invalid' +			], +			[ +				'[x]{TEXT}[/x]', +				'<script>{TEXT}</script>', +				'unsafe' +			], +		]; +	}  } diff --git a/tests/functional/acp_permissions_test.php b/tests/functional/acp_permissions_test.php index 0a40e76057..ccaa4aab29 100644 --- a/tests/functional/acp_permissions_test.php +++ b/tests/functional/acp_permissions_test.php @@ -16,7 +16,7 @@  */  class phpbb_functional_acp_permissions_test extends phpbb_functional_test_case  { -	public function setUp() +	public function setUp(): void  	{  		parent::setUp(); diff --git a/tests/functional/acp_profile_field_test.php b/tests/functional/acp_profile_field_test.php index 7a0a6ca941..4c0414f03a 100644 --- a/tests/functional/acp_profile_field_test.php +++ b/tests/functional/acp_profile_field_test.php @@ -16,7 +16,7 @@  */  class phpbb_functional_acp_profile_field_test extends phpbb_functional_test_case  { -	public function setUp() +	public function setUp(): void  	{  		parent::setUp(); diff --git a/tests/functional/acp_users_test.php b/tests/functional/acp_users_test.php index 78028aacb8..c8d0072c28 100644 --- a/tests/functional/acp_users_test.php +++ b/tests/functional/acp_users_test.php @@ -16,7 +16,7 @@  */  class phpbb_functional_acp_users_test extends phpbb_functional_test_case  { -	public function setUp() +	public function setUp(): void  	{  		parent::setUp(); diff --git a/tests/functional/common_avatar_test_case.php b/tests/functional/common_avatar_test_case.php index 924eb1273c..155f6e0c09 100644 --- a/tests/functional/common_avatar_test_case.php +++ b/tests/functional/common_avatar_test_case.php @@ -21,7 +21,7 @@ abstract class phpbb_functional_common_avatar_test_case extends phpbb_functional  	abstract function get_url(); -	public function setUp() +	public function setUp(): void  	{  		parent::setUp();  		$this->path = __DIR__ . '/fixtures/files/'; diff --git a/tests/functional/controllers_compatibility_test.php b/tests/functional/controllers_compatibility_test.php index 9499888a1a..36a34aa7c8 100644 --- a/tests/functional/controllers_compatibility_test.php +++ b/tests/functional/controllers_compatibility_test.php @@ -37,6 +37,13 @@ class phpbb_functional_controllers_compatibility_test extends phpbb_functional_t  		$this->assert301('feed.php?t=1', 'app.php/feed/topic/1');  	} +	public function test_cron_compatibility() +	{ +		$this->assert301('cron.php?cron_type=foo', 'app.php/cron/foo'); +		$this->assert301('cron.php?cron_type=foo&bar=foobar', 'app.php/cron/foo?bar=foobar'); +		$this->assert301('cron.php?cron_type=foo&bar=foobar&who=me', 'app.php/cron/foo?bar=foobar&who=me'); +	} +  	protected function assert301($from, $to)  	{  		self::$client->followRedirects(false); @@ -44,6 +51,7 @@ class phpbb_functional_controllers_compatibility_test extends phpbb_functional_t  		// Fix sid issues  		$location = self::$client->getResponse()->getHeader('Location'); +		$location = str_replace('&', '&', $location);  		$location = preg_replace('#sid=[^&]+(&(amp;)?)?#', '', $location);  		if (substr($location, -1) === '?')  		{ diff --git a/tests/functional/extension_acp_test.php b/tests/functional/extension_acp_test.php index ce0f4911e3..9a326dba68 100644 --- a/tests/functional/extension_acp_test.php +++ b/tests/functional/extension_acp_test.php @@ -37,7 +37,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case  		self::$helper->restore_original_ext_dir();  	} -	public function setUp() +	public function setUp(): void  	{  		parent::setUp(); @@ -86,7 +86,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case  		$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);  		$this->assertCount(1, $crawler->filter('.ext_enabled')); -		$this->assertCount(6, $crawler->filter('.ext_disabled')); +		$this->assertCount(7, $crawler->filter('.ext_disabled'));  		$this->assertContains('phpBB Foo Extension', $crawler->filter('.ext_enabled')->eq(0)->text());  		$this->assertContainsLang('EXTENSION_DISABLE', $crawler->filter('.ext_enabled')->eq(0)->text()); @@ -165,9 +165,14 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case  		$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid);  		$this->assertContains($this->lang('EXTENSION_ENABLE_CONFIRM', 'phpBB Moo Extension'), $crawler->filter('#main')->text()); -		// Correctly submit the enable form +		// Correctly submit the enable form, default not enableable message  		$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor3%2Ffoo&sid=' . $this->sid);  		$this->assertContainsLang('EXTENSION_NOT_ENABLEABLE', $crawler->filter('.errorbox')->text()); + +		// Custom reason messages returned by not enableable extension +		$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor5%2Ffoo&sid=' . $this->sid); +		$this->assertContains('Reason 1', $crawler->filter('.errorbox')->text()); +		$this->assertContains('Reason 2', $crawler->filter('.errorbox')->text());  	}  	public function test_disable_pre() @@ -195,7 +200,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case  		$this->assertContainsLang('EXTENSION_ACTIONS', $crawler->filter('div.main thead')->text());  		$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=delete_data_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); -		$this->assertContains('Are you sure that you wish to delete the data associated with “phpBB Moo Extension”?', $crawler->filter('.errorbox')->text()); +		$this->assertContains('Are you sure that you wish to delete the data associated with “phpBB Moo Extension”?', $crawler->filter('#main')->text());  	}  	public function test_actions() @@ -206,7 +211,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case  		// Correctly submit the enable form  		$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); -		$form = $crawler->selectButton('enable')->form(); +		$form = $crawler->selectButton('confirm')->form();  		$crawler = self::submit($form);  		$this->assertContainsLang('EXTENSION_ENABLE_SUCCESS', $crawler->filter('.successbox')->text()); @@ -216,7 +221,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case  		// Correctly submit the disable form  		$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); -		$form = $crawler->selectButton('disable')->form(); +		$form = $crawler->selectButton('confirm')->form();  		$crawler = self::submit($form);  		$this->assertContainsLang('EXTENSION_DISABLE_SUCCESS', $crawler->filter('.successbox')->text()); @@ -226,12 +231,17 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case  		// Correctly submit the delete data form  		$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=delete_data_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); -		$form = $crawler->selectButton('delete_data')->form(); +		$form = $crawler->selectButton('confirm')->form();  		$crawler = self::submit($form);  		$this->assertContainsLang('EXTENSION_DELETE_DATA_SUCCESS', $crawler->filter('.successbox')->text());  		// Attempt to enable invalid extension  		$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=barfoo&sid=' . $this->sid);  		$this->assertContainsLang('EXTENSION_DIR_INVALID', $crawler->filter('.errorbox')->text()); + +		// Test installing/uninstalling extension altogether +		$this->logout(); +		$this->install_ext('vendor/moo'); +		$this->uninstall_ext('vendor/moo');  	}  } diff --git a/tests/functional/extension_controller_test.php b/tests/functional/extension_controller_test.php index 58c3878b8b..c5ebf761c9 100644 --- a/tests/functional/extension_controller_test.php +++ b/tests/functional/extension_controller_test.php @@ -45,7 +45,7 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c  		self::$helper->restore_original_ext_dir();  	} -	public function setUp() +	public function setUp(): void  	{  		parent::setUp(); @@ -90,6 +90,15 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c  	}  	/** +	* Check includejs/includecss when the request_uri is a subdirectory +	*/ +	public function test_controller_template_include_js_css() +	{ +		$crawler = self::request('GET', 'app.php/help/faq'); +		$this->assertContains("./../../assets/javascript/core.js", $crawler->filter('body')->html()); +	} + +	/**  	* Check the error produced by calling a controller without a required  	* argument.  	*/ diff --git a/tests/functional/extension_global_lang_test.php b/tests/functional/extension_global_lang_test.php index a1e2547745..94c80a6d9a 100644 --- a/tests/functional/extension_global_lang_test.php +++ b/tests/functional/extension_global_lang_test.php @@ -41,10 +41,10 @@ class phpbb_functional_extension_global_lang_test extends phpbb_functional_test_  		self::$helper->restore_original_ext_dir();  	} -	public function setUp() +	public function setUp(): void  	{  		parent::setUp(); -		 +  		$this->get_db();  		$this->phpbb_extension_manager = $this->get_extension_manager(); @@ -52,7 +52,7 @@ class phpbb_functional_extension_global_lang_test extends phpbb_functional_test_  		$this->purge_cache();  	} -	public function tearDown() +	public function tearDown(): void  	{  		parent::tearDown(); diff --git a/tests/functional/extension_module_test.php b/tests/functional/extension_module_test.php index d3a66b9b35..09d0124990 100644 --- a/tests/functional/extension_module_test.php +++ b/tests/functional/extension_module_test.php @@ -40,7 +40,7 @@ class phpbb_functional_extension_module_test extends phpbb_functional_test_case  		self::$helper->restore_original_ext_dir();  	} -	public function setUp() +	public function setUp(): void  	{  		global $db; diff --git a/tests/functional/extension_permission_lang_test.php b/tests/functional/extension_permission_lang_test.php index f570d45215..e0721ad1ec 100644 --- a/tests/functional/extension_permission_lang_test.php +++ b/tests/functional/extension_permission_lang_test.php @@ -41,12 +41,12 @@ class phpbb_functional_extension_permission_lang_test extends phpbb_functional_t  		self::$helper->restore_original_ext_dir();  	} -	public function setUp() +	public function setUp(): void  	{  		parent::setUp(); -		 +  		$this->get_db(); -		 +  		$acl_ary = array(  			'auth_option'	=> 'u_foo',  			'is_global'		=> 1, diff --git a/tests/functional/feed_test.php b/tests/functional/feed_test.php index 725a44ae5e..24ddca9c64 100644 --- a/tests/functional/feed_test.php +++ b/tests/functional/feed_test.php @@ -20,7 +20,7 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case  	static public $init_values = array(); -	public function setUp() +	public function setUp(): void  	{  		parent::setUp();  		$this->purge_cache(); diff --git a/tests/functional/fileupload_form_test.php b/tests/functional/fileupload_form_test.php index ff9450be0d..b2f230b66f 100644 --- a/tests/functional/fileupload_form_test.php +++ b/tests/functional/fileupload_form_test.php @@ -18,14 +18,14 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case  {  	private $path; -	public function setUp() +	public function setUp(): void  	{  		parent::setUp();  		$this->path = __DIR__ . '/fixtures/files/';  		$this->add_lang('posting');  	} -	public function tearDown() +	public function tearDown(): void  	{  		$iterator = new DirectoryIterator(__DIR__ . '/../../phpBB/files/');  		foreach ($iterator as $fileinfo) diff --git a/tests/functional/fileupload_remote_test.php b/tests/functional/fileupload_remote_test.php index 426ebcee53..25fc9f0508 100644 --- a/tests/functional/fileupload_remote_test.php +++ b/tests/functional/fileupload_remote_test.php @@ -34,7 +34,7 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case  	/** @var string phpBB root path */  	protected $phpbb_root_path; -	public function setUp() +	public function setUp(): void  	{  		parent::setUp();  		// Only doing this within the functional framework because we need a @@ -54,7 +54,7 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case  		$this->filesystem = new \phpbb\filesystem\filesystem();  		$this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); -		$this->request = $this->getMock('\phpbb\request\request'); +		$this->request = $this->createMock('\phpbb\request\request');  		$this->php_ini = new \bantu\IniGetWrapper\IniGetWrapper;  		$container = new phpbb_mock_container_builder(); @@ -65,7 +65,7 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case  		$this->phpbb_root_path = $phpbb_root_path;  	} -	public function tearDown() +	public function tearDown(): void  	{  		global $config, $user;  		$user = null; diff --git a/tests/functional/forgot_password_test.php b/tests/functional/forgot_password_test.php index 64fa19557f..10946fe5a9 100644 --- a/tests/functional/forgot_password_test.php +++ b/tests/functional/forgot_password_test.php @@ -20,8 +20,8 @@ class phpbb_functional_forgot_password_test extends phpbb_functional_test_case  	{  		global $config;  		$this->add_lang('ucp'); -		$crawler = self::request('GET', 'ucp.php?mode=sendpassword'); -		$this->assertEquals($this->lang('SEND_PASSWORD'), $crawler->filter('h2')->text()); +		$crawler = self::request('GET', 'app.php/user/forgot_password'); +		$this->assertEquals($this->lang('RESET_PASSWORD'), $crawler->filter('h2')->text());  	}  	public function test_forgot_password_disabled() @@ -40,12 +40,12 @@ class phpbb_functional_forgot_password_test extends phpbb_functional_test_case  		$this->logout(); -		$crawler = self::request('GET', 'ucp.php?mode=sendpassword'); +		$crawler = self::request('GET', 'app.php/user/forgot_password');  		$this->assertContains($this->lang('UCP_PASSWORD_RESET_DISABLED', '', ''), $crawler->text());  	} -	public function tearDown() +	public function tearDown(): void  	{  		$this->login();  		$this->admin_login(); diff --git a/tests/functional/metadata_manager_test.php b/tests/functional/metadata_manager_test.php index 8456c40f00..4f4fad4434 100644 --- a/tests/functional/metadata_manager_test.php +++ b/tests/functional/metadata_manager_test.php @@ -24,7 +24,7 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case  		'foo/bar/',  	); -	public function tearDown() +	public function tearDown(): void  	{  		$this->purge_cache(); @@ -46,7 +46,7 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case  		self::$helper->restore_original_ext_dir();  	} -	public function setUp() +	public function setUp(): void  	{  		parent::setUp(); diff --git a/tests/functional/plupload_test.php b/tests/functional/plupload_test.php index 4ab1c8e9e5..b7b5b08360 100644 --- a/tests/functional/plupload_test.php +++ b/tests/functional/plupload_test.php @@ -30,7 +30,7 @@ class phpbb_functional_plupload_test extends phpbb_functional_test_case  		$db->sql_query($query);  	} -	public function setUp() +	public function setUp(): void  	{  		parent::setUp();  		$this->purge_cache(); @@ -40,7 +40,7 @@ class phpbb_functional_plupload_test extends phpbb_functional_test_case  		$this->login();  	} -	public function tearDown() +	public function tearDown(): void  	{  		$this->set_extension_group_permission(0);  		$iterator = new DirectoryIterator(__DIR__ . '/../../phpBB/files/'); diff --git a/tests/functional/prune_shadow_topic_test.php b/tests/functional/prune_shadow_topic_test.php index 2bf0280d62..1d4bb02a95 100644 --- a/tests/functional/prune_shadow_topic_test.php +++ b/tests/functional/prune_shadow_topic_test.php @@ -130,7 +130,16 @@ class phpbb_functional_prune_shadow_topic_test extends phpbb_functional_test_cas  		$crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Prune Shadow']}&sid={$this->sid}");  		$this->assertNotEmpty($crawler->filter('img')->last()->attr('src')); -		self::request('GET', "cron.php?cron_type=cron.task.core.prune_shadow_topics&f={$this->data['forums']['Prune Shadow']}&sid={$this->sid}", array(), false); +		self::request('GET', "app.php/cron/cron.task.core.prune_shadow_topics?f={$this->data['forums']['Prune Shadow']}&sid={$this->sid}", array(), false); + +		// Try to ensure that the cron can actually run before we start to wait for it +		sleep(1); +		$cron_lock = new \phpbb\lock\db('cron_lock', new \phpbb\config\db($this->db, new \phpbb\cache\driver\dummy(), 'phpbb_config'), $this->db); +		while (!$cron_lock->acquire()) +		{ +			// do nothing +		} + 		$cron_lock->release();  		$this->assert_forum_details($this->data['forums']['Prune Shadow'], array(  			'forum_posts_approved'		=> 0, diff --git a/tests/functional/subforum_test.php b/tests/functional/subforum_test.php new file mode 100644 index 0000000000..6ce4f53c20 --- /dev/null +++ b/tests/functional/subforum_test.php @@ -0,0 +1,113 @@ +<?php +/** + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited <https://www.phpbb.com> + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +/** + * @group functional + */ +class phpbb_functional_subforum_test extends phpbb_functional_test_case +{ +	public function test_setup_forums() +	{ +		$this->login(); +		$this->admin_login(); + +		$forum_name = 'Subforum Test #1'; +		$crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}"); +		$form = $crawler->selectButton('addforum')->form([ +			'forum_name'	=> $forum_name, +		]); +		$crawler = self::submit($form); +		$form = $crawler->selectButton('update')->form([ +			'forum_perm_from'	=> 2, +		]); +		self::submit($form); +		$forum_id = self::get_forum_id($forum_name); + +		// 'Feeds #1.1' is a sub-forum of 'Feeds #1' +		$forum_name = 'Subforum Test #1.1'; +		$crawler = self::request('GET', "adm/index.php?i=acp_forums&sid={$this->sid}&icat=6&mode=manage&parent_id={$forum_id}"); +		$form = $crawler->selectButton('addforum')->form([ +			'forum_name'	=> $forum_name, +		]); +		$crawler = self::submit($form); +		$form = $crawler->selectButton('update')->form([ +			'forum_perm_from'	=> 2, +		]); +		self::submit($form); +		$forum_id = self::get_forum_id('Subforum Test #1.1'); + +		// 'Feeds #news' will be used for feed.php?mode=news +		$crawler = self::request('GET', "adm/index.php?i=acp_forums&sid={$this->sid}&icat=6&mode=manage&parent_id={$forum_id}"); +		$form = $crawler->selectButton('addforum')->form([ +			'forum_name'	=> 'Subforum Test #1.1.1', +		]); +		$crawler = self::submit($form); +		$form = $crawler->selectButton('update')->form([ +			'forum_perm_from'	=> 2, +		]); +		self::submit($form); +	} + +	/** +	 * @depends test_setup_forums +	 */ +	public function test_display_subforums() +	{ +		$crawler = self::request('GET', "index.php?sid={$this->sid}"); +		$this->assertContains('Subforum Test #1.1', $crawler->html()); +		$this->assertContains('Subforum Test #1.1.1', $crawler->html()); +	} + +	/** +	 * @depends test_display_subforums +	 */ +	public function test_display_subforums_limit() +	{ +		$this->login(); +		$this->admin_login(); + +		// Disable listing subforums +		$forum_id = $this->get_forum_id('Subforum Test #1'); +		$crawler = self::request('GET', "adm/index.php?i=acp_forums&sid={$this->sid}&icat=7&mode=manage&parent_id=0&f={$forum_id}&action=edit"); +		$form = $crawler->selectButton('submit')->form([ +			'display_subforum_limit' => 1, +		]); +		self::submit($form); + +		$crawler = self::request('GET', "index.php?sid={$this->sid}"); +		$this->assertContains('Subforum Test #1.1', $crawler->html()); +		$this->assertNotContains('Subforum Test #1.1.1', $crawler->html()); +	} + +	protected function get_forum_id($forum_name) +	{ +		$this->db = $this->get_db(); +		$forum_id = 0; + +		$sql = 'SELECT * +				FROM ' . FORUMS_TABLE . ' +				WHERE ' . $this->db->sql_in_set('forum_name', $forum_name); +		$result = $this->db->sql_query($sql); +		while ($row = $this->db->sql_fetchrow($result)) +		{ +			if ($row['forum_name'] == $forum_name) +			{ +				$forum_id = (int) $row['forum_id']; +				break; +			} +		} +		$this->db->sql_freeresult($result); + +		return $forum_id; +	} +} diff --git a/tests/functional/ucp_pm_test.php b/tests/functional/ucp_pm_test.php index ddd5c8d791..53de247202 100644 --- a/tests/functional/ucp_pm_test.php +++ b/tests/functional/ucp_pm_test.php @@ -16,7 +16,7 @@  */  class phpbb_functional_ucp_pm_test extends phpbb_functional_test_case  { -	public function setUp() +	public function setUp(): void  	{  		parent::setUp();  		$this->login(); diff --git a/tests/functional/user_password_reset_test.php b/tests/functional/user_password_reset_test.php index 2361eed066..a97300b9ee 100644 --- a/tests/functional/user_password_reset_test.php +++ b/tests/functional/user_password_reset_test.php @@ -25,36 +25,53 @@ class phpbb_functional_user_password_reset_test extends phpbb_functional_test_ca  		// test without email  		$crawler = self::request('GET', "ucp.php?mode=sendpassword&sid={$this->sid}"); +		$this->assertContains('app.php/user/forgot_password', $crawler->getUri());  		$form = $crawler->selectButton('submit')->form();  		$crawler = self::submit($form);  		$this->assertContainsLang('NO_EMAIL_USER', $crawler->text());  		// test with non-existent email -		$crawler = self::request('GET', "ucp.php?mode=sendpassword&sid={$this->sid}"); +		$crawler = self::request('GET', "app.php/user/forgot_password?sid={$this->sid}");  		$form = $crawler->selectButton('submit')->form(array(  			'email'	=> 'non-existent@email.com',  		));  		$crawler = self::submit($form); -		$this->assertContainsLang('PASSWORD_UPDATED_IF_EXISTED', $crawler->text()); +		$this->assertContainsLang('PASSWORD_RESET_LINK_SENT', $crawler->text());  		// test with correct email -		$crawler = self::request('GET', "ucp.php?mode=sendpassword&sid={$this->sid}"); +		$crawler = self::request('GET', "app.php/user/forgot_password?sid={$this->sid}");  		$form = $crawler->selectButton('submit')->form(array(  			'email'		=> 'reset-password-test-user@test.com',  		));  		$crawler = self::submit($form); -		$this->assertContainsLang('PASSWORD_UPDATED_IF_EXISTED', $crawler->text()); +		$this->assertContainsLang('PASSWORD_RESET_LINK_SENT', $crawler->text());  		// Check if columns in database were updated for password reset  		$this->get_user_data('reset-password-test-user'); -		$this->assertNotNull($this->user_data['user_actkey']); -		$this->assertNotNull($this->user_data['user_newpasswd']); +		$this->assertNotEmpty($this->user_data['reset_token']); +		$this->assertNotEmpty($this->user_data['reset_token_expiration']); +		$reset_token = $this->user_data['reset_token']; +		$reset_token_expiration = $this->user_data['reset_token_expiration']; + +		// Check that reset token is only created once per day +		$crawler = self::request('GET', "app.php/user/forgot_password?sid={$this->sid}"); +		$form = $crawler->selectButton('submit')->form(array( +			'email'		=> 'reset-password-test-user@test.com', +		)); +		$crawler = self::submit($form); +		$this->assertContainsLang('PASSWORD_RESET_LINK_SENT', $crawler->text()); + +		$this->get_user_data('reset-password-test-user'); +		$this->assertNotEmpty($this->user_data['reset_token']); +		$this->assertNotEmpty($this->user_data['reset_token_expiration']); +		$this->assertEquals($reset_token, $this->user_data['reset_token']); +		$this->assertEquals($reset_token_expiration, $this->user_data['reset_token_expiration']);  		// Create another user with the same email  		$this->create_user('reset-password-test-user1', 'reset-password-test-user@test.com');  		// Test that username is now also required -		$crawler = self::request('GET', "ucp.php?mode=sendpassword&sid={$this->sid}"); +		$crawler = self::request('GET', "app.php/user/forgot_password?sid={$this->sid}");  		$form = $crawler->selectButton('submit')->form(array(  			'email'		=> 'reset-password-test-user@test.com',  		)); @@ -67,20 +84,13 @@ class phpbb_functional_user_password_reset_test extends phpbb_functional_test_ca  			'username'	=> 'reset-password-test-user1',  		));  		$crawler = self::submit($form); -		$this->assertContainsLang('PASSWORD_UPDATED_IF_EXISTED', $crawler->text()); +		$this->assertContainsLang('PASSWORD_RESET_LINK_SENT', $crawler->text());  		// Check if columns in database were updated for password reset  		$this->get_user_data('reset-password-test-user1'); -		$this->assertNotNull($this->user_data['user_actkey']); -		$this->assertNotNull($this->user_data['user_newpasswd']); - -		// Make sure we know the password -		$db = $this->get_db(); -		$this->passwords_manager = $this->get_passwords_manager(); -		$sql = 'UPDATE ' . USERS_TABLE . " -			SET user_newpasswd = '" . $db->sql_escape($this->passwords_manager->hash('reset-password-test-user')) . "' -			WHERE user_id = " . $user_id; -		$db->sql_query($sql); +		$this->assertNotEmpty($this->user_data['reset_token']); +		$this->assertNotEmpty($this->user_data['reset_token_expiration']); +		$this->assertGreaterThan(time(), $this->user_data['reset_token_expiration']);  	}  	public function test_login_after_reset() @@ -88,28 +98,45 @@ class phpbb_functional_user_password_reset_test extends phpbb_functional_test_ca  		$this->login('reset-password-test-user');  	} -	public function data_activate_new_password() +	public function data_reset_user_password()  	{ -		return array( -			array('WRONG_ACTIVATION', false, 'FOOBAR'), -			array('ALREADY_ACTIVATED', 2, 'FOOBAR'), -			array('PASSWORD_ACTIVATED', false, false), -			array('ALREADY_ACTIVATED', false, false), -		); +		return [ +			['RESET_TOKEN_EXPIRED_OR_INVALID', 0, 'abcdef'], +			['NO_USER', ' ', 'abcdef'], +			['NO_RESET_TOKEN', 0, ' '], +			['RESET_TOKEN_EXPIRED_OR_INVALID', 2, ''], +			['RESET_TOKEN_EXPIRED_OR_INVALID', 1e7, ''], +			['', 0, ''], +			['NO_RESET_TOKEN', 0, ''], // already reset +		];  	}  	/** -	* @dataProvider data_activate_new_password -	*/ -	public function test_activate_new_password($expected, $user_id, $act_key) +	 * @dataProvider data_reset_user_password +	 */ +	public function test_reset_user_password($expected, $user_id, $token)  	{  		$this->add_lang('ucp');  		$this->get_user_data('reset-password-test-user'); -		$user_id = (!$user_id) ? $this->user_data['user_id'] : $user_id; -		$act_key = (!$act_key) ? $this->user_data['user_actkey'] : $act_key; +		$user_id = !$user_id ? $this->user_data['user_id'] : $user_id; +		$token = !$token ? $this->user_data['reset_token'] : $token; + +		$crawler = self::request('GET', "app.php/user/reset_password?u=$user_id&token=$token"); -		$crawler = self::request('GET', "ucp.php?mode=activate&u=$user_id&k=$act_key&sid={$this->sid}"); -		$this->assertContainsLang($expected, $crawler->text()); +		if ($expected) +		{ +			$this->assertContainsLang($expected, $crawler->text()); +		} +		else +		{ +			$form = $crawler->filter('input[type=submit]')->form(); +			$values = array_merge($form->getValues(), [ +				'new_password'			=> 'reset-password-test-user', +				'new_password_confirm'	=> 'reset-password-test-user', +			]); +			$crawler = self::submit($form, $values); +			$this->assertContainsLang('PASSWORD_RESET', $crawler->text()); +		}  	}  	public function test_login() @@ -190,7 +217,7 @@ class phpbb_functional_user_password_reset_test extends phpbb_functional_test_ca  	protected function get_user_data($username)  	{  		$db = $this->get_db(); -		$sql = 'SELECT user_id, username, user_type, user_email, user_newpasswd, user_lang, user_notify_type, user_actkey, user_inactive_reason +		$sql = 'SELECT user_id, username, user_type, user_email, user_newpasswd, user_lang, user_notify_type, user_actkey, user_inactive_reason, reset_token, reset_token_expiration  			FROM ' . USERS_TABLE . "  			WHERE username = '" . $db->sql_escape($username) . "'";  		$result = $db->sql_query($sql); diff --git a/tests/functional/visibility_unapproved_posts_test.php b/tests/functional/visibility_unapproved_posts_test.php new file mode 100644 index 0000000000..9f6491d1d8 --- /dev/null +++ b/tests/functional/visibility_unapproved_posts_test.php @@ -0,0 +1,356 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_visibility_unapproved_test extends phpbb_functional_test_case +{ +	protected $data = []; + +	public function test_setup_forums() +	{ +		$this->login(); +		$this->admin_login(); + +		$crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}"); +		$form = $crawler->selectButton('addforum')->form([ +			'forum_name'	=> 'Unapproved Posts Test #1', +		]); +		$crawler = self::submit($form); +		$form = $crawler->selectButton('update')->form([ +			'forum_perm_from'	=> 2, +		]); +		$crawler = self::submit($form); + +		// Set flood interval to 0 +		$this->set_flood_interval(0); +	} + +	public function test_create_posts() +	{ +		$this->login(); +		$this->load_ids([ +			'forums' => [ +				'Unapproved Posts Test #1', +			], +		]); + +		$this->assert_forum_details($this->data['forums']['Unapproved Posts Test #1'], [ +			'forum_posts_approved'		=> 0, +			'forum_posts_unapproved'	=> 0, +			'forum_posts_softdeleted'	=> 0, +			'forum_topics_approved'		=> 0, +			'forum_topics_unapproved'	=> 0, +			'forum_topics_softdeleted'	=> 0, +			'forum_last_post_id'		=> 0, +		], 'initial comparison'); + +		// Test creating topic #1 +		$post = $this->create_topic($this->data['forums']['Unapproved Posts Test #1'], 'Unapproved Posts Test Topic #1', 'This is a test topic posted by the testing framework.'); +		$crawler = self::request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}"); + +		$this->assertContains('Unapproved Posts Test Topic #1', $crawler->filter('h2')->text()); +		$this->data['topics']['Unapproved Posts Test Topic #1'] = (int) $post['topic_id']; +		$this->data['posts']['Unapproved Posts Test Topic #1'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p'); + +		$this->assert_forum_details($this->data['forums']['Unapproved Posts Test #1'], [ +			'forum_posts_approved'		=> 1, +			'forum_posts_unapproved'	=> 0, +			'forum_posts_softdeleted'	=> 0, +			'forum_topics_approved'		=> 1, +			'forum_topics_unapproved'	=> 0, +			'forum_topics_softdeleted'	=> 0, +			'forum_last_post_id'		=> $this->data['posts']['Unapproved Posts Test Topic #1'], +		], 'after creating topic #1'); + +		$this->logout(); +		$this->create_user('unapproved_posts_test_user#1'); +		$this->add_user_group('NEWLY_REGISTERED', ['unapproved_posts_test_user#1']); +		$this->login('unapproved_posts_test_user#1'); + +		// Test creating a reply +		$post2 = $this->create_post($this->data['forums']['Unapproved Posts Test #1'], $post['topic_id'], 'Re: Unapproved Posts Test Topic #1-#2', 'This is a test post posted by the testing framework.', [], 'POST_STORED_MOD'); + +		$crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Unapproved Posts Test Topic #1']}&sid={$this->sid}"); +		$this->assertNotContains('Re: Unapproved Posts Test Topic #1-#2', $crawler->filter('#page-body')->text()); + +		$this->assert_forum_details($this->data['forums']['Unapproved Posts Test #1'], [ +			'forum_posts_approved'		=> 1, +			'forum_posts_unapproved'	=> 1, +			'forum_posts_softdeleted'	=> 0, +			'forum_topics_approved'		=> 1, +			'forum_topics_unapproved'	=> 0, +			'forum_topics_softdeleted'	=> 0, +			'forum_last_post_id'		=> $this->data['posts']['Unapproved Posts Test Topic #1'], +		], 'after replying'); + +		// Test creating topic #2 +		$post = $this->create_topic($this->data['forums']['Unapproved Posts Test #1'], 'Unapproved Posts Test Topic #2', 'This is a test topic posted by the testing framework.', [], 'POST_STORED_MOD'); +		$crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Unapproved Posts Test #1']}&sid={$this->sid}"); + +		$this->assertNotContains('Unapproved Posts Test Topic #2', $crawler->filter('html')->text()); + +		$this->assert_forum_details($this->data['forums']['Unapproved Posts Test #1'], [ +			'forum_posts_approved'		=> 1, +			'forum_posts_unapproved'	=> 2, +			'forum_posts_softdeleted'	=> 0, +			'forum_topics_approved'		=> 1, +			'forum_topics_unapproved'	=> 1, +			'forum_topics_softdeleted'	=> 0, +			'forum_last_post_id'		=> $this->data['posts']['Unapproved Posts Test Topic #1'], +		], 'after creating topic #2'); + +		$this->logout(); +	} + +	public function test_view_unapproved_post_disabled() +	{ +		// user who created post +		$this->login('unapproved_posts_test_user#1'); +		$this->load_ids([ +			'forums' => [ +				'Unapproved Posts Test #1', +			], +			'topics' => [ +				'Unapproved Posts Test Topic #1', +				'Unapproved Posts Test Topic #2', +			], +			'posts' => [ +				'Unapproved Posts Test Topic #1', +				'Re: Unapproved Posts Test Topic #1-#2', +				'Unapproved Posts Test Topic #2', +			], +		]); + +		$this->assert_forum_details($this->data['forums']['Unapproved Posts Test #1'], [ +			'forum_posts_approved'		=> 1, +			'forum_posts_unapproved'	=> 2, +			'forum_posts_softdeleted'	=> 0, +			'forum_topics_approved'		=> 1, +			'forum_topics_unapproved'	=> 1, +			'forum_topics_softdeleted'	=> 0, +			'forum_last_post_id'		=> $this->data['posts']['Unapproved Posts Test Topic #1'], +		], 'before approving post'); + +		$this->add_lang('posting'); +		$this->add_lang('viewtopic'); +		$this->add_lang('mcp'); + +		// should be able to see topic 1 but not unapproved post +		$crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Unapproved Posts Test Topic #1']}&sid={$this->sid}"); +		$this->assertContains('Unapproved Posts Test Topic #1', $crawler->filter('h2')->text()); +		$this->assertNotContains('Re: Unapproved Posts Test Topic #1-#2', $crawler->filter('#page-body')->text()); +		$this->assertNotContains('This post is not visible to other users until it has been approved', $crawler->filter('#page-body')->text()); + +		// should not be able to see topic 2 +		$crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Unapproved Posts Test #1']}&sid={$this->sid}"); +		$this->assertNotContains('Unapproved Posts Test Topic #2', $crawler->filter('html')->text()); +		$this->logout(); + +		// another user +		$this->create_user('unapproved_posts_test_user#2'); +		$this->login('unapproved_posts_test_user#2'); + +		$this->add_lang('posting', 'viewtopic', 'mcp'); + +		// should be able to see topic 1 but not unapproved post +		$crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Unapproved Posts Test Topic #1']}&sid={$this->sid}"); +		$this->assertContains('Unapproved Posts Test Topic #1', $crawler->filter('h2')->text()); +		$this->assertNotContains('Re: Unapproved Posts Test Topic #1-#2', $crawler->filter('#page-body')->text()); +		$this->assertNotContains('This post is not visible to other users until it has been approved', $crawler->filter('#page-body')->text()); + +		// should not be able to see topic 2 +		$crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Unapproved Posts Test #1']}&sid={$this->sid}"); +		$this->assertNotContains('Unapproved Posts Test Topic #2', $crawler->filter('html')->text()); +	} + +	public function test_view_unapproved_post_enabled() +	{ +		$this->config_display_unapproved_posts_state(true); + +		// user who created post +		$this->login('unapproved_posts_test_user#1'); +		$this->load_ids([ +			'forums' => [ +				'Unapproved Posts Test #1', +			], +			'topics' => [ +				'Unapproved Posts Test Topic #1', +				'Unapproved Posts Test Topic #2', +			], +			'posts' => [ +				'Unapproved Posts Test Topic #1', +				'Re: Unapproved Posts Test Topic #1-#2', +				'Unapproved Posts Test Topic #2', +			], +		]); + +		$this->assert_forum_details($this->data['forums']['Unapproved Posts Test #1'], [ +			'forum_posts_approved'		=> 1, +			'forum_posts_unapproved'	=> 2, +			'forum_posts_softdeleted'	=> 0, +			'forum_topics_approved'		=> 1, +			'forum_topics_unapproved'	=> 1, +			'forum_topics_softdeleted'	=> 0, +			'forum_last_post_id'		=> $this->data['posts']['Unapproved Posts Test Topic #1'], +		], 'before approving post'); + +		$this->add_lang('posting'); +		$this->add_lang('viewtopic'); +		$this->add_lang('mcp'); + +		// should be able to see topic 1 and unapproved post +		$crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Unapproved Posts Test Topic #1']}&sid={$this->sid}"); +		$this->assertContains('Unapproved Posts Test Topic #1', $crawler->filter('h2')->text()); +		$this->assertContains('Re: Unapproved Posts Test Topic #1-#2', $crawler->filter('#page-body')->text()); +		$this->assertContains('This post is not visible to other users until it has been approved', $crawler->filter('#page-body')->text()); + +		// should be able to see topic 2 +		$crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Unapproved Posts Test #1']}&sid={$this->sid}"); +		$this->assertContains('Unapproved Posts Test Topic #2', $crawler->filter('html')->text()); + +		// should be able to see post in topic 2 +		$crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Unapproved Posts Test Topic #2']}&sid={$this->sid}"); +		$this->assertContains('Unapproved Posts Test Topic #2', $crawler->filter('#page-body')->text()); +		$this->assertContains('This post is not visible to other users until it has been approved', $crawler->filter('#page-body')->text()); +		$this->logout(); + +		// another user +		$this->login('unapproved_posts_test_user#2'); + +		$this->add_lang('posting'); +		$this->add_lang('viewtopic'); +		$this->add_lang('mcp'); + +		// should be able to see topic 1 but not unapproved post +		$crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Unapproved Posts Test Topic #1']}&sid={$this->sid}"); +		$this->assertContains('Unapproved Posts Test Topic #1', $crawler->filter('h2')->text()); +		$this->assertNotContains('Re: Unapproved Posts Test Topic #1-#2', $crawler->filter('#page-body')->text()); +		$this->assertNotContains('This post is not visible to other users until it has been approved', $crawler->filter('#page-body')->text()); + +		// should not be able to see topic 2 +		$crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Unapproved Posts Test #1']}&sid={$this->sid}"); +		$this->assertNotContains('Unapproved Posts Test Topic #2', $crawler->filter('html')->text()); +		$this->logout(); +	} + +	public function test_reset_flood_interval() +	{ +		$this->login(); +		$this->admin_login(); + +		// Set flood interval back to 15 +		$this->set_flood_interval(15); +	} + +	protected function assert_forum_details($forum_id, $details, $additional_error_message = '') +	{ +		$this->db = $this->get_db(); + +		$sql = 'SELECT ' . implode(', ', array_keys($details)) . ' +			FROM phpbb_forums +			WHERE forum_id = ' . (int) $forum_id; +		$result = $this->db->sql_query($sql); +		$data = $this->db->sql_fetchrow($result); +		$this->db->sql_freeresult($result); + +		$this->assertEquals($details, $data, "Forum {$forum_id} does not match expected {$additional_error_message}"); +	} + +	protected function set_flood_interval($flood_interval) +	{ +		$crawler = self::request('GET', "adm/index.php?sid={$this->sid}&i=acp_board&mode=post"); + +		$form = $crawler->selectButton('Submit')->form(); +		$values = $form->getValues(); + +		$values['config[flood_interval]'] = $flood_interval; +		$form->setValues($values); +		$crawler = self::submit($form); +		$this->assertGreaterThan(0, $crawler->filter('.successbox')->count()); +	} + +	protected function load_ids($data) +	{ +		$this->db = $this->get_db(); + +		if (!empty($data['forums'])) +		{ +			$sql = 'SELECT forum_id, forum_name +				FROM phpbb_forums +				WHERE ' . $this->db->sql_in_set('forum_name', $data['forums']); +			$result = $this->db->sql_query($sql); +			while ($row = $this->db->sql_fetchrow($result)) +			{ +				if (in_array($row['forum_name'], $data['forums'])) +				{ +					$this->data['forums'][$row['forum_name']] = (int) $row['forum_id']; +				} +			} +			$this->db->sql_freeresult($result); +		} + +		if (!empty($data['topics'])) +		{ +			$sql = 'SELECT * +				FROM phpbb_topics +				WHERE ' . $this->db->sql_in_set('topic_title', $data['topics']); +			$result = $this->db->sql_query($sql); +			while ($row = $this->db->sql_fetchrow($result)) +			{ +				if (in_array($row['topic_title'], $data['topics'])) +				{ +					$this->data['topics'][$row['topic_title']] = (int) $row['topic_id']; +				} +			} +			$this->db->sql_freeresult($result); +		} + +		if (!empty($data['posts'])) +		{ +			$sql = 'SELECT * +				FROM phpbb_posts +				WHERE ' . $this->db->sql_in_set('post_subject', $data['posts']); +			$result = $this->db->sql_query($sql); +			while ($row = $this->db->sql_fetchrow($result)) +			{ +				if (in_array($row['post_subject'], $data['posts'])) +				{ +					$this->data['posts'][$row['post_subject']] = (int) $row['post_id']; +				} +			} +			$this->db->sql_freeresult($result); +		} +	} + +	protected function config_display_unapproved_posts_state($state) +	{ +		$this->login(); +		$this->admin_login(); + +		$crawler = self::request('GET', "adm/index.php?sid={$this->sid}&i=acp_board&mode=features"); + +		$form = $crawler->selectButton('Submit')->form(); +		$values = $form->getValues(); + +		// Enable display of unapproved posts to posters +		$values['config[display_unapproved_posts]'] = $state; + +		$form->setValues($values); + +		$crawler = self::submit($form); +		self::assertContainsLang('CONFIG_UPDATED', $crawler->filter('.successbox')->text()); +		$this->logout(); +	} +} | 
