1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-04-16 13:52:03 +02:00

Merge branch 'develop-olympus' of https://github.com/phpbb/phpbb3 into ticket/11548

This commit is contained in:
Marc Alexander 2013-07-11 17:30:32 -04:00
commit dc4687501a
53 changed files with 2209 additions and 311 deletions

View File

@ -33,9 +33,7 @@ else
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
error=0
errors=""
if ! which "$PHP_BIN" >/dev/null 2>&1
then
echo "PHP Syntax check failed:"
@ -73,63 +71,18 @@ do
# check the staged file content for syntax errors
# using php -l (lint)
# note: if display_errors=stderr in php.ini,
# parse errors are printed on stderr; otherwise
# they are printed on stdout.
# we filter everything other than parse errors
# with a grep below, therefore it should be safe
# to combine stdout and stderr in all circumstances
result=$(git cat-file -p $sha | "$PHP_BIN" -l 2>&1)
result=$(git cat-file -p $sha | "$PHP_BIN" -n -l -ddisplay_errors\=1 -derror_reporting\=E_ALL -dlog_errrors\=0 2>&1)
if [ $? -ne 0 ]
then
error=1
# Swap back in correct filenames
errors=$(echo "$errors"; echo "$result" |sed -e "s@in - on@in $filename on@g")
errors=$(echo "$errors"; echo "$result" | grep ':' | sed -e "s@in - on@in $filename on@g")
fi
done
unset IFS
if [ $error -eq 1 ]
if [ -n "$errors" ]
then
echo "PHP Syntax check failed:"
# php "display errors" (display_errors php.ini value)
# and "log errors" (log_errors php.ini value).
# these are independent settings - see main/main.c in php source.
# the "log errors" setting produces output which
# starts with "PHP Parse error:"; the "display errors"
# setting produces output starting with "Parse error:".
# if both are turned on php dumps the parse error twice.
# therefore here we try to grep for one version and
# if that yields no results grep for the other version.
#
# other fun php facts:
#
# 1. in cli, display_errors and log_errors have different
# destinations by default. display_errors prints to
# standard output and log_errors prints to standard error.
# whether these destinations make sense is left
# as an exercise for the reader.
# 2. as mentioned above, with all output turned on
# php will print parse errors twice, one time on stdout
# and one time on stderr.
# 3. it is possible to set both display_errors and log_errors
# to off. if this is done php will print the text
# "Errors parsing <file>" but will not say what
# the errors are. useful behavior, this.
# 4. on my system display_errors defaults to on and
# log_errors defaults to off, therefore providing
# by default one copy of messages. your mileage may vary.
# 5. by setting display_errors=stderr and log_errors=on,
# both sets of messages will be printed on stderr.
# 6. php-cgi binary, given display_errors=stderr and
# log_errors=on, still prints both sets of messages
# on stderr, but formats one set as an html fragment.
# 7. your entry here? ;)
$echo_e "$errors" | grep "^Parse error:"
if [ $? -ne 0 ]
then
# match failed
$echo_e "$errors" | grep "^PHP Parse error:"
fi
echo "PHP Syntax check failed: "
$echo_e "$errors"
exit 1
fi

View File

