diff options
author | Maat <maat-pub@mageia.biz> | 2020-05-08 21:52:11 +0200 |
---|---|---|
committer | Maat <maat-pub@mageia.biz> | 2020-05-08 21:52:11 +0200 |
commit | 8ea437e30605e0f66b5220bf904a61d7c1d11ddd (patch) | |
tree | e0db2bb4a012d5b06a633160b19f62f4868ecd28 /tests/test_framework | |
parent | 36bc1870f21fac04736a1049c1d5b8e127d729f4 (diff) | |
parent | 2fdd46b36431ae0f58bb2e78e42553168db9a0ff (diff) | |
download | forums-8ea437e30605e0f66b5220bf904a61d7c1d11ddd.tar forums-8ea437e30605e0f66b5220bf904a61d7c1d11ddd.tar.gz forums-8ea437e30605e0f66b5220bf904a61d7c1d11ddd.tar.bz2 forums-8ea437e30605e0f66b5220bf904a61d7c1d11ddd.tar.xz forums-8ea437e30605e0f66b5220bf904a61d7c1d11ddd.zip |
Merge remote-tracking branch 'upstream/prep-release-3.2.9'
Diffstat (limited to 'tests/test_framework')
-rw-r--r-- | tests/test_framework/mock/phpbb_mock_null_installer_task.php | 30 | ||||
-rw-r--r-- | tests/test_framework/phpbb_database_test_case.php | 88 | ||||
-rw-r--r-- | tests/test_framework/phpbb_database_test_connection_manager.php | 43 | ||||
-rw-r--r-- | tests/test_framework/phpbb_functional_test_case.php | 374 | ||||
-rw-r--r-- | tests/test_framework/phpbb_session_test_case.php | 3 | ||||
-rw-r--r-- | tests/test_framework/phpbb_test_case_helpers.php | 307 | ||||
-rw-r--r-- | tests/test_framework/phpbb_ui_test_case.php | 324 |
7 files changed, 860 insertions, 309 deletions
diff --git a/tests/test_framework/mock/phpbb_mock_null_installer_task.php b/tests/test_framework/mock/phpbb_mock_null_installer_task.php new file mode 100644 index 0000000000..c1b880d967 --- /dev/null +++ b/tests/test_framework/mock/phpbb_mock_null_installer_task.php @@ -0,0 +1,30 @@ +<?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. + * + */ + +class phpbb_mock_null_installer_task extends \phpbb\install\task_base +{ + public function run() + { + + } + + static public function get_step_count() + { + return 0; + } + + public function get_task_lang_name() + { + return ''; + } +} diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index fc1a3632f4..606c40a623 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -58,7 +58,7 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test $setup_extensions = static::setup_extensions(); - $finder = new \phpbb\finder(new \phpbb\filesystem(), $phpbb_root_path, null, $phpEx); + $finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), $phpbb_root_path, null, $phpEx); $finder->core_path('phpbb/db/migration/data/'); if (!empty($setup_extensions)) { @@ -76,8 +76,11 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test global $table_prefix; - $db = new \phpbb\db\driver\sqlite(); - $schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, new \phpbb\db\tools($db, true), $phpbb_root_path, $phpEx, $table_prefix); + $db = new \phpbb\db\driver\sqlite3(); + $factory = new \phpbb\db\tools\factory(); + $db_tools = $factory->get($db, true); + + $schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, $db_tools, $phpbb_root_path, $phpEx, $table_prefix); file_put_contents(self::$schema_file, json_encode($schema_generator->get_schema())); } @@ -139,9 +142,86 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test $manager->database_synchronisation($table_column_map); } + /** + * Create xml data set for insertion into database + * + * @param string $path Path to fixture XML + * @return PHPUnit_Extensions_Database_DataSet_DefaultDataSet|PHPUnit_Extensions_Database_DataSet_XmlDataSet + */ public function createXMLDataSet($path) { $this->fixture_xml_data = parent::createXMLDataSet($path); + + // Extend XML data set on MSSQL + if (strpos($this->get_database_config()['dbms'], 'mssql') !== false) + { + $newXmlData = new PHPUnit_Extensions_Database_DataSet_DefaultDataSet(); + $db = $this->new_dbal(); + foreach ($this->fixture_xml_data as $key => $value) + { + /** @var \PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData $tableMetaData */ + $tableMetaData = $value->getTableMetaData(); + $columns = $tableMetaData->getColumns(); + $primaryKeys = $tableMetaData->getPrimaryKeys(); + + $sql = "SELECT COLUMN_NAME AS identity_column + FROM INFORMATION_SCHEMA.COLUMNS + WHERE COLUMNPROPERTY(object_id(TABLE_SCHEMA + '.' + TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1 + AND TABLE_NAME = '$key' + ORDER BY TABLE_NAME"; + $result = $db->sql_query($sql); + $identity_columns = $db->sql_fetchrowset($result); + $has_default_identity = false; + $add_primary_keys = false; + + // Iterate over identity columns to check for missing primary + // keys in data set and special identity column 'mssqlindex' + // that might have been added when no default identity column + // exists in the current table. + foreach ($identity_columns as $column) + { + if (in_array($column['identity_column'], $columns) && !in_array($column['identity_column'], $primaryKeys)) + { + $primaryKeys[] = $column['identity_column']; + $add_primary_keys = true; + } + + if ($column['identity_column'] === 'mssqlindex') + { + $has_default_identity = true; + break; + } + } + + if ($has_default_identity || $add_primary_keys) + { + // Add default identity column to columns list + if ($has_default_identity) + { + $columns[] = 'mssqlindex'; + } + + $newMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($key, $columns, $primaryKeys); + $newTable = new PHPUnit_Extensions_Database_DataSet_DefaultTable($newMetaData); + for ($i = 0; $i < $value->getRowCount(); $i++) + { + $dataRow = $value->getRow($i); + if ($has_default_identity) + { + $dataRow['mssqlindex'] = $i + 1; + } + $newTable->addRow($dataRow); + } + $newXmlData->addTable($newTable); + } + else + { + $newXmlData->addTable($value); + } + } + + $this->fixture_xml_data = $newXmlData; + } return $this->fixture_xml_data; } @@ -226,7 +306,7 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test { // 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))) + if (count(array_diff($one, $two)) || count(array_diff($two, $one))) { // get a nice error message $this->assertEquals($one, $two); diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index 3b5bab749e..f3adbefc1b 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -11,7 +11,6 @@ * */ -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 @@ -56,7 +55,6 @@ class phpbb_database_test_connection_manager switch ($this->dbms['PDO']) { - case 'sqlite2': case 'sqlite': // SQLite3 driver $dsn .= $this->config['dbhost']; break; @@ -194,7 +192,6 @@ class phpbb_database_test_connection_manager { switch ($this->config['dbms']) { - case 'phpbb\db\driver\sqlite': case 'phpbb\db\driver\sqlite3': $this->connect(); // Drop all of the tables @@ -225,6 +222,14 @@ class phpbb_database_test_connection_manager $this->purge_extras(); break; + case 'phpbb\db\driver\mssql': + case 'phpbb\db\driver\mssqlnative': + $this->connect(); + // Drop all tables + $this->pdo->exec("EXEC sp_MSforeachtable 'DROP TABLE ?'"); + $this->purge_extras(); + break; + default: $this->connect(false); @@ -270,12 +275,6 @@ class phpbb_database_test_connection_manager $sql = 'SHOW TABLES'; break; - case 'phpbb\db\driver\sqlite': - $sql = 'SELECT name - FROM sqlite_master - WHERE type = "table"'; - break; - case 'phpbb\db\driver\sqlite3': $sql = 'SELECT name FROM sqlite_master @@ -351,10 +350,13 @@ class phpbb_database_test_connection_manager if (file_exists($filename)) { + global $phpbb_root_path; + $queries = file_get_contents($filename); - $sql = phpbb_remove_comments($queries); - $sql = split_sql_file($sql, $this->dbms['DELIM']); + $db_helper = new \phpbb\install\helper\database(new \phpbb\filesystem\filesystem(), $phpbb_root_path); + $sql = $db_helper->remove_comments($queries); + $sql = $db_helper->split_sql_file($sql, $this->dbms['DELIM']); foreach ($sql as $query) { @@ -372,16 +374,20 @@ class phpbb_database_test_connection_manager { global $phpbb_root_path, $phpEx, $table_prefix; - $finder = new \phpbb\finder(new \phpbb\filesystem(), $phpbb_root_path, null, $phpEx); + $finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), $phpbb_root_path, null, $phpEx); $classes = $finder->core_path('phpbb/db/migration/data/') ->get_classes(); - $db = new \phpbb\db\driver\sqlite(); - $schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, new \phpbb\db\tools($db, true), $phpbb_root_path, $phpEx, $table_prefix); + $db = new \phpbb\db\driver\sqlite3(); + $factory = new \phpbb\db\tools\factory(); + $db_tools = $factory->get($db, true); + + $schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, $db_tools, $phpbb_root_path, $phpEx, $table_prefix); $db_table_schema = $schema_generator->get_schema(); } - $db_tools = new \phpbb\db\tools($db, true); + $factory = new \phpbb\db\tools\factory(); + $db_tools = $factory->get($db, true); foreach ($db_table_schema as $table_name => $table_data) { $queries = $db_tools->sql_create_table( @@ -448,11 +454,6 @@ class phpbb_database_test_connection_manager 'DELIM' => ';', 'PDO' => 'pgsql', ), - 'phpbb\db\driver\sqlite' => array( - 'SCHEMA' => 'sqlite', - 'DELIM' => ';', - 'PDO' => 'sqlite2', - ), 'phpbb\db\driver\sqlite3' => array( 'SCHEMA' => 'sqlite', 'DELIM' => ';', @@ -628,7 +629,7 @@ class phpbb_database_test_connection_manager } // Combine all of the SETVALs into one query - if (sizeof($setval_queries)) + if (count($setval_queries)) { $queries[] = 'SELECT ' . implode(', ', $setval_queries); } diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 8107e45dc7..f1b30f0fed 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -12,13 +12,15 @@ */ use Symfony\Component\BrowserKit\CookieJar; -require_once __DIR__ . '/../../phpBB/includes/functions_install.php'; +require_once __DIR__ . '/mock/phpbb_mock_null_installer_task.php'; class phpbb_functional_test_case extends phpbb_test_case { + /** @var \Goutte\Client */ static protected $client; static protected $cookieJar; static protected $root_url; + static protected $install_success = false; protected $cache = null; protected $db = null; @@ -77,13 +79,15 @@ class phpbb_functional_test_case extends phpbb_test_case { parent::setUp(); + if (!self::$install_success) + { + $this->fail('Installing phpBB has failed.'); + } + $this->bootstrap(); self::$cookieJar = new CookieJar; self::$client = new Goutte\Client(array(), null, self::$cookieJar); - // Reset the curl handle because it is 0 at this point and not a valid - // resource - self::$client->getClient()->getCurlMulti()->reset(true); // Clear the language array so that things // that were added in other tests are gone @@ -169,7 +173,7 @@ class phpbb_functional_test_case extends phpbb_test_case */ static public function get_content() { - return self::$client->getResponse()->getContent(); + return (string) self::$client->getResponse()->getContent(); } // bootstrap, called after board is set up @@ -205,6 +209,12 @@ class phpbb_functional_test_case extends phpbb_test_case { if (!$this->cache) { + global $phpbb_container, $phpbb_root_path; + + $phpbb_container = new phpbb_mock_container_builder(); + $phpbb_container->setParameter('core.environment', PHPBB_ENVIRONMENT); + $phpbb_container->setParameter('core.cache_dir', $phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT . '/'); + $this->cache = new \phpbb\cache\driver\file; } @@ -226,7 +236,8 @@ class phpbb_functional_test_case extends phpbb_test_case $config = new \phpbb\config\config(array()); $db = $this->get_db(); - $db_tools = new \phpbb\db\tools($db); + $factory = new \phpbb\db\tools\factory(); + $db_tools = $factory->get($db); $container = new phpbb_mock_container_builder(); $migrator = new \phpbb\db\migrator( @@ -243,18 +254,16 @@ class phpbb_functional_test_case extends phpbb_test_case ); $container->set('migrator', $migrator); $container->set('dispatcher', new phpbb_mock_event_dispatcher()); - $user = new \phpbb\user('\phpbb\datetime'); $extension_manager = new \phpbb\extension\manager( $container, $db, $config, - new phpbb\filesystem(), - $user, + new phpbb\filesystem\filesystem(), self::$config['table_prefix'] . 'ext', dirname(__FILE__) . '/', $phpEx, - $this->get_cache_driver() + new \phpbb\cache\service($this->get_cache_driver(), $config, $this->db, $phpbb_root_path, $phpEx) ); return $extension_manager; @@ -282,120 +291,129 @@ class phpbb_functional_test_case extends phpbb_test_case } } - self::$cookieJar = new CookieJar; - self::$client = new Goutte\Client(array(), null, self::$cookieJar); - // Set client manually so we can increase the cURL timeout - self::$client->setClient(new Guzzle\Http\Client('', array( - Guzzle\Http\Client::DISABLE_REDIRECTS => true, - 'curl.options' => array( - CURLOPT_TIMEOUT => 120, - ), - ))); - - // Reset the curl handle because it is 0 at this point and not a valid - // resource - self::$client->getClient()->getCurlMulti()->reset(true); + $install_config_file = $phpbb_root_path . 'store/install_config.php'; - $parseURL = parse_url(self::$config['phpbb_functional_url']); + if (file_exists($install_config_file)) + { + unlink($install_config_file); + } - $crawler = self::request('GET', 'install/index.php?mode=install&language=en'); - self::assertContains('Welcome to Installation', $crawler->filter('#main')->text()); - $form = $crawler->selectButton('submit')->form(); + $container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); + $container = $container_builder + ->with_environment('installer') + ->without_extensions() + ->without_cache() + ->with_custom_parameters([ + 'core.disable_super_globals' => false, + 'installer.create_config_file.options' => [ + 'debug' => true, + 'environment' => 'test', + ], + 'cache.driver.class' => 'phpbb\cache\driver\file' + ]) + ->with_config(new \phpbb\config_php_file($phpbb_root_path, $phpEx)) + ->without_compiled_container() + ->get_container(); + + $container->register('installer.install_finish.notify_user')->setSynthetic(true); + $container->set('installer.install_finish.notify_user', new phpbb_mock_null_installer_task()); + $container->register('installer.install_finish.install_extensions')->setSynthetic(true); + $container->set('installer.install_finish.install_extensions', new phpbb_mock_null_installer_task()); + $container->compile(); + + $language = $container->get('language'); + $language->add_lang(array('common', 'acp/common', 'acp/board', 'install', 'posting')); + + $iohandler_factory = $container->get('installer.helper.iohandler_factory'); + $iohandler_factory->set_environment('cli'); + $iohandler = $iohandler_factory->get(); - // install/index.php?mode=install&sub=requirements - $crawler = self::submit($form); - self::assertContains('Installation compatibility', $crawler->filter('#main')->text()); - $form = $crawler->selectButton('submit')->form(); + $parseURL = parse_url(self::$config['phpbb_functional_url']); - // install/index.php?mode=install&sub=database - $crawler = self::submit($form); - self::assertContains('Database configuration', $crawler->filter('#main')->text()); - $form = $crawler->selectButton('submit')->form(array( - // Installer uses 3.0-style dbms name - 'dbms' => str_replace('phpbb\db\driver\\', '', self::$config['dbms']), - 'dbhost' => self::$config['dbhost'], - 'dbport' => self::$config['dbport'], - 'dbname' => self::$config['dbname'], - 'dbuser' => self::$config['dbuser'], - 'dbpasswd' => self::$config['dbpasswd'], - 'table_prefix' => self::$config['table_prefix'], - )); + $output = new \Symfony\Component\Console\Output\NullOutput(); + $style = new \Symfony\Component\Console\Style\SymfonyStyle( + new \Symfony\Component\Console\Input\ArrayInput(array()), + $output + ); + $iohandler->set_style($style, $output); + + $installer = $container->get('installer.installer.install'); + $installer->set_iohandler($iohandler); + + // Set data + $iohandler->set_input('admin_name', 'admin'); + $iohandler->set_input('admin_pass1', 'adminadmin'); + $iohandler->set_input('admin_pass2', 'adminadmin'); + $iohandler->set_input('board_email', 'nobody@example.com'); + $iohandler->set_input('submit_admin', 'submit'); + + $iohandler->set_input('default_lang', 'en'); + $iohandler->set_input('board_name', 'yourdomain.com'); + $iohandler->set_input('board_description', 'A short text to describe your forum'); + $iohandler->set_input('submit_board', 'submit'); + + $iohandler->set_input('dbms', str_replace('phpbb\db\driver\\', '', self::$config['dbms'])); + $iohandler->set_input('dbhost', self::$config['dbhost']); + $iohandler->set_input('dbport', self::$config['dbport']); + $iohandler->set_input('dbuser', self::$config['dbuser']); + $iohandler->set_input('dbpasswd', self::$config['dbpasswd']); + $iohandler->set_input('dbname', self::$config['dbname']); + $iohandler->set_input('table_prefix', self::$config['table_prefix']); + $iohandler->set_input('submit_database', 'submit'); + + $iohandler->set_input('email_enable', true); + $iohandler->set_input('smtp_delivery', '1'); + $iohandler->set_input('smtp_host', 'nxdomain.phpbb.com'); + $iohandler->set_input('smtp_auth', 'PLAIN'); + $iohandler->set_input('smtp_user', 'nxuser'); + $iohandler->set_input('smtp_pass', 'nxpass'); + $iohandler->set_input('submit_email', 'submit'); + + $iohandler->set_input('cookie_secure', '0'); + $iohandler->set_input('server_protocol', '0'); + $iohandler->set_input('force_server_vars', $parseURL['scheme'] . '://'); + $iohandler->set_input('server_name', $parseURL['host']); + $iohandler->set_input('server_port', isset($parseURL['port']) ? (int) $parseURL['port'] : 80); + $iohandler->set_input('script_path', $parseURL['path']); + $iohandler->set_input('submit_server', 'submit'); + + $installer->run(); - // install/index.php?mode=install&sub=database - $crawler = self::submit($form); - self::assertContains('Successful connection', $crawler->filter('#main')->text()); - $form = $crawler->selectButton('submit')->form(); + copy($config_file, $config_file_test); - // install/index.php?mode=install&sub=administrator - $crawler = self::submit($form); - self::assertContains('Administrator configuration', $crawler->filter('#main')->text()); - $form = $crawler->selectButton('submit')->form(array( - 'default_lang' => 'en', - 'admin_name' => 'admin', - 'admin_pass1' => 'adminadmin', - 'admin_pass2' => 'adminadmin', - 'board_email' => 'nobody@example.com', - )); + self::$install_success = true; - // install/index.php?mode=install&sub=administrator - $crawler = self::submit($form); - self::assertContains('Tests passed', $crawler->filter('#main')->text()); - $form = $crawler->selectButton('submit')->form(); - - // We have to skip install/index.php?mode=install&sub=config_file - // because that step will create a config.php file if phpBB has the - // permission to do so. We have to create the config file on our own - // in order to get the DEBUG constants defined. - $config_php_data = phpbb_create_config_file_data(self::$config, self::$config['dbms'], true, false, true); - $config_created = file_put_contents($config_file, $config_php_data) !== false; - if (!$config_created) + if (file_exists($phpbb_root_path . 'store/install_config.php')) { - self::markTestSkipped("Could not write $config_file file."); + self::$install_success = false; + @unlink($phpbb_root_path . 'store/install_config.php'); } - // We also have to create a install lock that is normally created by - // the installer. The file will be removed by the final step of the - // installer. - $install_lock_file = $phpbb_root_path . 'cache/install_lock'; - $lock_created = file_put_contents($install_lock_file, '') !== false; - if (!$lock_created) + if (file_exists($phpbb_root_path . 'cache/install_lock')) { - self::markTestSkipped("Could not create $lock_created file."); + @unlink($phpbb_root_path . 'cache/install_lock'); } - @chmod($install_lock_file, 0666); - - // install/index.php?mode=install&sub=advanced - $form_data = $form->getValues(); - unset($form_data['submit']); - - $crawler = self::request('POST', 'install/index.php?mode=install&sub=advanced', $form_data); - self::assertContains('The settings on this page are only necessary to set if you know that you require something different from the default.', $crawler->filter('#main')->text()); - $form = $crawler->selectButton('submit')->form(array( - 'email_enable' => true, - 'smtp_delivery' => true, - 'smtp_host' => 'nxdomain.phpbb.com', - 'smtp_auth' => 'PLAIN', - 'smtp_user' => 'nxuser', - 'smtp_pass' => 'nxpass', - 'cookie_secure' => false, - 'force_server_vars' => false, - 'server_protocol' => $parseURL['scheme'] . '://', - 'server_name' => 'localhost', - 'server_port' => isset($parseURL['port']) ? (int) $parseURL['port'] : 80, - 'script_path' => $parseURL['path'], - )); - // install/index.php?mode=install&sub=create_table - $crawler = self::submit($form); - self::assertContains('The database tables used by phpBB', $crawler->filter('#main')->text()); - self::assertContains('have been created and populated with some initial data.', $crawler->filter('#main')->text()); - $form = $crawler->selectButton('submit')->form(); + global $phpbb_container; + $phpbb_container->reset(); - // install/index.php?mode=install&sub=final - $crawler = self::submit($form); - self::assertContains('You have successfully installed', $crawler->text()); + // Purge cache to remove cached files + $phpbb_container = new phpbb_mock_container_builder(); + $phpbb_container->setParameter('core.environment', PHPBB_ENVIRONMENT); + $phpbb_container->setParameter('core.cache_dir', $phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT . '/'); - copy($config_file, $config_file_test); + $cache = new \phpbb\cache\driver\file; + $cache->purge(); + + $blacklist = ['phpbb_class_loader_mock', 'phpbb_class_loader_ext', 'phpbb_class_loader']; + + foreach (array_keys($GLOBALS) as $key) + { + if (is_object($GLOBALS[$key]) && !in_array($key, $blacklist, true)) + { + unset($GLOBALS[$key]); + } + } } public function install_ext($extension) @@ -415,7 +433,7 @@ class phpbb_functional_test_case extends phpbb_test_case $meta_refresh = $crawler->filter('meta[http-equiv="refresh"]'); // Wait for extension to be fully enabled - while (sizeof($meta_refresh)) + while (count($meta_refresh)) { preg_match('#url=.+/(adm+.+)#', $meta_refresh->attr('content'), $match); $url = $match[1]; @@ -490,7 +508,7 @@ class phpbb_functional_test_case extends phpbb_test_case )); $db->sql_query($sql); - if ($style_path != 'prosilver' && $style_path != 'subsilver2') + if ($style_path != 'prosilver') { @mkdir($phpbb_root_path . 'styles/' . $style_path, 0777); @mkdir($phpbb_root_path . 'styles/' . $style_path . '/template', 0777); @@ -499,7 +517,6 @@ class phpbb_functional_test_case extends phpbb_test_case else { $db->sql_multi_insert(STYLES_TABLE, array(array( - 'style_id' => $style_id, 'style_name' => $style_path, 'style_copyright' => '', 'style_active' => 1, @@ -529,7 +546,7 @@ class phpbb_functional_test_case extends phpbb_test_case $db->sql_query('DELETE FROM ' . STYLES_TEMPLATE_TABLE . ' WHERE template_id = ' . $style_id); $db->sql_query('DELETE FROM ' . STYLES_THEME_TABLE . ' WHERE theme_id = ' . $style_id); - if ($style_path != 'prosilver' && $style_path != 'subsilver2') + if ($style_path != 'prosilver') { @rmdir($phpbb_root_path . 'styles/' . $style_path . '/template'); @rmdir($phpbb_root_path . 'styles/' . $style_path); @@ -541,9 +558,10 @@ class phpbb_functional_test_case extends phpbb_test_case * Creates a new user with limited permissions * * @param string $username Also doubles up as the user's password + * @param string $email User email (defaults to nobody@example.com) * @return int ID of created user */ - protected function create_user($username) + protected function create_user($username, $email = 'nobody@example.com') { // Required by unique_id global $config; @@ -562,6 +580,9 @@ class phpbb_functional_test_case extends phpbb_test_case $config['rand_seed'] = ''; $config['rand_seed_last_update'] = time() + 600; + // Prevent new user to have an invalid style + $config['default_style'] = 1; + // Required by user_add global $db, $cache, $phpbb_dispatcher, $phpbb_container; $db = $this->get_db(); @@ -571,7 +592,7 @@ class phpbb_functional_test_case extends phpbb_test_case } $cache = new phpbb_mock_null_cache; - $cache_driver = new \phpbb\cache\driver\null(); + $cache_driver = new \phpbb\cache\driver\dummy(); $phpbb_container = new phpbb_mock_container_builder(); $phpbb_container->set('cache.driver', $cache_driver); $phpbb_notifications = new phpbb_mock_notification_manager(); @@ -585,15 +606,14 @@ class phpbb_functional_test_case extends phpbb_test_case { 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(); $passwords_manager = $this->get_passwords_manager(); $user_row = array( 'username' => $username, 'group_id' => 2, - 'user_email' => 'nobody@example.com', + 'user_email' => $email, 'user_type' => 0, 'user_lang' => 'en', 'user_timezone' => 'UTC', @@ -603,6 +623,25 @@ class phpbb_functional_test_case extends phpbb_test_case return user_add($user_row); } + /** + * Get group ID + * + * @param string $group_name Group name + * @return int Group id of specified group name + */ + protected function get_group_id($group_name) + { + $db = $this->get_db(); + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . " + WHERE group_name = '" . $db->sql_escape($group_name) . "'"; + $result = $db->sql_query($sql); + $group_id = (int) $db->sql_fetchfield('group_id'); + $db->sql_freeresult($result); + + return $group_id; + } + protected function remove_user_group($group_name, $usernames) { global $db, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_log, $phpbb_container, $phpbb_root_path, $phpEx; @@ -612,13 +651,16 @@ class phpbb_functional_test_case extends phpbb_test_case $db = $this->get_db(); $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $user = $this->getMock('\phpbb\user', array(), array('\phpbb\datetime')); + $user = $this->getMock('\phpbb\user', array(), array( + new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), + '\phpbb\datetime' + )); $auth = $this->getMock('\phpbb\auth\auth'); $phpbb_log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); $cache = new phpbb_mock_null_cache; - $cache_driver = new \phpbb\cache\driver\null(); + $cache_driver = new \phpbb\cache\driver\dummy(); $phpbb_container = new phpbb_mock_container_builder(); $phpbb_container->set('cache.driver', $cache_driver); $phpbb_container->set('notification_manager', new phpbb_mock_notification_manager()); @@ -632,12 +674,7 @@ class phpbb_functional_test_case extends phpbb_test_case require_once(__DIR__ . '/../../phpBB/includes/functions_user.php'); } - $sql = 'SELECT group_id - FROM ' . GROUPS_TABLE . " - WHERE group_name = '" . $db->sql_escape($group_name) . "'"; - $result = $db->sql_query($sql); - $group_id = (int) $db->sql_fetchfield('group_id'); - $db->sql_freeresult($result); + $group_id = $this->get_group_id($group_name); return group_user_del($group_id, false, $usernames, $group_name); } @@ -651,13 +688,16 @@ class phpbb_functional_test_case extends phpbb_test_case $db = $this->get_db(); $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $user = $this->getMock('\phpbb\user', array(), array('\phpbb\datetime')); + $user = $this->getMock('\phpbb\user', array(), array( + new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), + '\phpbb\datetime' + )); $auth = $this->getMock('\phpbb\auth\auth'); $phpbb_log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); $cache = new phpbb_mock_null_cache; - $cache_driver = new \phpbb\cache\driver\null(); + $cache_driver = new \phpbb\cache\driver\dummy(); $phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); $phpbb_container ->expects($this->any()) @@ -674,12 +714,7 @@ class phpbb_functional_test_case extends phpbb_test_case require_once(__DIR__ . '/../../phpBB/includes/functions_user.php'); } - $sql = 'SELECT group_id - FROM ' . GROUPS_TABLE . " - WHERE group_name = '" . $db->sql_escape($group_name) . "'"; - $result = $db->sql_query($sql); - $group_id = (int) $db->sql_fetchfield('group_id'); - $db->sql_freeresult($result); + $group_id = $this->get_group_id($group_name); return group_user_add($group_id, false, $usernames, $group_name, $default, $leader); } @@ -856,7 +891,7 @@ class phpbb_functional_test_case extends phpbb_test_case static public function assert_response_html($status_code = 200) { // Any output before the doc type means there was an error - $content = self::$client->getResponse()->getContent(); + $content = self::get_content(); self::assertNotContains('[phpBB Debug]', $content); self::assertStringStartsWith('<!DOCTYPE', trim($content), 'Output found before DOCTYPE specification.'); @@ -877,7 +912,7 @@ class phpbb_functional_test_case extends phpbb_test_case static public function assert_response_xml($status_code = 200) { // Any output before the xml opening means there was an error - $content = self::$client->getResponse()->getContent(); + $content = self::get_content(); self::assertNotContains('[phpBB Debug]', $content); self::assertStringStartsWith('<?xml', trim($content), 'Output found before XML specification.'); @@ -894,10 +929,15 @@ class phpbb_functional_test_case extends phpbb_test_case * status code. This assertion tries to catch that. * * @param int $status_code Expected status code - * @return null + * @return void */ static public function assert_response_status_code($status_code = 200) { + if ($status_code != self::$client->getResponse()->getStatus() && + preg_match('/^5[0-9]{2}/', self::$client->getResponse()->getStatus())) + { + self::fail("Encountered unexpected server error:\n" . self::$client->getResponse()->getContent()); + } self::assertEquals($status_code, self::$client->getResponse()->getStatus(), 'HTTP status code does not match'); } @@ -948,8 +988,7 @@ class phpbb_functional_test_case extends phpbb_test_case */ public function assert_checkbox_is_unchecked($crawler, $name, $message = '') { - $this->assertSame( - '', + $this->assertNull( $this->assert_find_one_checkbox($crawler, $name)->attr('checked'), $message ?: "Failed asserting that checkbox $name is unchecked." ); @@ -973,7 +1012,7 @@ class phpbb_functional_test_case extends phpbb_test_case $this->assertEquals( 1, - sizeof($result), + count($result), $message ?: 'Failed asserting that exactly one checkbox with name' . " $name exists in crawler scope." ); @@ -1136,28 +1175,14 @@ class phpbb_functional_test_case extends phpbb_test_case 'error' => UPLOAD_ERR_OK, ); - $crawler = self::$client->request('POST', $posting_url, array('add_file' => $this->lang('ADD_FILE')), array('fileupload' => $file)); - } - unset($form_data['upload_files']); - } - - $hidden_fields = array( - $crawler->filter('[type="hidden"]')->each(function ($node, $i) { - return array('name' => $node->attr('name'), 'value' => $node->attr('value')); - }), - ); + $file_form_data = array_merge(['add_file' => $this->lang('ADD_FILE')], $this->get_hidden_fields($crawler, $posting_url)); - foreach ($hidden_fields as $fields) - { - foreach($fields as $field) - { - $form_data[$field['name']] = $field['value']; + $crawler = self::$client->request('POST', $posting_url, $file_form_data, array('fileupload' => $file)); } + unset($form_data['upload_files']); } - // 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; + $form_data = array_merge($form_data, $this->get_hidden_fields($crawler, $posting_url)); // 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) @@ -1288,4 +1313,37 @@ class phpbb_functional_test_case extends phpbb_test_case return self::request('GET', substr($link, strpos($link, 'mcp.'))); } + + /** + * Get hidden fields for URL + * + * @param Symfony\Component\DomCrawler\Crawler|null $crawler Crawler instance or null + * @param string $url Request URL + * + * @return array Hidden form fields array + */ + protected function get_hidden_fields($crawler, $url) + { + if (!$crawler) + { + $crawler = self::$client->request('GET', $url); + } + $hidden_fields = [ + $crawler->filter('[type="hidden"]')->each(function ($node, $i) { + return ['name' => $node->attr('name'), 'value' => $node->attr('value')]; + }), + ]; + + $file_form_data = []; + + foreach ($hidden_fields as $fields) + { + foreach($fields as $field) + { + $file_form_data[$field['name']] = $field['value']; + } + } + + return $file_form_data; + } } diff --git a/tests/test_framework/phpbb_session_test_case.php b/tests/test_framework/phpbb_session_test_case.php index 1bf0277fe0..b3d7780d14 100644 --- a/tests/test_framework/phpbb_session_test_case.php +++ b/tests/test_framework/phpbb_session_test_case.php @@ -11,7 +11,6 @@ * */ -require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; require_once dirname(__FILE__) . '/../session/testable_factory.php'; require_once dirname(__FILE__) . '/../session/testable_facade.php'; @@ -34,7 +33,7 @@ abstract class phpbb_session_test_case extends phpbb_database_test_case $symfony_request = new \phpbb\symfony_request( new phpbb_mock_request() ); - $phpbb_filesystem = new \phpbb\filesystem(); + $phpbb_filesystem = new \phpbb\filesystem\filesystem(); $phpbb_path_helper = new \phpbb\path_helper( $symfony_request, $phpbb_filesystem, diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index dee70ad016..c792976b1e 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -11,6 +11,8 @@ * */ +use Symfony\Component\DependencyInjection\ContainerInterface; + class phpbb_test_case_helpers { protected $expectedTriggerError = false; @@ -120,17 +122,6 @@ class phpbb_test_case_helpers 'dbpasswd' => '', )); } - else if (extension_loaded('sqlite')) - { - $config = array_merge($config, array( - 'dbms' => 'phpbb\db\driver\sqlite', - 'dbhost' => dirname(__FILE__) . '/../phpbb_unit_tests.sqlite2', // filename - 'dbport' => '', - 'dbname' => '', - 'dbuser' => '', - 'dbpasswd' => '', - )); - } if (isset($_SERVER['PHPBB_TEST_CONFIG'])) { @@ -298,4 +289,298 @@ class phpbb_test_case_helpers } } } + + /** + * Set working instances of the text_formatter.* services + * + * If no container is passed, the global $phpbb_container will be used and/or + * created if applicable + * + * @param ContainerInterface $container Service container + * @param string $fixture Path to the XML fixture + * @param string $styles_path Path to the styles dir + * @return ContainerInterface + */ + public function set_s9e_services(ContainerInterface $container = null, $fixture = null, $styles_path = null) + { + static $first_run; + global $config, $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx, $request, $user; + + $cache_dir = __DIR__ . '/../tmp/'; + + // Remove old cache files on first run + if (!isset($first_run)) + { + $first_run = 1; + + array_map('unlink', array_merge( + glob($cache_dir . 'data_s9e_*'), + glob($cache_dir . 's9e_*') + )); + } + + if (!isset($container)) + { + if (!isset($phpbb_container)) + { + $phpbb_container = new phpbb_mock_container_builder; + } + + $container = $phpbb_container; + } + + if (!isset($fixture)) + { + $fixture = __DIR__ . '/../text_formatter/s9e/fixtures/default_formatting.xml'; + } + + if (!isset($styles_path)) + { + $styles_path = $phpbb_root_path . 'styles/'; + } + + $dataset = new DOMDocument; + $dataset->load($fixture); + + $tables = array( + 'phpbb_bbcodes' => array(), + 'phpbb_smilies' => array(), + 'phpbb_styles' => array(), + 'phpbb_words' => array() + ); + foreach ($dataset->getElementsByTagName('table') as $table) + { + $name = $table->getAttribute('name'); + $columns = array(); + + foreach ($table->getElementsByTagName('column') as $column) + { + $columns[] = $column->textContent; + } + + foreach ($table->getElementsByTagName('row') as $row) + { + $values = array(); + + foreach ($row->getElementsByTagName('value') as $value) + { + $values[] = $value->textContent; + } + + $tables[$name][] = array_combine($columns, $values); + } + } + + // Set up a default style if there's none set + if (empty($tables['phpbb_styles'])) + { + $tables['phpbb_styles'][] = array( + 'style_id' => 1, + 'style_path' => 'prosilver', + 'bbcode_bitfield' => 'kNg=' + ); + } + + // Mock the DAL, make it return data from the fixture + $mb = $this->test_case->getMockBuilder('phpbb\\textformatter\\data_access'); + $mb->setMethods(array('get_bbcodes', 'get_censored_words', 'get_smilies', 'get_styles')); + $mb->setConstructorArgs(array( + $this->test_case->getMockBuilder('phpbb\\db\\driver\\driver')->getMock(), + 'phpbb_bbcodes', + 'phpbb_smilies', + 'phpbb_styles', + 'phpbb_words', + $styles_path + )); + + $dal = $mb->getMock(); + $container->set('text_formatter.data_access', $dal); + + $dal->expects($this->test_case->any()) + ->method('get_bbcodes') + ->will($this->test_case->returnValue($tables['phpbb_bbcodes'])); + $dal->expects($this->test_case->any()) + ->method('get_smilies') + ->will($this->test_case->returnValue($tables['phpbb_smilies'])); + $dal->expects($this->test_case->any()) + ->method('get_styles') + ->will($this->test_case->returnValue($tables['phpbb_styles'])); + $dal->expects($this->test_case->any()) + ->method('get_censored_words') + ->will($this->test_case->returnValue($tables['phpbb_words'])); + + // Cache the parser and renderer with a key based on this method's arguments + $cache = new \phpbb\cache\driver\file($cache_dir); + $prefix = '_s9e_' . md5(serialize(func_get_args())); + $cache_key_parser = $prefix . '_parser'; + $cache_key_renderer = $prefix . '_renderer'; + $container->set('cache.driver', $cache); + + if (!$container->isFrozen()) + { + $container->setParameter('cache.dir', $cache_dir); + } + + // Create a path_helper + if (!$container->has('path_helper') || $container->getDefinition('path_helper')->isSynthetic()) + { + $path_helper = $this->test_case->getMockBuilder('phpbb\\path_helper') + ->disableOriginalConstructor() + ->setMethods(array('get_web_root_path')) + ->getMock(); + $path_helper->expects($this->test_case->any()) + ->method('get_web_root_path') + ->will($this->test_case->returnValue('phpBB/')); + + $container->set('path_helper', $path_helper); + } + else + { + $path_helper = $container->get('path_helper'); + } + + // Create an event dispatcher + if ($container->has('dispatcher')) + { + $dispatcher = $container->get('dispatcher'); + } + else if (isset($phpbb_dispatcher)) + { + $dispatcher = $phpbb_dispatcher; + } + else + { + $dispatcher = new phpbb_mock_event_dispatcher; + } + if (!isset($phpbb_dispatcher)) + { + $phpbb_dispatcher = $dispatcher; + } + + // Set up the a minimum config + if ($container->has('config')) + { + $config = $container->get('config'); + } + elseif (!isset($config)) + { + $config = new \phpbb\config\config(array()); + } + $default_config = array( + 'allow_nocensors' => false, + 'allowed_schemes_links' => 'http,https,ftp', + 'script_path' => '/phpbb', + 'server_name' => 'localhost', + 'server_port' => 80, + 'server_protocol' => 'http://', + 'smilies_path' => 'images/smilies', + ); + foreach ($default_config as $config_name => $config_value) + { + if (!isset($config[$config_name])) + { + $config[$config_name] = $config_value; + } + } + + // Create a fake request + if (!isset($request)) + { + $request = new phpbb_mock_request; + } + + // Get a log interface + $log = ($container->has('log')) ? $container->get('log') : $this->test_case->getMockBuilder('phpbb\\log\\log_interface')->getMock(); + + // Create and register the text_formatter.s9e.factory service + $factory = new \phpbb\textformatter\s9e\factory($dal, $cache, $dispatcher, $config, new \phpbb\textformatter\s9e\link_helper, $log, $cache_dir, $cache_key_parser, $cache_key_renderer); + $container->set('text_formatter.s9e.factory', $factory); + + // Create a user if none was provided, and add the common lang strings + if ($container->has('user')) + { + $user = $container->get('user'); + } + else + { + $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); + $lang = new \phpbb\language\language($lang_loader); + + $user = $this->test_case->getMockBuilder('\phpbb\user') + ->setConstructorArgs(array($lang, '\phpbb\datetime')) + ->setMethods(array('format_date')) + ->getMock(); + $user->expects($this->test_case->any()) + ->method('format_date') + ->will($this->test_case->returnCallback(__CLASS__ . '::format_date')); + + $user->date_format = 'Y-m-d H:i:s'; + $user->optionset('viewcensors', true); + $user->optionset('viewflash', true); + $user->optionset('viewimg', true); + $user->optionset('viewsmilies', true); + $user->timezone = new \DateTimeZone('UTC'); + $container->set('user', $user); + } + $user->add_lang('common'); + + if (!isset($user->style)) + { + $user->style = array('style_id' => 1); + } + + // Create and register a quote_helper + $quote_helper = new \phpbb\textformatter\s9e\quote_helper( + $container->get('user'), + $phpbb_root_path, + $phpEx + ); + $container->set('text_formatter.s9e.quote_helper', $quote_helper); + + // Create and register the text_formatter.s9e.parser service and its alias + $parser = new \phpbb\textformatter\s9e\parser( + $cache, + $cache_key_parser, + $factory, + $dispatcher + ); + $container->set('text_formatter.parser', $parser); + $container->set('text_formatter.s9e.parser', $parser); + + // Create and register the text_formatter.s9e.renderer service and its alias + $renderer = new \phpbb\textformatter\s9e\renderer( + $cache, + $cache_dir, + $cache_key_renderer, + $factory, + $dispatcher + ); + + // Calls configured in services.yml + $auth = ($container->has('auth')) ? $container->get('auth') : new \phpbb\auth\auth; + $renderer->configure_quote_helper($quote_helper); + $renderer->configure_smilies_path($config, $path_helper); + $renderer->configure_user($user, $config, $auth); + + $container->set('text_formatter.renderer', $renderer); + $container->set('text_formatter.s9e.renderer', $renderer); + + // Create and register the text_formatter.s9e.utils service and its alias + $utils = new \phpbb\textformatter\s9e\utils; + $container->set('text_formatter.utils', $utils); + $container->set('text_formatter.s9e.utils', $utils); + + return $container; + } + + /** + * Mocked replacement for \phpbb\user::format_date() + * + * @param integer $gmepoch unix timestamp + * @return string + */ + static public function format_date($gmepoch) + { + return gmdate('Y-m-d H:i:s', $gmepoch); + } } diff --git a/tests/test_framework/phpbb_ui_test_case.php b/tests/test_framework/phpbb_ui_test_case.php index e8b230ecbe..48e510abe3 100644 --- a/tests/test_framework/phpbb_ui_test_case.php +++ b/tests/test_framework/phpbb_ui_test_case.php @@ -11,12 +11,13 @@ * */ +use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\WebDriverBy; use Facebook\WebDriver\Exception\WebDriverCurlException; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\DesiredCapabilities; -require_once __DIR__ . '/../../phpBB/includes/functions_install.php'; +require_once __DIR__ . '/mock/phpbb_mock_null_installer_task.php'; class phpbb_ui_test_case extends phpbb_test_case { @@ -32,7 +33,6 @@ class phpbb_ui_test_case extends phpbb_test_case static protected $root_url; static protected $already_installed = false; static protected $install_success = false; - protected $cache = null; protected $db = null; protected $extension_manager = null; @@ -79,14 +79,18 @@ class phpbb_ui_test_case extends phpbb_test_case self::markTestSkipped('phpbb_functional_url was not set in test_config and wasn\'t set as PHPBB_FUNCTIONAL_URL environment variable either.'); } - if (!self::$webDriver) - { - try { - $capabilities = DesiredCapabilities::firefox(); - self::$webDriver = RemoteWebDriver::create(self::$host . ':' . self::$port, $capabilities); - } catch (WebDriverCurlException $e) { - self::markTestSkipped('PhantomJS webserver is not running.'); - } + try { + $capabilities = DesiredCapabilities::chrome(); + $chromeOptions = (new ChromeOptions)->addArguments(['headless', 'disable-gpu']); + $capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); + self::$webDriver = RemoteWebDriver::create( + self::$host . ':' . self::$port, + $capabilities, + 30 * 1000, // 30 seconds connection timeout + 30 * 1000 // 30 seconds request timeout + ); + } catch (WebDriverCurlException $e) { + self::markTestSkipped('PhantomJS webserver is not running.'); } if (!self::$already_installed) @@ -147,9 +151,33 @@ class phpbb_ui_test_case extends phpbb_test_case } } - static public function visit($path) + public function getDriver() { - self::$webDriver->get(self::$root_url . $path); + return self::$webDriver; + } + + public function visit($path) + { + // Retry three times on curl issues, e.g. timeout + $attempts = 0; + $retries = 3; + + while (true) + { + $attempts++; + try + { + $this->getDriver()->get(self::$root_url . $path); + break; + } + catch (Facebook\WebDriver\Exception\WebDriverCurlException $exception) + { + if ($attempts >= $retries) + { + throw $exception; + } + } + } } static protected function recreate_database($config) @@ -158,14 +186,14 @@ class phpbb_ui_test_case extends phpbb_test_case $db_conn_mgr->recreate_db(); } - static public function find_element($type, $value) + public function find_element($type, $value) { - return self::$webDriver->findElement(WebDriverBy::$type($value)); + return $this->getDriver()->findElement(WebDriverBy::$type($value)); } - static public function submit($type = 'id', $value = 'submit') + public function submit($type = 'id', $value = 'submit') { - $element = self::find_element($type, $value); + $element = $this->find_element($type, $value); $element->click(); } @@ -191,90 +219,121 @@ class phpbb_ui_test_case extends phpbb_test_case } } + $install_config_file = $phpbb_root_path . 'store/install_config.php'; + + if (file_exists($install_config_file)) + { + unlink($install_config_file); + } + + $container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); + $container = $container_builder + ->with_environment('installer') + ->without_extensions() + ->without_cache() + ->with_custom_parameters([ + 'core.disable_super_globals' => false, + 'installer.create_config_file.options' => [ + 'debug' => true, + 'environment' => 'test', + ], + 'cache.driver.class' => 'phpbb\cache\driver\file' + ]) + ->with_config(new \phpbb\config_php_file($phpbb_root_path, $phpEx)) + ->without_compiled_container() + ->get_container(); + + $container->register('installer.install_finish.notify_user')->setSynthetic(true); + $container->set('installer.install_finish.notify_user', new phpbb_mock_null_installer_task()); + $container->register('installer.install_finish.install_extensions')->setSynthetic(true); + $container->set('installer.install_finish.install_extensions', new phpbb_mock_null_installer_task()); + $container->compile(); + + $language = $container->get('language'); + $language->add_lang(array('common', 'acp/common', 'acp/board', 'install', 'posting')); + + $iohandler_factory = $container->get('installer.helper.iohandler_factory'); + $iohandler_factory->set_environment('cli'); + $iohandler = $iohandler_factory->get(); + $parseURL = parse_url(self::$config['phpbb_functional_url']); - self::visit('install/index.php?mode=install&language=en'); - self::assertContains('Welcome to Installation', self::find_element('id', 'main')->getText()); - - // install/index.php?mode=install&sub=requirements - self::submit(); - self::assertContains('Installation compatibility', self::find_element('id', 'main')->getText()); - - // install/index.php?mode=install&sub=database - self::submit(); - self::assertContains('Database configuration', self::find_element('id', 'main')->getText()); - - self::find_element('id','dbms')->sendKeys(str_replace('phpbb\db\driver\\', '', self::$config['dbms'])); - self::find_element('id','dbhost')->sendKeys(self::$config['dbhost']); - self::find_element('id','dbport')->sendKeys(self::$config['dbport']); - self::find_element('id','dbname')->sendKeys(self::$config['dbname']); - self::find_element('id','dbuser')->sendKeys(self::$config['dbuser']); - self::find_element('id','dbpasswd')->sendKeys(self::$config['dbpasswd']); - - // Need to clear default phpbb_ prefix - self::find_element('id','table_prefix')->clear(); - self::find_element('id','table_prefix')->sendKeys(self::$config['table_prefix']); - - // install/index.php?mode=install&sub=database - self::submit(); - self::assertContains('Successful connection', self::find_element('id','main')->getText()); - - // install/index.php?mode=install&sub=administrator - self::submit(); - self::assertContains('Administrator configuration', self::find_element('id','main')->getText()); - - self::find_element('id','admin_name')->sendKeys('admin'); - self::find_element('id','admin_pass1')->sendKeys('adminadmin'); - self::find_element('id','admin_pass2')->sendKeys('adminadmin'); - self::find_element('id','board_email')->sendKeys('nobody@example.com'); - - // install/index.php?mode=install&sub=administrator - self::submit(); - self::assertContains('Tests passed', self::find_element('id','main')->getText()); - - // install/index.php?mode=install&sub=config_file - self::submit(); - - // Installer has created a config.php file, we will overwrite it with a - // config file of our own in order to get the DEBUG constants defined - $config_php_data = phpbb_create_config_file_data(self::$config, self::$config['dbms'], true, false, true); - $config_created = file_put_contents($config_file, $config_php_data) !== false; - if (!$config_created) + $output = new \Symfony\Component\Console\Output\NullOutput(); + $style = new \Symfony\Component\Console\Style\SymfonyStyle( + new \Symfony\Component\Console\Input\ArrayInput(array()), + $output + ); + $iohandler->set_style($style, $output); + + $installer = $container->get('installer.installer.install'); + $installer->set_iohandler($iohandler); + + // Set data + $iohandler->set_input('admin_name', 'admin'); + $iohandler->set_input('admin_pass1', 'adminadmin'); + $iohandler->set_input('admin_pass2', 'adminadmin'); + $iohandler->set_input('board_email', 'nobody@example.com'); + $iohandler->set_input('submit_admin', 'submit'); + + $iohandler->set_input('default_lang', 'en'); + $iohandler->set_input('board_name', 'yourdomain.com'); + $iohandler->set_input('board_description', 'A short text to describe your forum'); + $iohandler->set_input('submit_board', 'submit'); + + $iohandler->set_input('dbms', str_replace('phpbb\db\driver\\', '', self::$config['dbms'])); + $iohandler->set_input('dbhost', self::$config['dbhost']); + $iohandler->set_input('dbport', self::$config['dbport']); + $iohandler->set_input('dbuser', self::$config['dbuser']); + $iohandler->set_input('dbpasswd', self::$config['dbpasswd']); + $iohandler->set_input('dbname', self::$config['dbname']); + $iohandler->set_input('table_prefix', self::$config['table_prefix']); + $iohandler->set_input('submit_database', 'submit'); + + $iohandler->set_input('email_enable', true); + $iohandler->set_input('smtp_delivery', '1'); + $iohandler->set_input('smtp_host', 'nxdomain.phpbb.com'); + $iohandler->set_input('smtp_auth', 'PLAIN'); + $iohandler->set_input('smtp_user', 'nxuser'); + $iohandler->set_input('smtp_pass', 'nxpass'); + $iohandler->set_input('submit_email', 'submit'); + + $iohandler->set_input('cookie_secure', '0'); + $iohandler->set_input('server_protocol', '0'); + $iohandler->set_input('force_server_vars', $parseURL['scheme'] . '://'); + $iohandler->set_input('server_name', $parseURL['host']); + $iohandler->set_input('server_port', isset($parseURL['port']) ? (int) $parseURL['port'] : 80); + $iohandler->set_input('script_path', $parseURL['path']); + $iohandler->set_input('submit_server', 'submit'); + + $installer->run(); + + copy($config_file, $config_file_test); + + self::$install_success = true; + + if (file_exists($phpbb_root_path . 'store/install_config.php')) { - self::markTestSkipped("Could not write $config_file file."); + self::$install_success = false; + @unlink($phpbb_root_path . 'store/install_config.php'); } - if (strpos(self::find_element('id','main')->getText(), 'The configuration file has been written') === false) + if (file_exists($phpbb_root_path . 'cache/install_lock')) { - self::submit('id', 'dldone'); + @unlink($phpbb_root_path . 'cache/install_lock'); } - self::assertContains('The configuration file has been written', self::find_element('id','main')->getText()); - - // install/index.php?mode=install&sub=advanced - self::submit(); - self::assertContains('The settings on this page are only necessary to set if you know that you require something different from the default.', self::find_element('id','main')->getText()); - - self::find_element('id','smtp_delivery')->sendKeys('1'); - self::find_element('id','smtp_host')->sendKeys('nxdomain.phpbb.com'); - self::find_element('id','smtp_user')->sendKeys('nxuser'); - self::find_element('id','smtp_pass')->sendKeys('nxpass'); - self::find_element('id','server_protocol')->sendKeys($parseURL['scheme'] . '://'); - self::find_element('id','server_name')->sendKeys('localhost'); - self::find_element('id','server_port')->sendKeys(isset($parseURL['port']) ? $parseURL['port'] : 80); - self::find_element('id','script_path')->sendKeys($parseURL['path']); - - // install/index.php?mode=install&sub=create_table - self::submit(); - self::assertContains('The database tables used by phpBB', self::find_element('id','main')->getText()); - self::assertContains('have been created and populated with some initial data.', self::find_element('id','main')->getText()); - - // install/index.php?mode=install&sub=final - self::submit(); - self::assertContains('You have successfully installed', self::find_element('id', 'main')->getText()); - copy($config_file, $config_file_test); + global $phpbb_container; + $phpbb_container->reset(); - self::$install_success = true; + $blacklist = ['phpbb_class_loader_mock', 'phpbb_class_loader_ext', 'phpbb_class_loader']; + + foreach (array_keys($GLOBALS) as $key) + { + if (is_object($GLOBALS[$key]) && !in_array($key, $blacklist, true)) + { + unset($GLOBALS[$key]); + } + } } public function install_ext($extension) @@ -285,21 +344,21 @@ class phpbb_ui_test_case extends phpbb_test_case $ext_path = str_replace('/', '%2F', $extension); $this->visit('adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=' . $ext_path . '&sid=' . $this->sid); - $this->assertNotEmpty(count(self::find_element('cssSelector', '.submit-buttons'))); + $this->assertNotEmpty(count($this->find_element('cssSelector', '.submit-buttons'))); - self::find_element('cssSelector', "input[value='Enable']")->submit(); + $this->find_element('cssSelector', "input[value='Enable']")->submit(); $this->add_lang('acp/extensions'); try { - $meta_refresh = self::find_element('cssSelector', 'meta[http-equiv="refresh"]'); + $meta_refresh = $this->find_element('cssSelector', 'meta[http-equiv="refresh"]'); // Wait for extension to be fully enabled - while (sizeof($meta_refresh)) + while (count($meta_refresh)) { preg_match('#url=.+/(adm+.+)#', $meta_refresh->getAttribute('content'), $match); - self::$webDriver->execute(array('method' => 'post', 'url' => $match[1])); - $meta_refresh = self::find_element('cssSelector', 'meta[http-equiv="refresh"]'); + $this->getDriver()->execute(array('method' => 'post', 'url' => $match[1])); + $meta_refresh = $this->find_element('cssSelector', 'meta[http-equiv="refresh"]'); } } catch (\Facebook\WebDriver\Exception\NoSuchElementException $e) @@ -307,7 +366,7 @@ class phpbb_ui_test_case extends phpbb_test_case // Probably no refresh triggered } - $this->assertContainsLang('EXTENSION_ENABLE_SUCCESS', self::find_element('cssSelector', 'div.successbox')->getText()); + $this->assertContainsLang('EXTENSION_ENABLE_SUCCESS', $this->find_element('cssSelector', 'div.successbox')->getText()); $this->logout(); } @@ -316,6 +375,12 @@ class phpbb_ui_test_case extends phpbb_test_case { if (!$this->cache) { + global $phpbb_container, $phpbb_root_path; + + $phpbb_container = new phpbb_mock_container_builder(); + $phpbb_container->setParameter('core.environment', PHPBB_ENVIRONMENT); + $phpbb_container->setParameter('core.cache_dir', $phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT . '/'); + $this->cache = new \phpbb\cache\driver\file; } @@ -395,7 +460,7 @@ class phpbb_ui_test_case extends phpbb_test_case } $this->visit('ucp.php?sid=' . $this->sid . '&mode=logout'); - $this->assertContains($this->lang('REGISTER'), self::$webDriver->getPageSource()); + $this->assertContains($this->lang('REGISTER'), $this->getDriver()->getPageSource()); unset($this->sid); } @@ -415,17 +480,17 @@ class phpbb_ui_test_case extends phpbb_test_case return; } - self::$webDriver->manage()->deleteAllCookies(); + $this->getDriver()->manage()->deleteAllCookies(); $this->visit('adm/index.php?sid=' . $this->sid); - $this->assertContains($this->lang('LOGIN_ADMIN_CONFIRM'), self::$webDriver->getPageSource()); + $this->assertContains($this->lang('LOGIN_ADMIN_CONFIRM'), $this->getDriver()->getPageSource()); - self::find_element('cssSelector', 'input[name=username]')->clear()->sendKeys($username); - self::find_element('cssSelector', 'input[type=password]')->sendKeys($username . $username); - self::find_element('cssSelector', 'input[name=login]')->click(); + $this->find_element('cssSelector', 'input[name=username]')->clear()->sendKeys($username); + $this->find_element('cssSelector', 'input[type=password]')->sendKeys($username . $username); + $this->find_element('cssSelector', 'input[name=login]')->click(); $this->assertContains($this->lang('ADMIN_PANEL'), $this->find_element('cssSelector', 'h1')->getText()); - $cookies = self::$webDriver->manage()->getCookies(); + $cookies = $this->getDriver()->manage()->getCookies(); // The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie foreach ($cookies as $cookie) @@ -530,19 +595,19 @@ class phpbb_ui_test_case extends phpbb_test_case { $this->add_lang('ucp'); - self::$webDriver->manage()->deleteAllCookies(); + $this->getDriver()->manage()->deleteAllCookies(); $this->visit('ucp.php'); - $this->assertContains($this->lang('LOGIN_EXPLAIN_UCP'), self::$webDriver->getPageSource()); + $this->assertContains($this->lang('LOGIN_EXPLAIN_UCP'), $this->getDriver()->getPageSource()); - self::$webDriver->manage()->deleteAllCookies(); + $this->getDriver()->manage()->deleteAllCookies(); - self::find_element('cssSelector', 'input[name=username]')->sendKeys($username); - self::find_element('cssSelector', 'input[name=password]')->sendKeys($username . $username); - self::find_element('cssSelector', 'input[name=login]')->click(); + $this->find_element('cssSelector', 'input[name=username]')->sendKeys($username); + $this->find_element('cssSelector', 'input[name=password]')->sendKeys($username . $username); + $this->find_element('cssSelector', 'input[name=login]')->click(); $this->assertNotContains($this->lang('LOGIN'), $this->find_element('className', 'navbar')->getText()); - $cookies = self::$webDriver->manage()->getCookies(); + $cookies = $this->getDriver()->manage()->getCookies(); // The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie foreach ($cookies as $cookie) @@ -566,6 +631,39 @@ class phpbb_ui_test_case extends phpbb_test_case // Change the Path to your own settings $screenshot = time() . ".png"; - self::$webDriver->takeScreenshot($screenshot); + $this->getDriver()->takeScreenshot($screenshot); + } + + /** + * Wait for AJAX. Should be called after an AJAX action is made. + * + * @param string $framework javascript frameworks jquery|prototype|dojo + * @throws \Facebook\WebDriver\Exception\NoSuchElementException + * @throws \Facebook\WebDriver\Exception\TimeOutException + */ + public function waitForAjax($framework = 'jquery') + { + switch ($framework) + { + case 'jquery': + $code = 'return jQuery.active;'; + break; + case 'prototype': + $code = 'return Ajax.activeRequestCount;'; + break; + case 'dojo': + $code = 'return dojo.io.XMLHTTPTransport.inFlight.length;'; + break; + default: + throw new \RuntimeException('Unsupported framework'); + break; + } + // wait for at most 30s, retry every 2000ms (2s) + $driver = $this->getDriver(); + $driver->wait(30, 2000)->until( + function () use ($driver, $code) { + return !$driver->executeScript($code); + } + ); } } |