diff options
63 files changed, 2841 insertions, 377 deletions
diff --git a/.travis.yml b/.travis.yml index 0bb6920412..5e2569dd22 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,25 +10,19 @@ env: - DB=mysql - DB=postgres -matrix: - allow_failures: - - php: 5.5 - before_script: - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi" - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'create database phpbb_tests;' -U postgres; fi" - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi" - - sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.2' ]; then pyrus set auto_discover 1; fi" - - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then pear install --force phpunit/DbUnit; else pyrus install --force phpunit/DbUnit; fi" - - phpenv rehash + - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then pear install --force phpunit/DbUnit; phpenv rehash; fi" - cd phpBB - - sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.2' ]; then php ../composer.phar install --dev; fi" + - sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.2' ]; then php ../composer.phar install --dev --no-interaction --prefer-source; fi" - cd .. - sh -c "if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.3.19', '>=');"` = "1" ]; then travis/setup-webserver.sh; fi" script: - - phpunit --configuration travis/phpunit-$DB-travis.xml - + - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then phpunit --configuration travis/phpunit-$DB-travis.xml; else phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml; fi" + notifications: email: recipients: diff --git a/build/build.xml b/build/build.xml index f9574a3d4d..75affb0f2d 100644 --- a/build/build.xml +++ b/build/build.xml @@ -56,7 +56,8 @@ <target name="test" depends="clean,prepare,composer"> <exec dir="." - command="phpunit --log-junit build/logs/phpunit.xml + command="phpBB/vendor/bin/phpunit + --log-junit build/logs/phpunit.xml --coverage-clover build/logs/clover.xml --coverage-html build/coverage" passthru="true" /> @@ -64,7 +65,8 @@ <target name="test-slow" depends="clean,prepare,composer"> <exec dir="." - command="phpunit --log-junit build/logs/phpunit.xml + command="phpBB/vendor/bin/phpunit + --log-junit build/logs/phpunit.xml --configuration phpunit.xml.all --group slow --coverage-clover build/logs/clover-slow.xml diff --git a/composer.phar b/composer.phar Binary files differindex af7b8c1a67..a035fdc911 100755 --- a/composer.phar +++ b/composer.phar diff --git a/git-tools/merge.php b/git-tools/merge.php index 034bd2032c..f6142095fb 100755 --- a/git-tools/merge.php +++ b/git-tools/merge.php @@ -78,12 +78,12 @@ function work($pull_id, $remote) add_remote($pull_user, 'phpbb3'); run("git fetch $pull_user"); run("git merge --no-ff $pull_user/$pull_branch"); - run("phpunit"); + run("phpBB/vendor/bin/phpunit"); run("git checkout develop"); run("git pull $remote develop"); run("git merge --no-ff develop-olympus"); - run("phpunit"); + run("phpBB/vendor/bin/phpunit"); break; case 'develop': @@ -93,7 +93,7 @@ function work($pull_id, $remote) add_remote($pull_user, 'phpbb3'); run("git fetch $pull_user"); run("git merge --no-ff $pull_user/$pull_branch"); - run("phpunit"); + run("phpBB/vendor/bin/phpunit"); break; default: @@ -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); + + 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 json_decode($contents); + 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; diff --git a/git-tools/setup_github_network.php b/git-tools/setup_github_network.php index 5f2e1609a7..4e144edae6 100755 --- a/git-tools/setup_github_network.php +++ b/git-tools/setup_github_network.php @@ -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, ); } diff --git a/phpBB/composer.json b/phpBB/composer.json index 8d5dd1d52e..14190f5e82 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -1,6 +1,7 @@ { - "minimum-stability": "beta", "require-dev": { - "fabpot/goutte": "v0.1.0" + "fabpot/goutte": "v0.1.0", + "phpunit/dbunit": "1.2.*", + "phpunit/phpunit": "3.7.*" } } diff --git a/phpBB/composer.lock b/phpBB/composer.lock index a78fff9a14..70b352a320 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -1,60 +1,11 @@ { - "hash": "23352b29002e6d22658e314a8e737f71", + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" + ], + "hash": "656de56578d4eb3e4779bc0ab95524f5", "packages": [ - { - "name": "symfony/event-dispatcher", - "version": "v2.1.4", - "target-dir": "Symfony/Component/EventDispatcher", - "source": { - "type": "git", - "url": "https://github.com/symfony/EventDispatcher", - "reference": "v2.1.4" - }, - "dist": { - "type": "zip", - "url": "https://github.com/symfony/EventDispatcher/archive/v2.1.4.zip", - "reference": "v2.1.4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/dependency-injection": "2.1.*" - }, - "suggest": { - "symfony/dependency-injection": "2.1.*", - "symfony/http-kernel": "2.1.*" - }, - "time": "2012-11-08 09:51:48", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "Symfony\\Component\\EventDispatcher": "" - } - }, - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "http://symfony.com" - } + ], "packages-dev": [ { @@ -72,28 +23,27 @@ "shasum": "" }, "require": { - "php": ">=5.3.0", "ext-curl": "*", + "guzzle/guzzle": "3.0.*", + "php": ">=5.3.0", "symfony/browser-kit": "2.1.*", "symfony/css-selector": "2.1.*", "symfony/dom-crawler": "2.1.*", "symfony/finder": "2.1.*", - "symfony/process": "2.1.*", - "guzzle/guzzle": "3.0.*" + "symfony/process": "2.1.*" }, - "time": "2012-12-02 13:44:35", "type": "application", "extra": { "branch-alias": { "dev-master": "1.0-dev" } }, - "installation-source": "source", "autoload": { "psr-0": { "Goutte": "." } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -107,26 +57,27 @@ "homepage": "https://github.com/fabpot/Goutte", "keywords": [ "scraper" - ] + ], + "time": "2012-12-02 13:44:35" }, { "name": "guzzle/guzzle", - "version": "v3.0.5", + "version": "v3.0.7", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle", - "reference": "v3.0.5" + "reference": "v3.0.7" }, "dist": { "type": "zip", - "url": "https://github.com/guzzle/guzzle/archive/v3.0.5.zip", - "reference": "v3.0.5", + "url": "https://github.com/guzzle/guzzle/archive/v3.0.7.zip", + "reference": "v3.0.7", "shasum": "" }, "require": { - "php": ">=5.3.2", "ext-curl": "*", - "symfony/event-dispatcher": "2.1.*" + "php": ">=5.3.2", + "symfony/event-dispatcher": ">=2.1" }, "replace": { "guzzle/batch": "self.version", @@ -153,23 +104,27 @@ }, "require-dev": { "doctrine/common": "*", - "symfony/class-loader": "*", "monolog/monolog": "1.*", - "zendframework/zend-cache": "2.0.*", - "zendframework/zend-log": "2.0.*", - "zend/zend-log1": "1.12", + "phpunit/phpunit": "3.7.*", + "symfony/class-loader": "*", "zend/zend-cache1": "1.12", - "phpunit/phpunit": "3.7.*" + "zend/zend-log1": "1.12", + "zendframework/zend-cache": "2.0.*", + "zendframework/zend-log": "2.0.*" }, - "time": "2012-11-19 00:15:33", "type": "library", - "installation-source": "dist", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, "autoload": { "psr-0": { "Guzzle\\Tests": "tests/", "Guzzle": "src/" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -187,54 +142,461 @@ "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", "homepage": "http://guzzlephp.org/", "keywords": [ - "framework", + "client", "curl", + "framework", "http", - "rest", "http client", - "client", + "rest", "web service" - ] + ], + "time": "2012-12-19 23:06:35" }, { - "name": "symfony/browser-kit", - "version": "v2.1.4", - "target-dir": "Symfony/Component/BrowserKit", + "name": "phpunit/dbunit", + "version": "1.2.3", "source": { "type": "git", - "url": "https://github.com/symfony/BrowserKit", - "reference": "v2.1.4" + "url": "https://github.com/sebastianbergmann/dbunit.git", + "reference": "1.2.3" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/BrowserKit/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/1.2.3", + "reference": "1.2.3", "shasum": "" }, "require": { + "ext-pdo": "*", + "ext-simplexml": "*", "php": ">=5.3.3", - "symfony/dom-crawler": "2.1.*" + "phpunit/phpunit": ">=3.7.0@stable" + }, + "bin": [ + "dbunit.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "DbUnit port for PHP/PHPUnit to support database interaction testing.", + "homepage": "https://github.com/sebastianbergmann/dbunit/", + "keywords": [ + "database", + "testing", + "xunit" + ], + "time": "2013-03-01 11:50:46" + }, + { + "name": "phpunit/php-code-coverage", + "version": "1.2.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "1.2.9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.9", + "reference": "1.2.9", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": ">=1.3.0@stable", + "phpunit/php-text-template": ">=1.1.1@stable", + "phpunit/php-token-stream": ">=1.1.3@stable" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.0.5" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2013-02-26 18:55:56" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.3.3", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "1.3.3" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-file-iterator/zipball/1.3.3", + "reference": "1.3.3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "File/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2012-10-11 04:44:38" + }, + { + "name": "phpunit/php-text-template", + "version": "1.1.4", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-text-template.git", + "reference": "1.1.4" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-text-template/zipball/1.1.4", + "reference": "1.1.4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2012-10-31 11:15:28" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.4", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-timer.git", + "reference": "1.0.4" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-timer/zipball/1.0.4", + "reference": "1.0.4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "timer" + ], + "time": "2012-10-11 04:45:58" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.1.5", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-token-stream.git", + "reference": "1.1.5" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-token-stream/zipball/1.1.5", + "reference": "1.1.5", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "tokenizer" + ], + "time": "2012-10-11 04:47:14" + }, + { + "name": "phpunit/phpunit", + "version": "3.7.19", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "3.7.19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.19", + "reference": "3.7.19", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpunit/php-code-coverage": ">=1.2.1,<1.3.0", + "phpunit/php-file-iterator": ">=1.3.1", + "phpunit/php-text-template": ">=1.1.1", + "phpunit/php-timer": ">=1.0.2,<1.1.0", + "phpunit/phpunit-mock-objects": ">=1.2.0,<1.3.0", + "symfony/yaml": ">=2.0.0,<2.3.0" }, "require-dev": { - "symfony/process": "2.1.*", - "symfony/css-selector": "2.1.*" + "pear-pear/pear": "1.9.4" }, "suggest": { - "symfony/process": "2.1.*" + "ext-json": "*", + "ext-simplexml": "*", + "ext-tokenizer": "*", + "phpunit/php-invoker": ">=1.1.0,<1.2.0" }, - "time": "2012-11-08 09:51:48", + "bin": [ + "composer/bin/phpunit" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "3.7.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2013-03-25 11:45:06" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "1.2.3", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "1.2.3" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects/archive/1.2.3.zip", + "reference": "1.2.3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-text-template": ">=1.1.1@stable" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2013-01-13 10:24:48" + }, + { + "name": "symfony/browser-kit", + "version": "v2.1.10", + "target-dir": "Symfony/Component/BrowserKit", + "source": { + "type": "git", + "url": "https://github.com/symfony/BrowserKit.git", + "reference": "v2.1.10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/v2.1.10", + "reference": "v2.1.10", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/dom-crawler": "2.1.*" + }, + "require-dev": { + "symfony/css-selector": "2.1.*", + "symfony/process": "2.1.*" + }, + "suggest": { + "symfony/process": "2.1.*" }, - "installation-source": "dist", + "type": "library", "autoload": { "psr-0": { "Symfony\\Component\\BrowserKit": "" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -249,39 +611,34 @@ } ], "description": "Symfony BrowserKit Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-04-29 20:22:06" }, { "name": "symfony/css-selector", - "version": "v2.1.4", + "version": "v2.1.10", "target-dir": "Symfony/Component/CssSelector", "source": { "type": "git", - "url": "https://github.com/symfony/CssSelector", - "reference": "v2.1.4" + "url": "https://github.com/symfony/CssSelector.git", + "reference": "v2.1.10" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/CssSelector/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://api.github.com/repos/symfony/CssSelector/zipball/v2.1.10", + "reference": "v2.1.10", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-11-08 09:51:48", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\CssSelector": "" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -296,21 +653,22 @@ } ], "description": "Symfony CssSelector Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-01-09 08:51:07" }, { "name": "symfony/dom-crawler", - "version": "v2.1.4", + "version": "v2.1.10", "target-dir": "Symfony/Component/DomCrawler", "source": { "type": "git", - "url": "https://github.com/symfony/DomCrawler", - "reference": "v2.1.4" + "url": "https://github.com/symfony/DomCrawler.git", + "reference": "v2.1.10" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/DomCrawler/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/v2.1.10", + "reference": "v2.1.10", "shasum": "" }, "require": { @@ -322,19 +680,13 @@ "suggest": { "symfony/css-selector": "2.1.*" }, - "time": "2012-11-29 10:32:18", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\DomCrawler": "" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -349,39 +701,88 @@ } ], "description": "Symfony DomCrawler Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-03-27 17:13:16" }, { - "name": "symfony/finder", - "version": "v2.1.4", - "target-dir": "Symfony/Component/Finder", + "name": "symfony/event-dispatcher", + "version": "v2.2.1", + "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", - "url": "https://github.com/symfony/Finder", - "reference": "v2.1.4" + "url": "https://github.com/symfony/EventDispatcher.git", + "reference": "v2.2.1" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Finder/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.1", + "reference": "v2.2.1", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-11-08 09:51:48", + "require-dev": { + "symfony/dependency-injection": ">=2.0,<3.0" + }, + "suggest": { + "symfony/dependency-injection": "2.2.*", + "symfony/http-kernel": "2.2.*" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\EventDispatcher\\": "" } }, - "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "http://symfony.com", + "time": "2013-02-11 11:26:43" + }, + { + "name": "symfony/finder", + "version": "v2.1.10", + "target-dir": "Symfony/Component/Finder", + "source": { + "type": "git", + "url": "https://github.com/symfony/Finder.git", + "reference": "v2.1.10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.1.10", + "reference": "v2.1.10", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", "autoload": { "psr-0": { "Symfony\\Component\\Finder": "" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -396,39 +797,81 @@ } ], "description": "Symfony Finder Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-03-06 19:26:55" }, { "name": "symfony/process", - "version": "v2.1.4", + "version": "v2.1.9", "target-dir": "Symfony/Component/Process", "source": { "type": "git", - "url": "https://github.com/symfony/Process", - "reference": "v2.1.4" + "url": "https://github.com/symfony/Process.git", + "reference": "v2.1.9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Process/zipball/v2.1.9", + "reference": "v2.1.9", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "psr-0": { + "Symfony\\Component\\Process": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "http://symfony.com", + "time": "2013-03-23 07:44:01" + }, + { + "name": "symfony/yaml", + "version": "v2.2.1", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "v2.2.1" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Process/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.2.1", + "reference": "v2.2.1", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-11-19 20:53:52", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } }, - "installation-source": "dist", "autoload": { "psr-0": { - "Symfony\\Component\\Process": "" + "Symfony\\Component\\Yaml\\": "" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -442,15 +885,22 @@ "homepage": "http://symfony.com/contributors" } ], - "description": "Symfony Process Component", - "homepage": "http://symfony.com" + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2013-03-23 07:49:54" } ], "aliases": [ ], - "minimum-stability": "beta", + "minimum-stability": "stable", "stability-flags": [ + ], + "platform": [ + + ], + "platform-dev": [ + ] } diff --git a/phpBB/docs/AUTHORS b/phpBB/docs/AUTHORS index fcef26daa1..5995bd2ab4 100644 --- a/phpBB/docs/AUTHORS +++ b/phpBB/docs/AUTHORS @@ -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] diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index cd113a7226..dd0ee0a82f 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -956,6 +956,8 @@ $action_ary = request_var('action', array('' => 0)); <h4>Login checks/redirection: </h4> <p>To show a forum login box use <code>login_forum_box($forum_data)</code>, else use the <code>login_box()</code> function.</p> + <p><code>$forum_data</code> should contain at least the <code>forum_id</code> and <code>forum_password</code> fields. If the field <code>forum_name</code> is available, then it is displayed on the forum login page.</p> + <p>The <code>login_box()</code> function can have a redirect as the first parameter. As a thumb of rule, specify an empty string if you want to redirect to the users current location, else do not add the <code>$SID</code> to the redirect string (for example within the ucp/login we redirect to the board index because else the user would be redirected to the login screen).</p> <h4>Sensitive Operations: </h4> @@ -2314,7 +2316,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <hr /> -<a name="disclaimer"></a><h2>8. Copyright and disclaimer</h2> +<a name="disclaimer"></a><h2>7. Copyright and disclaimer</h2> <div class="paragraph"> <div class="inner"><span class="corners-top"><span></span></span> diff --git a/phpBB/download/file.php b/phpBB/download/file.php index bf277c69fa..22be27c922 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -170,7 +170,7 @@ else if (!$attachment['in_message']) { // - $sql = 'SELECT p.forum_id, f.forum_password, f.parent_id + $sql = 'SELECT p.forum_id, f.forum_name, f.forum_password, f.parent_id FROM ' . POSTS_TABLE . ' p, ' . FORUMS_TABLE . ' f WHERE p.post_id = ' . $attachment['post_msg_id'] . ' AND p.forum_id = f.forum_id'; @@ -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; + } +} + ?>
\ No newline at end of file diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index beb7aefee5..9b9ea38e07 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -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); @@ -413,13 +423,21 @@ class acp_groups } } - // Validate the length of "Maximum number of allowed recipients per private message" setting. - // We use 16777215 as a maximum because it matches MySQL unsigned mediumint maximum value - // which is the lowest amongst DBMSes supported by phpBB3 - if ($max_recipients_error = validate_data($submit_ary, array('max_recipients' => array('num', false, 0, 16777215)))) + /* + * Validate the length of "Maximum number of allowed recipients per + * private message" setting. We use 16777215 as a maximum because it matches + * MySQL unsigned mediumint maximum value which is the lowest amongst DBMSes + * supported by phpBB3. Also validate the submitted colour value. + */ + $validation_checks = array( + 'max_recipients' => array('num', false, 0, 16777215), + 'colour' => array('hex_colour', true), + ); + + if ($validation_error = validate_data($submit_ary, $validation_checks)) { // Replace "error" string with its real, localised form - $error = array_merge($error, array_map(array(&$user, 'lang'), $max_recipients_error)); + $error = array_merge($error, array_map(array(&$user, 'lang'), $validation_error)); } if (!sizeof($error)) diff --git a/phpBB/includes/acp/acp_update.php b/phpBB/includes/acp/acp_update.php index 7e3d1a1024..5d3e9abcea 100644 --- a/phpBB/includes/acp/acp_update.php +++ b/phpBB/includes/acp/acp_update.php @@ -39,7 +39,7 @@ class acp_update $info = obtain_latest_version_info(request_var('versioncheck_force', false)); - if ($info === false) + if (empty($info)) { trigger_error('VERSIONCHECK_FAIL', E_USER_WARNING); } diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index ccd2d3147c..b2b12c1445 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1005,7 +1005,7 @@ if (!function_exists('stripos')) */ function is_absolute($path) { - return ($path[0] == '/' || (DIRECTORY_SEPARATOR == '\\' && preg_match('#^[a-z]:[/\\\]#i', $path))) ? true : false; + return (isset($path[0]) && $path[0] == '/' || preg_match('#^[a-z]:[/\\\]#i', $path)) ? true : false; } /** @@ -2740,7 +2740,7 @@ function meta_refresh($time, $url, $disable_cd_check = false) // For XHTML compatibility we change back & to & $template->assign_vars(array( - 'META' => '<meta http-equiv="refresh" content="' . $time . ';url=' . $url . '" />') + 'META' => '<meta http-equiv="refresh" content="' . $time . '; url=' . $url . '" />') ); return $url; @@ -3272,6 +3272,7 @@ function login_forum_box($forum_data) page_header($user->lang['LOGIN'], false); $template->assign_vars(array( + 'FORUM_NAME' => isset($forum_data['forum_name']) ? $forum_data['forum_name'] : '', 'S_LOGIN_ACTION' => build_url(array('f')), 'S_HIDDEN_FIELDS' => build_hidden_fields(array('f' => $forum_data['forum_id']))) ); diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 190185cfcf..a9d1db24a5 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -3319,7 +3319,7 @@ function obtain_latest_version_info($force_update = false, $warn_fail = false, $ $info = get_remote_file('version.phpbb.com', '/phpbb', ((defined('PHPBB_QA')) ? '30x_qa.txt' : '30x.txt'), $errstr, $errno); - if ($info === false) + if (empty($info)) { $cache->destroy('versioncheck'); if ($warn_fail) diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index e5cbae0d71..2e5130c5b8 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -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'); diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 5a6a0b4a05..ea8b0a4640 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -1247,8 +1247,9 @@ function validate_data($data, $val_ary) { $function = array_shift($validate); array_unshift($validate, $data[$var]); + $function_prefix = (function_exists('phpbb_validate_' . $function)) ? 'phpbb_validate_' : 'validate_'; - if ($result = call_user_func_array('validate_' . $function, $validate)) + if ($result = call_user_func_array($function_prefix . $function, $validate)) { // Since errors are checked later for their language file existence, we need to make sure custom errors are not adjusted. $error[] = (empty($user->lang[$result . '_' . strtoupper($var)])) ? $result : $result . '_' . strtoupper($var); @@ -1553,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') { @@ -1899,6 +1900,30 @@ function validate_jabber($jid) } /** +* Validate hex colour value +* +* @param string $colour The hex colour value +* @param bool $optional Whether the colour value is optional. True if an empty +* string will be accepted as correct input, false if not. +* @return bool|string Error message if colour value is incorrect, false if it +* fits the hex colour code +*/ +function phpbb_validate_hex_colour($colour, $optional = false) +{ + if ($colour === '') + { + return (($optional) ? false : 'WRONG_DATA'); + } + + if (!preg_match('/^([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/', $colour)) + { + return 'WRONG_DATA'; + } + + return false; +} + +/** * Verifies whether a style ID corresponds to an active style. * * @param int $style_id The style_id of a style which should be checked if activated or not. diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index bd4c003397..f28b8885e7 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -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 diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index b93f2ff65e..fe5357f32e 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -1661,7 +1661,7 @@ class user extends session if (!$this->theme) { - trigger_error('Could not get style data', E_USER_ERROR); + trigger_error('NO_STYLE_DATA', E_USER_ERROR); } // Now parse the cfg file and cache it diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index d62dbb1866..9365913541 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -595,6 +595,13 @@ class ucp_groups $error[] = $user->lang['FORM_INVALID']; } + // Validate submitted colour value + if ($colour_error = validate_data($submit_ary, array('colour' => array('hex_colour', true)))) + { + // Replace "error" string with its real, localised form + $error = array_merge($error, array_map(array(&$user, 'lang'), $colour_error)); + } + if (!sizeof($error)) { // Only set the rank, colour, etc. if it's changed or if we're adding a new diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index 8e82188aff..d7509a1072 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -271,19 +271,16 @@ function compose_pm($id, $mode, $action, $user_folders = array()) // Passworded forum? if ($post['forum_id']) { - $sql = 'SELECT forum_password + $sql = 'SELECT forum_id, forum_name, forum_password FROM ' . FORUMS_TABLE . ' WHERE forum_id = ' . (int) $post['forum_id']; $result = $db->sql_query($sql); - $forum_password = (string) $db->sql_fetchfield('forum_password'); + $forum_data = $db->sql_fetchrow($result); $db->sql_freeresult($result); - if ($forum_password) + if (!empty($forum_data['forum_password'])) { - login_forum_box(array( - 'forum_id' => $post['forum_id'], - 'forum_password' => $forum_password, - )); + login_forum_box($forum_data); } } } diff --git a/phpBB/install/install_convert.php b/phpBB/install/install_convert.php index 62efc3e46b..fb97255981 100644 --- a/phpBB/install/install_convert.php +++ b/phpBB/install/install_convert.php @@ -2087,7 +2087,7 @@ class install_convert extends module // Because we should not rely on correct settings, we simply use the relative path here directly. $template->assign_vars(array( 'S_REFRESH' => true, - 'META' => '<meta http-equiv="refresh" content="5;url=' . $url . '" />') + 'META' => '<meta http-equiv="refresh" content="5; url=' . $url . '" />') ); } } diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index 0575b58d92..4618cff855 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -1025,8 +1025,8 @@ class install_install extends module } // Replace backslashes and doubled slashes (could happen on some proxy setups) - $name = str_replace(array('\\', '//', '/install'), '/', $name); - $data['script_path'] = trim(dirname($name)); + $name = str_replace(array('\\', '//'), '/', $name); + $data['script_path'] = trim(dirname(dirname($name))); } foreach ($this->advanced_config_options as $config_key => $vars) diff --git a/phpBB/install/install_update.php b/phpBB/install/install_update.php index ec76f2a407..c18a0fb4ec 100644 --- a/phpBB/install/install_update.php +++ b/phpBB/install/install_update.php @@ -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) { diff --git a/phpBB/language/en/acp/search.php b/phpBB/language/en/acp/search.php index a7d687d7c2..79ac75c833 100644 --- a/phpBB/language/en/acp/search.php +++ b/phpBB/language/en/acp/search.php @@ -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:', diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 6dd390ed24..c986e8213d 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -391,6 +391,7 @@ $lang = array_merge($lang, array( 'NO_POSTS_TIME_FRAME' => 'No posts exist inside this topic for the selected time frame.', 'NO_FEED_ENABLED' => 'Feeds are not available on this board.', 'NO_FEED' => 'The requested feed is not available.', + 'NO_STYLE_DATA' => 'Could not get style data', 'NO_SUBJECT' => 'No subject specified', // Used for posts having no subject defined but displayed within management pages. 'NO_SUCH_SEARCH_MODULE' => 'The specified search backend doesn’t exist.', 'NO_SUPPORTED_AUTH_METHODS' => 'No supported authentication methods.', @@ -721,6 +722,7 @@ $lang = array_merge($lang, array( 'WHO_IS_ONLINE' => 'Who is online', 'WRONG_PASSWORD' => 'You entered an incorrect password.', + 'WRONG_DATA_COLOUR' => 'The colour value you entered is invalid.', 'WRONG_DATA_ICQ' => 'The number you entered is not a valid ICQ number.', 'WRONG_DATA_JABBER' => 'The name you entered is not a valid Jabber account name.', 'WRONG_DATA_LANG' => 'The language you specified is not valid.', diff --git a/phpBB/posting.php b/phpBB/posting.php index e57f5420f5..42c4f7bc55 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -196,6 +196,7 @@ if ($post_data['forum_password']) { login_forum_box(array( 'forum_id' => $forum_id, + 'forum_name' => $post_data['forum_name'], 'forum_password' => $post_data['forum_password']) ); } diff --git a/phpBB/styles/prosilver/template/login_forum.html b/phpBB/styles/prosilver/template/login_forum.html index a342a9aa24..81a83b6340 100644 --- a/phpBB/styles/prosilver/template/login_forum.html +++ b/phpBB/styles/prosilver/template/login_forum.html @@ -1,31 +1,36 @@ <!-- INCLUDE overall_header.html --> -<h2 class="solo">{L_LOGIN} {FORUM_NAME}</h2> +<!-- IF FORUM_NAME --><h2><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2><!-- ENDIF --> <form id="login_forum" method="post" action="{S_LOGIN_ACTION}"> {S_FORM_TOKEN} <div class="panel"> <div class="inner"><span class="corners-top"><span></span></span> - <p>{L_LOGIN_FORUM}</p> - - <fieldset class="fields2"> - <!-- IF LOGIN_ERROR --> - <dl> - <dt> </dt> - <dd class="error">{LOGIN_ERROR}</dd> - </dl> - <!-- ENDIF --> - <dl> - <dt><label for="password">{L_PASSWORD}:</label></dt> - <dd><input class="inputbox narrow" type="password" name="password" id="password" size="25" tabindex="1" /></dd> - </dl> - <dl class="fields2"> - <dt> </dt> - <dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" id="login" class="button1" value="{L_LOGIN}" tabindex="2" /></dd> - </dl> - {S_LOGIN_REDIRECT} - </fieldset> + <div class="content"> + <h2>{L_LOGIN}</h2> + + <p>{L_LOGIN_FORUM}</p> + + <fieldset class="fields1"> + <!-- IF LOGIN_ERROR --> + <dl> + <dt> </dt> + <dd class="error">{LOGIN_ERROR}</dd> + </dl> + <!-- ENDIF --> + + <dl> + <dt><label for="password">{L_PASSWORD}:</label></dt> + <dd><input type="password" tabindex="1" id="password" name="password" size="25" class="inputbox narrow" /></dd> + </dl> + {S_LOGIN_REDIRECT} + <dl> + <dt> </dt> + <dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" id="login" class="button1" value="{L_LOGIN}" tabindex="2" /></dd> + </dl> + </fieldset> + </div> <span class="corners-bottom"><span></span></span></div> </div> diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html index 9df648f644..e6a4bfba97 100644 --- a/phpBB/styles/prosilver/template/memberlist_search.html +++ b/phpBB/styles/prosilver/template/memberlist_search.html @@ -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"> diff --git a/phpBB/styles/prosilver/template/ucp_groups_manage.html b/phpBB/styles/prosilver/template/ucp_groups_manage.html index 87b548c23b..c90461312e 100644 --- a/phpBB/styles/prosilver/template/ucp_groups_manage.html +++ b/phpBB/styles/prosilver/template/ucp_groups_manage.html @@ -6,19 +6,18 @@ <div class="panel"> <div class="inner"><span class="corners-top"><span></span></span> - + + <!-- IF S_ERROR --> + <fieldset> + <p class="error">{ERROR_MSG}</p> + </fieldset> + <!-- ENDIF --> + <p>{L_GROUPS_EXPLAIN}</p> <!-- IF S_EDIT --> <h3>{L_GROUP_DETAILS}</h3> - - <!-- IF S_ERROR --> - <div class="errorbox"> - <h3>{L_WARNING}</h3> - <p>{ERROR_MSG}</p> - </div> - <!-- ENDIF --> - + <fieldset> <dl> <dt><label for="group_name">{L_GROUP_NAME}:</label></dt> @@ -55,7 +54,7 @@ <fieldset> <dl> <dt><label for="group_colour">{L_GROUP_COLOR}:</label><br /><span>{L_GROUP_COLOR_EXPLAIN}</span></dt> - <dd><input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="7" maxlength="7" class="inputbox narrow" /> <span style="background-color: {GROUP_COLOUR};"> </span> [ <a href="{U_SWATCH}" onclick="popup(this.href, 636, 150, '_swatch'); return false;">{L_COLOUR_SWATCH}</a> ]</dd> + <dd><input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="6" maxlength="6" class="inputbox narrow" /> <span style="background-color: {GROUP_COLOUR};"> </span> [ <a href="{U_SWATCH}" onclick="popup(this.href, 636, 150, '_swatch'); return false;">{L_COLOUR_SWATCH}</a> ]</dd> </dl> <dl> <dt><label for="group_rank">{L_GROUP_RANK}:</label></dt> diff --git a/phpBB/styles/subsilver2/template/login_forum.html b/phpBB/styles/subsilver2/template/login_forum.html index 96b025a2f9..e91a406611 100644 --- a/phpBB/styles/subsilver2/template/login_forum.html +++ b/phpBB/styles/subsilver2/template/login_forum.html @@ -1,5 +1,13 @@ <!-- INCLUDE overall_header.html --> +<!-- IF FORUM_NAME --> + <div id="pageheader"> + <h2><a class="titles" href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2> + </div> + + <br clear="all" /><br /> +<!-- ENDIF --> + <div id="pagecontent"> <form name="login_forum" method="post" action="{S_LOGIN_ACTION}"> diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.md index de9c751238..26a93f0430 100644 --- a/tests/RUNNING_TESTS.txt +++ b/tests/RUNNING_TESTS.md @@ -7,9 +7,14 @@ Prerequisites PHPUnit ------- -phpBB unit tests use PHPUnit framework. Version 3.5 or better is required -to run the tests. PHPUnit prefers to be installed via PEAR; refer to -http://www.phpunit.de/ for more information. +phpBB unit tests use the PHPUnit framework (see http://www.phpunit.de for more +information). Version 3.5 or higher is required to run the tests. PHPUnit can +be installed via Composer together with other development dependencies as +follows. + + $ cd phpBB + $ php ../composer.phar install --dev + $ cd .. PHP extensions -------------- @@ -74,14 +79,16 @@ In order to run tests on some of the databases that we support, it will be necessary to provide a custom DSN string in test_config.php. This is only needed for MSSQL 2000+ (PHP module), MSSQL via ODBC, and Firebird when PDO_Firebird does not work on your system -(https://bugs.php.net/bug.php?id=61183). The variable must be named $custom_dsn. +(https://bugs.php.net/bug.php?id=61183). The variable must be named `$custom_dsn`. Examples: Firebird using http://www.firebirdsql.org/en/odbc-driver/ -$custom_dsn = "Driver={Firebird/InterBase(r) driver};dbname=$dbhost:$dbname"; + + $custom_dsn = "Driver={Firebird/InterBase(r) driver};dbname=$dbhost:$dbname"; MSSQL -$custom_dsn = "Driver={SQL Server Native Client 10.0};Server=$dbhost;Database=$dbname"; + + $custom_dsn = "Driver={SQL Server Native Client 10.0};Server=$dbhost;Database=$dbname"; The other fields in test_config.php should be filled out as you would normally to connect to that database in phpBB. @@ -95,7 +102,7 @@ Running Once the prerequisites are installed, run the tests from the project root directory (above phpBB): - $ phpunit + $ phpBB/vendor/bin/phpunit Slow tests -------------- @@ -105,7 +112,7 @@ Thus these tests are in the `slow` group, which is excluded by default. You can enable slow tests by copying the phpunit.xml.all file to phpunit.xml. If you only want the slow tests, run: - $ phpunit --group slow + $ phpBB/vendor/bin/phpunit --group slow More Information ================ diff --git a/tests/dbal/order_lower_test.php b/tests/dbal/order_lower_test.php index b50494d506..b07f1baa91 100644 --- a/tests/dbal/order_lower_test.php +++ b/tests/dbal/order_lower_test.php @@ -14,7 +14,7 @@ class phpbb_dbal_order_lower_test extends phpbb_database_test_case return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/styles.xml'); } - public function test_cross_join() + public function test_order_lower() { $db = $this->new_dbal(); diff --git a/tests/functional/acp_groups_test.php b/tests/functional/acp_groups_test.php new file mode 100644 index 0000000000..3d8cabb086 --- /dev/null +++ b/tests/functional/acp_groups_test.php @@ -0,0 +1,21 @@ +<?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__) . '/common_groups_test.php'; + +/** +* @group functional +*/ +class phpbb_functional_acp_groups_test extends phpbb_functional_common_groups_test +{ + protected function get_url() + { + return 'adm/index.php?i=groups&mode=manage&action=edit'; + } +} diff --git a/tests/functional/auth_test.php b/tests/functional/auth_test.php index 662b1bd38b..afb4f15fc2 100644 --- a/tests/functional/auth_test.php +++ b/tests/functional/auth_test.php @@ -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()); } } diff --git a/tests/functional/browse_test.php b/tests/functional/browse_test.php index b5748059c6..18a2ad9464 100644 --- a/tests/functional/browse_test.php +++ b/tests/functional/browse_test.php @@ -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()); } } diff --git a/tests/functional/common_groups_test.php b/tests/functional/common_groups_test.php new file mode 100644 index 0000000000..7c88ec900d --- /dev/null +++ b/tests/functional/common_groups_test.php @@ -0,0 +1,44 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +abstract class phpbb_functional_common_groups_test extends phpbb_functional_test_case +{ + abstract protected function get_url(); + + public function groups_manage_test_data() + { + return array( + array('', 'GROUP_UPDATED'), + array('aa0000', 'GROUP_UPDATED'), + + array('AAG000','WRONG_DATA_COLOUR'), + array('#AA0000', 'WRONG_DATA_COLOUR'), + ); + } + + /** + * @dataProvider groups_manage_test_data + */ + public function test_groups_manage($input, $expected) + { + $this->login(); + $this->admin_login(); + $this->add_lang(array('ucp', 'acp/groups')); + + // Manage Administrators group + $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 = self::submit($form); + $this->assertContains($this->lang($expected), $crawler->text()); + } +} diff --git a/tests/functional/posting_test.php b/tests/functional/posting_test.php index d05207edf0..9bcfcc2fda 100644 --- a/tests/functional/posting_test.php +++ b/tests/functional/posting_test.php @@ -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(); diff --git a/tests/functional/ucp_groups_test.php b/tests/functional/ucp_groups_test.php new file mode 100644 index 0000000000..9c6b1edc5e --- /dev/null +++ b/tests/functional/ucp_groups_test.php @@ -0,0 +1,21 @@ +<?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__) . '/common_groups_test.php'; + +/** +* @group functional +*/ +class phpbb_functional_ucp_groups_test extends phpbb_functional_common_groups_test +{ + protected function get_url() + { + return 'ucp.php?i=groups&mode=manage&action=edit'; + } +} diff --git a/tests/functions/fixtures/language_select.xml b/tests/functions/fixtures/language_select.xml new file mode 100644 index 0000000000..d7232a3d28 --- /dev/null +++ b/tests/functions/fixtures/language_select.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_lang"> + <column>lang_id</column> + <column>lang_iso</column> + <column>lang_local_name</column> + <column>lang_english_name</column> + <row> + <value>1</value> + <value>en</value> + <value>English</value> + <value>English</value> + </row> + <row> + <value>2</value> + <value>cs</value> + <value>Čeština</value> + <value>Czech</value> + </row> + </table> +</dataset> diff --git a/tests/functions/fixtures/obtain_online.xml b/tests/functions/fixtures/obtain_online.xml new file mode 100644 index 0000000000..05bbe6a05e --- /dev/null +++ b/tests/functions/fixtures/obtain_online.xml @@ -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> diff --git a/tests/functions/fixtures/style_select.xml b/tests/functions/fixtures/style_select.xml new file mode 100644 index 0000000000..12d6392ab5 --- /dev/null +++ b/tests/functions/fixtures/style_select.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_styles"> + <column>style_id</column> + <column>style_name</column> + <column>style_active</column> + <row> + <value>1</value> + <value>prosilver</value> + <value>1</value> + </row> + <row> + <value>2</value> + <value>subsilver2</value> + <value>1</value> + </row> + <row> + <value>3</value> + <value>zoo</value> + <value>0</value> + </row> + </table> +</dataset> diff --git a/tests/functions/fixtures/validate_email.xml b/tests/functions/fixtures/validate_email.xml new file mode 100644 index 0000000000..de7fce8a08 --- /dev/null +++ b/tests/functions/fixtures/validate_email.xml @@ -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> diff --git a/tests/functions/fixtures/validate_username.xml b/tests/functions/fixtures/validate_username.xml new file mode 100644 index 0000000000..fbe398469c --- /dev/null +++ b/tests/functions/fixtures/validate_username.xml @@ -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> diff --git a/tests/functions/is_absolute_test.php b/tests/functions/is_absolute_test.php new file mode 100644 index 0000000000..7630b7c58c --- /dev/null +++ b/tests/functions/is_absolute_test.php @@ -0,0 +1,56 @@ +<?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'; + +class phpbb_functions_is_absolute_test extends phpbb_test_case +{ + static public function is_absolute_data() + { + return array( + // Empty + array('', false), + + // Absolute unix style + array('/etc/phpbb', true), + // Unix does not support \ so that is not an absolute path + array('\etc\phpbb', false), + + // Absolute windows style + array('c:\windows', true), + array('C:\Windows', true), + array('c:/windows', true), + array('C:/Windows', true), + + // Executable + array('etc/phpbb', false), + array('explorer.exe', false), + + // Relative subdir + array('Windows\System32', false), + array('Windows\System32\explorer.exe', false), + array('Windows/System32', false), + array('Windows/System32/explorer.exe', false), + + // Relative updir + array('..\Windows\System32', false), + array('..\Windows\System32\explorer.exe', false), + array('../Windows/System32', false), + array('../Windows/System32/explorer.exe', false), + ); + } + + /** + * @dataProvider is_absolute_data + */ + public function test_is_absolute($path, $expected) + { + $this->assertEquals($expected, is_absolute($path)); + } +} diff --git a/tests/functions/language_select_test.php b/tests/functions/language_select_test.php new file mode 100644 index 0000000000..3341e2a256 --- /dev/null +++ b/tests/functions/language_select_test.php @@ -0,0 +1,39 @@ +<?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'; + +class phpbb_functions_language_select_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/language_select.xml'); + } + + static public function language_select_data() + { + return array( + array('', '<option value="cs">Čeština</option><option value="en">English</option>'), + array('en', '<option value="cs">Čeština</option><option value="en" selected="selected">English</option>'), + array('cs', '<option value="cs" selected="selected">Čeština</option><option value="en">English</option>'), + array('de', '<option value="cs">Čeština</option><option value="en">English</option>'), + ); + } + + /** + * @dataProvider language_select_data + */ + public function test_language_select($default, $expected) + { + global $db; + $db = $this->new_dbal(); + + $this->assertEquals($expected, language_select($default)); + } +} diff --git a/tests/functions/obtain_online_test.php b/tests/functions/obtain_online_test.php new file mode 100644 index 0000000000..b3beb55a96 --- /dev/null +++ b/tests/functions/obtain_online_test.php @@ -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; + } +} diff --git a/tests/functions/style_select_test.php b/tests/functions/style_select_test.php new file mode 100644 index 0000000000..1e44f3c2cb --- /dev/null +++ b/tests/functions/style_select_test.php @@ -0,0 +1,41 @@ +<?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'; + +class phpbb_functions_style_select_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/style_select.xml'); + } + + static public function style_select_data() + { + return array( + array('', false, '<option value="1">prosilver</option><option value="2">subsilver2</option>'), + array('', true, '<option value="1">prosilver</option><option value="2">subsilver2</option><option value="3">zoo</option>'), + array('1', false, '<option value="1" selected="selected">prosilver</option><option value="2">subsilver2</option>'), + array('1', true, '<option value="1" selected="selected">prosilver</option><option value="2">subsilver2</option><option value="3">zoo</option>'), + array('3', false, '<option value="1">prosilver</option><option value="2">subsilver2</option>'), + array('3', true, '<option value="1">prosilver</option><option value="2">subsilver2</option><option value="3" selected="selected">zoo</option>'), + ); + } + + /** + * @dataProvider style_select_data + */ + public function test_style_select($default, $all, $expected) + { + global $db; + $db = $this->new_dbal(); + + $this->assertEquals($expected, style_select($default, $all)); + } +} diff --git a/tests/functions/validate_data_helper.php b/tests/functions/validate_data_helper.php new file mode 100644 index 0000000000..b92a3aa5eb --- /dev/null +++ b/tests/functions/validate_data_helper.php @@ -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]))); + } + } +} diff --git a/tests/functions/validate_date_test.php b/tests/functions/validate_date_test.php new file mode 100644 index 0000000000..1dcd1361a2 --- /dev/null +++ b/tests/functions/validate_date_test.php @@ -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'), + ), + */ + )); + } +} diff --git a/tests/functions/validate_email_test.php b/tests/functions/validate_email_test.php new file mode 100644 index 0000000000..9a6ce39251 --- /dev/null +++ b/tests/functions/validate_email_test.php @@ -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'), + ), + )); + } +} diff --git a/tests/functions/validate_hex_colour_test.php b/tests/functions/validate_hex_colour_test.php new file mode 100644 index 0000000000..812ebe5eeb --- /dev/null +++ b/tests/functions/validate_hex_colour_test.php @@ -0,0 +1,121 @@ +<?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'; + +class phpbb_functions_validate_hex_colour_test extends phpbb_test_case +{ + public function positive_match_data() + { + return array( + array('a00'), + array('AFF'), + array('AA0000'), + array('aa00FF'), + array('000'), + array('000000'), + ); + } + + public function negative_match_data() + { + return array( + // Invalid prefix + array('#aa0'), + array('#AA0000'), + array('vAA0000'), + + // Invalid suffix + array('AA0000v'), + + // Correct length, but out of hex range + array('ag0'), + array('AAG000'), + + // Too long + array('AA00000'), + array('AA0000 '), + array('AA0000 abf'), + array('AA0000 AA0000'), + + // empty() + array('0'), + ); + } + + public function optional_only_data() + { + return array( + // The empty colour, i.e. "no colour". + array(''), + ); + } + + public function strict_negative_match_data() + { + return array_merge( + $this->negative_match_data(), + $this->optional_only_data() + ); + } + + public function nonstrict_positive_match_data() + { + return array_merge( + $this->positive_match_data(), + $this->optional_only_data() + ); + } + + /** + * @dataProvider positive_match_data + */ + public function test_strict_positive_match($input) + { + $this->assertFalse( + phpbb_validate_hex_colour($input, false), + "Failed asserting that $input passes as a valid hex colour." + ); + } + + /** + * @dataProvider strict_negative_match_data + */ + public function test_strict_negative_match($input) + { + $this->assertSame( + 'WRONG_DATA', + phpbb_validate_hex_colour($input, false), + "Failed asserting that $input does not pass as a valid hex colour." + ); + } + + /** + * @dataProvider nonstrict_positive_match_data + */ + public function test_nonstrict_positive_match($input) + { + $this->assertFalse( + phpbb_validate_hex_colour($input, true), + "Failed asserting that $input passes as a valid or optional hex colour." + ); + } + + /** + * @dataProvider negative_match_data + */ + public function test_nonstrict_negative_match($input) + { + $this->assertSame( + 'WRONG_DATA', + phpbb_validate_hex_colour($input, true), + "Failed asserting that $input does not pass as a valid or optional hex colour." + ); + } +} diff --git a/tests/functions/validate_jabber_test.php b/tests/functions/validate_jabber_test.php new file mode 100644 index 0000000000..5a53c963bd --- /dev/null +++ b/tests/functions/validate_jabber_test.php @@ -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'), + ), + )); + } +} diff --git a/tests/functions/validate_lang_iso_test.php b/tests/functions/validate_lang_iso_test.php new file mode 100644 index 0000000000..c8a5b71021 --- /dev/null +++ b/tests/functions/validate_lang_iso_test.php @@ -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'), + ), + )); + } +} diff --git a/tests/functions/validate_match_test.php b/tests/functions/validate_match_test.php new file mode 100644 index 0000000000..73a363e003 --- /dev/null +++ b/tests/functions/validate_match_test.php @@ -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]$/'), + ), + )); + } +} diff --git a/tests/functions/validate_num_test.php b/tests/functions/validate_num_test.php new file mode 100644 index 0000000000..4deac02ebc --- /dev/null +++ b/tests/functions/validate_num_test.php @@ -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'), + ), + )); + } +} diff --git a/tests/functions/validate_password_test.php b/tests/functions/validate_password_test.php new file mode 100644 index 0000000000..4639f6cc89 --- /dev/null +++ b/tests/functions/validate_password_test.php @@ -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'), + ), + )); + } +} diff --git a/tests/functions/validate_string_test.php b/tests/functions/validate_string_test.php new file mode 100644 index 0000000000..ab44c28541 --- /dev/null +++ b/tests/functions/validate_string_test.php @@ -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), + ), + )); + } +} diff --git a/tests/functions/validate_username_test.php b/tests/functions/validate_username_test.php new file mode 100644 index 0000000000..0819974e54 --- /dev/null +++ b/tests/functions/validate_username_test.php @@ -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'), + ), + )); + } +} diff --git a/tests/mock/cache.php b/tests/mock/cache.php index aa0db5ab20..acf4288319 100644 --- a/tests/mock/cache.php +++ b/tests/mock/cache.php @@ -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; diff --git a/tests/mock/user.php b/tests/mock/user.php index ec14ce430e..bd547b3973 100644 --- a/tests/mock/user.php +++ b/tests/mock/user.php @@ -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; + } } diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index 429bb92bf1..28d3a716f0 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -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; } diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index 3b8c2e99ae..30f1fa6589 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -142,6 +142,28 @@ class phpbb_database_test_connection_manager } $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + switch ($this->config['dbms']) + { + case 'mysql': + case 'mysqli': + $this->pdo->exec('SET NAMES utf8'); + + /* + * The phpBB MySQL drivers set the STRICT_ALL_TABLES and + * STRICT_TRANS_TABLES flags/modes, so as a minimum requirement + * we want to make sure those are set for the PDO side of the + * test suite. + * + * The TRADITIONAL flag implies STRICT_ALL_TABLES and + * STRICT_TRANS_TABLES as well as other useful strictness flags + * the phpBB MySQL driver does not set. + */ + $this->pdo->exec("SET SESSION sql_mode='TRADITIONAL'"); + break; + + default: + } } /** @@ -459,11 +481,32 @@ class phpbb_database_test_connection_manager */ 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']) { @@ -520,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)) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 83c931f924..651ab013c7 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -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) + { + $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) { - return $this->client->request($method, $this->root_url . $path); + $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 @@ -148,28 +196,76 @@ class phpbb_functional_test_case extends phpbb_test_case } } - // 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); + // Reset the curl handle because it is 0 at this point and not a valid + // resource + self::$client->getClient()->getCurlMulti()->reset(true); - $data = array_merge($data, array( + $parseURL = parse_url(self::$config['phpbb_functional_url']); + + $crawler = self::request('GET', 'install/index.php?mode=install'); + self::assertContains('Welcome to Installation', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(); + + $crawler = self::submit($form); + self::assertContains('Installation compatibility', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(); + + $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'], + )); + + $crawler = self::submit($form); + self::assertContains('Successful connection', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(); + + $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' => 'admin', - 'admin_pass2' => 'admin', - 'board_email' => 'nobody@example.com', + 'admin_pass1' => 'adminadmin', + 'admin_pass2' => 'adminadmin', + 'board_email1' => 'nobody@example.com', + 'board_email2' => 'nobody@example.com', )); - $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::submit($form); + self::assertContains('Tests passed', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(); + + $crawler = self::submit($form); + self::assertContains('The configuration file has been written.', $crawler->filter('#main')->text()); + file_put_contents($phpbb_root_path . "config.$phpEx", phpbb_create_config_file_data(self::$config, self::$config['dbms'], array(), true, true)); + $form = $crawler->selectButton('submit')->form(); + + $crawler = self::submit($form); + 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 +273,15 @@ 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); - - $content = self::do_request('create_table', $data); - self::assertNotSame(false, $content); - self::assertContains('The database tables used by phpBB', $content); - // 3.0 or 3.1 - self::assertContains('have been created and populated with some initial data.', $content); - - $content = self::do_request('config_file', $data); - self::assertNotSame(false, $content); - self::assertContains('Configuration file', $content); - file_put_contents($phpbb_root_path . "config.$phpEx", phpbb_create_config_file_data($data, self::$config['dbms'], 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; + $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(); - 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); + $crawler = self::submit($form); + self::assertContains('You have successfully installed', $crawler->text()); + copy($phpbb_root_path . "config.$phpEx", $phpbb_root_path . "config_test.$phpEx"); } static private function recreate_database($config) @@ -270,7 +335,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 +344,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); @@ -299,6 +363,49 @@ class phpbb_functional_test_case extends phpbb_test_case } } + /** + * Login to the ACP + * You must run login() before calling this. + */ + protected function admin_login($username = 'admin') + { + $this->add_lang('acp/common'); + + // Requires login first! + if (empty($this->sid)) + { + $this->fail('$this->sid is empty. Make sure you call login() before admin_login()'); + return; + } + + $crawler = 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(); + + foreach ($form->getValues() as $field => $value) + { + if (strpos($field, 'password_') === 0) + { + $crawler = self::submit($form, array('username' => $username, $field => $username . $username)); + $this->assertContains($this->lang('LOGIN_ADMIN_SUCCESS'), $crawler->filter('html')->text()); + + $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); + { + if (substr($cookie->getName(), -4) == '_sid') + { + $this->sid = $cookie->getValue(); + } + } + + break; + } + } + } + protected function add_lang($lang_file) { if (is_array($lang_file)) @@ -337,20 +444,36 @@ class phpbb_functional_test_case extends phpbb_test_case } /** + * 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()); } } |