@ -124,19 +124,34 @@ function get_repository_url($username, $repository, $ssh = false)
function api_request($query)
{
$contents = file_get_contents("http://github.com/api/v2/json/$query");
return api_url_request("https://api.github.com/$query?per_page=100");
}
function api_url_request($url)
{
$contents = file_get_contents($url, false, stream_context_create(array(
'http' => array(
'header' => "User-Agent: phpBB/1.0\r\n",
),
)));
if ($contents === false)
{
throw new RuntimeException("Error: failed to retrieve pull request data\n", 4);
}
$contents = json_decode($contents);
return json_decode($contents);
if (isset($contents->message) && strpos($contents->message, 'API Rate Limit') === 0)
{
throw new RuntimeException('Reached github API Rate Limit. Please try again later' . "\n", 4);
}
return $contents;
}
function get_pull($username, $repository, $pull_id)
{
$request = api_request("pulls/$username/$repository/$pull_id");
$request = api_request("repos/$username/$repository/pulls/$pull_id");
$pull = $request->pull;

View File

@ -15,14 +15,14 @@ function show_usage()
echo "$filename adds repositories of a github network as remotes to a local git repository.\n";
echo "\n";
echo "Usage: [php] $filename -s collaborators|organisation|contributors|network [OPTIONS]\n";
echo "Usage: [php] $filename -s collaborators|organisation|contributors|forks [OPTIONS]\n";
echo "\n";
echo "Scopes:\n";
echo " collaborators Repositories of people who have push access to the specified repository\n";
echo " contributors Repositories of people who have contributed to the specified repository\n";
echo " organisation Repositories of members of the organisation at github\n";
echo " network All repositories of the whole github network\n";
echo " forks All repositories of the whole github network\n";
echo "\n";
echo "Options:\n";
@ -55,31 +55,31 @@ exit(work($scope, $username, $repository, $developer));
function work($scope, $username, $repository, $developer)
{
// Get some basic data
$network = get_network($username, $repository);
$forks = get_forks($username, $repository);
$collaborators = get_collaborators($username, $repository);
if ($network === false || $collaborators === false)
if ($forks === false || $collaborators === false)
{
echo "Error: failed to retrieve network or collaborators\n";
echo "Error: failed to retrieve forks or collaborators\n";
return 1;
}
switch ($scope)
{
case 'collaborators':
$remotes = array_intersect_key($network, $collaborators);
$remotes = array_intersect_key($forks, $collaborators);
break;
case 'organisation':
$remotes = array_intersect_key($network, get_organisation_members($username));
$remotes = array_intersect_key($forks, get_organisation_members($username));
break;
case 'contributors':
$remotes = array_intersect_key($network, get_contributors($username, $repository));
$remotes = array_intersect_key($forks, get_contributors($username, $repository));
break;
case 'network':
$remotes = $network;
case 'forks':
$remotes = $forks;
break;
default:
@ -145,26 +145,66 @@ function get_repository_url($username, $repository, $ssh = false)
function api_request($query)
{
$contents = file_get_contents("http://github.com/api/v2/json/$query");
return api_url_request("https://api.github.com/$query?per_page=100");
}
function api_url_request($url)
{
$contents = file_get_contents($url, false, stream_context_create(array(
'http' => array(
'header' => "User-Agent: phpBB/1.0\r\n",
),
)));
$sub_request_result = array();
// Check headers for pagination links
if (!empty($http_response_header))
{
foreach ($http_response_header as $header_element)
{
// Find Link Header which gives us a link to the next page
if (strpos($header_element, 'Link: ') === 0)
{
list($head, $header_content) = explode(': ', $header_element);
foreach (explode(', ', $header_content) as $links)
{
list($url, $rel) = explode('; ', $links);
if ($rel == 'rel="next"')
{
// Found a next link, follow it and merge the results
$sub_request_result = api_url_request(substr($url, 1, -1));
}
}
}
}
}
if ($contents === false)
{
return false;
}
return json_decode($contents);
$contents = json_decode($contents);
if (isset($contents->message) && strpos($contents->message, 'API Rate Limit') === 0)
{
throw new RuntimeException('Reached github API Rate Limit. Please try again later' . "\n", 4);
}
return ($sub_request_result) ? array_merge($sub_request_result, $contents) : $contents;
}
function get_contributors($username, $repository)
{
$request = api_request("repos/show/$username/$repository/contributors");
$request = api_request("repos/$username/$repository/stats/contributors");
if ($request === false)
{
return false;
}
$usernames = array();
foreach ($request->contributors as $contributor)
foreach ($request as $contribution)
{
$usernames[$contributor->login] = $contributor->login;
$usernames[$contribution->author->login] = $contribution->author->login;
}
return $usernames;
@ -172,14 +212,14 @@ function get_contributors($username, $repository)
function get_organisation_members($username)
{
$request = api_request("organizations/$username/public_members");
$request = api_request("orgs/$username/public_members");
if ($request === false)
{
return false;
}
$usernames = array();
foreach ($request->users as $member)
foreach ($request as $member)
{
$usernames[$member->login] = $member->login;
}
@ -189,35 +229,35 @@ function get_organisation_members($username)
function get_collaborators($username, $repository)
{
$request = api_request("repos/show/$username/$repository/collaborators");
$request = api_request("repos/$username/$repository/collaborators");
if ($request === false)
{
return false;
}
$usernames = array();
foreach ($request->collaborators as $collaborator)
foreach ($request as $collaborator)
{
$usernames[$collaborator] = $collaborator;
$usernames[$collaborator->login] = $collaborator->login;
}
return $usernames;
}
function get_network($username, $repository)
function get_forks($username, $repository)
{
$request = api_request("repos/show/$username/$repository/network");
$request = api_request("repos/$username/$repository/forks");
if ($request === false)
{
return false;
}
$usernames = array();
foreach ($request->network as $network)
foreach ($request as $fork)
{
$usernames[$network->owner] = array(
'username' => $network->owner,
'repository' => $network->name,
$usernames[$fork->owner->login] = array(
'username' => $fork->owner->login,
'repository' => $fork->name,
);
}

View File

@ -24,10 +24,9 @@ phpBB Lead Developer: naderman (Nils Adermann)
phpBB Developers: bantu (Andreas Fischer)
EXreaction (Nathan Guse)
igorw (Igor Wiedler)
dhruv.goel92 (Dhruv Goel)
imkingdavid (David King)
nickvergessen (Joas Schilling)
Oleg (Oleg Pudeyev)
Contributions by: leviatan21 (Gabriel Vazquez)
Raimon (Raimon Meuldijk)
@ -53,6 +52,8 @@ phpBB Developers: A_Jelly_Doughnut (Josh Woody) [01/2010 - 11/2010]
dhn (Dominik Dröscher) [05/2007 - 01/2011]
GrahamJE (Graham Eames) [09/2005 - 11/2006]
kellanved (Henry Sudhof) [04/2007 - 03/2011]
igorw (Igor Wiedler) [08/2010 - 02/2013]
Oleg (Oleg Pudeyev) [01/2011 - 05/2013]
rxu (Ruslan Uzdenov) [04/2010 - 12/2012]
TerraFrost (Jim Wigginton) [04/2009 - 01/2011]
ToonArmy (Chris Smith) [06/2008 - 11/2011]

View File

@ -41,7 +41,7 @@
<!-- BEGIN DOCUMENT -->
<p>Thank you for downloading phpBB3. This README will guide through the basics of installation and operation of phpBB3. Please ensure you read this and the accompanying documentation fully <strong>before</strong> proceeding with the installation.</p>
<p>Thank you for downloading phpBB3. This README will guide you through the basics of installation and operation of phpBB3. Please ensure you read this and the accompanying documentation fully <strong>before</strong> proceeding with the installation.</p>
<h1>Readme</h1>
@ -68,7 +68,7 @@
</ol>
</li>
<li><a href="#status">Status of this version</a></li>
<li><a href="#bugs">Reporting Bugs</a>
<li><a href="#bugs">Reporting bugs</a>
<ol style="list-style-type: lower-roman;">
<li><a href="#securitybugs">Security related bugs</a></li>
</ol>
@ -92,11 +92,11 @@
<div class="content">
<p>Installation, update and conversion instructions can be found in the <a href="INSTALL.html">INSTALL</a> document contained in this distribution. If you are intending to convert from a previous phpBB 2.0.x installation we highly recommend you backup any existing data before proceeding!</p>
<p>Installation, update and conversion instructions can be found in the <a href="INSTALL.html">INSTALL</a> document in this directory. If you are intending on converting from a phpBB 2.0.x installation we highly recommend that you backup any existing data before proceeding!</p>
<p>Users of phpBB3 Beta versions cannot directly update.</p>
<p>Please note that we won't support the following installation types:</p>
<p>Please note that we don't support the following installation types:</p>
<ul>
<li>Updates from phpBB3 Beta versions to phpBB3 RC1 and higher</li>
<li>Conversions from phpBB 2.0.x to phpBB3 Beta versions</li>
@ -109,7 +109,7 @@
<li>Updates from phpBB3 RC1 to the latest version</li>
<li>Note: if using the <em>Automatic Update Package</em>, updates are supported from phpBB 3.0.2 onward. To update a pre-3.0.2 installation, first update to 3.0.2 and then update to the current version.</li>
<li>Conversions from phpBB 2.0.x to the latest version</li>
<li>New installations of phpBB3 - always only the latest released version</li>
<li>New installations of phpBB3 - only the latest released version</li>
</ul>
</div>
@ -136,7 +136,7 @@
<p>For more information about language packs, please see: <a href="http://www.phpbb.com/languages/">http://www.phpbb.com/languages/</a></p>
<p>This is the <em>official</em> location for all supported language sets. If you download a package from a 3rd party site you do so with the understanding that we cannot offer support. So please, do not ask for help in these cases!</p>
<p>This is the <em>official</em> location for all supported language sets. If you download a package from a 3rd party site you do so with the understanding that we cannot offer support. Please do not ask for support if you download a language pack from a 3rd party site.</p>
<p>Installation of these packages is straightforward: simply download the required language pack, uncompress (unzip) it and via FTP transfer the included <code>language</code> and <code>styles</code> folders to the root of your board installation. The language can then be installed via the Administration Control Panel of your board: <code>System tab -&gt; General Tasks -&gt; Language packs</code>. A more detailed description of the process is in the Knowledge Base article, <a href="http://www.phpbb.com/kb/article/how-to-install-a-language-pack/">How to Install a Language Pack</a>.</p>
@ -180,15 +180,15 @@
<div class="content">
<p>phpBB3 can seem a little daunting to new users in places, particularly with regard the permission system. The first thing you should do is check the <a href="FAQ.html">FAQ</a> which covers a few basic getting started questions. If you need additional help there are several places you should look.</p>
<p>phpBB3 can sometimes seem a little daunting to new users, particularly with regards to the permission system. The first thing you should do is check the <a href="FAQ.html">FAQ</a>, which covers a few basic getting started questions. If you need additional help there are several places you can find it.</p>
<a name="docs"></a><h3>3.i. phpBB3 Documentation</h3>
<p>A comprehensive documentation is now available online and can be accessed from the following location:</p>
<p>Comprehensive documentation is now available on the phpBB website:</p>
<p><a href="http://www.phpbb.com/support/documentation/3.0/">http://www.phpbb.com/support/documentation/3.0/</a></p>
<p>This covers everything from installation through setting permissions and managing users.</p>
<p>This covers everything from installation to setting permissions and managing users.</p>
<a name="kb"></a><h3>3.ii. Knowledge Base</h3>
@ -202,7 +202,7 @@
<p><a href="http://www.phpbb.com/community/">http://www.phpbb.com/community/</a></p>
<p>If you do seek help via our forums please be sure to do a Search before posting. This may well save both you and us time and allow the developer, moderator and support groups to spend more time responding to people with unknown issues and problems. Please also remember that phpBB is an entirely volunteer effort, no one receives any compensation for the time they give, this includes moderators as well as developers. So please be respectful and mindful when awaiting responses.</p>
<p>If you do seek help via our forums please be sure to do a search before posting; if someone has experienced the issue before, then you may find that your question has already been answered. Please remember that phpBB is entirely staffed by volunteers, no one receives any compensation for the time they give, including moderators as well as developers; please be respectful and mindful when awaiting responses and receiving support.</p>
<a name="irc"></a><h3>3.iv Internet Relay Chat</h3>
@ -273,7 +273,7 @@
<p>The relevant database type/version is listed within the administration control panel.</p>
<p>Please also be as detailed as you can in your report, if possible list the steps required to duplicate the problem. If you have a patch that fixes the issue, please attach it to the ticket or submit a pull request <a href="https://github.com/phpbb/phpbb3">on GitHub</a>.</p>
<p>Please be as detailed as you can in your report, and if possible, list the steps required to duplicate the problem. If you have a patch that fixes the issue, please attach it to the ticket or submit a pull request to our repository <a href="https://github.com/phpbb/phpbb3">on GitHub</a>.</p>
<p>If you create a patch, it is very much appreciated (but not required) if you follow the phpBB coding guidelines. Please note that the coding guidelines are somewhat different between different versions of phpBB. For phpBB 3.0.x the coding guidelines may be found here: <a href="http://area51.phpbb.com/docs/30x/coding-guidelines.html">http://area51.phpbb.com/docs/30x/coding-guidelines.html</a></p>
@ -304,8 +304,8 @@
<p>This list is not complete but does represent those bugs which may affect users on a wider scale. Other bugs listed in the tracker have typically been shown to be limited to certain setups or methods of installation, updating and/or conversions.</p>
<ul>
<li>Conversions may fail to complete on large boards under some hosts</li>
<li>Updates may fail to complete on large update sets under some hosts</li>
<li>Conversions may fail to complete on large boards under some hosts.</li>
<li>Updates may fail to complete on large update sets under some hosts.</li>
<li>Smilies placed directly after bbcode tags will not get parsed. Smilies always need to be separated by spaces.</li>
</ul>
@ -325,9 +325,9 @@
<div class="content">
<p>phpBB is no longer supported on PHP3 due to several compatibility issues and we recommend that you upgrade to the latest stable release of PHP5 to run phpBB. The minimum version required is PHP 4.3.3.</p>
<p>phpBB is no longer supported on PHP3 due to several compatibility issues and we recommend that you upgrade to the latest stable release of PHP5 to run phpBB. The minimum version required is PHP 4.3.3. The minimum version that will be required for phpBB 3.1 is PHP 5.3.3.</p>
<p>Please remember that running any application on a developmental version of PHP can lead to strange/unexpected results which may appear to be bugs in the application (which may not be true). Therefore we recommend you upgrade to the newest stable version of PHP before running phpBB3. If you are running a developmental version of PHP please check any bugs you find on a system running a stable release before submitting.</p>
<p>Please remember that running any application on a development (unstable, e.g. a beta release) version of PHP can lead to strange/unexpected results which may appear to be bugs in the application. Therefore, we recommend you upgrade to the newest stable version of PHP before running phpBB3. If you are running a development version of PHP please check any bugs you find on a system running a stable release before submitting.</p>
<p>This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MSSQL Server 2000, PostgreSQL 7.x, Oracle 8, SQLite 2 and Firebird. Versions of PHP used range from 4.3.3 to 5.4.x without problem. </p>

View File

@ -285,7 +285,7 @@ else if (($display_cat == ATTACHMENT_CATEGORY_NONE/* || $display_cat == ATTACHME
$db->sql_query($sql);
}
if ($display_cat == ATTACHMENT_CATEGORY_IMAGE && $mode === 'view' && (strpos($attachment['mimetype'], 'image') === 0) && ((strpos(strtolower($user->browser), 'msie') !== false) && (strpos(strtolower($user->browser), 'msie 8.0') === false)))
if ($display_cat == ATTACHMENT_CATEGORY_IMAGE && $mode === 'view' && (strpos($attachment['mimetype'], 'image') === 0) && (strpos(strtolower($browser), 'msie') !== false) && !phpbb_is_greater_ie_version($user->browser, 7))
{
wrap_img_in_html(append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'id=' . $attachment['attach_id']), $attachment['real_filename']);
file_gc();
@ -343,8 +343,8 @@ function send_avatar_to_browser($file, $browser)
$image_data = @getimagesize($file_path);
header('Content-Type: ' . image_type_to_mime_type($image_data[2]));
if (strpos(strtolower($browser), 'msie') !== false && strpos(strtolower($browser), 'msie 8.0') === false)
if ((strpos(strtolower($browser), 'msie') !== false) && !phpbb_is_greater_ie_version($browser, 7))
{
header('Content-Disposition: attachment; ' . header_filename($file));
@ -477,10 +477,9 @@ function send_file_to_browser($attachment, $upload_dir, $category)
*/
// Send out the Headers. Do not set Content-Disposition to inline please, it is a security measure for users using the Internet Explorer.
$is_ie8 = (strpos(strtolower($user->browser), 'msie 8.0') !== false);
header('Content-Type: ' . $attachment['mimetype']);
if ($is_ie8)
if (phpbb_is_greater_ie_version($user->browser, 7))
{
header('X-Content-Type-Options: nosniff');
}
@ -492,7 +491,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)
}
else
{
if (empty($user->browser) || (!$is_ie8 && (strpos(strtolower($user->browser), 'msie') !== false)))
if (empty($user->browser) || ((strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($user->browser, 7)))
{
header('Content-Disposition: attachment; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
if (empty($user->browser) || (strpos(strtolower($user->browser), 'msie 6.0') !== false))
@ -503,7 +502,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)
else
{
header('Content-Disposition: ' . ((strpos($attachment['mimetype'], 'image') === 0) ? 'inline' : 'attachment') . '; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
if ($is_ie8 && (strpos($attachment['mimetype'], 'image') !== 0))
if (phpbb_is_greater_ie_version($user->browser, 7) && (strpos($attachment['mimetype'], 'image') !== 0))
{
header('X-Download-Options: noopen');
}
@ -680,7 +679,8 @@ function set_modified_headers($stamp, $browser)
{
// let's see if we have to send the file at all
$last_load = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime(trim($_SERVER['HTTP_IF_MODIFIED_SINCE'])) : false;
if ((strpos(strtolower($browser), 'msie 6.0') === false) && (strpos(strtolower($browser), 'msie 8.0') === false))
if (strpos(strtolower($browser), 'msie 6.0') === false && !phpbb_is_greater_ie_version($browser, 7))
{
if ($last_load !== false && $last_load >= $stamp)
{
@ -709,4 +709,25 @@ function file_gc()
exit;
}
/**
* Check if the browser is internet explorer version 7+
*
* @param string $user_agent User agent HTTP header
* @param int $version IE version to check against
*
* @return bool true if internet explorer version is greater than $version
*/
function phpbb_is_greater_ie_version($user_agent, $version)
{
if (preg_match('/msie (\d+)/', strtolower($user_agent), $matches))
{
$ie_version = (int) $matches[1];
return ($ie_version > $version);
}
else
{
return false;
}
}
?>

View File

@ -113,8 +113,8 @@ class acp_bbcodes
{
$template->assign_block_vars('token', array(
'TOKEN' => '{' . $token . '}',
'EXPLAIN' => $token_explain)
);
'EXPLAIN' => ($token === 'LOCAL_URL') ? sprintf($token_explain, generate_board_url() . '/') : $token_explain,
));
}
return;
@ -345,6 +345,9 @@ class acp_bbcodes
'LOCAL_URL' => array(
'!(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')!e' => "\$this->bbcode_specialchars('$1')"
),
'RELATIVE_URL' => array(
'!(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')!e' => "\$this->bbcode_specialchars('$1')"
),
'EMAIL' => array(
'!(' . get_preg_expression('email') . ')!ie' => "\$this->bbcode_specialchars('$1')"
),
@ -371,6 +374,7 @@ class acp_bbcodes
$sp_tokens = array(
'URL' => '(?i)((?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('url')) . ')|(?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('www_url')) . '))(?-i)',
'LOCAL_URL' => '(?i)(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')(?-i)',
'RELATIVE_URL' => '(?i)(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')(?-i)',
'EMAIL' => '(' . get_preg_expression('email') . ')',
'TEXT' => '(.*?)',
'SIMPLETEXT' => '([a-zA-Z0-9-+.,_ ]+)',
@ -427,7 +431,11 @@ class acp_bbcodes
$fp_replace = str_replace($token, $replace, $fp_replace);
$sp_match = str_replace(preg_quote($token, '!'), $sp_tokens[$token_type], $sp_match);
$sp_replace = str_replace($token, '${' . ($n + 1) . '}', $sp_replace);
// Prepend the board url to local relative links
$replace_prepend = ($token_type === 'LOCAL_URL') ? generate_board_url() . '/' : '';
$sp_replace = str_replace($token, $replace_prepend . '${' . ($n + 1) . '}', $sp_replace);
}
$fp_match = '!' . $fp_match . '!' . $modifiers;

View File

@ -124,6 +124,8 @@ class acp_captcha
'CAPTCHA_PREVIEW_TPL' => $demo_captcha->get_demo_template($id),
'S_CAPTCHA_HAS_CONFIG' => $demo_captcha->has_config(),
'CAPTCHA_SELECT' => $captcha_select,
'U_ACTION' => $this->u_action,
));
}
}

View File

@ -80,6 +80,11 @@ class acp_groups
case 'approve':
case 'demote':
case 'promote':
if (!check_form_key($form_key))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (!$group_id)
{
trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING);
@ -252,6 +257,11 @@ class acp_groups
break;
case 'addusers':
if (!check_form_key($form_key))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (!$group_id)
{
trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING);

View File

@ -157,6 +157,7 @@ define('PHYSICAL_LINK', 2);
define('CONFIRM_REG', 1);
define('CONFIRM_LOGIN', 2);
define('CONFIRM_POST', 3);
define('CONFIRM_REPORT', 4);
// Categories - Attachments
define('ATTACHMENT_CATEGORY_NONE', 0);

View File

@ -3121,7 +3121,7 @@ function get_remote_file($host, $directory, $filename, &$errstr, &$errno, $port
if ($fsock = @fsockopen($host, $port, $errno, $errstr, $timeout))
{
@fputs($fsock, "GET $directory/$filename HTTP/1.1\r\n");
@fputs($fsock, "GET $directory/$filename HTTP/1.0\r\n");
@fputs($fsock, "HOST: $host\r\n");
@fputs($fsock, "Connection: close\r\n\r\n");

View File

@ -423,16 +423,6 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
$cat_id = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] : ATTACHMENT_CATEGORY_NONE;
// Make sure the image category only holds valid images...
if ($cat_id == ATTACHMENT_CATEGORY_IMAGE && !$file->is_image())
{
$file->remove();
// If this error occurs a user tried to exploit an IE Bug by renaming extensions
// Since the image category is displaying content inline we need to catch this.
trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
}
// Do we have to create a thumbnail?
$filedata['thumbnail'] = ($cat_id == ATTACHMENT_CATEGORY_IMAGE && $config['img_create_thumbnail']) ? 1 : 0;
@ -473,6 +463,16 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
return $filedata;
}
// Make sure the image category only holds valid images...
if ($cat_id == ATTACHMENT_CATEGORY_IMAGE && !$file->is_image())
{
$file->remove();
// If this error occurs a user tried to exploit an IE Bug by renaming extensions
// Since the image category is displaying content inline we need to catch this.
trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
}
$filedata['filesize'] = $file->get('filesize');
$filedata['mimetype'] = $file->get('mimetype');
$filedata['extension'] = $file->get('extension');

View File

@ -1554,7 +1554,7 @@ function validate_username($username, $allowed_username = false)
*/
function validate_password($password)
{
global $config, $db, $user;
global $config;
if ($password === '' || $config['pass_complex'] === 'PASS_TYPE_ANY')
{

View File

@ -86,9 +86,16 @@ class fulltext_mysql extends search_backend
$engine = $info['Type'];
}
if ($engine != 'MyISAM')
$fulltext_supported =
$engine === 'MyISAM' ||
// FULLTEXT is supported on InnoDB since MySQL 5.6.4 according to
// http://dev.mysql.com/doc/refman/5.6/en/innodb-storage-engine.html
$engine === 'InnoDB' &&
phpbb_version_compare($db->sql_server_info(true), '5.6.4', '>=');
if (!$fulltext_supported)
{
return $user->lang['FULLTEXT_MYSQL_NOT_MYISAM'];
return $user->lang['FULLTEXT_MYSQL_NOT_SUPPORTED'];
}
$sql = 'SHOW VARIABLES

View File

@ -2204,6 +2204,36 @@ function change_database_data(&$no_updates, $version)
_sql($sql, $errored, $error_ary);
}
/**
* Update BBCodes that currently use the LOCAL_URL tag
*
* To fix http://tracker.phpbb.com/browse/PHPBB3-8319 we changed
* the second_pass_replace value, so that needs updating for existing ones
*/
$sql = 'SELECT *
FROM ' . BBCODES_TABLE . '
WHERE bbcode_match ' . $db->sql_like_expression($db->any_char . 'LOCAL_URL' . $db->any_char);
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if (!class_exists('acp_bbcodes'))
{
phpbb_require_updated('includes/acp/acp_bbcodes.' . $phpEx);
}
$bbcode_match = $row['bbcode_match'];
$bbcode_tpl = $row['bbcode_tpl'];
$acp_bbcodes = new acp_bbcodes();
$sql_ary = $acp_bbcodes->build_regexp($bbcode_match, $bbcode_tpl);
$sql = 'UPDATE ' . BBCODES_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
WHERE bbcode_id = ' . (int) $row['bbcode_id'];
$db->sql_query($sql);
}
$db->sql_freeresult($result);
$no_updates = false;
break;
}

View File

@ -1656,7 +1656,9 @@ class install_update extends module
{
case 'version_info':
global $phpbb_root_path, $phpEx;
$info = get_remote_file('www.phpbb.com', '/updatecheck', ((defined('PHPBB_QA')) ? '30x_qa.txt' : '30x.txt'), $errstr, $errno);
$info = get_remote_file('version.phpbb.com', '/phpbb',
((defined('PHPBB_QA')) ? '30x_qa.txt' : '30x.txt'), $errstr, $errno);
if ($info !== false)
{

View File

@ -83,7 +83,8 @@ $lang = array_merge($lang, array(
'NUMBER' => 'Any series of digits',
'EMAIL' => 'A valid e-mail address',
'URL' => 'A valid URL using any protocol (http, ftp, etc… cannot be used for javascript exploits). If none is given, “http://” is prefixed to the string.',
'LOCAL_URL' => 'A local URL. The URL must be relative to the topic page and cannot contain a server name or protocol.',
'LOCAL_URL' => 'A local URL. The URL must be relative to the topic page and cannot contain a server name or protocol, as links are prefixed with “%s”',
'RELATIVE_URL' => 'A relative URL. You can use this to match parts of a URL, but be careful: a full URL is a valid relative URL. When you want to use relative URLs of your board, use the LOCAL_URL token.',
'COLOR' => 'A HTML colour, can be either in the numeric form <samp>#FF1234</samp> or a <a href="http://www.w3.org/TR/CSS21/syndata.html#value-def-color">CSS colour keyword</a> such as <samp>fuchsia</samp> or <samp>InactiveBorder</samp>'
)
));

View File

@ -53,7 +53,7 @@ $lang = array_merge($lang, array(
'DELETING_INDEX_IN_PROGRESS_EXPLAIN' => 'The search backend is currently cleaning its index. This can take a few minutes.',
'FULLTEXT_MYSQL_INCOMPATIBLE_VERSION' => 'The MySQL fulltext backend can only be used with MySQL4 and above.',
'FULLTEXT_MYSQL_NOT_MYISAM' => 'MySQL fulltext indexes can only be used with MyISAM tables.',
'FULLTEXT_MYSQL_NOT_SUPPORTED' => 'MySQL fulltext indexes can only be used with MyISAM or InnoDB tables. MySQL 5.6.4 or later is required for fulltext indexes on InnoDB tables.',
'FULLTEXT_MYSQL_TOTAL_POSTS' => 'Total number of indexed posts',
'FULLTEXT_MYSQL_MBSTRING' => 'Support for non-latin UTF-8 characters using mbstring:',
'FULLTEXT_MYSQL_PCRE' => 'Support for non-latin UTF-8 characters using PCRE:',

View File

@ -133,9 +133,25 @@ else
}
}
if ($config['enable_post_confirm'] && !$user->data['is_registered'])
{
include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
$captcha =& phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_REPORT);
}
$error = array();
$s_hidden_fields = '';
// Submit report?
if ($submit && $reason_id)
{
$visual_confirmation_response = $captcha->validate();
if ($visual_confirmation_response)
{
$error[] = $visual_confirmation_response;
}
$sql = 'SELECT *
FROM ' . REPORTS_REASONS_TABLE . "
WHERE reason_id = $reason_id";
@ -145,78 +161,90 @@ if ($submit && $reason_id)
if (!$row || (!$report_text && strtolower($row['reason_title']) == 'other'))
{
trigger_error('EMPTY_REPORT');
$error[] = $user->lang('EMPTY_REPORT');
}
$sql_ary = array(
'reason_id' => (int) $reason_id,
'post_id' => $post_id,
'pm_id' => $pm_id,
'user_id' => (int) $user->data['user_id'],
'user_notify' => (int) $user_notify,
'report_closed' => 0,
'report_time' => (int) time(),
'report_text' => (string) $report_text
);
$sql = 'INSERT INTO ' . REPORTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
$db->sql_query($sql);
$report_id = $db->sql_nextid();
if ($post_id)
if (!sizeof($error))
{
$sql = 'UPDATE ' . POSTS_TABLE . '
SET post_reported = 1
WHERE post_id = ' . $post_id;
$db->sql_query($sql);
if (!$report_data['topic_reported'])
if (isset($captcha))
{
$sql = 'UPDATE ' . TOPICS_TABLE . '
SET topic_reported = 1
WHERE topic_id = ' . $report_data['topic_id'] . '
OR topic_moved_id = ' . $report_data['topic_id'];
$db->sql_query($sql);
$captcha->reset();
}
$lang_return = $user->lang['RETURN_TOPIC'];
$lang_success = $user->lang['POST_REPORTED_SUCCESS'];
}
else
{
$sql = 'UPDATE ' . PRIVMSGS_TABLE . '
SET message_reported = 1
WHERE msg_id = ' . $pm_id;
$db->sql_query($sql);
$sql_ary = array(
'msg_id' => $pm_id,
'user_id' => ANONYMOUS,
'author_id' => (int) $report_data['author_id'],
'pm_deleted' => 0,
'pm_new' => 0,
'pm_unread' => 0,
'pm_replied' => 0,
'pm_marked' => 0,
'pm_forwarded' => 0,
'folder_id' => PRIVMSGS_INBOX,
'reason_id' => (int) $reason_id,
'post_id' => $post_id,
'pm_id' => $pm_id,
'user_id' => (int) $user->data['user_id'],
'user_notify' => (int) $user_notify,
'report_closed' => 0,
'report_time' => (int) time(),
'report_text' => (string) $report_text
);
$sql = 'INSERT INTO ' . PRIVMSGS_TO_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
$sql = 'INSERT INTO ' . REPORTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
$db->sql_query($sql);
$report_id = $db->sql_nextid();
$lang_return = $user->lang['RETURN_PM'];
$lang_success = $user->lang['PM_REPORTED_SUCCESS'];
if ($post_id)
{
$sql = 'UPDATE ' . POSTS_TABLE . '
SET post_reported = 1
WHERE post_id = ' . $post_id;
$db->sql_query($sql);
if (!$report_data['topic_reported'])
{
$sql = 'UPDATE ' . TOPICS_TABLE . '
SET topic_reported = 1
WHERE topic_id = ' . $report_data['topic_id'] . '
OR topic_moved_id = ' . $report_data['topic_id'];
$db->sql_query($sql);
}
$lang_return = $user->lang['RETURN_TOPIC'];
$lang_success = $user->lang['POST_REPORTED_SUCCESS'];
}
else
{
$sql = 'UPDATE ' . PRIVMSGS_TABLE . '
SET message_reported = 1
WHERE msg_id = ' . $pm_id;
$db->sql_query($sql);
$sql_ary = array(
'msg_id' => $pm_id,
'user_id' => ANONYMOUS,
'author_id' => (int) $report_data['author_id'],
'pm_deleted' => 0,
'pm_new' => 0,
'pm_unread' => 0,
'pm_replied' => 0,
'pm_marked' => 0,
'pm_forwarded' => 0,
'folder_id' => PRIVMSGS_INBOX,
);
$sql = 'INSERT INTO ' . PRIVMSGS_TO_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
$db->sql_query($sql);
$lang_return = $user->lang['RETURN_PM'];
$lang_success = $user->lang['PM_REPORTED_SUCCESS'];
}
meta_refresh(3, $redirect_url);
$message = $lang_success . '<br /><br />' . sprintf($lang_return, '<a href="' . $redirect_url . '">', '</a>');
if ($return_forum_url)
{
$message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . $return_forum_url . '">', '</a>');
}
trigger_error($message);
}
meta_refresh(3, $redirect_url);
$message = $lang_success . '<br /><br />' . sprintf($lang_return, '<a href="' . $redirect_url . '">', '</a>');
if ($return_forum_url)
else if (isset($captcha) && $captcha->is_solved() !== false)
{
$message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . $return_forum_url . '">', '</a>');
$s_hidden_fields .= build_hidden_fields($captcha->get_hidden_fields());
}
trigger_error($message);
}
// Generate the reasons
@ -224,10 +252,20 @@ display_reasons($reason_id);
$page_title = ($pm_id) ? $user->lang['REPORT_MESSAGE'] : $user->lang['REPORT_POST'];
if (isset($captcha) && $captcha->is_solved() === false)
{
$template->assign_vars(array(
'S_CONFIRM_CODE' => true,
'CAPTCHA_TEMPLATE' => $captcha->get_template(),
));
}
$template->assign_vars(array(
'ERROR' => (sizeof($error)) ? implode('<br />', $error) : '',
'S_REPORT_POST' => ($pm_id) ? false : true,
'REPORT_TEXT' => $report_text,
'S_REPORT_ACTION' => append_sid("{$phpbb_root_path}report.$phpEx", 'f=' . $forum_id . '&amp;p=' . $post_id . '&amp;pm=' . $pm_id),
'S_HIDDEN_FIELDS' => (sizeof($s_hidden_fields)) ? $s_hidden_fields : null,
'S_NOTIFY' => $user_notify,
'S_CAN_NOTIFY' => ($user->data['is_registered']) ? true : false)

View File

@ -75,6 +75,10 @@ function insert_single(user)
<dt><label for="msn">{L_MSNM}:</label></dt>
<dd><input type="text" name="msn" id="msn" value="{MSNM}" class="inputbox" /></dd>
</dl>
<dl>
<dt><label for="jabber">{L_JABBER}:</label></dt>
<dd><input type="text" name="jabber" id="jabber" value="{JABBER}" class="inputbox" /></dd>
</dl>
</fieldset>
<fieldset class="fields1 column2">

View File

@ -10,6 +10,7 @@
<p><!-- IF S_REPORT_POST -->{L_REPORT_POST_EXPLAIN}<!-- ELSE -->{L_REPORT_MESSAGE_EXPLAIN}<!-- ENDIF --></p>
<fieldset>
<!-- IF ERROR --><dl><dd class="error">{ERROR}</dd></dl><!-- ENDIF -->
<dl class="fields2">
<dt><label for="reason_id">{L_REASON}:</label></dt>
<dd><select name="reason_id" id="reason_id" class="full"><!-- BEGIN reason --><option value="{reason.ID}"<!-- IF reason.S_SELECTED --> selected="selected"<!-- ENDIF -->>{reason.DESCRIPTION}</option><!-- END reason --></select></dd>
@ -27,6 +28,9 @@
<dt><label for="report_text">{L_MORE_INFO}:</label><br /><span>{L_CAN_LEAVE_BLANK}</span></dt>
<dd><textarea name="report_text" id="report_text" rows="10" cols="76" class="inputbox">{REPORT_TEXT}</textarea></dd>
</dl>
<!-- IF CAPTCHA_TEMPLATE -->
<!-- INCLUDE {CAPTCHA_TEMPLATE} -->
<!-- ENDIF -->
</fieldset>
</div>

View File

@ -6,6 +6,11 @@
<tr>
<th colspan="2"><!-- IF S_REPORT_POST -->{L_REPORT_POST}<!-- ELSE -->{L_REPORT_MESSAGE}<!-- ENDIF --></th>
</tr>
<!-- IF ERROR -->
<tr>
<td class="row3" colspan="2" align="center"><span class="genmed error">{ERROR}</span></td>
</tr>
<!-- ENDIF -->
<tr>
<td class="row3" colspan="2"><span class="gensmall"><!-- IF S_REPORT_POST -->{L_REPORT_POST_EXPLAIN}<!-- ELSE -->{L_REPORT_MESSAGE_EXPLAIN}<!-- ENDIF --></span></td>
</tr>
@ -25,6 +30,9 @@
<td class="row1" valign="top"><span class="gen"><b>{L_MORE_INFO}:</b></span><br /><span class="gensmall">{L_CAN_LEAVE_BLANK}</span></td>
<td class="row2"><textarea class="post" name="report_text" rows="10" cols="50">{REPORT_TEXT}</textarea></td>
</tr>
<!-- IF CAPTCHA_TEMPLATE -->
<!-- INCLUDE {CAPTCHA_TEMPLATE} -->
<!-- ENDIF -->
<tr>
<td class="cat" colspan="2" align="center"><input type="submit" name="submit" class="btnmain" value="{L_SUBMIT}" />&nbsp;<input type="submit" name="cancel" class="btnlite" value="{L_CANCEL}" /></td>
</tr>

View File

@ -146,7 +146,14 @@ if ($view && !$post_id)
if (!$row)
{
$user->setup('viewtopic');
$sql = 'SELECT forum_style
FROM ' . FORUMS_TABLE . "
WHERE forum_id = $forum_id";
$result = $db->sql_query($sql);
$forum_style = (int) $db->sql_fetchfield('forum_style');
$db->sql_freeresult($result);
$user->setup('viewtopic', $forum_style);
trigger_error(($view == 'next') ? 'NO_NEWER_TOPICS' : 'NO_OLDER_TOPICS');
}
else

View File

@ -47,9 +47,11 @@ Database Tests
By default all tests requiring a database connection will use sqlite. If you
do not have sqlite installed the tests will be skipped. If you wish to run the
tests on a different database you have to create a test_config.php file within
your tests directory following the same format as phpBB's config.php. An
example for mysqli can be found below. More information on configuration
options can be found on the wiki (see below).
your tests directory following the same format as phpBB's config.php. Testing
makes use of a seperate database defined in this config file and before running
the tests each time this database is deleted. An example for mysqli can be
found below. More information on configuration options can be found on the
wiki (see below).
<?php
$dbms = 'mysqli';
@ -114,8 +116,36 @@ only want the slow tests, run:
$ phpBB/vendor/bin/phpunit --group slow
Functional tests
-----------------
Functional tests test software the way a user would. They simulate a user
browsing the website, but they do these steps in an automated way.
phpBB allows you to write such tests.
Running
=======
Running the tests requires your phpBB3 repository to be accessible through a
local web server. You will need to supply the URL to the webserver in
the 'tests/test_config.php' file. This is as simple as defining the
'$phpbb_functional_url' variable, which contains the URL for the directory containing
the board. Make sure you include the trailing slash. Note that without extensive
changes to the test framework, you cannot use a board outside of the repository
on which to run tests.
$phpbb_functional_url = 'http://localhost/phpBB3/';
To then run the tests, you run PHPUnit, but use the phpunit.xml.functional
config file instead of the default one. Specify this through the "-c" option:
$ phpBB/vendor/bin/phpunit -c phpunit.xml.functional
This will change your board's config.php file, but it makes a backup at
config_dev.php, so you can restore it after the test run is complete.
More Information
================
Further information is available on phpbb wiki:
http://wiki.phpbb.com/Unit_Tests
http://wiki.phpbb.com/Automated_Tests

View File

@ -18,6 +18,11 @@ class phpbb_dbal_order_lower_test extends phpbb_database_test_case
{
$db = $this->new_dbal();
if (strpos($db->sql_layer, 'mysql') === 0 && version_compare($db->sql_server_info(true, false), '5.6', '>='))
{
$this->markTestSkipped('MySQL 5.6 fails to order things correctly. See also: http://tracker.phpbb.com/browse/PHPBB3-11571 http://bugs.mysql.com/bug.php?id=69005');
}
// http://tracker.phpbb.com/browse/PHPBB3-10507
// Test ORDER BY LOWER(style_name)
$db->sql_return_on_error(true);
@ -55,7 +60,7 @@ class phpbb_dbal_order_lower_test extends phpbb_database_test_case
'theme_id' => 2,
'imageset_id' => 2
)
),
),
$db->sql_fetchrowset($result)
);
}

View File

@ -17,8 +17,7 @@ class phpbb_functional_auth_test extends phpbb_functional_test_case
$this->login();
// check for logout link
$crawler = $this->request('GET', 'index.php');
$this->assert_response_success();
$crawler = self::request('GET', 'index.php');
$this->assertContains($this->lang('LOGOUT_USER', 'admin'), $crawler->filter('.navbar')->text());
}
@ -26,8 +25,7 @@ class phpbb_functional_auth_test extends phpbb_functional_test_case
{
$this->create_user('anothertestuser');
$this->login('anothertestuser');
$crawler = $this->request('GET', 'index.php');
$this->assert_response_success();
$crawler = self::request('GET', 'index.php');
$this->assertContains('anothertestuser', $crawler->filter('.icon-logout')->text());
}
@ -40,13 +38,11 @@ class phpbb_functional_auth_test extends phpbb_functional_test_case
$this->add_lang('ucp');
// logout
$crawler = $this->request('GET', 'ucp.php?sid=' . $this->sid . '&mode=logout');
$this->assert_response_success();
$crawler = self::request('GET', 'ucp.php?sid=' . $this->sid . '&mode=logout');
$this->assertContains($this->lang('LOGOUT_REDIRECT'), $crawler->filter('#message')->text());
// look for a register link, which should be visible only when logged out
$crawler = $this->request('GET', 'index.php');
$this->assert_response_success();
$crawler = self::request('GET', 'index.php');
$this->assertContains($this->lang('REGISTER'), $crawler->filter('.navbar')->text());
}
}

View File

@ -14,22 +14,19 @@ class phpbb_functional_browse_test extends phpbb_functional_test_case
{
public function test_index()
{
$crawler = $this->request('GET', 'index.php');
$this->assert_response_success();
$crawler = self::request('GET', 'index.php');
$this->assertGreaterThan(0, $crawler->filter('.topiclist')->count());
}
public function test_viewforum()
{
$crawler = $this->request('GET', 'viewforum.php?f=2');
$this->assert_response_success();
$crawler = self::request('GET', 'viewforum.php?f=2');
$this->assertGreaterThan(0, $crawler->filter('.topiclist')->count());
}
public function test_viewtopic()
{
$crawler = $this->request('GET', 'viewtopic.php?t=1');
$this->assert_response_success();
$crawler = self::request('GET', 'viewtopic.php?t=1');
$this->assertGreaterThan(0, $crawler->filter('.postbody')->count());
}
}

View File

@ -35,11 +35,10 @@ abstract class phpbb_functional_common_groups_test extends phpbb_functional_test
$this->add_lang(array('ucp', 'acp/groups'));
// Manage Administrators group
$crawler = $this->request('GET', $this->get_url() . '&g=5&sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', $this->get_url() . '&g=5&sid=' . $this->sid);
$form = $crawler->selectButton($this->lang('SUBMIT'))->form();
$form['group_colour']->setValue($input);
$crawler = $this->client->submit($form);
$crawler = self::submit($form);
$this->assertContains($this->lang($expected), $crawler->text());
}
}

View File

@ -0,0 +1,45 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @group functional
*/
class phpbb_functional_forum_style_test extends phpbb_functional_test_case
{
public function test_default_forum_style()
{
$crawler = self::request('GET', 'viewtopic.php?t=1&f=2');
$this->assertContains('styles/prosilver/', $crawler->filter('head > link[rel=stylesheet]')->attr('href'));
$crawler = self::request('GET', 'viewtopic.php?t=1');
$this->assertContains('styles/prosilver/', $crawler->filter('head > link[rel=stylesheet]')->attr('href'));
$crawler = self::request('GET', 'viewtopic.php?t=1&view=next');
$this->assertContains('styles/prosilver/', $crawler->filter('head > link[rel=stylesheet]')->attr('href'));
}
public function test_custom_forum_style()
{
$db = $this->get_db();
$this->add_style(2, 'test_style');
$db->sql_query('UPDATE ' . FORUMS_TABLE . ' SET forum_style = 2 WHERE forum_id = 2');
$crawler = self::request('GET', 'viewtopic.php?t=1&f=2');
$this->assertContains('styles/test_style/', $crawler->filter('head > link[rel=stylesheet]')->attr('href'));
$crawler = self::request('GET', 'viewtopic.php?t=1');
$this->assertContains('styles/test_style/', $crawler->filter('head > link[rel=stylesheet]')->attr('href'));
$crawler = self::request('GET', 'viewtopic.php?t=1&view=next');
$this->assertContains('styles/test_style/', $crawler->filter('head > link[rel=stylesheet]')->attr('href'));
$db->sql_query('UPDATE ' . FORUMS_TABLE . ' SET forum_style = 0 WHERE forum_id = 2');
$this->delete_style(2, 'test_style');
}
}

View File

@ -19,18 +19,17 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
// Test creating topic
$post = $this->create_topic(2, 'Test Topic 1', 'This is a test topic posted by the testing framework.');
$crawler = $this->request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}");
$crawler = self::request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}");
$this->assertContains('This is a test topic posted by the testing framework.', $crawler->filter('html')->text());
// Test creating a reply
$post2 = $this->create_post(2, $post['topic_id'], 'Re: Test Topic 1', 'This is a test post posted by the testing framework.');
$crawler = $this->request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
$crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
$this->assertContains('This is a test post posted by the testing framework.', $crawler->filter('html')->text());
// Test quoting a message
$crawler = $this->request('GET', "posting.php?mode=quote&f=2&t={$post2['topic_id']}&p={$post2['post_id']}&sid={$this->sid}");
$this->assert_response_success();
$crawler = self::request('GET', "posting.php?mode=quote&f=2&t={$post2['topic_id']}&p={$post2['post_id']}&sid={$this->sid}");
$this->assertContains('This is a test post posted by the testing framework.', $crawler->filter('html')->text());
}
@ -55,7 +54,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
'post' => true,
), $additional_form_data);
return $this->submit_post($posting_url, 'POST_TOPIC', $form_data);
return self::submit_post($posting_url, 'POST_TOPIC', $form_data);
}
/**
@ -79,7 +78,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
'post' => true,
), $additional_form_data);
return $this->submit_post($posting_url, 'POST_REPLY', $form_data);
return self::submit_post($posting_url, 'POST_REPLY', $form_data);
}
/**
@ -94,8 +93,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
{
$this->add_lang('posting');
$crawler = $this->request('GET', $posting_url);
$this->assert_response_success();
$crawler = self::request('GET', $posting_url);
$this->assertContains($this->lang($posting_contains), $crawler->filter('html')->text());
$hidden_fields = array(
@ -119,8 +117,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
// I use a request because the form submission method does not allow you to send data that is not
// contained in one of the actual form fields that the browser sees (i.e. it ignores "hidden" inputs)
// Instead, I send it as a request with the submit button "post" set to true.
$crawler = $this->client->request('POST', $posting_url, $form_data);
$this->assert_response_success();
$crawler = self::request('POST', $posting_url, $form_data);
$this->assertContains($this->lang('POST_STORED'), $crawler->filter('html')->text());
$url = $crawler->selectLink($this->lang('VIEW_MESSAGE', '', ''))->link()->getUri();

View File

@ -0,0 +1,61 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @group functional
*/
class phpbb_functional_report_post_captcha_test extends phpbb_functional_test_case
{
public function test_user_report_post()
{
$this->login();
$crawler = self::request('GET', 'report.php?f=2&p=1');
$this->assertNotContains($this->lang('CONFIRM_CODE'), $crawler->filter('html')->text());
}
public function test_guest_report_post()
{
$crawler = self::request('GET', 'report.php?f=2&p=1');
$this->add_lang('mcp');
$this->assertContains($this->lang('USER_CANNOT_REPORT'), $crawler->filter('html')->text());
$this->set_reporting_guest(1);
$crawler = self::request('GET', 'report.php?f=2&p=1');
$this->assertContains($this->lang('CONFIRM_CODE'), $crawler->filter('html')->text());
$this->set_reporting_guest(-1);
}
protected function set_reporting_guest($report_post_allowed)
{
$this->login();
$this->admin_login();
$crawler = self::request('GET', 'adm/index.php?i=permissions&icat=12&mode=setting_group_local&sid=' . $this->sid);
$form = $crawler->selectButton('Submit')->form();
$values = $form->getValues();
$values["group_id[0]"] = 1;
$form->setValues($values);
$crawler = self::submit($form);
$form = $crawler->selectButton('Submit')->form();
$values = $form->getValues();
$values["forum_id"] = 2;
$form->setValues($values);
$crawler = self::submit($form);
$this->add_lang('acp/permissions');
$form = $crawler->selectButton($this->lang('APPLY_ALL_PERMISSIONS'))->form();
$values = $form->getValues();
$values["setting[1][2][f_report]"] = $report_post_allowed;
$form->setValues($values);
$crawler = self::submit($form);
$crawler = self::request('GET', 'ucp.php?mode=logout&sid=' . $this->sid);
}
}

View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
<table name="phpbb_sessions">
<column>session_id</column>
<column>session_user_id</column>
<column>session_forum_id</column>
<column>session_time</column>
<column>session_ip</column>
<column>session_viewonline</column>
</table>
<table name="phpbb_users">
<column>user_id</column>
<column>username_clean</column>
<column>username</column>
<column>user_allow_viewonline</column>
<column>user_permissions</column>
<column>user_sig</column>
<column>user_occ</column>
<column>user_interests</column>
<row>
<value>1</value>
<value>anonymous</value>
<value>anonymous</value>
<value>1</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>2</value>
<value>2</value>
<value>2</value>
<value>1</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>3</value>
<value>3</value>
<value>3</value>
<value>1</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>4</value>
<value>4</value>
<value>4</value>
<value>1</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>5</value>
<value>5</value>
<value>5</value>
<value>1</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>6</value>
<value>6</value>
<value>6</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>7</value>
<value>7</value>
<value>7</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>8</value>
<value>8</value>
<value>8</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>9</value>
<value>9</value>
<value>9</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>10</value>
<value>10</value>
<value>10</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
</table>
</dataset>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
<table name="phpbb_users">
<column>user_id</column>
<column>username</column>
<column>username_clean</column>
<column>user_permissions</column>
<column>user_sig</column>
<column>user_occ</column>
<column>user_interests</column>
<column>user_email_hash</column>
<row>
<value>1</value>
<value>admin</value>
<value>admin</value>
<value></value>
<value></value>
<value></value>
<value></value>
<value>143317126117</value>
</row>
</table>
</dataset>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
<table name="phpbb_groups">
<column>group_name</column>
<column>group_desc</column>
<row>
<value>foobar_group</value>
<value>test123</value>
</row>
</table>
<table name="phpbb_users">
<column>user_id</column>
<column>username</column>
<column>username_clean</column>
<column>user_permissions</column>
<column>user_sig</column>
<column>user_occ</column>
<column>user_interests</column>
<row>
<value>1</value>
<value>admin</value>
<value>admin</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>2</value>
<value>moderator</value>
<value>moderator</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
</table>
</dataset>

View File

@ -0,0 +1,75 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_admin.php';
/**
* @group slow
*/
class phpbb_functions_get_remote_file extends phpbb_test_case
{
public function test_version_phpbb_com()
{
$hostname = 'version.phpbb.com';
if (!phpbb_checkdnsrr($hostname, 'A'))
{
$this->markTestSkipped(sprintf(
'Could not find a DNS record for hostname %s. ' .
'Assuming network is down.',
$hostname
));
}
$errstr = $errno = null;
$file = get_remote_file($hostname, '/phpbb', '30x.txt', $errstr, $errno);
$this->assertNotEquals(
0,
strlen($file),
'Failed asserting that the response is not empty.'
);
$this->assertSame(
'',
$errstr,
'Failed asserting that the error string is empty.'
);
$this->assertSame(
0,
$errno,
'Failed asserting that the error number is 0 (i.e. no error occurred).'
);
$lines = explode("\n", $file);
$this->assertGreaterThanOrEqual(
2,
sizeof($lines),
'Failed asserting that the version file has at least two lines.'
);
$this->assertStringStartsWith(
'3.',
$lines[0],
"Failed asserting that the first line of the version file starts with '3.'"
);
$this->assertNotSame(
false,
filter_var($lines[1], FILTER_VALIDATE_URL),
'Failed asserting that the second line of the version file is a valid URL.'
);
$this->assertContains('http', $lines[1]);
$this->assertContains('phpbb.com', $lines[1], '', true);
}
}

View File

@ -0,0 +1,238 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/auth.php';
class phpbb_functions_obtain_online_test extends phpbb_database_test_case
{
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/obtain_online.xml');
}
protected function setUp()
{
parent::setUp();
global $config, $db;
$db = $this->db = $this->new_dbal();
$config = array(
'load_online_time' => 5,
);
}
static public function obtain_guest_count_data()
{
return array(
array(0, 2),
array(1, 1),
);
}
/**
* @dataProvider obtain_guest_count_data
*/
public function test_obtain_guest_count($forum_id, $expected)
{
$this->db->sql_query('DELETE FROM phpbb_sessions');
$time = time();
$this->create_guest_sessions($time);
$this->assertEquals($expected, obtain_guest_count($forum_id));
}
static public function obtain_users_online_data()
{
return array(
array(0, false, array(
'online_users' => array(2 => 2, 3 => 3, 6 => 6, 7 => 7, 10 => 10),
'hidden_users' => array(6 => 6, 7 => 7, 10 => 10),
'total_online' => 5,
'visible_online' => 2,
'hidden_online' => 3,
'guests_online' => 0,
)),
array(0, true, array(
'online_users' => array(2 => 2, 3 => 3, 6 => 6, 7 => 7, 10 => 10),
'hidden_users' => array(6 => 6, 7 => 7, 10 => 10),
'total_online' => 7,
'visible_online' => 2,
'hidden_online' => 3,
'guests_online' => 2,
)),
array(1, false, array(
'online_users' => array(3 => 3, 7 => 7),
'hidden_users' => array(7 => 7),
'total_online' => 2,
'visible_online' => 1,
'hidden_online' => 1,
'guests_online' => 0,
)),
array(1, true, array(
'online_users' => array(3 => 3, 7 => 7),
'hidden_users' => array(7 => 7),
'total_online' => 3,
'visible_online' => 1,
'hidden_online' => 1,
'guests_online' => 1,
)),
array(2, false, array(
'online_users' => array(),
'hidden_users' => array(),
'total_online' => 0,
'visible_online' => 0,
'hidden_online' => 0,
'guests_online' => 0,
)),
array(2, true, array(
'online_users' => array(),
'hidden_users' => array(),
'total_online' => 0,
'visible_online' => 0,
'hidden_online' => 0,
'guests_online' => 0,
)),
);
}
/**
* @dataProvider obtain_users_online_data
*/
public function test_obtain_users_online($forum_id, $display_guests, $expected)
{
$this->db->sql_query('DELETE FROM phpbb_sessions');
global $config;
$config['load_online_guests'] = $display_guests;
$time = time();
$this->create_guest_sessions($time);
$this->create_user_sessions($time);
$this->assertEquals($expected, obtain_users_online($forum_id));
}
static public function obtain_users_online_string_data()
{
return array(
array(0, false, array(
'online_userlist' => 'REGISTERED_USERS 2, 3',
'l_online_users' => 'ONLINE_USERS_TOTAL 5REG_USERS_TOTAL_AND 2HIDDEN_USERS_TOTAL 3',
)),
array(0, true, array(
'online_userlist' => 'REGISTERED_USERS 2, 3',
'l_online_users' => 'ONLINE_USERS_TOTAL 7REG_USERS_TOTAL 2HIDDEN_USERS_TOTAL_AND 3GUEST_USERS_TOTAL 2',
)),
array(1, false, array(
'online_userlist' => 'BROWSING_FORUM 3',
'l_online_users' => 'ONLINE_USERS_TOTAL 2REG_USER_TOTAL_AND 1HIDDEN_USER_TOTAL 1',
)),
array(1, true, array(
'online_userlist' => 'BROWSING_FORUM_GUEST 3 1',
'l_online_users' => 'ONLINE_USERS_TOTAL 3REG_USER_TOTAL 1HIDDEN_USER_TOTAL_AND 1GUEST_USER_TOTAL 1',
)),
array(2, false, array(
'online_userlist' => 'BROWSING_FORUM NO_ONLINE_USERS',
'l_online_users' => 'ONLINE_USERS_ZERO_TOTAL 0REG_USERS_ZERO_TOTAL_AND 0HIDDEN_USERS_ZERO_TOTAL 0',
)),
array(2, true, array(
'online_userlist' => 'BROWSING_FORUM_GUESTS NO_ONLINE_USERS 0',
'l_online_users' => 'ONLINE_USERS_ZERO_TOTAL 0REG_USERS_ZERO_TOTAL 0HIDDEN_USERS_ZERO_TOTAL_AND 0GUEST_USERS_ZERO_TOTAL 0',
)),
);
}
/**
* @dataProvider obtain_users_online_string_data
*/
public function test_obtain_users_online_string($forum_id, $display_guests, $expected)
{
$this->db->sql_query('DELETE FROM phpbb_sessions');
global $config, $user, $auth;
$config['load_online_guests'] = $display_guests;
$user->lang = $this->load_language();
$auth = $this->getMock('auth');
$acl_get_map = array(
array('u_viewonline', true),
);
$auth->expects($this->any())
->method('acl_get')
->with($this->stringContains('_'),
$this->anything())
->will($this->returnValueMap($acl_get_map));
$time = time();
$this->create_guest_sessions($time);
$this->create_user_sessions($time);
$online_users = obtain_users_online($forum_id);
$this->assertEquals($expected, obtain_users_online_string($online_users, $forum_id));
}
protected function create_guest_sessions($time)
{
$this->add_session(1, '0001', '192.168.0.1', 0, true, $time);
$this->add_session(1, '0002', '192.168.0.2', 1, true, $time);
$this->add_session(1, '0003', '192.168.0.3', 0, true, $time, 10);
$this->add_session(1, '0004', '192.168.0.4', 1, true, $time, 10);
}
protected function create_user_sessions($time)
{
$this->add_session(2, '0005', '192.168.0.5', 0, true, $time);
$this->add_session(3, '0006', '192.168.0.6', 1, true, $time);
$this->add_session(4, '0007', '192.168.0.7', 0, true, $time, 10);
$this->add_session(5, '0008', '192.168.0.8', 1, true, $time, 10);
$this->add_session(6, '0005', '192.168.0.9', 0, false, $time);
$this->add_session(7, '0006', '192.168.0.10', 1, false, $time);
$this->add_session(8, '0007', '192.168.0.11', 0, false, $time, 10);
$this->add_session(9, '0008', '192.168.0.12', 1, false, $time, 10);
$this->add_session(10, '009', '192.168.0.13', 0, false, $time);
}
protected function add_session($user_id, $session_id, $user_ip, $forum_id, $view_online, $time, $time_delta = 0)
{
$sql_ary = array(
'session_id' => $user_id . '_' . $forum_id . '_session00000000000000000' . $session_id,
'session_user_id' => $user_id,
'session_ip' => $user_ip,
'session_forum_id' => $forum_id,
'session_time' => $time - $time_delta * 60,
'session_viewonline' => $view_online,
);
$this->db->sql_query('INSERT INTO phpbb_sessions ' . $this->db->sql_build_array('INSERT', $sql_ary));
}
protected function load_language()
{
$lang = array(
'NO_ONLINE_USERS' => 'NO_ONLINE_USERS',
'REGISTERED_USERS' => 'REGISTERED_USERS',
'BROWSING_FORUM' => 'BROWSING_FORUM %s',
'BROWSING_FORUM_GUEST' => 'BROWSING_FORUM_GUEST %s %d',
'BROWSING_FORUM_GUESTS' => 'BROWSING_FORUM_GUESTS %s %d',
);
$vars_online = array('ONLINE', 'REG', 'HIDDEN', 'GUEST');
foreach ($vars_online as $online)
{
$lang = array_merge($lang, array(
$online . '_USERS_ZERO_TOTAL' => $online . '_USERS_ZERO_TOTAL %d',
$online . '_USER_TOTAL' => $online . '_USER_TOTAL %d',
$online . '_USERS_TOTAL' => $online . '_USERS_TOTAL %d',
$online . '_USERS_ZERO_TOTAL_AND' => $online . '_USERS_ZERO_TOTAL_AND %d',
$online . '_USER_TOTAL_AND' => $online . '_USER_TOTAL_AND %d',
$online . '_USERS_TOTAL_AND' => $online . '_USERS_TOTAL_AND %d',
));
}
return $lang;
}
}

View File

@ -0,0 +1,36 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
class phpbb_functions_validate_data_helper
{
protected $test_case;
public function __construct($test_case)
{
$this->test_case = $test_case;
}
/**
* Test provided input data with supplied checks and compare to expected
* results
*
* @param array $data Array containing one or more subarrays with the
* test data. The first element of a subarray is the
* expected result, the second one is the input, and the
* third is the data that should be passed to the function
* validate_data().
*/
public function assert_valid_data($data)
{
foreach ($data as $key => $test)
{
$this->test_case->assertEquals($test[0], validate_data(array($test[1]), array($test[2])));
}
}
}

View File

@ -0,0 +1,82 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_date_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_date()
{
$this->helper->assert_valid_data(array(
'empty' => array(
array('INVALID'),
'',
array('date'),
),
'empty_opt' => array(
array(),
'',
array('date', true),
),
'double_single' => array(
array(),
'17-06-1990',
array('date'),
),
'single_single' => array(
array(),
'05-05-2009',
array('date'),
),
'double_double' => array(
array(),
'17-12-1990',
array('date'),
),
'month_high' => array(
array('INVALID'),
'17-17-1990',
array('date'),
),
'month_low' => array(
array('INVALID'),
'01-00-1990',
array('date'),
),
'day_high' => array(
array('INVALID'),
'64-01-1990',
array('date'),
),
'day_low' => array(
array('INVALID'),
'00-12-1990',
array('date'),
),
// Currently fails
/*
'zero_year' => array(
array(),
'01-01-0000',
array('date'),
),
*/
));
}
}

View File

@ -0,0 +1,108 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/../mock/user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_email_test extends phpbb_database_test_case
{
protected $db;
protected $user;
protected $helper;
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/validate_email.xml');
}
protected function setUp()
{
parent::setUp();
$this->db = $this->new_dbal();
$this->user = new phpbb_mock_user;
$this->helper = new phpbb_functions_validate_data_helper($this);
}
/**
* Get validation prerequesites
*
* @param bool $check_mx Whether mx records should be checked
*/
protected function set_validation_prerequisites($check_mx)
{
global $config, $db, $user;
$config['email_check_mx'] = $check_mx;
$db = $this->db;
$user = $this->user;
$user->optionset('banned_users', array('banned@example.com'));
}
public function test_validate_email()
{
$this->set_validation_prerequisites(false);
$this->helper->assert_valid_data(array(
'empty' => array(
array(),
'',
array('email'),
),
'allowed' => array(
array(),
'foobar@example.com',
array('email', 'foobar@example.com'),
),
'invalid' => array(
array('EMAIL_INVALID'),
'fööbar@example.com',
array('email'),
),
'valid_complex' => array(
array(),
"'%$~test@example.com",
array('email'),
),
'taken' => array(
array('EMAIL_TAKEN'),
'admin@example.com',
array('email'),
),
'banned' => array(
array('EMAIL_BANNED'),
'banned@example.com',
array('email'),
),
));
}
/**
* @group slow
*/
public function test_validate_email_mx()
{
$this->set_validation_prerequisites(true);
$this->helper->assert_valid_data(array(
'valid' => array(
array(),
'foobar@phpbb.com',
array('email'),
),
'no_mx' => array(
array('DOMAIN_NO_MX_RECORD'),
'test@does-not-exist.phpbb.com',
array('email'),
),
));
}
}

View File

@ -0,0 +1,79 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_jabber_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_jabber()
{
$this->helper->assert_valid_data(array(
'empty' => array(
array(),
'',
array('jabber'),
),
'no_seperator' => array(
array('WRONG_DATA'),
'testjabber.ccc',
array('jabber'),
),
'no_user' => array(
array('WRONG_DATA'),
'@jabber.ccc',
array('jabber'),
),
'no_realm' => array(
array('WRONG_DATA'),
'user@',
array('jabber'),
),
'dot_realm' => array(
array('WRONG_DATA'),
'user@.....',
array('jabber'),
),
'-realm' => array(
array('WRONG_DATA'),
'user@-jabber.ccc',
array('jabber'),
),
'realm-' => array(
array('WRONG_DATA'),
'user@jabber.ccc-',
array('jabber'),
),
'correct' => array(
array(),
'user@jabber.09A-z.org',
array('jabber'),
),
'prohibited' => array(
array('WRONG_DATA'),
'u@ser@jabber.ccc.org',
array('jabber'),
),
'prohibited_char' => array(
array('WRONG_DATA'),
'u<s>er@jabber.ccc.org',
array('jabber'),
),
));
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_lang_iso_test extends phpbb_database_test_case
{
protected $db;
protected $helper;
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/language_select.xml');
}
protected function setUp()
{
parent::setUp();
$this->db = $this->new_dbal();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_lang_iso()
{
global $db;
$db = $this->db;
$this->helper->assert_valid_data(array(
'empty' => array(
array('WRONG_DATA'),
'',
array('language_iso_name'),
),
'en' => array(
array(),
'en',
array('language_iso_name'),
),
'cs' => array(
array(),
'cs',
array('language_iso_name'),
),
'de' => array(
array('WRONG_DATA'),
'de',
array('language_iso_name'),
),
));
}
}

View File

@ -0,0 +1,49 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_match_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_match()
{
$this->helper->assert_valid_data(array(
'empty_opt' => array(
array(),
'',
array('match', true, '/[a-z]$/'),
),
'empty_empty_match' => array(
array(),
'',
array('match'),
),
'foobar' => array(
array(),
'foobar',
array('match', false, '/[a-z]$/'),
),
'foobar_fail' => array(
array('WRONG_DATA'),
'foobar123',
array('match', false, '/[a-z]$/'),
),
));
}
}

View File

@ -0,0 +1,59 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_num_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_num()
{
$this->helper->assert_valid_data(array(
'empty' => array(
array(),
'',
array('num'),
),
'zero' => array(
array(),
'0',
array('num'),
),
'five_minmax_correct' => array(
array(),
'5',
array('num', false, 2, 6),
),
'five_minmax_short' => array(
array('TOO_SMALL'),
'5',
array('num', false, 7, 10),
),
'five_minmax_long' => array(
array('TOO_LARGE'),
'5',
array('num', false, 2, 3),
),
'string' => array(
array(),
'foobar',
array('num'),
),
));
}
}

View File

@ -0,0 +1,96 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_password_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function validate_password_data()
{
return array(
array('PASS_TYPE_ANY', array(
'empty' => array(),
'foobar_any' => array(),
'foobar_mixed' => array(),
'foobar_alpha' => array(),
'foobar_symbol' => array(),
)),
array('PASS_TYPE_CASE', array(
'empty' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_mixed' => array(),
'foobar_alpha' => array(),
'foobar_symbol' => array(),
)),
array('PASS_TYPE_ALPHA', array(
'empty' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_mixed' => array('INVALID_CHARS'),
'foobar_alpha' => array(),
'foobar_symbol' => array(),
)),
array('PASS_TYPE_SYMBOL', array(
'empty' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_mixed' => array('INVALID_CHARS'),
'foobar_alpha' => array('INVALID_CHARS'),
'foobar_symbol' => array(),
)),
);
}
/**
* @dataProvider validate_password_data
*/
public function test_validate_password($pass_complexity, $expected)
{
global $config;
// Set complexity to mixed case letters, numbers and symbols
$config['pass_complex'] = $pass_complexity;
$this->helper->assert_valid_data(array(
'empty' => array(
$expected['empty'],
'',
array('password'),
),
'foobar_any' => array(
$expected['foobar_any'],
'foobar',
array('password'),
),
'foobar_mixed' => array(
$expected['foobar_mixed'],
'FooBar',
array('password'),
),
'foobar_alpha' => array(
$expected['foobar_alpha'],
'F00bar',
array('password'),
),
'foobar_symbol' => array(
$expected['foobar_symbol'],
'fooBar123*',
array('password'),
),
));
}
}

View File

@ -0,0 +1,70 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_string_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_string()
{
$this->helper->assert_valid_data(array(
'empty_opt' => array(
array(),
'',
array('string', true),
),
'empty' => array(
array(),
'',
array('string'),
),
'foo' => array(
array(),
'foobar',
array('string'),
),
'foo_minmax_correct' => array(
array(),
'foobar',
array('string', false, 2, 6),
),
'foo_minmax_short' => array(
array('TOO_SHORT'),
'foobar',
array('string', false, 7, 9),
),
'foo_minmax_long' => array(
array('TOO_LONG'),
'foobar',
array('string', false, 2, 5),
),
'empty_short' => array(
array('TOO_SHORT'),
'',
array('string', false, 1, 6),
),
'empty_length_opt' => array(
array(),
'',
array('string', true, 1, 6),
),
));
}
}

View File

@ -0,0 +1,190 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php';
require_once dirname(__FILE__) . '/../mock/cache.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_data_test extends phpbb_database_test_case
{
protected $db;
protected $cache;
protected $helper;
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/validate_username.xml');
}
protected function setUp()
{
parent::setUp();
$this->db = $this->new_dbal();
$this->cache = new phpbb_mock_cache;
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function validate_username_data()
{
return array(
array('USERNAME_CHARS_ANY', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array(),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array(),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array(),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('USERNAME_TAKEN'),
)),
array('USERNAME_ALPHA_ONLY', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array('INVALID_CHARS'),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array('INVALID_CHARS'),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('INVALID_CHARS'),
)),
array('USERNAME_ALPHA_SPACERS', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array(),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array('INVALID_CHARS'),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('USERNAME_TAKEN'),
)),
array('USERNAME_LETTER_NUM', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array('INVALID_CHARS'),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array('INVALID_CHARS'),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('INVALID_CHARS'),
)),
array('USERNAME_LETTER_NUM_SPACERS', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array(),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array(),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('USERNAME_TAKEN'),
)),
array('USERNAME_ASCII', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array(),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array(),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array('INVALID_CHARS'),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('USERNAME_TAKEN'),
)),
);
}
/**
* @dataProvider validate_username_data
*/
public function test_validate_username($allow_name_chars, $expected)
{
global $cache, $config, $db;
$db = $this->db;
$cache = $this->cache;
$cache->put('_disallowed_usernames', array('barfoo'));
$config['allow_name_chars'] = $allow_name_chars;
$this->helper->assert_valid_data(array(
'foobar_allow' => array(
$expected['foobar_allow'],
'foobar',
array('username', 'foobar'),
),
'foobar_ascii' => array(
$expected['foobar_ascii'],
'foobar',
array('username'),
),
'foobar_any' => array(
$expected['foobar_any'],
'f*~*^=oo_bar1',
array('username'),
),
'foobar_alpha' => array(
$expected['foobar_alpha'],
'fo0Bar',
array('username'),
),
'foobar_alpha_spacers' => array(
$expected['foobar_alpha_spacers'],
'Fo0-[B]_a+ R',
array('username'),
),
'foobar_letter_num' => array(
$expected['foobar_letter_num'],
'fo0Bar0',
array('username'),
),
'foobar_letter_num_sp' => array(
$expected['foobar_letter_num_sp'],
'Fö0-[B]_a+ R',
array('username'),
),
'foobar_quot' => array(
$expected['foobar_quot'],
'"foobar"',
array('username'),
),
'barfoo_disallow' => array(
$expected['barfoo_disallow'],
'barfoo',
array('username'),
),
'admin_taken' => array(
$expected['admin_taken'],
'admin',
array('username'),
),
'group_taken' => array(
$expected['group_taken'],
'foobar_group',
array('username'),
),
));
}
}

View File

@ -74,6 +74,21 @@ class phpbb_mock_cache
);
}
/**
* Obtain disallowed usernames. Input data via standard put method.
*/
public function obtain_disallowed_usernames()
{
if (($usernames = $this->get('_disallowed_usernames')) !== false)
{
return $usernames;
}
else
{
return array();
}
}
public function set_bots($bots)
{
$this->data['_bots'] = $bots;

View File

@ -33,4 +33,17 @@ class phpbb_mock_user
{
$this->options[$item] = $value;
}
public function check_ban($user_id = false, $user_ips = false, $user_email = false, $return = false)
{
$banned_users = $this->optionget('banned_users');
foreach ($banned_users as $banned)
{
if ($banned == $user_id || $banned == $user_ips || $banned == $user_email)
{
return true;
}
}
return false;
}
}

View File

@ -10,7 +10,7 @@
require_once dirname(__FILE__) . '/../mock/cache.php';
require_once dirname(__FILE__) . '/testable_factory.php';
class phpbb_session_init_test extends phpbb_database_test_case
class phpbb_session_creation_test extends phpbb_database_test_case
{
public function getDataSet()
{
@ -35,10 +35,11 @@ class phpbb_session_init_test extends phpbb_database_test_case
$this->assertSqlResultEquals(
array(array('session_user_id' => 3)),
$sql,
'Check if exacly one session for user id 3 was created'
'Check if exactly one session for user id 3 was created'
);
$cookie_expire = $session->time_now + 31536000; // default is one year
$one_year_in_seconds = 365 * 24 * 60 * 60;
$cookie_expire = $session->time_now + $one_year_in_seconds;
$session->check_cookies($this, array(
'u' => array(null, $cookie_expire),

View File

@ -69,9 +69,14 @@ class phpbb_template_template_test extends phpbb_test_case
$this->markTestSkipped("Template cache directory ({$template_cache_dir}) is not writable.");
}
foreach (glob($this->template->cachepath . '*') as $file)
$file_array = scandir($template_cache_dir);
$file_prefix = basename($this->template->cachepath);
foreach ($file_array as $file)
{
unlink($file);
if (strpos($file, $file_prefix) === 0)
{
unlink($template_cache_dir . '/' . $file);
}
}
$GLOBALS['config'] = array(
@ -84,9 +89,15 @@ class phpbb_template_template_test extends phpbb_test_case
{
if (is_object($this->template))
{
foreach (glob($this->template->cachepath . '*') as $file)
$template_cache_dir = dirname($this->template->cachepath);
$file_array = scandir($template_cache_dir);
$file_prefix = basename($this->template->cachepath);
foreach ($file_array as $file)
{
unlink($file);
if (strpos($file, $file_prefix) === 0)
{
unlink($template_cache_dir . '/' . $file);
}
}
}
}

View File

@ -11,6 +11,8 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
{
static private $already_connected;
private $db_connections;
protected $test_case_helpers;
protected $fixture_xml_data;
@ -28,6 +30,22 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
'phpbb_database_test_case' => array('already_connected'),
);
$this->db_connections = array();
}
protected function tearDown()
{
parent::tearDown();
// Close all database connections from this test
if (!empty($this->db_connections))
{
foreach ($this->db_connections as $db)
{
$db->sql_close();
}
}
}
protected function setUp()
@ -44,6 +62,21 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
}
}
/**
* Performs synchronisations for a given table/column set on the database
*
* @param array $table_column_map Information about the tables/columns to synchronise
*
* @return null
*/
protected function database_synchronisation($table_column_map)
{
$config = $this->get_database_config();
$manager = $this->create_connection_manager($config);
$manager->connect();
$manager->database_synchronisation($table_column_map);
}
public function createXMLDataSet($path)
{
$db_config = $this->get_database_config();
@ -123,6 +156,8 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
$db = new $dbal();
$db->sql_connect($config['dbhost'], $config['dbuser'], $config['dbpasswd'], $config['dbname'], $config['dbport']);
$this->db_connections[] = $db;
return $db;
}

View File

@ -480,12 +480,33 @@ class phpbb_database_test_connection_manager
* @return null
*/
public function post_setup_synchronisation($xml_data_set)
{
$table_names = $xml_data_set->getTableNames();
$tables = array();
foreach ($table_names as $table)
{
$tables[$table] = $xml_data_set->getTableMetaData($table)->getColumns();
}
$this->database_synchronisation($tables);
}
/**
* Performs synchronisations on the database after a fixture has been loaded
*
* @param array $table_column_map Array of tables/columns to synchronise
* array(table1 => array(column1, column2))
*
* @return null
*/
public function database_synchronisation($table_column_map)
{
$this->ensure_connected(__METHOD__);
$queries = array();
// Get escaped versions of the table names used in the fixture
$table_names = array_map(array($this->pdo, 'PDO::quote'), $xml_data_set->getTableNames());
// Get escaped versions of the table names to synchronise
$table_names = array_map(array($this->pdo, 'PDO::quote'), array_keys($table_column_map));
switch ($this->config['dbms'])
{
@ -542,7 +563,7 @@ class phpbb_database_test_connection_manager
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
// Get the columns used in the fixture for this table
$column_names = $xml_data_set->getTableMetaData($row['table_name'])->getColumns();
$column_names = $table_column_map[$row['table_name']];
// Skip sequences that weren't specified in the fixture
if (!in_array($row['column_name'], $column_names))

View File

@ -14,8 +14,9 @@ require_once __DIR__ . '/../../phpBB/includes/cache.php';
class phpbb_functional_test_case extends phpbb_test_case
{
protected $client;
protected $root_url;
static protected $client;
static protected $cookieJar;
static protected $root_url;
protected $cache = null;
protected $db = null;
@ -40,6 +41,7 @@ class phpbb_functional_test_case extends phpbb_test_case
parent::setUpBeforeClass();
self::$config = phpbb_test_case_helpers::get_test_config();
self::$root_url = self::$config['phpbb_functional_url'];
if (!isset(self::$config['phpbb_functional_url']))
{
@ -59,12 +61,12 @@ class phpbb_functional_test_case extends phpbb_test_case
$this->bootstrap();
$this->cookieJar = new CookieJar;
$this->client = new Goutte\Client(array(), null, $this->cookieJar);
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
$this->client->getClient()->getCurlMulti()->reset(true);
$this->root_url = self::$config['phpbb_functional_url'];
self::$client->getClient()->getCurlMulti()->reset(true);
// Clear the language array so that things
// that were added in other tests are gone
$this->lang = array();
@ -72,9 +74,55 @@ class phpbb_functional_test_case extends phpbb_test_case
$this->purge_cache();
}
public function request($method, $path)
/**
* Perform a request to page
*
* @param string $method HTTP Method
* @param string $path Page path, relative from phpBB root path
* @param array $form_data An array of form field values
* @param bool $assert_response_html Should we perform standard assertions for a normal html page
* @return Symfony\Component\DomCrawler\Crawler
*/
static public function request($method, $path, $form_data = array(), $assert_response_html = true)
{
return $this->client->request($method, $this->root_url . $path);
$crawler = self::$client->request($method, self::$root_url . $path, $form_data);
if ($assert_response_html)
{
self::assert_response_html();
}
return $crawler;
}
/**
* Submits a form
*
* @param Symfony\Component\DomCrawler\Form $form A Form instance
* @param array $values An array of form field values
* @param bool $assert_response_html Should we perform standard assertions for a normal html page
* @return Symfony\Component\DomCrawler\Crawler
*/
static public function submit(Symfony\Component\DomCrawler\Form $form, array $values = array(), $assert_response_html = true)
{
$crawler = self::$client->submit($form, $values);
if ($assert_response_html)
{
self::assert_response_html();
}
return $crawler;
}
/**
* Get Client Content
*
* @return string HTML page
*/
static public function get_content()
{
return self::$client->getResponse()->getContent();
}
// bootstrap, called after board is set up
@ -136,40 +184,118 @@ class phpbb_functional_test_case extends phpbb_test_case
self::$config['table_prefix'] = 'phpbb_';
self::recreate_database(self::$config);
if (file_exists($phpbb_root_path . "config.$phpEx"))
$config_file = $phpbb_root_path . "config.$phpEx";
$config_file_dev = $phpbb_root_path . "config_dev.$phpEx";
$config_file_test = $phpbb_root_path . "config_test.$phpEx";
if (file_exists($config_file))
{
if (!file_exists($phpbb_root_path . "config_dev.$phpEx"))
if (!file_exists($config_file_dev))
{
rename($phpbb_root_path . "config.$phpEx", $phpbb_root_path . "config_dev.$phpEx");
rename($config_file, $config_file_dev);
}
else
{
unlink($phpbb_root_path . "config.$phpEx");
unlink($config_file);
}
}
// begin data
$data = array();
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,
),
)));
$data = array_merge($data, self::$config);
$data = array_merge($data, array(
'default_lang' => 'en',
'admin_name' => 'admin',
'admin_pass1' => 'admin',
'admin_pass2' => 'admin',
'board_email' => 'nobody@example.com',
));
// Reset the curl handle because it is 0 at this point and not a valid
// resource
self::$client->getClient()->getCurlMulti()->reset(true);
$parseURL = parse_url(self::$config['phpbb_functional_url']);
$data = array_merge($data, array(
'email_enable' => false,
'smtp_delivery' => false,
'smtp_host' => '',
'smtp_auth' => '',
'smtp_user' => '',
'smtp_pass' => '',
$crawler = self::request('GET', 'install/index.php?mode=install');
self::assertContains('Welcome to Installation', $crawler->filter('#main')->text());
$form = $crawler->selectButton('submit')->form();
// install/index.php?mode=install&sub=requirements
$crawler = self::submit($form);
self::assertContains('Installation compatibility', $crawler->filter('#main')->text());
$form = $crawler->selectButton('submit')->form();
// 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'],
));
// install/index.php?mode=install&sub=database
$crawler = self::submit($form);
self::assertContains('Successful connection', $crawler->filter('#main')->text());
$form = $crawler->selectButton('submit')->form();
// 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_email1' => 'nobody@example.com',
'board_email2' => 'nobody@example.com',
));
// 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'], array(), true, true);
$config_created = file_put_contents($config_file, $config_php_data) !== false;
if (!$config_created)
{
self::markTestSkipped("Could not write $config_file file.");
}
// 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)
{
self::markTestSkipped("Could not create $lock_created file.");
}
@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'] . '://',
@ -177,46 +303,18 @@ class phpbb_functional_test_case extends phpbb_test_case
'server_port' => isset($parseURL['port']) ? (int) $parseURL['port'] : 80,
'script_path' => $parseURL['path'],
));
// end data
$content = self::do_request('install');
self::assertNotSame(false, $content);
self::assertContains('Welcome to Installation', $content);
// 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();
$content = self::do_request('create_table', $data);
self::assertNotSame(false, $content);
self::assertContains('The database tables used by phpBB', $content);
// 3.0 or 3.1
self::assertContains('have been created and populated with some initial data.', $content);
// install/index.php?mode=install&sub=final
$crawler = self::submit($form);
self::assertContains('You have successfully installed', $crawler->text());
$content = self::do_request('config_file', $data);
self::assertNotSame(false, $content);
self::assertContains('Configuration file', $content);
file_put_contents($phpbb_root_path . "config.$phpEx", phpbb_create_config_file_data($data, self::$config['dbms'], array(), true, true));
$content = self::do_request('final', $data);
self::assertNotSame(false, $content);
self::assertContains('You have successfully installed', $content);
copy($phpbb_root_path . "config.$phpEx", $phpbb_root_path . "config_test.$phpEx");
}
static private function do_request($sub, $post_data = null)
{
$context = null;
if ($post_data)
{
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query($post_data),
'ignore_errors' => true,
),
));
}
return file_get_contents(self::$config['phpbb_functional_url'] . 'install/index.php?mode=install&sub=' . $sub, false, $context);
copy($config_file, $config_file_test);
}
static private function recreate_database($config)
@ -225,6 +323,90 @@ class phpbb_functional_test_case extends phpbb_test_case
$db_conn_mgr->recreate_db();
}
/**
* Creates a new style
*
* @param string $style_id Style ID
* @param string $style_path Style directory
* @param string $parent_style_id Parent style id. Default = 1
* @param string $parent_style_path Parent style directory. Default = 'prosilver'
*/
protected function add_style($style_id, $style_path, $parent_style_id = 1, $parent_style_path = 'prosilver')
{
global $phpbb_root_path;
$db = $this->get_db();
$sql = 'INSERT INTO ' . STYLES_TABLE . ' ' . $db->sql_build_array('INSERT', array(
'style_id' => $style_id,
'style_name' => $style_path,
'style_copyright' => '',
'style_active' => 1,
'template_id' => $style_id,
'theme_id' => $style_id,
'imageset_id' => $style_id,
));
$db->sql_query($sql);
$sql = 'INSERT INTO ' . STYLES_IMAGESET_TABLE . ' ' . $db->sql_build_array('INSERT', array(
'imageset_id' => $style_id,
'imageset_name' => $style_path,
'imageset_copyright' => '',
'imageset_path' => $style_path,
));
$db->sql_query($sql);
$sql = 'INSERT INTO ' . STYLES_TEMPLATE_TABLE . ' ' . $db->sql_build_array('INSERT', array(
'template_id' => $style_id,
'template_name' => $style_path,
'template_copyright' => '',
'template_path' => $style_path,
'bbcode_bitfield' => 'kNg=',
'template_inherits_id' => $parent_style_id,
'template_inherit_path' => $parent_style_path,
));
$db->sql_query($sql);
$sql = 'INSERT INTO ' . STYLES_THEME_TABLE . ' ' . $db->sql_build_array('INSERT', array(
'theme_id' => $style_id,
'theme_name' => $style_path,
'theme_copyright' => '',
'theme_path' => $style_path,
'theme_storedb' => 0,
'theme_mtime' => 0,
'theme_data' => '',
));
$db->sql_query($sql);
if ($style_path != 'prosilver' && $style_path != 'subsilver2')
{
@mkdir($phpbb_root_path . 'styles/' . $style_path, 0777);
@mkdir($phpbb_root_path . 'styles/' . $style_path . '/template', 0777);
}
}
/**
* Remove temporary style created by add_style()
*
* @param string $style_id Style ID
* @param string $style_path Style directory
*/
protected function delete_style($style_id, $style_path)
{
global $phpbb_root_path;
$db = $this->get_db();
$db->sql_query('DELETE FROM ' . STYLES_TABLE . ' WHERE style_id = ' . $style_id);
$db->sql_query('DELETE FROM ' . STYLES_IMAGESET_TABLE . ' WHERE imageset_id = ' . $style_id);
$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')
{
@rmdir($phpbb_root_path . 'styles/' . $style_path . '/template');
@rmdir($phpbb_root_path . 'styles/' . $style_path);
}
}
/**
* Creates a new user with limited permissions
*
@ -270,7 +452,7 @@ class phpbb_functional_test_case extends phpbb_test_case
'user_lang' => 'en',
'user_timezone' => 0,
'user_dateformat' => '',
'user_password' => phpbb_hash($username),
'user_password' => phpbb_hash($username . $username),
);
return user_add($user_row);
}
@ -279,15 +461,14 @@ class phpbb_functional_test_case extends phpbb_test_case
{
$this->add_lang('ucp');
$crawler = $this->request('GET', 'ucp.php');
$crawler = self::request('GET', 'ucp.php');
$this->assertContains($this->lang('LOGIN_EXPLAIN_UCP'), $crawler->filter('html')->text());
$form = $crawler->selectButton($this->lang('LOGIN'))->form();
$crawler = $this->client->submit($form, array('username' => $username, 'password' => $username));
$this->assert_response_success();
$crawler = self::submit($form, array('username' => $username, 'password' => $username . $username));
$this->assertContains($this->lang('LOGIN_REDIRECT'), $crawler->filter('html')->text());
$cookies = $this->cookieJar->all();
$cookies = self::$cookieJar->all();
// The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie
foreach ($cookies as $cookie);
@ -314,7 +495,7 @@ class phpbb_functional_test_case extends phpbb_test_case
return;
}
$crawler = $this->request('GET', 'adm/index.php?sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid);
$this->assertContains($this->lang('LOGIN_ADMIN_CONFIRM'), $crawler->filter('html')->text());
$form = $crawler->selectButton($this->lang('LOGIN'))->form();
@ -323,11 +504,10 @@ class phpbb_functional_test_case extends phpbb_test_case
{
if (strpos($field, 'password_') === 0)
{
$crawler = $this->client->submit($form, array('username' => $username, $field => $username));
$this->assert_response_success();
$crawler = self::submit($form, array('username' => $username, $field => $username . $username));
$this->assertContains($this->lang('LOGIN_ADMIN_SUCCESS'), $crawler->filter('html')->text());
$cookies = $this->cookieJar->all();
$cookies = self::$cookieJar->all();
// The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie
foreach ($cookies as $cookie);
@ -380,21 +560,37 @@ class phpbb_functional_test_case extends phpbb_test_case
return call_user_func_array('sprintf', $args);
}
/**
* Perform some basic assertions for the page
*
* Checks for debug/error output before the actual page content and the status code
*
* @param mixed $status_code Expected status code, false to disable check
* @return null
*/
static public function assert_response_html($status_code = 200)
{
if ($status_code !== false)
{
self::assert_response_status_code($status_code);
}
// Any output before the doc type means there was an error
$content = self::$client->getResponse()->getContent();
self::assertStringStartsWith('<!DOCTYPE', trim($content), 'Output found before DOCTYPE specification.');
}
/**
* Heuristic function to check that the response is success.
*
* When php decides to die with a fatal error, it still sends 200 OK
* status code. This assertion tries to catch that.
*
* @param int $status_code Expected status code
* @return null
*/
public function assert_response_success()
static public function assert_response_status_code($status_code = 200)
{
$this->assertEquals(200, $this->client->getResponse()->getStatus());
$content = $this->client->getResponse()->getContent();
$this->assertNotContains('Fatal error:', $content);
$this->assertNotContains('Notice:', $content);
$this->assertNotContains('Warning:', $content);
$this->assertNotContains('[phpBB Debug]', $content);
self::assertEquals($status_code, self::$client->getResponse()->getStatus());
}
}