diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..dfb8fea7d3 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,145 @@ +build: false +clone_folder: c:\projects\phpbb +version: '{build}' + +services: + - iis + +environment: + matrix: + - db: mssql + db_version: sql2012sp1 + php: 7.0 + - db: mssql + db_version: sql2014 + php: 7.0 + - db: mssql + db_version: sql2016 + php: 7.1.12 +# - db: mssql +# db_version: sql2017 +# php: 7.1 +# - db: mariadb +# php: 7.1 +# - db: mysqli +# php: 7.1 +# - db: sqlite +# php: 7.1 +# - db: postgresql +# php: 7.1 + +hosts: + phpbb.test: 127.0.0.1 + +init: + - SET PATH=%systemroot%\system32\inetsrv\;C:\Program Files\OpenSSL;C:\tools\php;c:\php;%PATH% + - SET ANSICON=121x90 (121x90) + - REG ADD "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v DelayedExpansion /t REG_DWORD /d 1 /f + +before_test: + - ps: | + Set-Service wuauserv -StartupType Manual + choco install chocolatey -y --version 0.10.13 --allow-downgrade + choco install php -y --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','') + Get-ChildItem -Path "c:\tools\php$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1$2')" -Recurse | + Move-Item -destination "c:\tools\php" + cd c:\tools\php + cat php.ini-development | %{$_ -replace "memory_limit = 128M","memory_limit = 1024M"} | Out-File -Encoding "Default" php.ini + Add-Content php.ini "`n date.timezone=UTC" + Add-Content php.ini "`n display_errors=On" + Add-Content php.ini "`n extension_dir=ext" + Add-Content php.ini "`n extension=php_openssl.dll" + Add-Content php.ini "`n extension=php_mbstring.dll" + Add-Content php.ini "`n extension=php_curl.dll" + Add-Content php.ini "`n extension=php_gd2.dll" + Add-Content php.ini "`n extension=php_tidy.dll" + Add-Content php.ini "`n extension=php_fileinfo.dll" + Add-Content php.ini "`n extension=php_pdo_sqlite.dll" + Add-Content php.ini "`n extension=php_sqlite3.dll" + Add-Content php.ini "`n extension=php_pdo_mysql.dll" + Add-Content php.ini "`n extension=php_mysqli.dll" + Add-Content php.ini "`n extension=php_pdo_pgsql.dll" + Add-Content php.ini "`n extension=php_pgsql.dll" + + # Get MSSQL driver + if ($env:db -eq "mssql") { + cd c:\tools\php\ext + $DLLVersion = "4.1.6.1" + curl -o php_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip https://windows.php.net/downloads/pecl/releases/sqlsrv/$($:DLLVersion)/php_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip + 7z x -y php_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip > $null + curl -o php_pdo_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip https://windows.php.net/downloads/pecl/releases/pdo_sqlsrv/$($DLLVersion)/php_pdo_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip + 7z x -y php_pdo_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip > $null + Remove-Item c:\tools\php\* -include .zip + cd c:\tools\php + Add-Content php.ini "`nextension=php_sqlsrv.dll" + Add-Content php.ini "`nextension=php_pdo_sqlsrv.dll" + Add-Content php.ini "`n" + + $instanceName = $env:db_version.ToUpper() + Start-Service "MSSQL`$$instanceName" + Set-Variable -Name "sqlServerPath" -Value "(local)\$($env:db_version.ToUpper())" + + # Create database write test config + sqlcmd -S $sqlServerPath -Q "Use [master]; CREATE DATABASE [phpbb_test] COLLATE Latin1_General_CI_AS" + $data = "", "`n`t`n`t`t`n`t") | Set-Content c:\projects\phpbb\phpBB\web.config + (Get-Content c:\projects\phpbb\phpBB\web.config).replace("`t", "`t`t`n`t") | Set-Content c:\projects\phpbb\phpBB\web.config + - cd c:\projects\phpbb\phpBB + - php ..\composer.phar install + - choco install urlrewrite -y + - ps: New-WebSite -Name 'phpBBTest' -PhysicalPath 'c:\projects\phpbb\phpBB' -Force + - ps: Import-Module WebAdministration; Set-ItemProperty 'IIS:\Sites\phpBBTest' -name Bindings -value @{protocol='http';bindingInformation='*:80:phpbb.test'} + - echo Change default anonymous user AUTH to ApplicationPool + - appcmd set config -section:anonymousAuthentication /username:"" --password + - echo Setup FAST-CGI configuration + - appcmd set config /section:system.webServer/fastCGI /+[fullPath='C:\tools\php\php-cgi.exe'] + - echo Setup FACT-CGI handler + - appcmd set config /section:system.webServer/handlers /+[name='PHP-FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='C:\tools\php\php-cgi.exe',resourceType='Either'] + - iisreset + - NET START W3SVC + - mkdir "C:\projects\phpbb\phpBB\cache\test" + - mkdir "C:\projects\phpbb\phpBB\cache\installer" + - icacls "C:\projects\phpbb\phpBB\cache" /grant Users:F /T + - icacls "C:\projects\phpbb\phpBB\files" /grant Users:F /T + - icacls "C:\projects\phpbb\phpBB\store" /grant Users:F /T + - icacls "C:\projects\phpbb\phpBB\images\avatars\upload" /grant Users:F /T + +test_script: + - cd c:\projects\phpbb + - php -e phpBB\vendor\phpunit\phpunit\phpunit --verbose + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 39eb83e454..cacfcf1118 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,9 +1,9 @@ Checklist: -- [ ] Correct branch: master for new features; 3.2.x, 3.1.x for fixes +- [ ] Correct branch: master for new features; 3.2.x for fixes - [ ] Tests pass -- [ ] Code follows coding guidelines: [master / 3.2.x](https://area51.phpbb.com/docs/master/coding-guidelines.html), [3.1.x](https://area51.phpbb.com/docs/31x/coding-guidelines.html) -- [ ] Commit follows commit message [format](https://wiki.phpbb.com/Git#Commit_Messages) +- [ ] Code follows coding guidelines: [master](https://area51.phpbb.com/docs/dev/master/development/coding_guidelines.html) and [3.2.x](https://area51.phpbb.com/docs/dev/3.2.x/development/coding_guidelines.html) +- [ ] Commit follows commit message [format](https://area51.phpbb.com/docs/dev/3.2.x/development/git.html) Tracker ticket (set the ticket ID to **your ticket ID**): diff --git a/.travis.yml b/.travis.yml index fa2a86c0db..3f3cf2b018 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: php -sudo: required -dist: precise +dist: trusty matrix: include: @@ -26,12 +25,11 @@ matrix: env: DB=mysqli - php: 7.1 env: DB=mysqli + - php: 7.2 + env: DB=mysqli - php: nightly env: DB=mysqli - - php: hhvm - env: DB=mysqli allow_failures: - - php: hhvm - php: nightly fast_finish: true @@ -53,4 +51,4 @@ script: - sh -c "if [ '$SLOWTESTS' != '1' -a '$DB' = 'mysqli' ]; then phpBB/vendor/bin/phpunit tests/lint_test.php; fi" - sh -c "if [ '$NOTESTS' != '1' -a '$SLOWTESTS' != '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --verbose --stop-on-error; fi" - sh -c "if [ '$SLOWTESTS' = '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --group slow; fi" - - sh -c "set -x;if [ '$NOTESTS' = '1' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..FETCH_HEAD; fi" + - sh -c "set -x;if [ '$NOTESTS' = '1' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git remote set-branches --add origin $TRAVIS_BRANCH && git fetch && git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..$TRAVIS_PULL_REQUEST_SHA; fi" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..ce992b2ce7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,281 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + diff --git a/README.md b/README.md index 63ccfedf1b..d1854dc74d 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ To be able to run an installation from the repo (and not from a pre-built packag 1. [Create an account on phpBB.com](http://www.phpbb.com/community/ucp.php?mode=register) 2. [Create a ticket (unless there already is one)](http://tracker.phpbb.com/secure/CreateIssue!default.jspa) -3. Read our [Coding guidelines](https://wiki.phpbb.com/Coding_guidelines) and [Git Contribution Guidelines](http://wiki.phpbb.com/Git) +3. Read our [Coding guidelines](https://area51.phpbb.com/docs/dev/development/coding_guidelines.html) and [Git Contribution Guidelines](https://area51.phpbb.com/docs/dev/development/git.html) 4. Send us a pull request ## VAGRANT @@ -29,11 +29,11 @@ Read our [Vagrant documentation](phpBB/docs/vagrant.md) to find out how to use V ## AUTOMATED TESTING -We have unit and functional tests in order to prevent regressions. You can view the bamboo continuous integration [here](http://bamboo.phpbb.com) or check our travis builds below: +We have unit and functional tests in order to prevent regressions. You can view the bamboo continuous integration [here](https://bamboo.phpbb.com) or check our travis builds below: -* [![Build Status](https://secure.travis-ci.org/phpbb/phpbb.png?branch=master)](http://travis-ci.org/phpbb/phpbb) **master** - Latest development version -* [![Build Status](https://secure.travis-ci.org/phpbb/phpbb.png?branch=3.2.x)](http://travis-ci.org/phpbb/phpbb) **3.2.x** - Development of version 3.2.x -* [![Build Status](https://secure.travis-ci.org/phpbb/phpbb.png?branch=3.1.x)](http://travis-ci.org/phpbb/phpbb) **3.1.x** - Development of version 3.1.x +* [![Build Status](https://travis-ci.org/phpbb/phpbb.svg?branch=master)](http://travis-ci.org/phpbb/phpbb)[![Build status](https://ci.appveyor.com/api/projects/status/8g98ybngd2f3axy1/branch/master?svg=true)](https://ci.appveyor.com/project/phpBB/phpbb/branch/master) **master** - Latest development version +* [![Build Status](https://travis-ci.org/phpbb/phpbb.svg?branch=3.2.x)](http://travis-ci.org/phpbb/phpbb)[![Build status](https://ci.appveyor.com/api/projects/status/8g98ybngd2f3axy1/branch/3.2.x?svg=true)](https://ci.appveyor.com/project/phpBB/phpbb/branch/3.2.x) **3.2.x** - Development of version 3.2.x +* [![Build Status](https://travis-ci.org/phpbb/phpbb.svg?branch=3.1.x)](http://travis-ci.org/phpbb/phpbb) **3.1.x** - Development of version 3.1.x ## LICENSE diff --git a/build/build.xml b/build/build.xml index 42f242b59d..006f9225e9 100644 --- a/build/build.xml +++ b/build/build.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/build/build_helper.php b/build/build_helper.php index 3ff1b89eab..c33e2419c6 100644 --- a/build/build_helper.php +++ b/build/build_helper.php @@ -33,14 +33,14 @@ class build_package var $status_begun = false; var $num_dots = 0; - function build_package($versions, $verbose = false) + function __construct($versions, $verbose = false) { $this->versions = $versions; $this->verbose = $verbose; // Get last two entries - $_latest = $this->versions[sizeof($this->versions) - 1]; - $_before = $this->versions[sizeof($this->versions) - 2]; + $_latest = $this->versions[count($this->versions) - 1]; + $_before = $this->versions[count($this->versions) - 2]; $this->locations = array( 'new_version' => dirname(dirname(__FILE__)) . '/phpBB/', diff --git a/build/package.php b/build/package.php index 178a27faad..18798d0602 100755 --- a/build/package.php +++ b/build/package.php @@ -33,7 +33,7 @@ echo "Now all three package types (patch, files, release) are built as well as t // Go trough all versions making a diff if we even have old versions // For phpBB 3.0.x we might choose a different update method, rendering the things below useless... -if (sizeof($package->old_packages)) +if (count($package->old_packages)) { chdir($package->locations['old_versions']); @@ -76,7 +76,7 @@ if (sizeof($package->old_packages)) // Create Directories along the way? $file = explode('/', $file); // Remove filename portion - $file[sizeof($file)-1] = ''; + $file[count($file)-1] = ''; chdir($dest_filename_dir); foreach ($file as $entry) @@ -169,7 +169,7 @@ if (sizeof($package->old_packages)) // Create Directories along the way? $file = explode('/', $file); // Remove filename portion - $file[sizeof($file)-1] = ''; + $file[count($file)-1] = ''; chdir($dest_filename_dir . '/install/update/old'); foreach ($file as $entry) @@ -214,7 +214,7 @@ if (sizeof($package->old_packages)) // Create Directories along the way? $file = explode('/', $file); // Remove filename portion - $file[sizeof($file)-1] = ''; + $file[count($file)-1] = ''; chdir($dest_filename_dir . '/install/update/new'); foreach ($file as $entry) @@ -321,7 +321,7 @@ $update_info = array( \'version\' => array(\'from\' => \'' . str_replace('_to_', '', $package->old_packages[$_package_name]) . '\', \'to\' => \'' . $package->get('new_version_number') . '\'), '; - if (sizeof($file_contents['all'])) + if (count($file_contents['all'])) { $index_contents .= "\t'files' => array(\n\t\t'" . implode("',\n\t\t'", $file_contents['all']) . "',\n\t),\n"; } @@ -330,7 +330,7 @@ $update_info = array( $index_contents .= "\t'files' => array(),\n"; } - if (sizeof($file_contents['binary'])) + if (count($file_contents['binary'])) { $index_contents .= "\t'binary' => array(\n\t\t'" . implode("',\n\t\t'", $file_contents['binary']) . "',\n\t),\n"; } @@ -339,7 +339,7 @@ $update_info = array( $index_contents .= "\t'binary' => array(),\n"; } - if (sizeof($file_contents['deleted'])) + if (count($file_contents['deleted'])) { $index_contents .= "\t'deleted' => array(\n\t\t'" . implode("',\n\t\t'", $file_contents['deleted']) . "',\n\t),\n"; } @@ -380,7 +380,7 @@ $compress_programs = array( 'zip' => 'zip -r' ); -if (sizeof($package->old_packages)) +if (count($package->old_packages)) { // Build Patch Files chdir($package->get('patch_directory')); diff --git a/composer.phar b/composer.phar index fca2a8d72d..348c86d916 100755 Binary files a/composer.phar and b/composer.phar differ diff --git a/git-tools/hooks/commit-msg b/git-tools/hooks/commit-msg index 136606252c..b73005b34d 100755 --- a/git-tools/hooks/commit-msg +++ b/git-tools/hooks/commit-msg @@ -147,6 +147,15 @@ then quit $ERR_LENGTH; fi +# Check for CR/LF line breaks +if grep -q $'\r$' "$1" +then + complain "The commit message uses CR/LF line breaks, which are not permitted." >&2 + complain >&2 + + quit $ERR_EOF; +fi + lines=$(wc -l "$1" | awk '{ print $1; }'); expecting=header; in_description=0; diff --git a/phpBB/adm/style/acp_attachments.html b/phpBB/adm/style/acp_attachments.html index e1f7f140c9..6129d6a1a5 100644 --- a/phpBB/adm/style/acp_attachments.html +++ b/phpBB/adm/style/acp_attachments.html @@ -37,12 +37,6 @@ - -
-

{L_NO_THUMBNAIL_SUPPORT}

-
- -
@@ -329,42 +323,71 @@
{L_TITLE} - - - - - - - - - - - - - + + + +
{L_FILENAME}{L_FILEDATE}{L_FILESIZE}{L_ATTACH_POST_ID}{L_ATTACH_TO_POST}{L_DELETE}
+ - - - - - - + + + + + + - - - - - - - -
{orphan.REAL_FILENAME}{orphan.FILETIME}{orphan.FILESIZE}{L_ATTACH_ID}{L_COLON} {L_FILENAME}{L_FILEDATE}{L_FILESIZE}{L_ATTACH_POST_ID}{L_ATTACH_TO_POST}{L_DELETE}
 {L_MARK_ALL} :: {L_UNMARK_ALL}{L_MARK_ALL} :: {L_UNMARK_ALL}
+ + + + + {orphan.REAL_FILENAME} + {orphan.FILETIME} + {orphan.FILESIZE} + {L_ATTACH_ID}{L_COLON} + + + + + +   + {L_MARK_ALL} :: {L_UNMARK_ALL} + {L_MARK_ALL} :: {L_UNMARK_ALL} + + + + +
+

{L_NO_ATTACHMENTS}

+
+ -
+ + + + + +

+   + +

+ -

-   - -

{S_FORM_TOKEN}
@@ -398,17 +421,25 @@ - + {% for attachments in attachments %} - {L_EXTENSION_GROUP}{L_COLON} {attachments.EXT_GROUP_NAME}{L_NO_EXT_GROUP}
{attachments.L_DOWNLOAD_COUNT}
{L_IN} {L_PRIVATE_MESSAGE} - {attachments.REAL_FILENAME}
{attachments.COMMENT}
{attachments.L_DOWNLOAD_COUNT}
{L_TOPIC}{L_COLON} {attachments.TOPIC_TITLE} + {{ lang('EXTENSION_GROUP') ~ lang('COLON') }} {{ attachments.EXT_GROUP_NAME }} + {% if attachments.S_IN_MESSAGE %} +
{{ attachments.L_DOWNLOAD_COUNT }} +
{{ lang('IN') }} {{ lang('PRIVATE_MESSAGE') }} + {% else %} +
{{ attachments.REAL_FILENAME }} + {% if attachments.COMMENT %}
{{ attachments.COMMENT }}{% endif %} +
{{ attachments.L_DOWNLOAD_COUNT }} +
{{ lang('TOPIC') ~ lang('COLON') }} {{ attachments.TOPIC_TITLE }} + {% endif %} - {attachments.FILETIME}
{L_POST_BY_AUTHOR} {attachments.ATTACHMENT_POSTER} - {attachments.FILESIZE} - + {{ attachments.FILETIME }}
{{ lang('POST_BY_AUTHOR') }} {{ attachments.ATTACHMENT_POSTER }} + {{ attachments.FILESIZE }} + - + {% endfor %} @@ -440,7 +471,7 @@

{L_MARK_ALL} • - {L_UNMARK_ALL} + {L_UNMARK_ALL}

diff --git a/phpBB/adm/style/acp_database.html b/phpBB/adm/style/acp_database.html index 39f06319f9..cc0b57b411 100644 --- a/phpBB/adm/style/acp_database.html +++ b/phpBB/adm/style/acp_database.html @@ -20,7 +20,6 @@

    -

{S_FORM_TOKEN} @@ -68,13 +67,6 @@ -
-
-
- - -
-
+ {S_FORM_TOKEN} diff --git a/phpBB/adm/style/acp_prune_forums.html b/phpBB/adm/style/acp_prune_forums.html index b8c681ea00..ef3880e851 100644 --- a/phpBB/adm/style/acp_prune_forums.html +++ b/phpBB/adm/style/acp_prune_forums.html @@ -94,7 +94,9 @@
- + + +

{S_HIDDEN_FIELDS} {S_FORM_TOKEN} diff --git a/phpBB/adm/style/acp_styles.html b/phpBB/adm/style/acp_styles.html index 43c2f96a65..cfa804090f 100644 --- a/phpBB/adm/style/acp_styles.html +++ b/phpBB/adm/style/acp_styles.html @@ -33,7 +33,7 @@

{L_EXPLAIN}

- {L_BROWSE_STYLES_DATABASE} + {L_BROWSE_STYLES_DATABASE}
@@ -96,6 +96,7 @@ {L_STYLE_NAME} + {L_STYLE_PHPBB_VERSION} {L_STYLE_USED_BY} {L_ACTIONS} {STYLES_LIST_EXTRA} @@ -129,6 +130,7 @@
{L_STYLE_PATH}{L_COLON} {styles_list.STYLE_PATH_FULL}
+ {styles_list.STYLE_PHPBB_VERSION} {styles_list.USERS} @@ -144,7 +146,9 @@ {styles_list.EXTRA} - + {% if styles_list.STYLE_NAME !== 'prosilver' %} + + {% endif %}   diff --git a/phpBB/adm/style/acp_users_prefs.html b/phpBB/adm/style/acp_users_prefs.html index 61904adc23..484c5b3976 100644 --- a/phpBB/adm/style/acp_users_prefs.html +++ b/phpBB/adm/style/acp_users_prefs.html @@ -33,7 +33,7 @@

{L_NOTIFY_METHOD_EXPLAIN}
-
+
diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css index 41d0ae8d42..7cf6c22236 100644 --- a/phpBB/adm/style/admin.css +++ b/phpBB/adm/style/admin.css @@ -525,7 +525,6 @@ li { padding: 0; border-right: 1px solid #CCCFD3; position: relative; - z-index: 1; } .rtl #menu { @@ -841,6 +840,7 @@ table.zebra-table tbody tr:nth-child(odd) { } .row2 { + word-break: break-all; background-color: #DCEBFE; } @@ -1891,7 +1891,6 @@ li.pagination ul { color: #000; text-align: center; border: 1px solid #AAA; - opacity: .95; } .tooltip span.top { @@ -2461,6 +2460,9 @@ fieldset.permissions .padding { text-align: left; } +.rtl .dropdown li { + text-align: right; +} .wrap .dropdown li, .dropdown.wrap li { white-space: normal; } @@ -2475,6 +2477,10 @@ fieldset.permissions .padding { width: 250px; } +.rtl .roles-options > .dropdown { + right: auto; +} + .roles-options { -webkit-user-select: none; -moz-user-select: none; @@ -2493,6 +2499,10 @@ fieldset.permissions .padding { background: url('../images/arrow_down.gif') no-repeat 245px .7em; } +.rtl .roles-options > span { + background: url('../images/arrow_down.gif') no-repeat 7px .7em; +} + .roles-options li { list-style: none; } diff --git a/phpBB/adm/style/installer_footer.html b/phpBB/adm/style/installer_footer.html index fefa8f6d3f..54e6951a12 100644 --- a/phpBB/adm/style/installer_footer.html +++ b/phpBB/adm/style/installer_footer.html @@ -6,7 +6,9 @@ diff --git a/phpBB/adm/style/installer_form.html b/phpBB/adm/style/installer_form.html index a38f33c7c2..592d361d1e 100644 --- a/phpBB/adm/style/installer_form.html +++ b/phpBB/adm/style/installer_form.html @@ -1,3 +1,4 @@ +

{FORM_TITLE}

@@ -8,9 +9,9 @@ - -
+
+ {options.LEGEND}
@@ -49,7 +50,7 @@
{L_SUBMIT} - disabled="disabled" /> + disabled="disabled" />
diff --git a/phpBB/adm/style/permission_mask.html b/phpBB/adm/style/permission_mask.html index 017d29d832..c556664b8c 100644 --- a/phpBB/adm/style/permission_mask.html +++ b/phpBB/adm/style/permission_mask.html @@ -41,7 +41,7 @@
{% if p_mask.f_mask.role_options %}
- - - - + + + @@ -34,5 +34,7 @@ {$SCRIPTS} +{% EVENT simple_footer_body_after %} + diff --git a/phpBB/styles/prosilver/template/ucp_agreement.html b/phpBB/styles/prosilver/template/ucp_agreement.html index 943774c6ec..d4fef9f0a5 100644 --- a/phpBB/styles/prosilver/template/ucp_agreement.html +++ b/phpBB/styles/prosilver/template/ucp_agreement.html @@ -3,8 +3,7 @@ - @@ -65,8 +62,6 @@

{SITENAME} - {AGREEMENT_TITLE}

{AGREEMENT_TEXT}

-
-

{L_BACK}

diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html index 696f621116..cfdbf9c7ea 100644 --- a/phpBB/styles/prosilver/template/ucp_attachments.html +++ b/phpBB/styles/prosilver/template/ucp_attachments.html @@ -44,7 +44,7 @@
{attachrow.DOWNLOAD_COUNT}
{attachrow.POST_TIME}
-
+
diff --git a/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html b/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html index 18316613b0..60061a3139 100644 --- a/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html +++ b/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html @@ -1,5 +1,5 @@ - +

{oauth.SERVICE_NAME}

diff --git a/phpBB/styles/prosilver/template/ucp_footer.html b/phpBB/styles/prosilver/template/ucp_footer.html index f2f1a68db3..eb07f52e05 100644 --- a/phpBB/styles/prosilver/template/ucp_footer.html +++ b/phpBB/styles/prosilver/template/ucp_footer.html @@ -9,6 +9,4 @@ - - diff --git a/phpBB/styles/prosilver/template/ucp_pm_history.html b/phpBB/styles/prosilver/template/ucp_pm_history.html index e97befc552..b53eb0c7ec 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_history.html +++ b/phpBB/styles/prosilver/template/ucp_pm_history.html @@ -6,10 +6,8 @@
-
@@ -38,7 +36,7 @@

{history_row.MINI_POST} {L_SENT_AT}{L_COLON} {history_row.SENT_DATE}
- {L_MESSAGE_BY_AUTHOR} {history_row.MESSAGE_AUTHOR_FULL} + {L_MESSAGE_BY_AUTHOR} {history_row.MESSAGE_AUTHOR_FULL}

{history_row.MESSAGE}{L_MESSAGE_REMOVED_FROM_OUTBOX}
@@ -56,4 +54,3 @@ {L_BACK_TO_TOP}

- diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html index 4295867c05..7cb44a0189 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html @@ -91,28 +91,28 @@
  • - {L_POST_EDIT_PM} + {L_BUTTON_EDIT}
  • - {L_DELETE_MESSAGE} + {L_BUTTON_DELETE}
  • - {L_REPORT_PM} + {L_BUTTON_REPORT}
  • - {L_POST_QUOTE_PM} + {L_BUTTON_QUOTE}
  • @@ -124,8 +124,8 @@

    {L_SENT_AT}{L_COLON} {SENT_DATE}
    {L_PM_FROM}{L_COLON} {MESSAGE_AUTHOR_FULL} -
    {L_TO}{L_COLON} {to_recipient.NAME_FULL}{to_recipient.NAME}  -
    {L_BCC}{L_COLON} {bcc_recipient.NAME_FULL}{bcc_recipient.NAME}  +
    {L_TO}{L_COLON} {to_recipient.NAME_FULL} style="color:{to_recipient.COLOUR};">{to_recipient.NAME}  +
    {L_BCC}{L_COLON} {bcc_recipient.NAME_FULL} style="color:{bcc_recipient.COLOUR};">{bcc_recipient.NAME} 

    diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html index 9377eeb9f5..41ff5b898a 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html @@ -8,6 +8,7 @@ {SITENAME} • {PAGE_TITLE} + @@ -41,7 +42,14 @@
    diff --git a/phpBB/styles/prosilver/template/ucp_prefs_personal.html b/phpBB/styles/prosilver/template/ucp_prefs_personal.html index 4cd9f6655b..1650705d4b 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_personal.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_personal.html @@ -85,8 +85,7 @@
    - diff --git a/phpBB/styles/prosilver/template/ucp_profile_signature.html b/phpBB/styles/prosilver/template/ucp_profile_signature.html index 614f6f440d..ed28b7ab02 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_signature.html +++ b/phpBB/styles/prosilver/template/ucp_profile_signature.html @@ -24,6 +24,7 @@

    {L_OPTIONS}

    + {% EVENT ucp_profile_signature_posting_editor_options_prepend %}
    diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html index 38413addba..bf39990c35 100644 --- a/phpBB/styles/prosilver/template/ucp_register.html +++ b/phpBB/styles/prosilver/template/ucp_register.html @@ -1,7 +1,6 @@ -
    diff --git a/phpBB/styles/prosilver/template/ucp_remind.html b/phpBB/styles/prosilver/template/ucp_remind.html index 0ab1251d9e..8b700de430 100644 --- a/phpBB/styles/prosilver/template/ucp_remind.html +++ b/phpBB/styles/prosilver/template/ucp_remind.html @@ -9,14 +9,19 @@

    {L_SEND_PASSWORD}

    + {% if USERNAME_REQUIRED %} +

    {{ lang('EMAIL_NOT_UNIQUE') }}

    + {% endif %} +
    +

    {L_EMAIL_REMIND}
    +
    +
    + {% if USERNAME_REQUIRED %}
    -
    -

    {L_EMAIL_REMIND}
    -
    -
    + {% endif %}
     
    {S_HIDDEN_FIELDS} 
    diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index b7093cbac5..40beb784d7 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -114,6 +114,7 @@
    {S_LOGIN_REDIRECT} + {S_FORM_TOKEN_LOGIN}
    @@ -156,7 +157,7 @@
  • - style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;" title="{topicrow.TOPIC_FOLDER_IMG_ALT}"> + style="background-image: url('{T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}'); background-repeat: no-repeat;" title="{topicrow.TOPIC_FOLDER_IMG_ALT}">
    @@ -165,10 +166,10 @@ {NEW_POST} - {topicrow.TOPIC_TITLE} + {topicrow.TOPIC_TITLE}{topicrow.TOPIC_TITLE} - - {L_TOPIC_UNAPPROVED} + + {L_TOPIC_UNAPPROVED}{L_POSTS_UNAPPROVED} @@ -186,7 +187,7 @@ @@ -197,7 +198,9 @@
    - {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » + {% EVENT topiclist_row_topic_by_author_before %} + {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » + {% EVENT topiclist_row_topic_by_author_after %} » {L_IN} {topicrow.FORUM_NAME}
    @@ -223,8 +226,8 @@
    {topicrow.REPLIES} {L_REPLIES}
    {topicrow.VIEWS} {L_VIEWS}
    - {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} - + {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} + {VIEW_LATEST_POST} @@ -250,10 +253,10 @@ {L_NO_TOPICS}
    - +
    - {L_NO_FORUMS} + {L_NO_FORUMS_IN_CATEGORY}
    diff --git a/phpBB/styles/prosilver/template/viewonline_body.html b/phpBB/styles/prosilver/template/viewonline_body.html index dd0ca72502..c019977179 100644 --- a/phpBB/styles/prosilver/template/viewonline_body.html +++ b/phpBB/styles/prosilver/template/viewonline_body.html @@ -29,7 +29,7 @@ - {user_row.USERNAME_FULL} {L_IP}{L_COLON} {user_row.USER_IP} » {L_WHOIS} + {user_row.USERNAME_FULL} {L_IP}{L_COLON} {user_row.USER_IP} » {L_WHOIS}
    {user_row.USER_BROWSER} {user_row.FORUM_LOCATION} {user_row.LASTUPDATE} diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index 0de641c985..f77b99dc29 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -242,35 +242,35 @@
  • - {L_DELETE_POST} + {L_BUTTON_DELETE}
  • - {L_REPORT_POST} + {L_BUTTON_REPORT}
  • - {L_WARN_USER} + {L_BUTTON_WARN}
  • - {L_INFORMATION} + {L_BUTTON_INFORMATION}
  • - {L_QUOTE} + {L_BUTTON_QUOTE}
  • @@ -326,6 +326,8 @@
    {postrow.MESSAGE}
    + +
    diff --git a/phpBB/styles/prosilver/template/viewtopic_print.html b/phpBB/styles/prosilver/template/viewtopic_print.html index 3c1ed4c3f1..658062f9fd 100644 --- a/phpBB/styles/prosilver/template/viewtopic_print.html +++ b/phpBB/styles/prosilver/template/viewtopic_print.html @@ -8,9 +8,10 @@ {SITENAME} • {PAGE_TITLE} + - +
    @@ -37,7 +38,14 @@
    diff --git a/phpBB/styles/prosilver/template/viewtopic_topic_tools.html b/phpBB/styles/prosilver/template/viewtopic_topic_tools.html index 397c807bb3..272a434f6a 100644 --- a/phpBB/styles/prosilver/template/viewtopic_topic_tools.html +++ b/phpBB/styles/prosilver/template/viewtopic_topic_tools.html @@ -11,7 +11,7 @@
  • - {S_WATCH_TOPIC_TITLE} + {S_WATCH_TOPIC_TITLE}
  • diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css index 923ff3e792..79b769b1e7 100644 --- a/phpBB/styles/prosilver/theme/bidi.css +++ b/phpBB/styles/prosilver/theme/bidi.css @@ -239,6 +239,10 @@ /* Pagination ---------------------------------------- */ +.rtl .page-number { + float: left; +} + .rtl .pagination { text-align: left; float: left; @@ -451,6 +455,10 @@ li.breadcrumbs span:first-child > a { /* Post body styles ----------------------------------------*/ +.rtl .date { + float: left; +} + .rtl .postbody, .rtl .postbody h3 { float: right; } diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 348355e8c4..a0dc5e043b 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -981,8 +981,15 @@ fieldset.fields1 dl.pmlist dd.recipients { /* Miscellaneous styles ---------------------------------------- */ .copyright { - padding: 5px; + font-size: 10px; text-align: center; + padding: 10px; +} + +.footer-row { + font-size: 10px; + line-height: 1.8; + margin: 0; } .small { @@ -1267,6 +1274,10 @@ ul.linklist:after, width: 50px; } +.dropdown .clone.hidden { + display: none; +} + .dropdown .clone.hidden + li.separator { display: none; } diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index a071e63c69..807633864c 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -18,7 +18,7 @@ ul.topiclist dl { } ul.topiclist li.row dl { - padding: 2px 0; + margin: 2px 0; } ul.topiclist dt, ul.topiclist dd { @@ -70,6 +70,11 @@ ul.topiclist dd { box-sizing: border-box; } +ul.topiclist li.row dd { + padding: 4px 0 999px 0; + margin-bottom: -995px; +} + ul.topiclist dfn { /* Labels for post/view counts */ position: absolute; @@ -524,6 +529,7 @@ blockquote .codebox { /* Attachments ----------------------------------------*/ .attachbox { + font-size: 13px; float: left; width: auto; max-width: 100%; diff --git a/phpBB/styles/prosilver/theme/cp.css b/phpBB/styles/prosilver/theme/cp.css index d54c948343..0041417022 100644 --- a/phpBB/styles/prosilver/theme/cp.css +++ b/phpBB/styles/prosilver/theme/cp.css @@ -300,11 +300,14 @@ ol.def-rules li { padding: 0 3px; } +/* DEPRECATED 3.2.6 .pmlist li.pm_message_reported_colour, .pm_message_reported_colour { border-left-color: transparent; border-right-color: transparent; } +*/ +.pmlist li.pm_message_reported_colour, .pm_message_reported_colour, .pmlist li.pm_marked_colour, .pm_marked_colour, .pmlist li.pm_replied_colour, .pm_replied_colour, .pmlist li.pm_friend_colour, .pm_friend_colour, diff --git a/phpBB/styles/prosilver/theme/plupload.css b/phpBB/styles/prosilver/theme/plupload.css index f466803964..b1f3ae2da8 100644 --- a/phpBB/styles/prosilver/theme/plupload.css +++ b/phpBB/styles/prosilver/theme/plupload.css @@ -3,6 +3,10 @@ margin-bottom: 1em; } +.attach-row-tpl { + display: none; +} + .file-list td { vertical-align: middle; } diff --git a/phpBB/styles/prosilver/theme/print.css b/phpBB/styles/prosilver/theme/print.css index a83270b742..9445279773 100644 --- a/phpBB/styles/prosilver/theme/print.css +++ b/phpBB/styles/prosilver/theme/print.css @@ -133,6 +133,8 @@ ol, ul { /* Misc page elements */ div.spacer { clear: both; } +code { display: block; } + /* Accessibility tweaks: Mozilla.org */ .skip_link { display: none; } diff --git a/phpBB/styles/prosilver/theme/responsive.css b/phpBB/styles/prosilver/theme/responsive.css index fcc11f1fc2..ca4054c27f 100644 --- a/phpBB/styles/prosilver/theme/responsive.css +++ b/phpBB/styles/prosilver/theme/responsive.css @@ -421,6 +421,7 @@ .column1, .column2, .left-box.profile-details { float: none; width: auto; + clear: both; } /* Polls diff --git a/phpBB/ucp.php b/phpBB/ucp.php index 7eca5ede62..96a3efea97 100644 --- a/phpBB/ucp.php +++ b/phpBB/ucp.php @@ -30,6 +30,12 @@ if (in_array($mode, array('login', 'login_link', 'logout', 'confirm', 'sendpassw define('IN_LOGIN', true); } +if ($mode === 'delete_cookies') +{ + define('SKIP_CHECK_BAN', true); + define('SKIP_CHECK_DISABLED', true); +} + // Start session management $user->session_begin(); $auth->acl($user->data); @@ -138,7 +144,7 @@ switch ($mode) 'AGREEMENT_TITLE' => $user->lang[$title], 'AGREEMENT_TEXT' => sprintf($user->lang[$message], $config['sitename'], generate_board_url()), 'U_BACK' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login'), - 'L_BACK' => $user->lang['BACK_TO_LOGIN'], + 'L_BACK' => $user->lang['BACK_TO_PREV'], )); page_footer(); diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index 94309afc5a..a77c08cdd0 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -87,7 +87,7 @@ if (isset($_GET['e']) && !$user->data['is_registered']) } // Permissions check -if (!$auth->acl_gets('f_list', 'f_read', $forum_id) || ($forum_data['forum_type'] == FORUM_LINK && $forum_data['forum_link'] && !$auth->acl_get('f_read', $forum_id))) +if (!$auth->acl_gets('f_list', 'f_list_topics', 'f_read', $forum_id) || ($forum_data['forum_type'] == FORUM_LINK && $forum_data['forum_link'] && !$auth->acl_get('f_read', $forum_id))) { if ($user->data['user_id'] != ANONYMOUS) { @@ -161,7 +161,22 @@ $phpbb_content_visibility = $phpbb_container->get('content.visibility'); $topics_count = $phpbb_content_visibility->get_count('forum_topics', $forum_data, $forum_id); $start = $pagination->validate_start($start, $config['topics_per_page'], $topics_count); -page_header($forum_data['forum_name'] . ($start ? ' - ' . $user->lang('PAGE_TITLE_NUMBER', $pagination->get_on_page($config['topics_per_page'], $start)) : ''), true, $forum_id); +$page_title = $forum_data['forum_name'] . ($start ? ' - ' . $user->lang('PAGE_TITLE_NUMBER', $pagination->get_on_page($config['topics_per_page'], $start)) : ''); + +/** +* You can use this event to modify the page title of the viewforum page +* +* @event core.viewforum_modify_page_title +* @var string page_title Title of the viewforum page +* @var array forum_data Array with forum data +* @var int forum_id The forum ID +* @var int start Start offset used to calculate the page +* @since 3.2.2-RC1 +*/ +$vars = array('page_title', 'forum_data', 'forum_id', 'start'); +extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_page_title', compact($vars))); + +page_header($page_title, true, $forum_id); $template->set_filenames(array( 'body' => 'viewforum_body.html') @@ -181,7 +196,7 @@ if (!($forum_data['forum_type'] == FORUM_POST || (($forum_data['forum_flags'] & // Ok, if someone has only list-access, we only display the forum list. // We also make this circumstance available to the template in case we want to display a notice. ;) -if (!$auth->acl_get('f_read', $forum_id)) +if (!$auth->acl_gets('f_read', 'f_list_topics', $forum_id)) { $template->assign_vars(array( 'S_NO_READ_ACCESS' => true, @@ -270,6 +285,20 @@ $limit_days = array(0 => $user->lang['ALL_TOPICS'], 1 => $user->lang['1_DAY'], 7 $sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 'r' => $user->lang['REPLIES'], 's' => $user->lang['SUBJECT'], 'v' => $user->lang['VIEWS']); $sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => array('t.topic_last_post_time', 't.topic_last_post_id'), 'r' => (($auth->acl_get('m_approve', $forum_id)) ? 't.topic_posts_approved + t.topic_posts_unapproved + t.topic_posts_softdeleted' : 't.topic_posts_approved'), 's' => 'LOWER(t.topic_title)', 'v' => 't.topic_views'); +/** + * Modify the topic ordering if needed + * + * @event core.viewforum_modify_topic_ordering + * @var array sort_by_text Topic ordering options + * @var array sort_by_sql Topic orderings options SQL equivalent + * @since 3.2.5-RC1 + */ +$vars = array( + 'sort_by_text', + 'sort_by_sql', +); +extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topic_ordering', compact($vars))); + $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = ''; gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param, $default_sort_days, $default_sort_key, $default_sort_dir); @@ -385,7 +414,7 @@ $template->assign_vars(array( 'S_SELECT_SORT_DIR' => $s_sort_dir, 'S_SELECT_SORT_KEY' => $s_sort_key, 'S_SELECT_SORT_DAYS' => $s_limit_days, - 'S_TOPIC_ICONS' => ($s_display_active && sizeof($active_forum_ary)) ? max($active_forum_ary['enable_icons']) : (($forum_data['enable_icons']) ? true : false), + 'S_TOPIC_ICONS' => ($s_display_active && count($active_forum_ary)) ? max($active_forum_ary['enable_icons']) : (($forum_data['enable_icons']) ? true : false), 'U_WATCH_FORUM_LINK' => $s_watching_forum['link'], 'U_WATCH_FORUM_TOGGLE' => $s_watching_forum['link_toggle'], 'S_WATCH_FORUM_TITLE' => $s_watching_forum['title'], @@ -395,7 +424,7 @@ $template->assign_vars(array( 'S_DISPLAY_SEARCHBOX' => ($auth->acl_get('u_search') && $auth->acl_get('f_search', $forum_id) && $config['load_search']) ? true : false, 'S_SEARCHBOX_ACTION' => append_sid("{$phpbb_root_path}search.$phpEx"), 'S_SEARCH_LOCAL_HIDDEN_FIELDS' => build_hidden_fields($s_search_hidden_fields), - 'S_SINGLE_MODERATOR' => (!empty($moderators[$forum_id]) && sizeof($moderators[$forum_id]) > 1) ? false : true, + 'S_SINGLE_MODERATOR' => (!empty($moderators[$forum_id]) && count($moderators[$forum_id]) > 1) ? false : true, 'S_IS_LOCKED' => ($forum_data['forum_status'] == ITEM_LOCKED) ? true : false, 'S_VIEWFORUM' => true, @@ -465,7 +494,7 @@ if ($user->data['is_registered']) $sql_array['LEFT_JOIN'][] = array('FROM' => array(TOPICS_TRACK_TABLE => 'tt'), 'ON' => 'tt.topic_id = t.topic_id AND tt.user_id = ' . $user->data['user_id']); $sql_array['SELECT'] .= ', tt.mark_time'; - if ($s_display_active && sizeof($active_forum_ary)) + if ($s_display_active && count($active_forum_ary)) { $sql_array['LEFT_JOIN'][] = array('FROM' => array(FORUMS_TRACK_TABLE => 'ft'), 'ON' => 'ft.forum_id = t.forum_id AND ft.user_id = ' . $user->data['user_id']); $sql_array['SELECT'] .= ', ft.mark_time AS forum_mark_time'; @@ -491,7 +520,7 @@ if ($forum_data['forum_type'] == FORUM_POST) 'WHERE' => '(t.forum_id = ' . $forum_id . ' AND t.topic_type = ' . POST_ANNOUNCE . ') OR - (' . $db->sql_in_set('t.forum_id', $g_forum_ary) . ' + (' . $db->sql_in_set('t.forum_id', $g_forum_ary, false, true) . ' AND t.topic_type = ' . POST_GLOBAL . ')', 'ORDER_BY' => 't.topic_time DESC', @@ -523,7 +552,7 @@ if ($forum_data['forum_type'] == FORUM_POST) while ($row = $db->sql_fetchrow($result)) { - if ($row['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $row['forum_id'])) + if (!$phpbb_content_visibility->is_visible('topic', $row['forum_id'], $row)) { // Do not display announcements that are waiting for approval or soft deleted. continue; @@ -573,8 +602,8 @@ if ($start > $topics_count / 2) // Select the sort order $direction = (($sort_dir == 'd') ? 'ASC' : 'DESC'); - $sql_limit = $pagination->reverse_limit($start, $sql_limit, $topics_count - sizeof($announcement_list)); - $sql_start = $pagination->reverse_start($start, $sql_limit, $topics_count - sizeof($announcement_list)); + $sql_limit = $pagination->reverse_limit($start, $sql_limit, $topics_count - count($announcement_list)); + $sql_start = $pagination->reverse_start($start, $sql_limit, $topics_count - count($announcement_list)); } else { @@ -583,6 +612,18 @@ else $sql_start = $start; } +/** + * Modify the topics sort ordering if needed + * + * @event core.viewforum_modify_sort_direction + * @var string direction Topics sort order + * @since 3.2.5-RC1 + */ +$vars = array( + 'direction', +); +extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_sort_direction', compact($vars))); + if (is_array($sort_by_sql[$sort_key])) { $sql_sort_order = implode(' ' . $direction . ', ', $sort_by_sql[$sort_key]) . ' ' . $direction; @@ -592,7 +633,7 @@ else $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . $direction; } -if ($forum_data['forum_type'] == FORUM_POST || !sizeof($active_forum_ary)) +if ($forum_data['forum_type'] == FORUM_POST || !count($active_forum_ary)) { $sql_where = 't.forum_id = ' . $forum_id; } @@ -603,7 +644,7 @@ else if (empty($active_forum_ary['exclude_forum_id'])) else { $get_forum_ids = array_diff($active_forum_ary['forum_id'], $active_forum_ary['exclude_forum_id']); - $sql_where = (sizeof($get_forum_ids)) ? $db->sql_in_set('t.forum_id', $get_forum_ids) : 't.forum_id = ' . $forum_id; + $sql_where = (count($get_forum_ids)) ? $db->sql_in_set('t.forum_id', $get_forum_ids) : 't.forum_id = ' . $forum_id; } // Grab just the sorted topic ids @@ -662,7 +703,7 @@ $db->sql_freeresult($result); // For storing shadow topics $shadow_topic_list = array(); -if (sizeof($topic_list)) +if (count($topic_list)) { // SQL array for obtaining topics/stickies $sql_array = array( @@ -692,7 +733,7 @@ if (sizeof($topic_list)) } // If we have some shadow topics, update the rowset to reflect their topic information -if (sizeof($shadow_topic_list)) +if (count($shadow_topic_list)) { // SQL array for obtaining shadow topics $sql_array = array( @@ -732,7 +773,7 @@ if (sizeof($shadow_topic_list)) } // Do not include those topics the user has no permission to access - if (!$auth->acl_get('f_read', $row['forum_id'])) + if (!$auth->acl_gets('f_read', 'f_list_topics', $row['forum_id'])) { // We need to remove any trace regarding this topic. :) unset($rowset[$orig_topic_id]); @@ -767,7 +808,7 @@ if ($s_display_active) // We need to remove the global announcements from the forums total topic count, // otherwise the number is different from the one on the forum list -$total_topic_count = $topics_count - sizeof($announcement_list); +$total_topic_count = $topics_count - count($announcement_list); $base_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '')); $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total_topic_count, $config['topics_per_page'], $start); @@ -794,7 +835,7 @@ $vars = array('topic_list', 'rowset', 'total_topic_count', 'forum_id'); extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topics_data', compact($vars))); // Okay, lets dump out the page ... -if (sizeof($topic_list)) +if (count($topic_list)) { $mark_forum_read = true; $mark_time_forum = 0; @@ -875,7 +916,7 @@ if (sizeof($topic_list)) // Generate all the URIs ... $view_topic_url_params = 'f=' . $row['forum_id'] . '&t=' . $topic_id; - $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params); + $view_topic_url = $auth->acl_get('f_read', $forum_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params) : false; $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $row['forum_id'])); $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $row['forum_id'])); @@ -932,8 +973,8 @@ if (sizeof($topic_list)) 'S_TOPIC_LOCKED' => ($row['topic_status'] == ITEM_LOCKED) ? true : false, 'S_TOPIC_MOVED' => ($row['topic_status'] == ITEM_MOVED) ? true : false, - 'U_NEWEST_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&view=unread') . '#unread', - 'U_LAST_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'], + 'U_NEWEST_POST' => $auth->acl_get('f_read', $forum_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&view=unread') . '#unread' : false, + 'U_LAST_POST' => $auth->acl_get('f_read', $forum_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'] : false, 'U_LAST_POST_AUTHOR' => get_username_string('profile', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), 'U_TOPIC_AUTHOR' => get_username_string('profile', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), 'U_VIEW_TOPIC' => $view_topic_url, @@ -1010,7 +1051,7 @@ extract($phpbb_dispatcher->trigger_event('core.viewforum_generate_page_after', c // on all topics (as we do in 2.0.x). It looks for unread or new topics, if it doesn't find // any it updates the forum last read cookie. This requires that the user visit the forum // after reading a topic -if ($forum_data['forum_type'] == FORUM_POST && sizeof($topic_list) && $mark_forum_read) +if ($forum_data['forum_type'] == FORUM_POST && count($topic_list) && $mark_forum_read) { update_forum_tracking_info($forum_id, $forum_data['forum_last_post_time'], false, $mark_time_forum); } diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index a1dc60955c..e49959b3b5 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -32,7 +32,7 @@ $topic_id = $request->variable('t', 0); $post_id = $request->variable('p', 0); $voted_id = $request->variable('vote_id', array('' => 0)); -$voted_id = (sizeof($voted_id) > 1) ? array_unique($voted_id) : $voted_id; +$voted_id = (count($voted_id) > 1) ? array_unique($voted_id) : $voted_id; $start = $request->variable('start', 0); @@ -263,8 +263,26 @@ if (!$topic_data) $forum_id = (int) $topic_data['forum_id']; +/** + * Modify the forum ID to handle the correct display of viewtopic if needed + * + * @event core.viewtopic_modify_forum_id + * @var string forum_id forum ID + * @var array topic_data array of topic's data + * @since 3.2.5-RC1 + */ +$vars = array( + 'forum_id', + 'topic_data', +); +extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_forum_id', compact($vars))); + +// If the request is missing the f parameter, the forum id in the user session data is 0 at the moment. +// Let's fix that now so that the user can't hide from the forum's Who Is Online list. +$user->page['forum'] = $forum_id; + // Now we know the forum_id and can check the permissions -if ($topic_data['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $forum_id)) +if (!$phpbb_content_visibility->is_visible('topic', $forum_id, $topic_data)) { trigger_error('NO_TOPIC'); } @@ -338,6 +356,12 @@ if (($topic_data['topic_type'] != POST_NORMAL) && $topic_data['topic_time_limit' // Setup look and feel $user->setup('viewtopic', $topic_data['forum_style']); +if ($view == 'print' && !$auth->acl_get('f_print', $forum_id)) +{ + send_status_line(403, 'Forbidden'); + trigger_error('NO_AUTH_PRINT_TOPIC'); +} + $overrides_f_read_check = false; $overrides_forum_password_check = false; $topic_tracking_info = isset($topic_tracking_info) ? $topic_tracking_info : null; @@ -429,6 +453,38 @@ $join_user_sql = array('a' => true, 't' => false, 's' => false); $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = ''; +/** +* Event to add new sorting options +* +* @event core.viewtopic_gen_sort_selects_before +* @var array limit_days Limit results by time +* @var array sort_by_text Language strings for sorting options +* @var array sort_by_sql SQL conditions for sorting options +* @var array join_user_sql SQL joins required for sorting options +* @var int sort_days User selected sort days +* @var string sort_key User selected sort key +* @var string sort_dir User selected sort direction +* @var string s_limit_days Initial value of limit days selectbox +* @var string s_sort_key Initial value of sort key selectbox +* @var string s_sort_dir Initial value of sort direction selectbox +* @var string u_sort_param Initial value of sorting form action +* @since 3.2.8-RC1 +*/ +$vars = array( + 'limit_days', + 'sort_by_text', + 'sort_by_sql', + 'join_user_sql', + 'sort_days', + 'sort_key', + 'sort_dir', + 's_limit_days', + 's_sort_key', + 's_sort_dir', + 'u_sort_param', +); +extract($phpbb_dispatcher->trigger_event('core.viewtopic_gen_sort_selects_before', compact($vars))); + gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param, $default_sort_days, $default_sort_key, $default_sort_dir); // Obtain correct post count and ordering SQL if user has @@ -736,7 +792,7 @@ $template->assign_vars(array( 'TOTAL_POSTS' => $user->lang('VIEW_TOPIC_POSTS', (int) $total_posts), 'U_MCP' => ($auth->acl_get('m_', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=main&mode=topic_view&f=$forum_id&t=$topic_id" . (($start == 0) ? '' : "&start=$start") . ((strlen($u_sort_param)) ? "&$u_sort_param" : ''), true, $user->session_id) : '', - 'MODERATORS' => (isset($forum_moderators[$forum_id]) && sizeof($forum_moderators[$forum_id])) ? implode($user->lang['COMMA_SEPARATOR'], $forum_moderators[$forum_id]) : '', + 'MODERATORS' => (isset($forum_moderators[$forum_id]) && count($forum_moderators[$forum_id])) ? implode($user->lang['COMMA_SEPARATOR'], $forum_moderators[$forum_id]) : '', 'POST_IMG' => ($topic_data['forum_status'] == ITEM_LOCKED) ? $user->img('button_topic_locked', 'FORUM_LOCKED') : $user->img('button_topic_new', 'POST_NEW_TOPIC'), 'QUOTE_IMG' => $user->img('icon_post_quote', 'REPLY_WITH_QUOTE'), @@ -759,7 +815,7 @@ $template->assign_vars(array( 'S_SELECT_SORT_DIR' => $s_sort_dir, 'S_SELECT_SORT_KEY' => $s_sort_key, 'S_SELECT_SORT_DAYS' => $s_limit_days, - 'S_SINGLE_MODERATOR' => (!empty($forum_moderators[$forum_id]) && sizeof($forum_moderators[$forum_id]) > 1) ? false : true, + 'S_SINGLE_MODERATOR' => (!empty($forum_moderators[$forum_id]) && count($forum_moderators[$forum_id]) > 1) ? false : true, 'S_TOPIC_ACTION' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id" . (($start == 0) ? '' : "&start=$start")), 'S_MOD_ACTION' => $s_quickmod_action, @@ -776,7 +832,7 @@ $template->assign_vars(array( 'U_TOPIC' => "{$server_path}viewtopic.$phpEx?f=$forum_id&t=$topic_id", 'U_FORUM' => $server_path, - 'U_VIEW_TOPIC' => $viewtopic_url, + 'U_VIEW_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id" . (($start == 0) ? '' : "&start=$start") . (strlen($u_sort_param) ? "&$u_sort_param" : '')), 'U_CANONICAL' => generate_board_url() . '/' . append_sid("viewtopic.$phpEx", "t=$topic_id" . (($start) ? "&start=$start" : ''), true, ''), 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id), 'U_VIEW_OLDER_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id&view=previous"), @@ -852,9 +908,9 @@ if (!empty($topic_data['poll_start'])) (($topic_data['poll_length'] != 0 && $topic_data['poll_start'] + $topic_data['poll_length'] > time()) || $topic_data['poll_length'] == 0) && $topic_data['topic_status'] != ITEM_LOCKED && $topic_data['forum_status'] != ITEM_LOCKED && - (!sizeof($cur_voted_id) || + (!count($cur_voted_id) || ($auth->acl_get('f_votechg', $forum_id) && $topic_data['poll_vote_change']))) ? true : false; - $s_display_results = (!$s_can_vote || ($s_can_vote && sizeof($cur_voted_id)) || $view == 'viewpoll') ? true : false; + $s_display_results = (!$s_can_vote || ($s_can_vote && count($cur_voted_id)) || $view == 'viewpoll') ? true : false; /** * Event to manipulate the poll data @@ -889,16 +945,16 @@ if (!empty($topic_data['poll_start'])) if ($update && $s_can_vote) { - if (!sizeof($voted_id) || sizeof($voted_id) > $topic_data['poll_max_options'] || in_array(VOTE_CONVERTED, $cur_voted_id) || !check_form_key('posting')) + if (!count($voted_id) || count($voted_id) > $topic_data['poll_max_options'] || in_array(VOTE_CONVERTED, $cur_voted_id) || !check_form_key('posting')) { $redirect_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id" . (($start == 0) ? '' : "&start=$start")); meta_refresh(5, $redirect_url); - if (!sizeof($voted_id)) + if (!count($voted_id)) { $message = 'NO_VOTE_OPTION'; } - else if (sizeof($voted_id) > $topic_data['poll_max_options']) + else if (count($voted_id) > $topic_data['poll_max_options']) { $message = 'TOO_MANY_VOTE_OPTIONS'; } @@ -992,8 +1048,31 @@ if (!empty($topic_data['poll_start'])) 'user_votes' => array_flip($valid_user_votes), 'vote_counts' => $vote_counts, 'total_votes' => array_sum($vote_counts), - 'can_vote' => !sizeof($valid_user_votes) || ($auth->acl_get('f_votechg', $forum_id) && $topic_data['poll_vote_change']), + 'can_vote' => !count($valid_user_votes) || ($auth->acl_get('f_votechg', $forum_id) && $topic_data['poll_vote_change']), ); + + /** + * Event to manipulate the poll data sent by AJAX response + * + * @event core.viewtopic_modify_poll_ajax_data + * @var array data JSON response data + * @var array valid_user_votes Valid user votes + * @var array vote_counts Vote counts + * @var int forum_id Forum ID + * @var array topic_data Topic data + * @var array poll_info Array with the poll information + * @since 3.2.4-RC1 + */ + $vars = array( + 'data', + 'valid_user_votes', + 'vote_counts', + 'forum_id', + 'topic_data', + 'poll_info', + ); + extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_poll_ajax_data', compact($vars))); + $json_response = new \phpbb\json_response(); $json_response->send($data); } @@ -1012,7 +1091,7 @@ if (!empty($topic_data['poll_start'])) $parse_flags = ($poll_info[0]['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES; - for ($i = 0, $size = sizeof($poll_info); $i < $size; $i++) + for ($i = 0, $size = count($poll_info); $i < $size; $i++) { $poll_info[$i]['poll_option_text'] = generate_text_for_display($poll_info[$i]['poll_option_text'], $poll_info[$i]['bbcode_uid'], $poll_option['bbcode_bitfield'], $parse_flags, true); } @@ -1144,6 +1223,29 @@ $sql = 'SELECT p.post_id " . (($join_user_sql[$sort_key]) ? 'AND u.user_id = p.poster_id': '') . " $limit_posts_time ORDER BY $sql_sort_order"; + +/** +* Event to modify the SQL query that gets post_list +* +* @event core.viewtopic_modify_post_list_sql +* @var string sql The SQL query to generate the post_list +* @var int sql_limit The number of posts the query fetches +* @var int sql_start The index the query starts to fetch from +* @var string sort_key Key the posts are sorted by +* @var string sort_days Display posts of previous x days +* @var int forum_id Forum ID +* @since 3.2.4-RC1 +*/ +$vars = array( + 'sql', + 'sql_limit', + 'sql_start', + 'sort_key', + 'sort_days', + 'forum_id', +); +extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_post_list_sql', compact($vars))); + $result = $db->sql_query_limit($sql, $sql_limit, $sql_start); $i = ($store_reverse) ? $sql_limit - 1 : 0; @@ -1154,7 +1256,7 @@ while ($row = $db->sql_fetchrow($result)) } $db->sql_freeresult($result); -if (!sizeof($post_list)) +if (!count($post_list)) { if ($sort_days) { @@ -1478,7 +1580,7 @@ if ($config['load_cpf_viewtopic']) } // Generate online information for user -if ($config['load_onlinetrack'] && sizeof($id_cache)) +if ($config['load_onlinetrack'] && count($id_cache)) { $sql = 'SELECT session_user_id, MAX(session_time) as online_time, MIN(session_viewonline) AS viewonline FROM ' . SESSIONS_TABLE . ' @@ -1496,7 +1598,7 @@ if ($config['load_onlinetrack'] && sizeof($id_cache)) unset($id_cache); // Pull attachment data -if (sizeof($attach_list)) +if (count($attach_list)) { if ($auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id)) { @@ -1514,7 +1616,7 @@ if (sizeof($attach_list)) $db->sql_freeresult($result); // No attachments exist, but post table thinks they do so go ahead and reset post_attach flags - if (!sizeof($attachments)) + if (!count($attachments)) { $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_attachment = 0 @@ -1522,7 +1624,7 @@ if (sizeof($attach_list)) $db->sql_query($sql); // We need to update the topic indicator too if the complete topic is now without an attachment - if (sizeof($rowset) != $total_posts) + if (count($rowset) != $total_posts) { // Not all posts are displayed so we query the db to find if there's any attachment for this topic $sql = 'SELECT a.post_msg_id as post_id @@ -1572,19 +1674,27 @@ if (sizeof($attach_list)) } } -// Get the list of users who can receive private messages -$can_receive_pm_list = $auth->acl_get_list(array_keys($user_cache), 'u_readpm'); -$can_receive_pm_list = (empty($can_receive_pm_list) || !isset($can_receive_pm_list[0]['u_readpm'])) ? array() : $can_receive_pm_list[0]['u_readpm']; +if ($config['enable_accurate_pm_button']) +{ + // Get the list of users who can receive private messages + $can_receive_pm_list = $auth->acl_get_list(array_keys($user_cache), 'u_readpm'); + $can_receive_pm_list = (empty($can_receive_pm_list) || !isset($can_receive_pm_list[0]['u_readpm'])) ? array() : $can_receive_pm_list[0]['u_readpm']; -// Get the list of permanently banned users -$permanently_banned_users = phpbb_get_banned_user_ids(array_keys($user_cache), false); + // Get the list of permanently banned users + $permanently_banned_users = phpbb_get_banned_user_ids(array_keys($user_cache), false); +} +else +{ + $can_receive_pm_list = array_keys($user_cache); + $permanently_banned_users = []; +} -$i_total = sizeof($rowset) - 1; +$i_total = count($rowset) - 1; $prev_post_id = ''; $template->assign_vars(array( 'S_HAS_ATTACHMENTS' => $topic_data['topic_attachment'], - 'S_NUM_POSTS' => sizeof($post_list)) + 'S_NUM_POSTS' => count($post_list)) ); /** @@ -1629,7 +1739,7 @@ extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_post_data', comp // Output the posts $first_unread = $post_unread = false; -for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) +for ($i = 0, $end = count($post_list); $i < $end; ++$i) { // A non-existing rowset only happens if there was no user present for the entered poster_id // This could be a broken posts table. @@ -1672,7 +1782,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) if (($row['post_edit_count'] && $config['display_last_edited']) || $row['post_edit_reason']) { // Get usernames for all following posts if not already stored - if (!sizeof($post_edit_list) && ($row['post_edit_reason'] || ($row['post_edit_user'] && !isset($user_cache[$row['post_edit_user']])))) + if (!count($post_edit_list) && ($row['post_edit_reason'] || ($row['post_edit_user'] && !isset($user_cache[$row['post_edit_user']])))) { // Remove all post_ids already parsed (we do not have to check them) $post_storage_list = (!$store_reverse) ? array_slice($post_list, $i) : array_slice(array_reverse($post_list), $i); @@ -1736,7 +1846,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) if ($row['post_visibility'] == ITEM_DELETED && $row['post_delete_user']) { // Get usernames for all following posts if not already stored - if (!sizeof($post_delete_list) && ($row['post_delete_reason'] || ($row['post_delete_user'] && !isset($user_cache[$row['post_delete_user']])))) + if (!count($post_delete_list) && ($row['post_delete_reason'] || ($row['post_delete_user'] && !isset($user_cache[$row['post_delete_user']])))) { // Remove all post_ids already parsed (we do not have to check them) $post_storage_list = (!$store_reverse) ? array_slice($post_list, $i) : array_slice(array_reverse($post_list), $i); @@ -1980,7 +2090,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false, - 'S_MULTIPLE_ATTACHMENTS' => !empty($attachments[$row['post_id']]) && sizeof($attachments[$row['post_id']]) > 1, + 'S_MULTIPLE_ATTACHMENTS' => !empty($attachments[$row['post_id']]) && count($attachments[$row['post_id']]) > 1, 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) ? true : false, 'S_POST_DELETED' => ($row['post_visibility'] == ITEM_DELETED) ? true : false, 'L_POST_DELETED_MESSAGE' => $l_deleted_message, @@ -1989,8 +2099,9 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'S_FRIEND' => ($row['friend']) ? true : false, 'S_UNREAD_POST' => $post_unread, 'S_FIRST_UNREAD' => $s_first_unread, - 'S_CUSTOM_FIELDS' => (isset($cp_row['row']) && sizeof($cp_row['row'])) ? true : false, + 'S_CUSTOM_FIELDS' => (isset($cp_row['row']) && count($cp_row['row'])) ? true : false, 'S_TOPIC_POSTER' => ($topic_data['topic_poster'] == $poster_id) ? true : false, + 'S_FIRST_POST' => ($topic_data['topic_first_post_id'] == $row['post_id']) ? true : false, 'S_IGNORE_POST' => ($row['foe']) ? true : false, 'L_IGNORE_POST' => ($row['foe']) ? sprintf($user->lang['POST_BY_FOE'], get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username'])) : '', @@ -2045,7 +2156,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) $i = $current_row_number; - if (isset($cp_row['row']) && sizeof($cp_row['row'])) + if (isset($cp_row['row']) && count($cp_row['row'])) { $post_row = array_merge($post_row, $cp_row['row']); } @@ -2057,7 +2168,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) array( 'ID' => 'pm', 'NAME' => $user->lang['SEND_PRIVATE_MESSAGE'], - 'U_CONTACT' => $u_pm, + 'U_CONTACT' => $post_row['U_PM'], ), array( 'ID' => 'email', @@ -2158,7 +2269,7 @@ if (isset($user->data['session_page']) && !$user->data['is_bot'] && (strpos($use $db->sql_query($sql); // Update the attachment download counts - if (sizeof($update_count)) + if (count($update_count)) { $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET download_count = download_count + 1 @@ -2237,7 +2348,6 @@ if ($s_can_vote || $s_quick_reply) $qr_hidden_fields = array( 'topic_cur_post_id' => (int) $topic_data['topic_last_post_id'], - 'lastclick' => (int) time(), 'topic_id' => (int) $topic_data['topic_id'], 'forum_id' => (int) $forum_id, ); diff --git a/tests/RUNNING_TESTS.md b/tests/RUNNING_TESTS.md index c9941d61e5..12ae7fa687 100644 --- a/tests/RUNNING_TESTS.md +++ b/tests/RUNNING_TESTS.md @@ -143,14 +143,14 @@ If you want all tests, run: Functional tests ------------------ +================ Functional tests test software the way a user would. They simulate a user browsing the website, but they do these steps in an automated way. phpBB allows you to write such tests. Running -======= +------- Running the tests requires your phpBB3 repository to be accessible through a local web server. You will need to supply the URL to the webserver in @@ -170,6 +170,27 @@ If you only want the functional tests, run: This will change your board's config.php file, but it makes a backup at config_dev.php, so you can restore it after the test run is complete. +UI tests +======== + +UI tests are functional tests that also support running JavaScript in a +headless browser. These should be used when functionality that is only +executed using JS needs to be tested. They require a running +[PhantomJS WebDriver instance](http://phantomjs.org/). The executable can +either be downloaded from [PhantomJS](http://phantomjs.org/download.html) +or alternatively be installed with npm: + + $ npm install -g phantomjs-prebuilt + +You might have to run the command as superuser / administrator on some +systems. Afterwards, a new WebDriver instance can be started via command +line: + + $ phantomjs --webdriver=127.0.0.1:8910 + +Port 8910 is the default port that will be used by UI tests to connect +to the WebDriver instance. + More Information ================ diff --git a/tests/attachment/fixtures/resync.xml b/tests/attachment/fixtures/resync.xml index 6e2cc62f68..af04701b4a 100644 --- a/tests/attachment/fixtures/resync.xml +++ b/tests/attachment/fixtures/resync.xml @@ -1,6 +1,7 @@ + attach_idpost_msg_idtopic_idin_message @@ -9,6 +10,7 @@ physical_filenamethumbnail + 1 1 1 0 @@ -18,6 +20,7 @@ 0 + 2 1 1 1 @@ -27,6 +30,7 @@ 0 + 3 1 1 1 @@ -37,13 +41,16 @@
    + extension_idextensiongroup_id + 1 jpg 1 + 2 png 1 diff --git a/tests/avatar/manager_test.php b/tests/avatar/manager_test.php index 9e826a3a59..d1e907b53d 100644 --- a/tests/avatar/manager_test.php +++ b/tests/avatar/manager_test.php @@ -99,7 +99,7 @@ class phpbb_avatar_manager_test extends \phpbb_database_test_case $this->config['allow_avatar_' . get_class($this->avatar_barfoo)] = false; // Set up avatar manager - $this->manager = new \phpbb\avatar\manager($this->config, $avatar_drivers, $phpbb_container); + $this->manager = new \phpbb\avatar\manager($this->config, $dispatcher, $avatar_drivers); $this->db = $this->new_dbal(); $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); $lang = new \phpbb\language\language($lang_loader); @@ -185,7 +185,7 @@ class phpbb_avatar_manager_test extends \phpbb_database_test_case $avatar_settings = $this->manager->get_avatar_settings($this->avatar_foobar); $expected_settings = array( - 'allow_avatar_' . get_class($this->avatar_foobar) => array('lang' => 'ALLOW_' . strtoupper(get_class($this->avatar_foobar)), 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'allow_avatar_' . get_class($this->avatar_foobar) => array('lang' => 'ALLOW_' . strtoupper(get_class($this->avatar_foobar)), 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), ); $this->assertEquals($expected_settings, $avatar_settings); diff --git a/tests/cache/apcu_driver_test.php b/tests/cache/apcu_driver_test.php index 9de1d82a15..57f640c313 100644 --- a/tests/cache/apcu_driver_test.php +++ b/tests/cache/apcu_driver_test.php @@ -49,10 +49,27 @@ class phpbb_cache_apcu_driver_test extends phpbb_cache_common_test_case protected function setUp() { + global $phpbb_container, $phpbb_root_path; + parent::setUp(); + $phpbb_container = new phpbb_mock_container_builder(); + $phpbb_container->setParameter('core.cache_dir', $phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT . '/'); + $this->driver = new \phpbb\cache\driver\apcu; $this->driver->purge(); } + + public function test_purge() + { + /* add a cache entry which does not match our key */ + $foreign_key = 'test_' . $this->driver->key_prefix . 'test'; + $this->assertSame(true, apcu_store($foreign_key, 0, 600)); + $this->assertSame(true, apcu_exists($foreign_key)); + + parent::test_purge(); + + $this->assertSame(true, apcu_exists($foreign_key)); + } } diff --git a/tests/cache/cache_memory.php b/tests/cache/cache_memory.php index 806edb963a..565e9a48eb 100644 --- a/tests/cache/cache_memory.php +++ b/tests/cache/cache_memory.php @@ -18,7 +18,7 @@ class phpbb_cache_memory extends \phpbb\cache\driver\memory /** * Set cache path */ - function phpbb_cache_memory() + function __construct() { } diff --git a/tests/cache/cache_memory_test.php b/tests/cache/cache_memory_test.php index 9f92e8d8dc..ba1010bcf3 100644 --- a/tests/cache/cache_memory_test.php +++ b/tests/cache/cache_memory_test.php @@ -116,7 +116,7 @@ class phpbb_cache_memory_test extends phpbb_database_test_case $results[] = $row; } $this->cache->sql_freeresult($query_id); - $this->assertEquals($query[1], sizeof($results)); + $this->assertEquals($query[1], count($results)); } $this->cache->destroy('sql', $table); diff --git a/tests/console/thumbnail_test.php b/tests/console/thumbnail_test.php index 439e3623fa..e425d998a2 100644 --- a/tests/console/thumbnail_test.php +++ b/tests/console/thumbnail_test.php @@ -46,7 +46,7 @@ class phpbb_console_command_thumbnail_test extends phpbb_database_test_case $config = $this->config = new \phpbb\config\config(array( 'img_min_thumb_filesize' => 2, 'img_max_thumb_width' => 2, - 'img_imagick' => '', + 'upload_path' => 'files', )); $this->db = $this->db = $this->new_dbal(); @@ -64,8 +64,8 @@ class phpbb_console_command_thumbnail_test extends phpbb_database_test_case ))); $this->application = new Application(); - $this->application->add(new generate($this->user, $this->db, $this->cache, $this->phpbb_root_path, $this->phpEx)); - $this->application->add(new delete($this->user, $this->db, $this->phpbb_root_path)); + $this->application->add(new generate($config, $this->user, $this->db, $this->cache, $this->phpbb_root_path, $this->phpEx)); + $this->application->add(new delete($config, $this->user, $this->db, $this->phpbb_root_path)); $this->application->add(new recreate($this->user)); $phpbb_filesystem = new \phpbb\filesystem\filesystem(); diff --git a/tests/console/user/add_test.php b/tests/console/user/add_test.php index 8641bf87b6..bdfb8a8d2a 100644 --- a/tests/console/user/add_test.php +++ b/tests/console/user/add_test.php @@ -14,12 +14,15 @@ use Symfony\Component\Console\Application; use Symfony\Component\Console\Tester\CommandTester; use phpbb\console\command\user\add; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\Question; require_once dirname(__FILE__) . '/base.php'; class phpbb_console_user_add_test extends phpbb_console_user_base { - public function get_command_tester() + public function get_command_tester($question_answers = []) { $application = new Application(); $application->add(new add( @@ -34,7 +37,42 @@ class phpbb_console_user_add_test extends phpbb_console_user_base $command = $application->find('user:add'); $this->command_name = $command->getName(); - $this->question = $command->getHelper('question'); + + if (!empty($question_answers)) + { + $ask = function(InputInterface $input, OutputInterface $output, Question $question) use ($question_answers) + { + $text = $question->getQuestion(); + + // handle a question + foreach ($question_answers as $expected_question => $answer) + { + if (strpos($text, $expected_question) !== false) + { + $response = $answer; + } + } + + if (!isset($response)) + { + throw new \RuntimeException('Was asked for input on an unhandled question: ' . $text); + } + + $output->writeln(print_r($response, true)); + return $response; + }; + $helper = $this->getMock('\Symfony\Component\Console\Helper\QuestionHelper', array('ask')); + $helper->expects($this->any()) + ->method('ask') + ->will($this->returnCallback($ask)); + $this->question = $helper; + $command->getHelperSet()->set($helper, 'question'); + } + else + { + $this->question = $command->getHelper('question'); + } + return new CommandTester($command); } @@ -57,7 +95,11 @@ class phpbb_console_user_add_test extends phpbb_console_user_base public function test_add_dialog() { - $command_tester = $this->get_command_tester(); + $command_tester = $this->get_command_tester([ + 'USERNAME' => 'bar', + 'PASSWORD' => 'password', + 'EMAIL_ADDRESS' => 'bar@test.com', + ]); $this->assertEquals(2, $this->get_user_id('Admin')); diff --git a/tests/console/user/base.php b/tests/console/user/base.php index b84c0bb267..ad328ac893 100644 --- a/tests/console/user/base.php +++ b/tests/console/user/base.php @@ -94,6 +94,11 @@ abstract class phpbb_console_user_base extends phpbb_database_test_case 'auth.provider_collection', $provider_collection ); + $phpbb_container->setParameter('tables.auth_provider_oauth_token_storage', 'phpbb_oauth_tokens'); + $phpbb_container->setParameter('tables.auth_provider_oauth_states', 'phpbb_oauth_states'); + $phpbb_container->setParameter('tables.auth_provider_oauth_account_assoc', 'phpbb_oauth_accounts'); + + $phpbb_container->setParameter('tables.user_notifications', 'phpbb_user_notifications'); parent::setUp(); } diff --git a/tests/cron/manager_test.php b/tests/cron/manager_test.php index f4dd69b19b..76f8c753bf 100644 --- a/tests/cron/manager_test.php +++ b/tests/cron/manager_test.php @@ -40,7 +40,7 @@ class phpbb_cron_manager_test extends \phpbb_test_case public function test_manager_finds_all_ready_tasks() { $tasks = $this->manager->find_all_ready_tasks(); - $this->assertEquals(3, sizeof($tasks)); + $this->assertEquals(3, count($tasks)); } public function test_manager_finds_one_ready_task() diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php index f9243e7266..0365463a48 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -203,8 +203,15 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case public function test_list_columns() { + $config = $this->get_database_config(); + $table_columns = $this->table_data['COLUMNS']; + + if (strpos($config['dbms'], 'mssql') !== false) + { + ksort($table_columns); + } $this->assertEquals( - array_keys($this->table_data['COLUMNS']), + array_keys($table_columns), array_values($this->tools->sql_list_columns('prefix_table_name')) ); } @@ -432,28 +439,37 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case $this->markTestIncomplete('The table prefix length is too long for proper testing of index shortening function.'); } + $max_index_length = 30; + + if ($this->tools instanceof \phpbb\db\tools\mssql) + { + $max_length_method = new ReflectionMethod('\phpbb\db\tools\mssql', 'get_max_index_name_length'); + $max_length_method->setAccessible(true); + $max_index_length = $max_length_method->invoke($this->tools); + } + $table_suffix = str_repeat('a', 25 - strlen($table_prefix)); $table_name = $table_prefix . $table_suffix; $this->tools->sql_create_table($table_name, $this->table_data); - // Index name and table suffix and table prefix have > 30 chars in total. - // Index name and table suffix have <= 30 chars in total. - $long_index_name = str_repeat('i', 30 - strlen($table_suffix)); + // Index name and table suffix and table prefix have > maximum index length chars in total. + // Index name and table suffix have <= maximum index length chars in total. + $long_index_name = str_repeat('i', $max_index_length - strlen($table_suffix)); $this->assertFalse($this->tools->sql_index_exists($table_name, $long_index_name)); $this->assertTrue($this->tools->sql_create_index($table_name, $long_index_name, array('c_timestamp'))); $this->assertTrue($this->tools->sql_index_exists($table_name, $long_index_name)); - // Index name and table suffix have > 30 chars in total. - $very_long_index_name = str_repeat('i', 30); + // Index name and table suffix have > maximum index length chars in total. + $very_long_index_name = str_repeat('i', $max_index_length); $this->assertFalse($this->tools->sql_index_exists($table_name, $very_long_index_name)); $this->assertTrue($this->tools->sql_create_index($table_name, $very_long_index_name, array('c_timestamp'))); $this->assertTrue($this->tools->sql_index_exists($table_name, $very_long_index_name)); $this->tools->sql_table_drop($table_name); - // Index name has > 30 chars - that should not be possible. - $too_long_index_name = str_repeat('i', 31); + // Index name has > maximum index length chars - that should not be possible. + $too_long_index_name = str_repeat('i', $max_index_length + 1); $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', $too_long_index_name)); $this->setExpectedTriggerError(E_USER_ERROR); $this->tools->sql_create_index('prefix_table_name', $too_long_index_name, array('c_timestamp')); diff --git a/tests/dbal/ext/foo/bar/acp/acp_test_info.php b/tests/dbal/ext/foo/bar/acp/acp_test_info.php new file mode 100644 index 0000000000..ac92623c3a --- /dev/null +++ b/tests/dbal/ext/foo/bar/acp/acp_test_info.php @@ -0,0 +1,37 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace foo\bar\acp; + +class acp_test_info +{ + public function module() + { + return array( + 'filename' => '\foo\bar\acp\acp_test_module', + 'title' => 'ACP_NEW_MODULE', + 'modes' => array( + 'mode_1' => array( + 'title' => 'ACP_NEW_MODULE_MODE_1', + 'auth' => '', + 'cat' => array('ACP_NEW_MODULE'), + ), + 'mode_2' => array( + 'title' => 'ACP_NEW_MODULE_MODE_2', + 'auth' => '', + 'cat' => array('ACP_NEW_MODULE'), + ), + ), + ); + } +} diff --git a/tests/dbal/ext/foo/bar/acp/acp_test_module.php b/tests/dbal/ext/foo/bar/acp/acp_test_module.php new file mode 100644 index 0000000000..01ce5c17dc --- /dev/null +++ b/tests/dbal/ext/foo/bar/acp/acp_test_module.php @@ -0,0 +1,25 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace foo\bar\acp; + +class acp_test_module +{ + var $u_action; + + function main($id, $mode) + { + $this->tpl_name = 'foobar'; + $this->page_title = 'Bertie'; + } +} diff --git a/tests/dbal/ext/foo/bar/composer.json b/tests/dbal/ext/foo/bar/composer.json new file mode 100644 index 0000000000..2edfd43d84 --- /dev/null +++ b/tests/dbal/ext/foo/bar/composer.json @@ -0,0 +1,24 @@ +{ + "name": "foo/bar", + "type": "phpbb-extension", + "description": "An example/sample extension to be used for testing purposes in phpBB Development.", + "version": "1.0.0", + "time": "2012-02-15 01:01:01", + "license": "GNU GPL v2", + "authors": [{ + "name": "John Smith", + "username": "JohnSmith27", + "email": "email@phpbb.com", + "homepage": "http://phpbb.com", + "role": "N/A" + }], + "require": { + "php": ">=5.4.7" + }, + "extra": { + "display-name": "phpBB BarFoo Extension", + "soft-require": { + "phpbb/phpbb": "3.2.*@dev" + } + } +} diff --git a/tests/dbal/ext/foo/bar/ucp/ucp_test_info.php b/tests/dbal/ext/foo/bar/ucp/ucp_test_info.php new file mode 100644 index 0000000000..d3489af832 --- /dev/null +++ b/tests/dbal/ext/foo/bar/ucp/ucp_test_info.php @@ -0,0 +1,37 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace foo\bar\ucp; + +class ucp_test_info +{ + public function module() + { + return array( + 'filename' => '\foo\bar\ucp\ucp_test_module', + 'title' => 'UCP_NEW_MODULE', + 'modes' => array( + 'mode_1' => array( + 'title' => 'UCP_NEW_MODULE_MODE_1', + 'auth' => '', + 'cat' => array('UCP_NEW_MODULE'), + ), + 'mode_2' => array( + 'title' => 'UCP_NEW_MODULE_MODE_2', + 'auth' => '', + 'cat' => array('UCP_NEW_MODULE'), + ), + ), + ); + } +} diff --git a/tests/dbal/ext/foo/bar/ucp/ucp_test_module.php b/tests/dbal/ext/foo/bar/ucp/ucp_test_module.php new file mode 100644 index 0000000000..b06b3238b6 --- /dev/null +++ b/tests/dbal/ext/foo/bar/ucp/ucp_test_module.php @@ -0,0 +1,25 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace foo\bar\ucp; + +class ucp_test_module +{ + var $u_action; + + function main($id, $mode) + { + $this->tpl_name = 'foobar'; + $this->page_title = 'Bertie'; + } +} diff --git a/tests/dbal/fixtures/boolean_processor.xml b/tests/dbal/fixtures/boolean_processor.xml index c5da677116..d31d679f45 100644 --- a/tests/dbal/fixtures/boolean_processor.xml +++ b/tests/dbal/fixtures/boolean_processor.xml @@ -60,25 +60,31 @@
    user_idgroup_id + group_leader 1 1 + 2 2 1 + 2 3 1 + 2 4 2 + 2 5 2 + 2
    diff --git a/tests/dbal/migrator_tool_module_test.php b/tests/dbal/migrator_tool_module_test.php index 29b21166b6..e34ee7b59c 100644 --- a/tests/dbal/migrator_tool_module_test.php +++ b/tests/dbal/migrator_tool_module_test.php @@ -11,6 +11,9 @@ * */ +require_once dirname(__FILE__) . '/ext/foo/bar/acp/acp_test_info.php'; +require_once dirname(__FILE__) . '/ext/foo/bar/ucp/ucp_test_info.php'; + class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case { public function getDataSet() @@ -39,6 +42,9 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case $auth = $this->getMock('\phpbb\auth\auth'); $phpbb_log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); + // Correctly set the root path for this test to this directory, so the classes can be found + $phpbb_root_path = dirname(__FILE__) . '/'; + $phpbb_extension_manager = new phpbb_mock_extension_manager($phpbb_root_path); $module_manager = new \phpbb\module\module_manager($cache, $this->db, $phpbb_extension_manager, MODULES_TABLE, $phpbb_root_path, $phpEx); @@ -52,11 +58,39 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case array( '', 'ACP_CAT', + false, true, ), array( 0, 'ACP_CAT', + false, + true, + ), + array( + false, + 'ACP_CAT', + false, + true, + ), + + // Test the existing category lazily + array( + '', + 'ACP_CAT', + true, + true, + ), + array( + 0, + 'ACP_CAT', + true, + true, + ), + array( + false, + 'ACP_CAT', + true, true, ), @@ -65,15 +99,38 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case '', 'ACP_MODULE', false, + false, ), array( false, 'ACP_MODULE', + false, true, ), array( 'ACP_CAT', 'ACP_MODULE', + false, + true, + ), + + // Test the existing module lazily + array( + '', + 'ACP_MODULE', + true, + false, + ), + array( + false, + 'ACP_MODULE', + true, + true, + ), + array( + 'ACP_CAT', + 'ACP_MODULE', + true, true, ), @@ -82,11 +139,39 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case '', 'ACP_NON_EXISTANT_CAT', false, + false, + ), + array( + false, + 'ACP_NON_EXISTANT_CAT', + false, + false, ), array( 'ACP_CAT', 'ACP_NON_EXISTANT_MODULE', false, + false, + ), + + // Test for non-existant modules lazily + array( + '', + 'ACP_NON_EXISTANT_CAT', + true, + false, + ), + array( + false, + 'ACP_NON_EXISTANT_CAT', + true, + false, + ), + array( + 'ACP_CAT', + 'ACP_NON_EXISTANT_MODULE', + true, + false, ), ); } @@ -94,9 +179,9 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case /** * @dataProvider exists_data_acp */ - public function test_exists_acp($parent, $module, $expected) + public function test_exists_acp($parent, $module, $lazy, $expected) { - $this->assertEquals($expected, $this->tool->exists('acp', $parent, $module)); + $this->assertEquals($expected, $this->tool->exists('acp', $parent, $module, $lazy)); } public function exists_data_ucp() @@ -106,11 +191,39 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case array( '', 'UCP_MAIN_CAT', + false, true, ), array( 0, 'UCP_MAIN_CAT', + false, + true, + ), + array( + false, + 'UCP_MAIN_CAT', + false, + true, + ), + + // Test the existing category lazily + array( + '', + 'UCP_MAIN_CAT', + true, + true, + ), + array( + 0, + 'UCP_MAIN_CAT', + true, + true, + ), + array( + false, + 'UCP_MAIN_CAT', + true, true, ), @@ -119,21 +232,51 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case '', 'UCP_SUBCATEGORY', false, + false, ), array( false, 'UCP_SUBCATEGORY', + false, + true, + ), + array( + 'UCP_MAIN_CAT', + 'UCP_SUBCATEGORY', + false, + true, + ), + array( + 'UCP_SUBCATEGORY', + 'UCP_MODULE', + false, + true, + ), + + // Test the existing module lazily + array( + '', + 'UCP_SUBCATEGORY', + true, + false, + ), + array( + false, + 'UCP_SUBCATEGORY', + true, true, ), array( 'UCP_MAIN_CAT', 'UCP_SUBCATEGORY', true, + true, ), array( 'UCP_SUBCATEGORY', 'UCP_MODULE', true, + true, ), // Test for non-existant modules @@ -141,11 +284,27 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case '', 'UCP_NON_EXISTANT_CAT', false, + false, ), array( 'UCP_MAIN_CAT', 'UCP_NON_EXISTANT_MODULE', false, + false, + ), + + // Test for non-existant modules lazily + array( + '', + 'UCP_NON_EXISTANT_CAT', + true, + false, + ), + array( + 'UCP_MAIN_CAT', + 'UCP_NON_EXISTANT_MODULE', + true, + false, ), ); } @@ -153,9 +312,9 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case /** * @dataProvider exists_data_ucp */ - public function test_exists_ucp($parent, $module, $expected) + public function test_exists_ucp($parent, $module, $lazy, $expected) { - $this->assertEquals($expected, $this->tool->exists('ucp', $parent, $module)); + $this->assertEquals($expected, $this->tool->exists('ucp', $parent, $module, $lazy)); } public function test_add() @@ -193,25 +352,6 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case } $this->assertEquals(true, $this->tool->exists('acp', 'ACP_NEW_CAT', 'ACP_NEW_MODULE')); - // Test adding module when plural parent module_langname exists - // PHPBB3-14703 - // Adding fail - try - { - $this->tool->add('acp', 'ACP_FORUM_BASED_PERMISSIONS', array( - 'module_basename' => 'acp_new_permissions_module', - 'module_langname' => 'ACP_NEW_PERMISSIONS_MODULE', - 'module_mode' => 'test', - 'module_auth' => '', - )); - $this->fail('Exception not thrown'); - } - catch (Exception $e) - { - $this->assertEquals('phpbb\db\migration\exception', get_class($e)); - $this->assertEquals('MODULE_EXIST_MULTIPLE', $e->getMessage()); - } - // Test adding module when plural parent module_langname exists // PHPBB3-14703 // Adding success @@ -269,6 +409,35 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case $this->fail($e); } $this->assertEquals(true, $this->tool->exists('ucp', 'UCP_NEW_SUBCAT', 'UCP_NEW_MODULE')); + + // Test adding new UCP module the automatic way, single mode + try + { + $this->tool->add('ucp', 'UCP_NEW_CAT', array( + 'module_basename' => '\foo\bar\ucp\ucp_test_module', + 'modes' => array('mode_1'), + )); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals(true, $this->tool->exists('ucp', 'UCP_NEW_CAT', 'UCP_NEW_MODULE_MODE_1')); + $this->assertEquals(false, $this->tool->exists('ucp', 'UCP_NEW_CAT', 'UCP_NEW_MODULE_MODE_2')); + + // Test adding new ACP module the automatic way, all modes + try + { + $this->tool->add('acp', 'ACP_NEW_CAT', array( + 'module_basename' => '\foo\bar\acp\acp_test_module', + )); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals(true, $this->tool->exists('acp', 'ACP_NEW_CAT', 'ACP_NEW_MODULE_MODE_1')); + $this->assertEquals(true, $this->tool->exists('acp', 'ACP_NEW_CAT', 'ACP_NEW_MODULE_MODE_2')); } public function test_remove() diff --git a/tests/dbal/migrator_tool_permission_test.php b/tests/dbal/migrator_tool_permission_test.php index d84f6a68ff..ccad6a1387 100644 --- a/tests/dbal/migrator_tool_permission_test.php +++ b/tests/dbal/migrator_tool_permission_test.php @@ -163,7 +163,7 @@ class phpbb_dbal_migrator_tool_permission_test extends phpbb_database_test_case $this->assertFalse($this->tool->exists('global_test', true)); } - public function test_permission_set_data() + public function data_test_permission_set() { return array( array( @@ -188,7 +188,7 @@ class phpbb_dbal_migrator_tool_permission_test extends phpbb_database_test_case } /** - * @dataProvider test_permission_set_data + * @dataProvider data_test_permission_set */ public function test_permission_set($group_name, $auth_option, $type, $has_permission) { diff --git a/tests/dbal/write_test.php b/tests/dbal/write_test.php index 98709fb043..4fa5cc37a2 100644 --- a/tests/dbal/write_test.php +++ b/tests/dbal/write_test.php @@ -67,7 +67,7 @@ class phpbb_dbal_write_test extends phpbb_database_test_case $result = $db->sql_query($sql); $rows = $db->sql_fetchrowset($result); - $this->assertEquals(1, sizeof($rows)); + $this->assertEquals(1, count($rows)); $this->assertEquals('config2', $rows[0]['config_name']); $db->sql_freeresult($result); diff --git a/tests/error_collector_test.php b/tests/error_collector_test.php index 273284c8fc..8ed89bbe52 100644 --- a/tests/error_collector_test.php +++ b/tests/error_collector_test.php @@ -52,8 +52,8 @@ class phpbb_error_collector_test extends phpbb_test_case 1/0; $line = __LINE__; // Cause a notice - $array = array('ITEM' => 'value'); - $value = $array[ITEM]; $line2 = __LINE__; + $array = array(0 => 'value'); + $value = $array[1]; $line2 = __LINE__; $collector->uninstall(); diff --git a/tests/event/dispatcher_test.php b/tests/event/dispatcher_test.php index 7bba5bf337..da28d24daa 100644 --- a/tests/event/dispatcher_test.php +++ b/tests/event/dispatcher_test.php @@ -29,5 +29,21 @@ class phpbb_event_dispatcher_test extends phpbb_test_case $result = $dispatcher->trigger_event('core.test_event', compact($vars)); $this->assertSame(array('foo' => 'foo2', 'bar' => 'bar2'), $result); + + // Test migrating events + $dispatcher->addListener('core.foo_br', function(\phpbb\event\data $event) { + $event['pi'] = '3.14159'; + }); + $dispatcher->addListener('core.foo_bar', function(\phpbb\event\data $event) { + $event['pi'] = '3.1'; + }); + + + $pi = '3'; + + $vars = array('pi'); + $result = $dispatcher->trigger_event(['core.foo_bar', 'core.foo_br'], compact($vars)); + + $this->assertSame(array('pi' => '3.14159'), $result); } } diff --git a/tests/event/fixtures/event_migration.test b/tests/event/fixtures/event_migration.test new file mode 100644 index 0000000000..b2df9f95df --- /dev/null +++ b/tests/event/fixtures/event_migration.test @@ -0,0 +1,30 @@ +trigger_event(['core.ucp_pm_view_message', 'core.ucp_pm_view_messsage'], compact($vars))); diff --git a/tests/event/fixtures/extra_description.test b/tests/event/fixtures/extra_description.test index ce8f97ce89..e93a1044ac 100644 --- a/tests/event/fixtures/extra_description.test +++ b/tests/event/fixtures/extra_description.test @@ -3,7 +3,7 @@ /** * Description * -* NOTE: This will not be exported +* NOTE: This will also be exported * * @event extra_description.dispatch * @since 3.1.0-b2 diff --git a/tests/event/md_exporter_test.php b/tests/event/md_exporter_test.php index 607f442fdf..2eeb48ea05 100644 --- a/tests/event/md_exporter_test.php +++ b/tests/event/md_exporter_test.php @@ -92,7 +92,7 @@ class phpbb_event_md_exporter_test extends phpbb_test_case public function test_crawl_eventsmd($file, $min_version, $max_version, $events) { $exporter = new \phpbb\event\md_exporter(dirname(__FILE__) . '/fixtures/', null, $min_version, $max_version); - $this->assertSame(sizeof($events), $exporter->crawl_eventsmd($file, 'adm')); + $this->assertSame(count($events), $exporter->crawl_eventsmd($file, 'adm')); $this->assertEquals($events, $exporter->get_events()); } @@ -146,7 +146,7 @@ class phpbb_event_md_exporter_test extends phpbb_test_case $exporter->crawl_eventsmd('docs/events.md', $filter); $events = $exporter->crawl_file_for_events($file); - $this->assertGreaterThanOrEqual(0, sizeof($events)); + $this->assertGreaterThanOrEqual(0, count($events)); $this->assertTrue($exporter->validate_events_from_file($file, $events)); } } diff --git a/tests/event/php_exporter_test.php b/tests/event/php_exporter_test.php index 692a57f93c..c6670e1340 100644 --- a/tests/event/php_exporter_test.php +++ b/tests/event/php_exporter_test.php @@ -37,6 +37,18 @@ class phpbb_event_php_exporter_test extends phpbb_test_case ), ), ), + array( + 'event_migration.test', + array( + 'core.ucp_pm_view_message' => array( + 'event' => 'core.ucp_pm_view_message', + 'file' => 'event_migration.test', + 'arguments' => array('cp_row', 'folder', 'folder_id', 'id', 'message_row', 'mode', 'msg_data', 'msg_id', 'user_info'), + 'since' => '3.1.0-a1', + 'description' => 'Modify pm and sender data before it is assigned to the template', + ), + ), + ), array( 'extra_description.test', array( @@ -45,7 +57,7 @@ class phpbb_event_php_exporter_test extends phpbb_test_case 'file' => 'extra_description.test', 'arguments' => array(), 'since' => '3.1.0-b2', - 'description' => 'Description', + 'description' => 'Description

    NOTE: This will also be exported', ), ), ), @@ -240,6 +252,8 @@ class phpbb_event_php_exporter_test extends phpbb_test_case array("\t\$phpbb_dispatcher->dispatch('dispatch.one2.thr_ee4');", 'dispatch.one2.thr_ee4'), array("\$this->dispatcher->dispatch('dispatch.one2');", 'dispatch.one2'), array("\$phpbb_dispatcher->dispatch('dis_patch.one');", 'dis_patch.one'), + array("\$phpbb_dispatcher->dispatch(['dis_patch.one', 'dis_patch.one2']);", 'dis_patch.one'), + array("\$phpbb_dispatcher->dispatch(['dis_patch.one', 'dis_patch.one2', 'dis_patch.two3']);", 'dis_patch.one'), ); } @@ -259,6 +273,8 @@ class phpbb_event_php_exporter_test extends phpbb_test_case array("\$phpbb_dispatcher->dispatch('');"), array("\$phpbb_dispatcher->dispatch('dispatch.2one');"), array("\$phpbb_dispatcher->dispatch('dispatch');"), + array("\$phpbb_dispatcher->dispatch(['dispatch.one']);"), + array("\$phpbb_dispatcher->dispatch(array('dispatch.one', 'dispatch.one2'));"), ); } @@ -279,6 +295,8 @@ class phpbb_event_php_exporter_test extends phpbb_test_case array("\textract(\$phpbb_dispatcher->trigger_event('dispatch.one2.thr_ee4', compact(\$vars)));", 'dispatch.one2.thr_ee4'), array("extract(\$this->dispatcher->trigger_event('dispatch.one2', compact(\$vars)));", 'dispatch.one2'), array("extract(\$phpbb_dispatcher->trigger_event('dis_patch.one', compact(\$vars)));", 'dis_patch.one'), + array("extract(\$phpbb_dispatcher->trigger_event(['dis_patch.one', 'dis_patch.one2'], compact(\$vars)));", 'dis_patch.one'), + array("extract(\$phpbb_dispatcher->trigger_event(['dis_patch.one', 'dis_patch.one2', 'dis_patch.two3'], compact(\$vars)));", 'dis_patch.one'), ); } @@ -301,6 +319,7 @@ class phpbb_event_php_exporter_test extends phpbb_test_case array("extract(\$phpbb_dispatcher->trigger_event('dispatch.one', \$vars));"), array("extract(\$phpbb_dispatcher->trigger_event('dispatch.one', compact(\$var)));"), array("extract(\$phpbb_dispatcher->trigger_event('dispatch.one', compact(\$array)));"), + array("extract(\$phpbb_dispatcher->trigger_event(['dispatch.one'], compact(\$vars)));"), array("\$phpbb_dispatcher->trigger_event('dis_patch.one', compact(\$vars));", 'dis_patch.one'), ); } diff --git a/tests/feed/attachments_base_test.php b/tests/feed/attachments_base_test.php index dd432d13f5..573218be42 100644 --- a/tests/feed/attachments_base_test.php +++ b/tests/feed/attachments_base_test.php @@ -31,13 +31,25 @@ class phpbb_feed_attachments_base_test extends phpbb_database_test_case $this->filesystem = new \phpbb\filesystem(); $config = new \phpbb\config\config(array()); + $path_helper = new \phpbb\path_helper( + new \phpbb\symfony_request( + new phpbb_mock_request() + ), + $this->filesystem, + $this->getMock('\phpbb\request\request'), + $phpbb_root_path, + 'php' + ); $user = new \phpbb\user( new \phpbb\language\language( new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx) ), '\phpbb\datetime' ); - $feed_helper = new \phpbb\feed\helper($config, $user, $phpbb_root_path, $phpEx); + $container = new phpbb_mock_container_builder(); + $this->get_test_case_helpers()->set_s9e_services($container); + $container->set('feed.quote_helper', new \phpbb\feed\quote_helper($user, $phpbb_root_path, 'php')); + $feed_helper = new \phpbb\feed\helper($config, $container, $path_helper, $container->get('text_formatter.renderer'), $user); $db = $this->new_dbal(); $cache = new \phpbb_mock_cache(); $auth = new \phpbb\auth\auth(); diff --git a/tests/functional/acp_attachments_test.php b/tests/functional/acp_attachments_test.php deleted file mode 100644 index 8e810a508a..0000000000 --- a/tests/functional/acp_attachments_test.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @license GNU General Public License, version 2 (GPL-2.0) - * - * For full copyright and license information, please see - * the docs/CREDITS.txt file. - * - */ - -/** - * @group functional - */ -class phpbb_functional_acp_attachments_test extends phpbb_functional_test_case -{ - public function data_imagick_path_linux() - { - return array( - array('/usr/bin', 'Configuration updated successfully'), - array('/usr/foobar', 'The entered path “/usr/foobar” does not exist.'), - array('/usr/bin/which', 'The entered path “/usr/bin/which” is not a directory.'), - ); - } - - /** - * @dataProvider data_imagick_path_linux - */ - public function test_imagick_path_linux($imagick_path, $expected) - { - if (strtolower(substr(PHP_OS, 0, 5)) !== 'linux') - { - $this->markTestSkipped('Unable to test linux specific paths on other OS.'); - } - - $this->login(); - $this->admin_login(); - - $crawler = self::request('GET', 'adm/index.php?i=attachments&mode=attach&sid=' . $this->sid); - - $form = $crawler->selectButton('Submit')->form(array('config[img_imagick]' => $imagick_path)); - - $crawler = self::submit($form); - $this->assertContains($expected, $crawler->filter('#main')->text()); - } - - public function data_imagick_path_windows() - { - return array( - array('C:\Windows', 'Configuration updated successfully'), - array('C:\Windows\foobar1', 'The entered path “C:\Windows\foobar1” does not exist.'), - array('C:\Windows\explorer.exe', 'The entered path “C:\Windows\explorer.exe” is not a directory.'), - ); - } - - /** - * @dataProvider data_imagick_path_windows - */ - public function test_imagick_path_windows($imagick_path, $expected) - { - if (strtolower(substr(PHP_OS, 0, 3)) !== 'win') - { - $this->markTestSkipped('Unable to test windows specific paths on other OS.'); - } - - $this->login(); - $this->admin_login(); - - $crawler = self::request('GET', 'adm/index.php?i=attachments&mode=attach&sid=' . $this->sid); - - $form = $crawler->selectButton('Submit')->form(array('config[img_imagick]' => $imagick_path)); - - $crawler = self::submit($form); - $this->assertContains($expected, $crawler->filter('#main')->text()); - } -} diff --git a/tests/functional/acp_profile_field_test.php b/tests/functional/acp_profile_field_test.php index 88df782faa..7a0a6ca941 100644 --- a/tests/functional/acp_profile_field_test.php +++ b/tests/functional/acp_profile_field_test.php @@ -28,18 +28,20 @@ class phpbb_functional_acp_profile_field_test extends phpbb_functional_test_case public function data_add_profile_field() { return array( - array('bool', 'profilefields.type.bool', + array('profilefields.type.bool', array( + 'field_ident' => 'bool', + 'lang_name' => 'bool', 'lang_options[0]' => 'foo', 'lang_options[1]' => 'bar', ), - array(), ), - array('dropdown', 'profilefields.type.dropdown', + array('profilefields.type.dropdown', array( + 'field_ident' => 'dropdown', + 'lang_name' => 'dropdown', 'lang_options' => "foo\nbar\nbar\nfoo", ), - array(), ), ); } @@ -47,13 +49,12 @@ class phpbb_functional_acp_profile_field_test extends phpbb_functional_test_case /** * @dataProvider data_add_profile_field */ - public function test_add_profile_field($name, $type, $page1_settings, $page2_settings) + public function test_add_profile_field($type, $page1_settings) { // Custom profile fields page $crawler = self::request('GET', 'adm/index.php?i=acp_profile&mode=profile&sid=' . $this->sid); // these language strings are html $form = $crawler->selectButton('Create new field')->form(array( - 'field_ident' => $name, 'field_type' => $type, )); $crawler = self::submit($form); @@ -63,7 +64,7 @@ class phpbb_functional_acp_profile_field_test extends phpbb_functional_test_case $crawler = self::submit($form); // Fill form for profile field specific options - $form = $crawler->selectButton('Save')->form($page2_settings); + $form = $crawler->selectButton('Save')->form(); $crawler= self::submit($form); $this->assertContainsLang('ADDED_PROFILE_FIELD', $crawler->text()); diff --git a/tests/functional/extension_acp_test.php b/tests/functional/extension_acp_test.php index 8a71a5ce04..ce0f4911e3 100644 --- a/tests/functional/extension_acp_test.php +++ b/tests/functional/extension_acp_test.php @@ -26,7 +26,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case { parent::setUpBeforeClass(); - self::$helper = new phpbb_test_case_helpers(self); + self::$helper = new phpbb_test_case_helpers(__CLASS__); self::$helper->copy_ext_fixtures(dirname(__FILE__) . '/../extension/ext/', self::$fixtures); } @@ -133,7 +133,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case for ($i = 0; $i < $crawler->filter('dl')->count(); $i++) { - $text = $crawler->filter('dl')->eq($i)->text(); + $text = trim($crawler->filter('dl')->eq($i)->text()); $match = false; diff --git a/tests/functional/extension_controller_test.php b/tests/functional/extension_controller_test.php index 18eb9ad4c6..58c3878b8b 100644 --- a/tests/functional/extension_controller_test.php +++ b/tests/functional/extension_controller_test.php @@ -34,7 +34,7 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c { parent::setUpBeforeClass(); - self::$helper = new phpbb_test_case_helpers(self); + self::$helper = new phpbb_test_case_helpers(__CLASS__); self::$helper->copy_ext_fixtures(dirname(__FILE__) . '/fixtures/ext/', self::$fixtures); } diff --git a/tests/functional/extension_global_lang_test.php b/tests/functional/extension_global_lang_test.php index f615114c08..a1e2547745 100644 --- a/tests/functional/extension_global_lang_test.php +++ b/tests/functional/extension_global_lang_test.php @@ -30,7 +30,7 @@ class phpbb_functional_extension_global_lang_test extends phpbb_functional_test_ { parent::setUpBeforeClass(); - self::$helper = new phpbb_test_case_helpers(self); + self::$helper = new phpbb_test_case_helpers(__CLASS__); self::$helper->copy_ext_fixtures(dirname(__FILE__) . '/fixtures/ext/', self::$fixtures); } diff --git a/tests/functional/extension_module_test.php b/tests/functional/extension_module_test.php index 95107665cd..d3a66b9b35 100644 --- a/tests/functional/extension_module_test.php +++ b/tests/functional/extension_module_test.php @@ -29,7 +29,7 @@ class phpbb_functional_extension_module_test extends phpbb_functional_test_case { parent::setUpBeforeClass(); - self::$helper = new phpbb_test_case_helpers(self); + self::$helper = new phpbb_test_case_helpers(__CLASS__); self::$helper->copy_ext_fixtures(dirname(__FILE__) . '/fixtures/ext/', self::$fixtures); } diff --git a/tests/functional/extension_permission_lang_test.php b/tests/functional/extension_permission_lang_test.php index 92d8d596c7..f570d45215 100644 --- a/tests/functional/extension_permission_lang_test.php +++ b/tests/functional/extension_permission_lang_test.php @@ -30,7 +30,7 @@ class phpbb_functional_extension_permission_lang_test extends phpbb_functional_t { parent::setUpBeforeClass(); - self::$helper = new phpbb_test_case_helpers(self); + self::$helper = new phpbb_test_case_helpers(__CLASS__); self::$helper->copy_ext_fixtures(dirname(__FILE__) . '/fixtures/ext/', self::$fixtures); } diff --git a/tests/functional/fileupload_form_test.php b/tests/functional/fileupload_form_test.php index d381fa1ae2..b0780172ff 100644 --- a/tests/functional/fileupload_form_test.php +++ b/tests/functional/fileupload_form_test.php @@ -99,7 +99,6 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case $form = $crawler->selectButton('Submit')->form(array( 'config[check_attachment_content]' => 0, - 'config[img_imagick]' => '', )); self::submit($form); diff --git a/tests/functional/fileupload_remote_test.php b/tests/functional/fileupload_remote_test.php index 88f8999005..426ebcee53 100644 --- a/tests/functional/fileupload_remote_test.php +++ b/tests/functional/fileupload_remote_test.php @@ -102,7 +102,7 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case ->set_allowed_extensions(array('gif')) ->set_max_filesize(2000); $file = $upload->handle_upload('files.types.remote', self::$root_url . 'develop/test.gif'); - $this->assertEquals(0, sizeof($file->error)); + $this->assertEquals(0, count($file->error)); $this->assertTrue(file_exists($file->get('filename'))); $this->assertTrue($file->is_uploaded()); } @@ -115,7 +115,7 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case ->set_allowed_extensions(array('gif')) ->set_max_filesize(100); $file = $upload->handle_upload('files.types.remote', self::$root_url . 'develop/test.gif'); - $this->assertEquals(1, sizeof($file->error)); + $this->assertEquals(1, count($file->error)); $this->assertEquals('WRONG_FILESIZE', $file->error[0]); } } diff --git a/tests/functional/metadata_manager_test.php b/tests/functional/metadata_manager_test.php index 0d2fdf082e..8456c40f00 100644 --- a/tests/functional/metadata_manager_test.php +++ b/tests/functional/metadata_manager_test.php @@ -35,7 +35,7 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case { parent::setUpBeforeClass(); - self::$helper = new phpbb_test_case_helpers(self); + self::$helper = new phpbb_test_case_helpers(__CLASS__); self::$helper->copy_ext_fixtures(dirname(__FILE__) . '/fixtures/ext/', self::$fixtures); } diff --git a/tests/functional/posting_test.php b/tests/functional/posting_test.php index 8e6328d1d3..764376a945 100644 --- a/tests/functional/posting_test.php +++ b/tests/functional/posting_test.php @@ -235,7 +235,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case )); $crawler = self::submit($form); $this->assertContains( - 'My signature', + 'My signature', $crawler->filter('#preview .signature')->html() ); } diff --git a/tests/functional/user_password_reset_test.php b/tests/functional/user_password_reset_test.php index 3da78407cf..2361eed066 100644 --- a/tests/functional/user_password_reset_test.php +++ b/tests/functional/user_password_reset_test.php @@ -21,25 +21,56 @@ class phpbb_functional_user_password_reset_test extends phpbb_functional_test_ca public function test_password_reset() { $this->add_lang('ucp'); - $user_id = $this->create_user('reset-password-test-user'); + $user_id = $this->create_user('reset-password-test-user', 'reset-password-test-user@test.com'); + // test without email $crawler = self::request('GET', "ucp.php?mode=sendpassword&sid={$this->sid}"); - $form = $crawler->selectButton('submit')->form(array( - 'username' => 'reset-password-test-user', - )); + $form = $crawler->selectButton('submit')->form(); $crawler = self::submit($form); $this->assertContainsLang('NO_EMAIL_USER', $crawler->text()); + // test with non-existent email $crawler = self::request('GET', "ucp.php?mode=sendpassword&sid={$this->sid}"); $form = $crawler->selectButton('submit')->form(array( - 'username' => 'reset-password-test-user', - 'email' => 'nobody@example.com', + 'email' => 'non-existent@email.com', )); $crawler = self::submit($form); - $this->assertContainsLang('PASSWORD_UPDATED', $crawler->text()); + $this->assertContainsLang('PASSWORD_UPDATED_IF_EXISTED', $crawler->text()); + + // test with correct email + $crawler = self::request('GET', "ucp.php?mode=sendpassword&sid={$this->sid}"); + $form = $crawler->selectButton('submit')->form(array( + 'email' => 'reset-password-test-user@test.com', + )); + $crawler = self::submit($form); + $this->assertContainsLang('PASSWORD_UPDATED_IF_EXISTED', $crawler->text()); // Check if columns in database were updated for password reset - $this->get_user_data(); + $this->get_user_data('reset-password-test-user'); + $this->assertNotNull($this->user_data['user_actkey']); + $this->assertNotNull($this->user_data['user_newpasswd']); + + // Create another user with the same email + $this->create_user('reset-password-test-user1', 'reset-password-test-user@test.com'); + + // Test that username is now also required + $crawler = self::request('GET', "ucp.php?mode=sendpassword&sid={$this->sid}"); + $form = $crawler->selectButton('submit')->form(array( + 'email' => 'reset-password-test-user@test.com', + )); + $crawler = self::submit($form); + $this->assertContainsLang('EMAIL_NOT_UNIQUE', $crawler->text()); + + // Provide both username and email + $form = $crawler->selectButton('submit')->form(array( + 'email' => 'reset-password-test-user@test.com', + 'username' => 'reset-password-test-user1', + )); + $crawler = self::submit($form); + $this->assertContainsLang('PASSWORD_UPDATED_IF_EXISTED', $crawler->text()); + + // Check if columns in database were updated for password reset + $this->get_user_data('reset-password-test-user1'); $this->assertNotNull($this->user_data['user_actkey']); $this->assertNotNull($this->user_data['user_newpasswd']); @@ -73,7 +104,7 @@ class phpbb_functional_user_password_reset_test extends phpbb_functional_test_ca public function test_activate_new_password($expected, $user_id, $act_key) { $this->add_lang('ucp'); - $this->get_user_data(); + $this->get_user_data('reset-password-test-user'); $user_id = (!$user_id) ? $this->user_data['user_id'] : $user_id; $act_key = (!$act_key) ? $this->user_data['user_actkey'] : $act_key; @@ -119,7 +150,7 @@ class phpbb_functional_user_password_reset_test extends phpbb_functional_test_ca public function test_acivateAfterDeactivate() { // User is active, actkey should not exist - $this->get_user_data(); + $this->get_user_data('reset-password-test-user'); $this->assertEmpty($this->user_data['user_actkey']); $this->login(); @@ -143,7 +174,7 @@ class phpbb_functional_user_password_reset_test extends phpbb_functional_test_ca $crawler = self::request('GET', preg_replace('#(.+)(adm/index.php.+)#', '$2', $link->getUri())); // Ensure again that actkey is empty after deactivation - $this->get_user_data(); + $this->get_user_data('reset-password-test-user'); $this->assertEmpty($this->user_data['user_actkey']); // Force reactivation of account and check that act key is not empty anymore @@ -152,16 +183,16 @@ class phpbb_functional_user_password_reset_test extends phpbb_functional_test_ca $crawler = self::submit($form, array('action' => 'reactivate')); $this->assertContainsLang('FORCE_REACTIVATION_SUCCESS', $crawler->filter('html')->text()); - $this->get_user_data(); + $this->get_user_data('reset-password-test-user'); $this->assertNotEmpty($this->user_data['user_actkey']); } - protected function get_user_data() + protected function get_user_data($username) { $db = $this->get_db(); $sql = 'SELECT user_id, username, user_type, user_email, user_newpasswd, user_lang, user_notify_type, user_actkey, user_inactive_reason FROM ' . USERS_TABLE . " - WHERE username = 'reset-password-test-user'"; + WHERE username = '" . $db->sql_escape($username) . "'"; $result = $db->sql_query($sql); $this->user_data = $db->sql_fetchrow($result); $db->sql_freeresult($result); diff --git a/tests/functions/fixtures/validate_username.xml b/tests/functions/fixtures/validate_username.xml index 1b85a2f06d..add8f76553 100644 --- a/tests/functions/fixtures/validate_username.xml +++ b/tests/functions/fixtures/validate_username.xml @@ -1,9 +1,11 @@ + group_idgroup_namegroup_desc + 10 foobar_group test123 diff --git a/tests/functions/get_remote_file_test.php b/tests/functions/get_remote_file_test.php index 1550aa37e6..75e5a6dc61 100644 --- a/tests/functions/get_remote_file_test.php +++ b/tests/functions/get_remote_file_test.php @@ -58,7 +58,7 @@ class phpbb_functions_get_remote_file extends phpbb_test_case $this->assertGreaterThanOrEqual( 2, - sizeof($lines), + count($lines), 'Failed asserting that the version file has at least two lines.' ); diff --git a/tests/functions/make_clickable_test.php b/tests/functions/make_clickable_test.php index a351a6d527..a6af12b624 100644 --- a/tests/functions/make_clickable_test.php +++ b/tests/functions/make_clickable_test.php @@ -52,6 +52,14 @@ class phpbb_functions_make_clickable_test extends phpbb_test_case 'http://testhost/viewtopic.php?t=1', 'viewtopic.php?t=1' ), + array( + 'javascript://testhost/viewtopic.php?t=1', + 'javascript://testhost/viewtopic.php?t=1' + ), + array( + "java\nscri\npt://testhost/viewtopic.php?t=1", + "java\nscri\npt://testhost/viewtopic.php?t=1" + ), array( 'email@domain.com', 'email@domain.com' @@ -89,6 +97,10 @@ class phpbb_functions_make_clickable_test extends phpbb_test_case 'ftp://ftp.täst.de/', 'ftp://ftp.täst.de/' ), + array( + 'javascript://täst.de/', + 'javascript://täst.de/' + ), array( 'sip://bantu@täst.de', 'sip://bantu@täst.de' diff --git a/tests/functions/user_delete_test.php b/tests/functions/user_delete_test.php index db9b6e0c90..f419c90e9e 100644 --- a/tests/functions/user_delete_test.php +++ b/tests/functions/user_delete_test.php @@ -82,6 +82,12 @@ class phpbb_functions_user_delete_test extends phpbb_database_test_case $phpbb_container->set('auth.provider.oauth.service.google', $oauth_provider_google); $phpbb_container->set('auth.provider_collection', $provider_collection); $phpbb_container->set('notification_manager', $notification_manager); + + $phpbb_container->setParameter('tables.auth_provider_oauth_token_storage', 'phpbb_oauth_tokens'); + $phpbb_container->setParameter('tables.auth_provider_oauth_states', 'phpbb_oauth_states'); + $phpbb_container->setParameter('tables.auth_provider_oauth_account_assoc', 'phpbb_oauth_accounts'); + + $phpbb_container->setParameter('tables.user_notifications', 'phpbb_user_notifications'); } public function test_user_delete() diff --git a/tests/functions/validate_username_test.php b/tests/functions/validate_username_test.php index d310f58036..cee5d38400 100644 --- a/tests/functions/validate_username_test.php +++ b/tests/functions/validate_username_test.php @@ -47,6 +47,7 @@ class phpbb_functions_validate_data_test extends phpbb_database_test_case 'foobar_letter_num' => array(), 'foobar_letter_num_sp' => array(), 'foobar_quot' => array('INVALID_CHARS'), + 'foobar_emoji' => array('INVALID_EMOJIS'), 'barfoo_disallow' => array('USERNAME_DISALLOWED'), 'admin_taken' => array('USERNAME_TAKEN'), 'group_taken' => array('USERNAME_TAKEN'), @@ -60,6 +61,7 @@ class phpbb_functions_validate_data_test extends phpbb_database_test_case 'foobar_letter_num' => array(), 'foobar_letter_num_sp' => array('INVALID_CHARS'), 'foobar_quot' => array('INVALID_CHARS'), + 'foobar_emoji' => array('INVALID_EMOJIS'), 'barfoo_disallow' => array('USERNAME_DISALLOWED'), 'admin_taken' => array('USERNAME_TAKEN'), 'group_taken' => array('INVALID_CHARS'), @@ -73,6 +75,7 @@ class phpbb_functions_validate_data_test extends phpbb_database_test_case 'foobar_letter_num' => array(), 'foobar_letter_num_sp' => array('INVALID_CHARS'), 'foobar_quot' => array('INVALID_CHARS'), + 'foobar_emoji' => array('INVALID_EMOJIS'), 'barfoo_disallow' => array('USERNAME_DISALLOWED'), 'admin_taken' => array('USERNAME_TAKEN'), 'group_taken' => array('USERNAME_TAKEN'), @@ -86,6 +89,7 @@ class phpbb_functions_validate_data_test extends phpbb_database_test_case 'foobar_letter_num' => array(), 'foobar_letter_num_sp' => array('INVALID_CHARS'), 'foobar_quot' => array('INVALID_CHARS'), + 'foobar_emoji' => array('INVALID_EMOJIS'), 'barfoo_disallow' => array('USERNAME_DISALLOWED'), 'admin_taken' => array('USERNAME_TAKEN'), 'group_taken' => array('INVALID_CHARS'), @@ -99,6 +103,7 @@ class phpbb_functions_validate_data_test extends phpbb_database_test_case 'foobar_letter_num' => array(), 'foobar_letter_num_sp' => array(), 'foobar_quot' => array('INVALID_CHARS'), + 'foobar_emoji' => array('INVALID_EMOJIS'), 'barfoo_disallow' => array('USERNAME_DISALLOWED'), 'admin_taken' => array('USERNAME_TAKEN'), 'group_taken' => array('USERNAME_TAKEN'), @@ -112,6 +117,7 @@ class phpbb_functions_validate_data_test extends phpbb_database_test_case 'foobar_letter_num' => array(), 'foobar_letter_num_sp' => array('INVALID_CHARS'), 'foobar_quot' => array('INVALID_CHARS'), + 'foobar_emoji' => array('INVALID_EMOJIS'), 'barfoo_disallow' => array('USERNAME_DISALLOWED'), 'admin_taken' => array('USERNAME_TAKEN'), 'group_taken' => array('USERNAME_TAKEN'), @@ -173,6 +179,11 @@ class phpbb_functions_validate_data_test extends phpbb_database_test_case '"foobar"', array('username'), ), + 'foobar_emoji' => array( + $expected['foobar_emoji'], + 'username😮', + array('username'), + ), 'barfoo_disallow' => array( $expected['barfoo_disallow'], 'barfoo', diff --git a/tests/functions_acp/validate_config_vars_test.php b/tests/functions_acp/validate_config_vars_test.php index 5c31888291..3bd2204de9 100644 --- a/tests/functions_acp/validate_config_vars_test.php +++ b/tests/functions_acp/validate_config_vars_test.php @@ -19,10 +19,11 @@ class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case { parent::setUp(); - global $user; + global $language, $user; $user = new phpbb_mock_user(); $user->lang = new phpbb_mock_lang(); + $language = $user->lang; } /** @@ -44,6 +45,7 @@ class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case 'test_int_32' => array('lang' => 'TEST_INT', 'validate' => 'int:32'), 'test_int_32_64' => array('lang' => 'TEST_INT', 'validate' => 'int:32:64'), 'test_lang' => array('lang' => 'TEST_LANG', 'validate' => 'lang'), + 'test_url' => array('lang' => 'TEST_URL', 'validate' => 'url'), /* 'test_sp' => array('lang' => 'TEST_SP', 'validate' => 'script_path'), 'test_rpath' => array('lang' => 'TEST_RPATH', 'validate' => 'rpath'), @@ -64,6 +66,7 @@ class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case 'test_int_32' => 32, 'test_int_32_64' => 48, 'test_lang' => 'en', + 'test_url' => 'http://foobar.com', ), ), ); @@ -148,6 +151,11 @@ class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case array('test_lang' => 'this_is_no_language'), array('WRONG_DATA_LANG'), ), + array( + array('test_url' => array('lang' => 'TEST_URL', 'validate' => 'url')), + array('test_url' => 'javascript://foobar.com'), + array('URL_INVALID TEST_URL'), + ), ); } @@ -161,100 +169,4 @@ class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case $this->assertEquals($expected, $phpbb_error); } - - public function data_validate_path_linux() - { - return array( - array('/usr/bin', 'absolute_path', true), - array('/usr/bin/', 'absolute_path:50:200', true), - array('/usr/bin/which', 'absolute_path', 'DIRECTORY_NOT_DIR'), - array('/foo/bar', 'absolute_path', 'DIRECTORY_DOES_NOT_EXIST'), - array('C:\Windows', 'absolute_path', 'DIRECTORY_DOES_NOT_EXIST'), - array('.', 'absolute_path', true), - array('', 'absolute_path', true), - array('mkdir /foo/bar', 'absolute_path', 'DIRECTORY_DOES_NOT_EXIST'), - // Make sure above command didn't do anything - array('/foo/bar', 'absolute_path', 'DIRECTORY_DOES_NOT_EXIST'), - ); - } - - /** - * @dataProvider data_validate_path_linux - */ - public function test_validate_path_linux($path, $validation_type, $expected) - { - if (strtolower(substr(PHP_OS, 0, 5)) !== 'linux') - { - $this->markTestSkipped('Unable to test linux specific paths on other OS.'); - } - - $error = array(); - $config_ary = array( - 'path' => $path, - ); - - validate_config_vars(array( - 'path' => array('lang' => 'FOOBAR', 'validate' => $validation_type), - ), - $config_ary, - $error - ); - - if ($expected === true) - { - $this->assertEmpty($error); - } - else - { - $this->assertEquals(array($expected), $error); - } - } - - public function data_validate_path_windows() - { - return array( - array('C:\Windows', 'absolute_path', true), - array('C:\Windows\\', 'absolute_path:50:200', true), - array('C:\Windows\explorer.exe', 'absolute_path', 'DIRECTORY_NOT_DIR'), - array('C:\foobar', 'absolute_path', 'DIRECTORY_DOES_NOT_EXIST'), - array('/usr/bin', 'absolute_path', 'DIRECTORY_DOES_NOT_EXIST'), - array('.', 'absolute_path', true), - array('', 'absolute_path', true), - array('mkdir C:\Windows\foobar', 'absolute_path', 'DIRECTORY_DOES_NOT_EXIST'), - // Make sure above command didn't do anything - array('C:\Windows\foobar', 'absolute_path', 'DIRECTORY_DOES_NOT_EXIST'), - ); - } - - /** - * @dataProvider data_validate_path_windows - */ - public function test_validate_path_windows($path, $validation_type, $expected) - { - if (strtolower(substr(PHP_OS, 0, 3)) !== 'win') - { - $this->markTestSkipped('Unable to test windows specific paths on other OS.'); - } - - $error = array(); - $config_ary = array( - 'path' => $path, - ); - - validate_config_vars(array( - 'path' => array('lang' => 'FOOBAR', 'validate' => $validation_type), - ), - $config_ary, - $error - ); - - if ($expected === true) - { - $this->assertEmpty($error); - } - else - { - $this->assertEquals(array($expected), $error); - } - } } diff --git a/tests/functions_content/phpbb_format_quote_test.php b/tests/functions_content/phpbb_format_quote_test.php new file mode 100644 index 0000000000..cbbd46d0a9 --- /dev/null +++ b/tests/functions_content/phpbb_format_quote_test.php @@ -0,0 +1,57 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +require_once dirname(__FILE__) . '/../../phpBB/includes/message_parser.php'; + +class phpbb_functions_content_phpbb_format_quote_test extends phpbb_test_case +{ + /** @var \phpbb\language\language */ + protected $lang; + + public function setUp() + { + global $cache, $user, $phpbb_root_path, $phpEx; + + $lang_file_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); + $this->lang = new \phpbb\language\language($lang_file_loader); + $user = new \phpbb\user($this->lang, '\phpbb\datetime'); + $cache = new phpbb_mock_cache(); + + parent::setUp(); + } + + public function data_phpbb_format_quote() + { + return [ + [true, ['author' => 'admin', 'user_id' => 2], '[quote="username"]quoted[/quote]', '', "[quote=admin user_id=2][quote="username"]quoted[/quote][/quote]\n\n"], + [false, ['author' => 'admin', 'user_id' => 2], '[quote="username"]quoted[/quote]', '', "admin wrote:\n> [quote="username"]quoted[/quote]\n"], + [true, ['author' => 'admin', 'user_id' => 2], '[quote="username"]quoted[/quote]', "[url=http://viewtopic.php?p=1#p1]Subject: Foo[/url]\n\n", "[url=http://viewtopic.php?p=1#p1]Subject: Foo[/url]\n\n[quote=admin user_id=2][quote="username"]quoted[/quote][/quote]\n\n"], + [false, ['author' => 'admin', 'user_id' => 2], '[quote="username"]quoted[/quote]', "http://viewtopic.php?p=1#p1 - Subject: Foo\n\n", "http://viewtopic.php?p=1#p1 - Subject: Foo\n\nadmin wrote:\n> [quote="username"]quoted[/quote]\n"], + ]; + } + + + /** + * @dataProvider data_phpbb_format_quote + */ + public function test_phpbb_format_quote($bbcode_status, $quote_attributes, $message, $message_link, $expected) + { + $text_formatter_utils = new \phpbb\textformatter\s9e\utils(); + + $message_parser = new parse_message($message); + + phpbb_format_quote($this->lang, $message_parser, $text_formatter_utils, $bbcode_status, $quote_attributes, $message_link); + + $this->assertEquals($expected, $message_parser->message); + } +} diff --git a/tests/functions_user/delete_user_test.php b/tests/functions_user/delete_user_test.php index 25042d9f1b..09ed51890c 100644 --- a/tests/functions_user/delete_user_test.php +++ b/tests/functions_user/delete_user_test.php @@ -46,6 +46,11 @@ class phpbb_functions_user_delete_user_test extends phpbb_database_test_case 'auth.provider_collection', $provider_collection ); + $phpbb_container->setParameter('tables.auth_provider_oauth_token_storage', 'phpbb_oauth_tokens'); + $phpbb_container->setParameter('tables.auth_provider_oauth_states', 'phpbb_oauth_states'); + $phpbb_container->setParameter('tables.auth_provider_oauth_account_assoc', 'phpbb_oauth_accounts'); + + $phpbb_container->setParameter('tables.user_notifications', 'phpbb_user_notifications'); } public function first_last_post_data() diff --git a/tests/functions_user/fixtures/delete_user.xml b/tests/functions_user/fixtures/delete_user.xml index 56014b35d1..8de2659722 100644 --- a/tests/functions_user/fixtures/delete_user.xml +++ b/tests/functions_user/fixtures/delete_user.xml @@ -515,35 +515,44 @@
    user_id + folder_id 2 + 1 3 + 2
    user_idrule_string + rule_id 2 + 1 3 + 2
    user_iddraft_message + draft_id 2 + 1 3 + 2
    diff --git a/tests/group/helper_get_name_string_test.php b/tests/group/helper_get_name_string_test.php new file mode 100644 index 0000000000..c626328dcc --- /dev/null +++ b/tests/group/helper_get_name_string_test.php @@ -0,0 +1,115 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +require_once dirname(__FILE__) . '/helper_test_case.php'; + +class phpbb_group_helper_get_name_string_test extends phpbb_group_helper_test_case +{ + + public function get_name_string_profile_data() + { + global $phpbb_root_path, $phpEx; + + return array( + array(0, 'Non existing group', '', false, ''), + array(2, 'Administrators', 'AA0000', false, "{$phpbb_root_path}memberlist.$phpEx?mode=group&g=2"), + array(42, 'Example Group', '', 'http://www.example.org/group.php?mode=show', 'http://www.example.org/group.php?mode=show&g=42'), + ); + } + + /** + * @dataProvider get_name_string_profile_data + */ + public function test_get_name_string_profile($group_id, $group_name, $group_colour, $custom_profile_url, $expected) + { + $this->assertEquals($expected, $this->group_helper->get_name_string('profile', $group_id, $group_name, $group_colour, $custom_profile_url)); + } + + public function get_name_string_group_name_data() + { + return array( + // Should be fine + array(0, 'BOTS', 'AA0000', false, 'Bots'), + array(1, 'new_group', '', false, 'Some new group'), + array(2, 'group_with_ümlauts', '', 'http://www.example.org/group.php?mode=show', 'Should work'), + + // Should fail and thus return the same + array(3, 'not_uppercase', 'FFFFFF', false, 'not_uppercase'), + array(4, 'Awesome group', '', false, 'Awesome group'), + ); + } + + /** + * @dataProvider get_name_string_group_name_data + */ + public function test_get_name_string_group_name($group_id, $group_name, $group_colour, $custom_profile_url, $expected) + { + $this->assertEquals($expected, $this->group_helper->get_name_string('group_name', $group_id, $group_name, $group_colour, $custom_profile_url)); + } + + public function get_name_string_colour_data() + { + return array( + array(0, '', '', false, ''), + array(0, '', 'F0F0F0', false, '#F0F0F0'), + array(1, 'Guests', '000000', false, '#000000'), + array(2, 'Administrators', '', false, ''), + ); + } + + /** + * @dataProvider get_name_string_colour_data + */ + public function test_get_name_string_colour($group_id, $group_name, $group_colour, $custom_profile_url, $expected) + { + $this->assertEquals($expected, $this->group_helper->get_name_string('colour', $group_id, $group_name, $group_colour, $custom_profile_url)); + } + + public function get_name_string_full_data() + { + global $phpbb_root_path, $phpEx; + + return array( + array(0, 'BOTS', '000000', false, 'Bots'), + array(1, 'BOTS', '111111', false, 'Bots'), + array(7, 'new_group', 'FFA500', false, 'Some new group'), + array(14, 'Awesome group', '', 'http://www.example.org/group.php?mode=show', 'Awesome group'), + ); + } + + /** + * @dataProvider get_name_string_full_data + */ + public function test_get_name_string_full($group_id, $group_name, $group_colour, $custom_profile_url, $expected) + { + $this->assertEquals($expected, $this->group_helper->get_name_string('full', $group_id, $group_name, $group_colour, $custom_profile_url)); + } + + public function get_name_string_no_profile_data() + { + return array( + array(0, 'BOTS', '000000', false, 'Bots'), + array(1, 'new_group', '', false, 'Some new group'), + array(2, 'not_uppercase', 'FF0000', false, 'not_uppercase'), + array(5, 'Awesome group', '', 'http://www.example.org/group.php?mode=show', 'Awesome group'), + ); + } + + /** + * @dataProvider get_name_string_no_profile_data + */ + public function test_get_name_string_no_profile($group_id, $group_name, $group_colour, $custom_profile_url, $expected) + { + $this->assertEquals($expected, $this->group_helper->get_name_string('no_profile', $group_id, $group_name, $group_colour, $custom_profile_url)); + } +} diff --git a/tests/group/helper_get_name_test.php b/tests/group/helper_get_name_test.php new file mode 100644 index 0000000000..b39b2cbedd --- /dev/null +++ b/tests/group/helper_get_name_test.php @@ -0,0 +1,31 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +require_once dirname(__FILE__) . '/helper_test_case.php'; + +class phpbb_group_helper_get_name_test extends phpbb_group_helper_test_case +{ + public function test_get_name() + { + // They should be totally fine + $this->assertEquals('Bots', $this->group_helper->get_name('Bots')); + $this->assertEquals('Some new group', $this->group_helper->get_name('new_group')); + $this->assertEquals('Should work', $this->group_helper->get_name('group_with_ümlauts')); + + // This should fail (obviously) + $this->assertNotEquals('The key does not contain uppercase letters', $this->group_helper->get_name('not_uppercase')); + + // The key doesn't exist so just return group name... + $this->assertEquals('Awesome group', $this->group_helper->get_name('Awesome group')); + } +} diff --git a/tests/group/helper_get_rank_test.php b/tests/group/helper_get_rank_test.php new file mode 100644 index 0000000000..5efd8ad95e --- /dev/null +++ b/tests/group/helper_get_rank_test.php @@ -0,0 +1,43 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +require_once dirname(__FILE__) . '/helper_test_case.php'; + +class phpbb_group_helper_get_rank_test extends phpbb_group_helper_test_case +{ + public function get_rank_data() + { + global $phpbb_root_path; + + return array( + array( + array('group_id' => 0, 'group_rank' => 1), + array( + 'title' => 'Site admin', + 'img' => 'Site admin', + 'img_src' => $phpbb_root_path . 'images/ranks/siteadmin.png', + ) + ), + array(array('group_id' => 1, 'group_rank' => 0), array('title' => null, 'img' => null, 'img_src' => null)), + array(array('group_id' => 2, 'group_rank' => 2), array('title' => 'Test member', 'img' => '', 'img_src' => '')), + ); + } + + /** + * @dataProvider get_rank_data + */ + public function test_get_rank($group_data, $expected) + { + $this->assertEquals($expected, $this->group_helper->get_rank($group_data)); + } +} diff --git a/tests/group/helper_test.php b/tests/group/helper_test.php deleted file mode 100644 index 2377a6f47c..0000000000 --- a/tests/group/helper_test.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @license GNU General Public License, version 2 (GPL-2.0) - * - * For full copyright and license information, please see - * the docs/CREDITS.txt file. - * - */ - -class phpbb_group_helper_test extends phpbb_test_case -{ - /** @var \phpbb\group\helper */ - protected $group_helper; - - public function setUp() - { - global $phpbb_root_path, $phpEx; - - // Set up language service - $lang = new \phpbb\language\language( - new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx) - ); - - // Set up language data for testing - $reflection_class = new ReflectionClass('\phpbb\language\language'); - - // Set default language files loaded flag to true - $loaded_flag = $reflection_class->getProperty('common_language_files_loaded'); - $loaded_flag->setAccessible(true); - $loaded_flag->setValue($lang, true); - - // Set up test language data - $lang_array = $reflection_class->getProperty('lang'); - $lang_array->setAccessible(true); - $lang_array->setValue($lang, $this->get_test_language_data_set()); - - // Set up group helper - $this->group_helper = new \phpbb\group\helper($lang); - } - - public function test_get_name() - { - // They should be totally fine - $this->assertEquals('Bots', $this->group_helper->get_name('Bots')); - $this->assertEquals('Some new group', $this->group_helper->get_name('new_group')); - $this->assertEquals('Should work', $this->group_helper->get_name('group_with_ümlauts')); - - // This should fail (obviously) - $this->assertNotEquals('They key does not contain uppercase letters', $this->group_helper->get_name('not_uppercase')); - - // The key doesn't exist so just return group name... - $this->assertEquals('Awesome group', $this->group_helper->get_name('Awesome group')); - } - - protected function get_test_language_data_set() - { - return array( - 'G_BOTS' => 'Bots', - 'G_NEW_GROUP' => 'Some new group', - 'G_not_uppercase' => 'The key does not contain uppercase letters', - 'G_GROUP_WITH_ÜMLAUTS' => 'Should work', - ); - } -} diff --git a/tests/group/helper_test_case.php b/tests/group/helper_test_case.php new file mode 100644 index 0000000000..e298770331 --- /dev/null +++ b/tests/group/helper_test_case.php @@ -0,0 +1,123 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +class phpbb_group_helper_test_case extends phpbb_test_case +{ + /** @var \phpbb\group\helper */ + protected $group_helper; + + protected function config_defaults() + { + $defaults = array( + 'ranks_path' => 'images/ranks' + ); + return $defaults; + } + + protected function get_test_language_data_set() + { + return array( + 'G_BOTS' => 'Bots', + 'G_NEW_GROUP' => 'Some new group', + 'G_not_uppercase' => 'The key does not contain uppercase letters', + 'G_GROUP_WITH_ÜMLAUTS' => 'Should work', + ); + } + + protected function get_test_rank_data_set() + { + return array( + 'special' => array( + 1 => array( + 'rank_id' => 1, + 'rank_title' => 'Site admin', + 'rank_special' => 1, + 'rank_image' => 'siteadmin.png', + ), + 2 => array( + 'rank_id' => 2, + 'rank_title' => 'Test member', + 'rank_special' => 1, + 'rank_image' => '', + ) + ) + ); + } + + protected function setup_engine(array $new_config = array()) + { + global $phpbb_dispatcher, $phpbb_root_path, $phpEx; + + // Set up authentication data for testing + $auth = $this->getMock('\phpbb\auth\auth'); + $auth->expects($this->any()) + ->method('acl_get') + ->with($this->stringContains('_'), $this->anything()) + ->will($this->returnValueMap(array( + array('u_viewprofile', true), + ))); + + // Set up cache service + $cache_service = $this->getMockBuilder('\phpbb\cache\service')->disableOriginalConstructor()->getMock(); + $cache_service->expects($this->any()) + ->method('obtain_ranks') + ->will($this->returnValue($this->get_test_rank_data_set())); + + // Set up configuration + $defaults = $this->config_defaults(); + $config = new \phpbb\config\config(array_merge($defaults, $new_config)); + + // Set up language service + $lang = new \phpbb\language\language( + new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx) + ); + + // Set up language data for testing + $reflection_class = new ReflectionClass('\phpbb\language\language'); + + // Set default language files loaded flag to true + $loaded_flag = $reflection_class->getProperty('common_language_files_loaded'); + $loaded_flag->setAccessible(true); + $loaded_flag->setValue($lang, true); + + // Set up test language data + $lang_array = $reflection_class->getProperty('lang'); + $lang_array->setAccessible(true); + $lang_array->setValue($lang, $this->get_test_language_data_set()); + + // Set up event dispatcher + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + + // Set up path helper + $path_helper = $this->getMockBuilder('\phpbb\path_helper') + ->disableOriginalConstructor() + ->setMethods(array()) + ->getMock(); + $path_helper->method('get_phpbb_root_path') + ->willReturn($phpbb_root_path); + $path_helper->method('get_php_ext') + ->willReturn($phpEx); + $path_helper->method('update_web_root_path') + ->will($this->returnArgument(0)); + + $user = new \phpbb\user($lang, '\phpbb\datetime'); + $user->data['user_id'] = ANONYMOUS; + + $this->group_helper = new \phpbb\group\helper($auth, $cache_service, $config, $lang, $phpbb_dispatcher, $path_helper, $user); + } + + public function setUp() + { + $this->setup_engine(); + } +} diff --git a/tests/lint_test.php b/tests/lint_test.php index 70046bdfd2..8ab31f976c 100644 --- a/tests/lint_test.php +++ b/tests/lint_test.php @@ -67,6 +67,12 @@ class phpbb_lint_test extends phpbb_test_case { $files = array(); $dh = opendir($root); + + if ($dh === false) + { + return $files; + } + while (($filename = readdir($dh)) !== false) { if ($filename == '.' || $filename == '..') @@ -89,6 +95,7 @@ class phpbb_lint_test extends phpbb_test_case // PHP Fatal error: Cannot declare class Container because the name is already in use in /var/www/projects/phpbb3/tests/../phpBB/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php on line 20 // https://gist.github.com/e003913ffd493da63cbc dirname(__FILE__) . '/../phpBB/vendor', + dirname(__FILE__) . '/../node_modules', ))) { $files = array_merge($files, $this->check($path)); diff --git a/tests/migrator/get_callable_from_step_test.php b/tests/migrator/get_callable_from_step_test.php new file mode 100644 index 0000000000..af636f5d21 --- /dev/null +++ b/tests/migrator/get_callable_from_step_test.php @@ -0,0 +1,136 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +class get_callable_from_step_test extends phpbb_database_test_case +{ + public function setUp() + { + global $phpbb_root_path, $php_ext, $table_prefix, $phpbb_log; + + parent::setUp(); + + $phpbb_log = $this->getMockBuilder('\phpbb\log\log')->disableOriginalConstructor()->getMock(); + $db = $this->new_dbal(); + $factory = new \phpbb\db\tools\factory(); + $cache_service = $this->getMockBuilder('\phpbb\cache\service')->disableOriginalConstructor()->getMock(); + $user = $this->getMockBuilder('\phpbb\user')->disableOriginalConstructor()->getMock(); + $module_manager = new \phpbb\module\module_manager( + $this->getMockBuilder('\phpbb\cache\driver\dummy')->disableOriginalConstructor()->getMock(), + $db, + new phpbb_mock_extension_manager($phpbb_root_path), + 'phpbb_modules', + $phpbb_root_path, + $php_ext + ); + $module_tools = new \phpbb\db\migration\tool\module($db, $cache_service, $user, $module_manager, $phpbb_root_path, $php_ext, 'phpbb_modules'); + $this->migrator = new \phpbb\db\migrator( + new phpbb_mock_container_builder(), + new \phpbb\config\config(array()), + $db, + $factory->get($db), + 'phpbb_migrations', + $phpbb_root_path, + $php_ext, + $table_prefix, + array($module_tools), + new \phpbb\db\migration\helper() + ); + + if (!$module_tools->exists('acp', 0, 'new_module_langname')) + { + $module_tools->add('acp', 0, array( + 'module_basename' => 'new_module_basename', + 'module_langname' => 'new_module_langname', + 'module_mode' => 'settings', + 'module_auth' => '', + 'module_display' => true, + 'before' => false, + 'after' => false, + )); + $this->module_added = true; + } + } + + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__).'/../dbal/fixtures/migrator.xml'); + } + + public function get_callable_from_step_provider() + { + return array( + array( + array('if', array( + false, + array('permission.add', array('some_data')), + )), + true, // expects false + ), + array( + array('if', array( + array('module.exists', array( + 'mcp', + 'RANDOM_PARENT', + 'RANDOM_MODULE' + )), + array('permission.add', array('some_data')), + )), + true, // expects false + ), + array( + array('if', array( + array('module.exists', array( + 'acp', + 0, + 'new_module_langname' + )), + array('module.add', array( + 'acp', + 0, + 'module_basename' => 'new_module_basename2', + 'module_langname' => 'new_module_langname2', + 'module_mode' => 'settings', + 'module_auth' => '', + 'module_display' => true, + 'before' => false, + 'after' => false, + )), + )), + false, // expects false + ), + ); + } + + /** + * @dataProvider get_callable_from_step_provider + */ + public function test_get_callable_from_step($step, $expects_false) + { + if ($expects_false) + { + $this->assertFalse($this->call_get_callable_from_step($step)); + } + else + { + $this->assertNotFalse($this->call_get_callable_from_step($step)); + } + } + + protected function call_get_callable_from_step($step) + { + $class = new ReflectionClass($this->migrator); + $method = $class->getMethod('get_callable_from_step'); + $method->setAccessible(true); + return $method->invokeArgs($this->migrator, array($step)); + } +} diff --git a/tests/mock/sql_insert_buffer.php b/tests/mock/sql_insert_buffer.php index c751764d45..e57983684d 100644 --- a/tests/mock/sql_insert_buffer.php +++ b/tests/mock/sql_insert_buffer.php @@ -15,7 +15,7 @@ class phpbb_mock_sql_insert_buffer extends \phpbb\db\sql_insert_buffer { public function flush() { - return (sizeof($this->buffer)) ? true : false; + return (count($this->buffer)) ? true : false; } public function get_buffer() diff --git a/tests/network/checkdnsrr_test.php b/tests/network/checkdnsrr_test.php index 6503a4c40b..8cbd4f7e97 100644 --- a/tests/network/checkdnsrr_test.php +++ b/tests/network/checkdnsrr_test.php @@ -38,7 +38,7 @@ class phpbb_network_checkdnsrr_test extends phpbb_test_case array('does-not-exist.phpbb.com', 'AAAA', false), // Existing CNAME record - array('news.cnet.com', 'CNAME', true), + array('area51.phpbb.com', 'CNAME', true), // Non-existing CNAME record array('does-not-exist.phpbb.com', 'CNAME', false), diff --git a/tests/notification/base.php b/tests/notification/base.php index b64e25cf8c..80b9a0d777 100644 --- a/tests/notification/base.php +++ b/tests/notification/base.php @@ -163,7 +163,7 @@ abstract class phpbb_tests_notification_base extends phpbb_database_test_case 'order_dir' => 'ASC', ), $options)); - $this->assertEquals(sizeof($expected), $notifications['unread_count']); + $this->assertEquals(count($expected), $notifications['unread_count']); $i = 0; foreach ($notifications['notifications'] as $notification) diff --git a/tests/notification/fixtures/submit_post_notification.type.bookmark.xml b/tests/notification/fixtures/submit_post_notification.type.bookmark.xml index 7f069abc59..db1cef2ef6 100644 --- a/tests/notification/fixtures/submit_post_notification.type.bookmark.xml +++ b/tests/notification/fixtures/submit_post_notification.type.bookmark.xml @@ -29,6 +29,7 @@ + notification_idnotification_type_iduser_iditem_id @@ -36,6 +37,7 @@ notification_readnotification_data + 1 1 5 1 diff --git a/tests/notification/fixtures/submit_post_notification.type.post.xml b/tests/notification/fixtures/submit_post_notification.type.post.xml index a4bf9d3ee4..920b271525 100644 --- a/tests/notification/fixtures/submit_post_notification.type.post.xml +++ b/tests/notification/fixtures/submit_post_notification.type.post.xml @@ -21,6 +21,7 @@
    + notification_idnotification_type_iduser_iditem_id @@ -28,6 +29,7 @@ notification_readnotification_data + 1 1 5 1 @@ -36,6 +38,7 @@ + 2 1 8 1 diff --git a/tests/notification/fixtures/submit_post_notification.type.post_in_queue.xml b/tests/notification/fixtures/submit_post_notification.type.post_in_queue.xml index 0a955c48d2..12e73b0ff2 100644 --- a/tests/notification/fixtures/submit_post_notification.type.post_in_queue.xml +++ b/tests/notification/fixtures/submit_post_notification.type.post_in_queue.xml @@ -1,6 +1,7 @@
    + notification_idnotification_type_iduser_iditem_id @@ -8,6 +9,7 @@ notification_readnotification_data + 1 1 6 1 diff --git a/tests/notification/fixtures/submit_post_notification.type.quote.xml b/tests/notification/fixtures/submit_post_notification.type.quote.xml index c66830fbf5..9f4ba91475 100644 --- a/tests/notification/fixtures/submit_post_notification.type.quote.xml +++ b/tests/notification/fixtures/submit_post_notification.type.quote.xml @@ -1,6 +1,7 @@
    + notification_idnotification_type_iduser_iditem_id @@ -8,6 +9,7 @@ notification_readnotification_data + 1 1 5 1 diff --git a/tests/notification/fixtures/submit_post_notification.type.topic.xml b/tests/notification/fixtures/submit_post_notification.type.topic.xml index e0f6583f48..1f96ed2ee7 100644 --- a/tests/notification/fixtures/submit_post_notification.type.topic.xml +++ b/tests/notification/fixtures/submit_post_notification.type.topic.xml @@ -21,6 +21,7 @@
    + notification_idnotification_type_iduser_iditem_id @@ -28,6 +29,7 @@ notification_readnotification_data + 1 1 8 1 diff --git a/tests/notification/group_request_test.php b/tests/notification/group_request_test.php index 92e758a336..e849c66fa5 100644 --- a/tests/notification/group_request_test.php +++ b/tests/notification/group_request_test.php @@ -49,9 +49,23 @@ class phpbb_notification_group_request_test extends phpbb_tests_notification_bas $this->cache->get_driver() )); $this->container->set('group_helper', new \phpbb\group\helper( + $this->getMock('\phpbb\auth\auth'), + $this->cache, + $this->config, new \phpbb\language\language( new phpbb\language\language_file_loader($phpbb_root_path, $phpEx) - ) + ), + new phpbb_mock_event_dispatcher(), + new \phpbb\path_helper( + new \phpbb\symfony_request( + new phpbb_mock_request() + ), + new \phpbb\filesystem\filesystem(), + $this->getMock('\phpbb\request\request'), + $phpbb_root_path, + $phpEx + ), + $this->user )); $phpbb_dispatcher = new phpbb_mock_event_dispatcher; $phpbb_log = new \phpbb\log\dummy(); diff --git a/tests/notification/notification_test.php b/tests/notification/notification_test.php index ec42aa193c..6bbabfc602 100644 --- a/tests/notification/notification_test.php +++ b/tests/notification/notification_test.php @@ -108,7 +108,7 @@ class phpbb_notification_test extends phpbb_tests_notification_base $types = array('notification.type.quote', 'notification.type.bookmark', 'notification.type.post', 'test'); foreach ($types as $id => $type) { - $this->db->sql_query('INSERT INTO phpbb_notification_types ' . + $this->getConnection()->createQueryTable('insertNotification', 'INSERT INTO phpbb_notification_types ' . $this->db->sql_build_array('INSERT', array( 'notification_type_id' => ($id + 1), 'notification_type_name' => $type, diff --git a/tests/profilefields/type_string_test.php b/tests/profilefields/type_string_test.php index 7c7fa3f3e6..54bb406838 100644 --- a/tests/profilefields/type_string_test.php +++ b/tests/profilefields/type_string_test.php @@ -24,7 +24,7 @@ class phpbb_profilefield_type_string_test extends phpbb_test_case */ public function setUp() { - global $request, $user, $cache, $phpbb_root_path, $phpEx; + global $config, $request, $user, $cache, $phpbb_root_path, $phpEx; $user = $this->getMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), @@ -34,6 +34,7 @@ class phpbb_profilefield_type_string_test extends phpbb_test_case $user->expects($this->any()) ->method('lang') ->will($this->returnCallback(array($this, 'return_callback_implode'))); + $config = new \phpbb\config\config([]); $request = $this->getMock('\phpbb\request\request'); $template = $this->getMock('\phpbb\template\template'); @@ -269,6 +270,18 @@ class phpbb_profilefield_type_string_test extends phpbb_test_case null, 'Field should simply output null for empty vlaue', ), + array( + 'http://foobar.com', + array('field_show_novalue' => false), + 'foobar.com', + 'Field should output the given value and make it clickable', + ), + array( + 'javascript://foobar.com', + array('field_show_novalue' => true), + 'javascript://foobar.com', + 'Field should output the given value but not make it clickable', + ), ); } diff --git a/tests/profilefields/type_url_test.php b/tests/profilefields/type_url_test.php index 1d90e2c34c..3bb5d52899 100644 --- a/tests/profilefields/type_url_test.php +++ b/tests/profilefields/type_url_test.php @@ -11,6 +11,10 @@ * */ +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; + class phpbb_profilefield_type_url_test extends phpbb_test_case { protected $cp; @@ -24,8 +28,10 @@ class phpbb_profilefield_type_url_test extends phpbb_test_case */ public function setUp() { - global $phpbb_root_path, $phpEx; + global $config, $request, $user, $cache, $phpbb_root_path, $phpEx; + $config = new \phpbb\config\config([]); + $cache = new phpbb_mock_cache; $user = $this->getMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' @@ -92,6 +98,19 @@ class phpbb_profilefield_type_url_test extends phpbb_test_case 'FIELD_INVALID_URL-field', 'Field should reject invalid URL having multi value parameters', ), + // Not allowed schemes + array( + 'ftp://example.com/', + array(), + 'FIELD_INVALID_URL-field', + 'Field should reject invalid URL having multi value parameters', + ), + array( + 'javascript://alert.com', + array(), + 'FIELD_INVALID_URL-field', + 'Field should reject invalid URL having multi value parameters', + ), // IDN url type profilefields array( @@ -165,6 +184,55 @@ class phpbb_profilefield_type_url_test extends phpbb_test_case ); } + public function profile_value_data() + { + return array( + array( + 'http://foobar.com', + array('field_show_novalue' => true), + 'foobar.com', + 'Field should output the given value', + ), + array( + 'http://foobar.com', + array('field_show_novalue' => false), + 'foobar.com', + 'Field should output the given value', + ), + array( + 'test', + array('field_show_novalue' => true), + null, + 'Field should output nothing for empty value', + ), + array( + 'test', + array('field_show_novalue' => false), + null, + 'Field should simply output null for empty value', + ), + array( + 'javascript://foobar.com', + array('field_show_novalue' => true), + null, + 'Field should output nothing for empty value', + ), + ); + } + + + /** + * @dataProvider profile_value_data + */ + public function test_get_profile_value($value, $field_options, $expected, $description) + { + $field_options = array_merge($this->field_options, $field_options); + + $result = $this->cp->get_profile_value($value, $field_options); + + $this->assertSame($expected, $result, $description); + } + /** * @dataProvider profile_value_raw_data */ diff --git a/tests/random/gen_rand_string_test.php b/tests/random/gen_rand_string_test.php index a9d1ea20de..428db6ac98 100644 --- a/tests/random/gen_rand_string_test.php +++ b/tests/random/gen_rand_string_test.php @@ -40,7 +40,10 @@ class phpbb_random_gen_rand_string_test extends phpbb_test_case $random_string_length = strlen($random_string); $this->assertTrue($random_string_length >= self::MIN_STRING_LENGTH); - $this->assertTrue($random_string_length <= $num_chars); + $this->assertTrue( + $random_string_length == $num_chars, + sprintf('Failed asserting that random string length matches expected length. Expected %1$u, Actual %2$u', $num_chars, $random_string_length) + ); $this->assertRegExp('#^[A-Z0-9]+$#', $random_string); } } @@ -56,7 +59,10 @@ class phpbb_random_gen_rand_string_test extends phpbb_test_case $random_string_length = strlen($random_string); $this->assertTrue($random_string_length >= self::MIN_STRING_LENGTH); - $this->assertTrue($random_string_length <= $num_chars); + $this->assertTrue( + $random_string_length == $num_chars, + sprintf('Failed asserting that random string length matches expected length. Expected %1$u, Actual %2$u', $num_chars, $random_string_length) + ); $this->assertRegExp('#^[A-NP-Z1-9]+$#', $random_string); } } diff --git a/tests/request/type_cast_helper_test.php b/tests/request/type_cast_helper_test.php index 143c05aa9c..6407dca894 100644 --- a/tests/request/type_cast_helper_test.php +++ b/tests/request/type_cast_helper_test.php @@ -20,16 +20,6 @@ class phpbb_type_cast_helper_test extends phpbb_test_case $this->type_cast_helper = new \phpbb\request\type_cast_helper(); } - public function test_addslashes_recursively() - { - $data = array('some"string' => array('that"' => 'really"', 'needs"' => '"escaping')); - $expected = array('some\\"string' => array('that\\"' => 'really\\"', 'needs\\"' => '\\"escaping')); - - $this->type_cast_helper->addslashes_recursively($data); - - $this->assertEquals($expected, $data); - } - public function test_simple_recursive_set_var() { $data = 'eviL<3'; diff --git a/tests/search/fixtures/posts.xml b/tests/search/fixtures/posts.xml index 16232b8f39..4916cd188b 100644 --- a/tests/search/fixtures/posts.xml +++ b/tests/search/fixtures/posts.xml @@ -1,25 +1,30 @@
    + post_idpost_usernamepost_subjectpost_text + 1 foo foo foo + 2 bar bar bar + 3 commonword commonword commonword + 4 baaz baaz baaz diff --git a/tests/search/native_test.php b/tests/search/native_test.php index 29d0d0a8d3..0e6f719cef 100644 --- a/tests/search/native_test.php +++ b/tests/search/native_test.php @@ -70,7 +70,7 @@ class phpbb_search_native_test extends phpbb_search_test_case 'ba*az', 'all', true, - array('\'ba%az\''), + array(4), array(), array(), ), @@ -78,7 +78,7 @@ class phpbb_search_native_test extends phpbb_search_test_case 'ba*z', 'all', true, - array('\'ba%z\''), + array(), // <= 3 chars after removing * array(), array(), ), @@ -86,7 +86,7 @@ class phpbb_search_native_test extends phpbb_search_test_case 'baa* baaz*', 'all', true, - array('\'baa%\'', '\'baaz%\''), + array('\'baa%\'', 4), array(), array(), ), @@ -94,7 +94,7 @@ class phpbb_search_native_test extends phpbb_search_test_case 'ba*z baa*', 'all', true, - array('\'ba%z\'', '\'baa%\''), + array('\'baa%\''), // baz is <= 3 chars, only baa* is left array(), array(), ), diff --git a/tests/security/redirect_test.php b/tests/security/redirect_test.php index 40cb7d2f04..0177eb4259 100644 --- a/tests/security/redirect_test.php +++ b/tests/security/redirect_test.php @@ -109,7 +109,7 @@ class phpbb_security_redirect_test extends phpbb_security_test_base if ($expected_error !== false) { - $this->setExpectedTriggerError(E_USER_ERROR, $user->lang[$expected_error]); + $this->setExpectedTriggerError(E_USER_WARNING, $user->lang[$expected_error]); } $result = redirect($test, true, $disable_cd_check); diff --git a/tests/session/check_ban_test.php b/tests/session/check_ban_test.php index 04da5f08b9..16a65b0ade 100644 --- a/tests/session/check_ban_test.php +++ b/tests/session/check_ban_test.php @@ -72,7 +72,8 @@ class phpbb_session_check_ban_test extends phpbb_session_test_case { try { - $is_banned = $this->session->check_ban($user_id, $user_ips, $user_email, $return); + $ban = $this->session->check_ban($user_id, $user_ips, $user_email, $return); + $is_banned = !empty($ban); } catch (PHPUnit_Framework_Error_Notice $e) { diff --git a/tests/template/context_test.php b/tests/template/context_test.php new file mode 100644 index 0000000000..52ce6c8fde --- /dev/null +++ b/tests/template/context_test.php @@ -0,0 +1,96 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +class context_test extends phpbb_test_case +{ + protected $context; + protected function setUp() + { + $this->context = new \phpbb\template\context(); + + for ($i = 0; $i < 10; $i++) + { + $this->context->assign_block_vars('block' . $i, array( + 'FOO' . $i => 'foo' . $i, + 'BAR' . $i => 'bar' . $i, + )); + + for ($j = 0; $j < 10; $j++) + { + $this->context->assign_block_vars('block' . $i . '.subblock', array( + 'SUBFOO' => 'subfoo' . $j, + 'SUBBAR' => 'subbar' . $j, + )); + + for ($k = 0; $k < 10; $k++) + { + $this->context->assign_block_vars('block' . $i . '.subblock.subsubblock', array( + 'SUBSUBFOO' => 'subsubfoo' . $k, + 'SUBSUBBAR' => 'subsubbar' . $k, + )); + } + } + } + } + + public function retrieve_block_vars_data() + { + return array( + array('foo', array(), array()), // non-existent top-level block + array('block1.foo', array(), array()), // non-existent sub-level block + array('block1', array(), array( // top-level block, all vars + 'FOO1' => 'foo1', + 'BAR1' => 'bar1', + )), + array('block1', array('FOO1'), array( // top-level block, one var + 'FOO1' => 'foo1', + )), + array('block2.subblock', array(), array( // sub-level block, all vars + 'SUBFOO' => 'subfoo9', + 'SUBBAR' => 'subbar9', + )), + array('block2.subblock', array('SUBBAR'), array( // sub-level block, one var + 'SUBBAR' => 'subbar9', + )), + array('block2.subblock.subsubblock', array(), array( // sub-sub-level block, all vars + 'SUBSUBFOO' => 'subsubfoo9', + 'SUBSUBBAR' => 'subsubbar9', + )), + array('block2.subblock.subsubblock', array('SUBSUBBAR'), array( // sub-sub-level block, one var + 'SUBSUBBAR' => 'subsubbar9', + )), + array('block3.subblock[2]', array(), array( // sub-level, exact index, all vars + 'SUBFOO' => 'subfoo2', + 'SUBBAR' => 'subbar2', + )), + array('block3.subblock[2]', array('SUBBAR'), array( // sub-level, exact index, one var + 'SUBBAR' => 'subbar2', + )), + array('block3.subblock[3].subsubblock[5]', array(), array( // sub-sub-level, exact index, all vars + 'SUBSUBFOO' => 'subsubfoo5', + 'SUBSUBBAR' => 'subsubbar5', + )), + array('block3.subblock[4].subsubblock[6]', array('SUBSUBFOO'), array( // sub-sub-level, exact index, one var + 'SUBSUBFOO' => 'subsubfoo6', + )), + ); + } + + /** + * @dataProvider retrieve_block_vars_data + */ + public function test_retrieve_block_vars($blockname, $vararray, $result) + { + $this->assertEquals($result, $this->context->retrieve_block_vars($blockname, $vararray)); + } +} diff --git a/tests/template/template_includecss_test.php b/tests/template/template_includecss_test.php index bc871aa612..4eb30eda1e 100644 --- a/tests/template/template_includecss_test.php +++ b/tests/template/template_includecss_test.php @@ -95,19 +95,19 @@ class phpbb_template_template_includecss_test extends phpbb_template_template_te */ array( array('TEST' => 1), - '', + '', ), array( array('TEST' => 2), - '', + '', ), array( array('TEST' => 3), - '', + '', ), array( array('TEST' => 4), - '', + '', ), ); } diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index 232f551b4a..19c016ae5e 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -28,67 +28,67 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes */ array( array('TEST' => 1), - '', + '', ), array( array('TEST' => 2), - '', + '', ), array( array('TEST' => 3), - '', + '', ), array( array('TEST' => 4), - '', + '', ), array( array('TEST' => 6), - '', + '', ), array( array('TEST' => 7), - '', + '', ), array( array('TEST' => 8), - '', + '', ), array( array('TEST' => 9), - '', + '', ), array( array('TEST' => 10), - '', + '', ), array( array('TEST' => 11), - '', + '', ), array( array('TEST' => 12), - '', + '', ), array( array('TEST' => 14), - '', + '', ), array( array('TEST' => 15), - '', + '', ), array( array('TEST' => 16), - '', + '', ), array( array('TEST' => 17), - '', + '', ), array( array('TEST' => 18), - '', + '', ), ); } diff --git a/tests/template/template_test.php b/tests/template/template_test.php index 9f2124418d..727f35e9d2 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -364,7 +364,7 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), array(), array(), - "Value'\n1 O'Clock\nValue\\x27\n1\\x20O\\x27Clock", + "Value'\n1 O'Clock\nValue\\u0027\n1\\u0020O\\u0027Clock", array('VARIABLE' => "Value'", '1_VARIABLE' => "1 O'Clock"), ), array( @@ -998,6 +998,46 @@ EOT $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Deleting by index out of bounds, ignored'); } + public function test_indexed_assign_block_vars() + { + $this->template->set_filenames(array('test' => 'loop_nested.html')); + + $this->template->assign_var('TEST_MORE', true); + + // @todo Change this + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + + $expect = 'outer - 0[outer|3]middle - 0[middle|1]outer - 1[outer|3]middle - 0[middle|2]middle - 1[middle|2]outer - 2[outer|3]middle - 0[middle|3]middle - 1[middle|3]middle - 2[middle|3]'; + $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Ensuring template is built correctly before modification'); + + $this->template->assign_block_vars('outer[0].middle', array('VARIABLE' => 'test')); + + $expect = 'outer - 0[outer|3]middle - 0[middle|2]middle - 1 - test[middle|2]outer - 1[outer|3]middle - 0[middle|2]middle - 1[middle|2]outer - 2[outer|3]middle - 0[middle|3]middle - 1[middle|3]middle - 2[middle|3]'; + $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Inserting at the first outer block'); + + $this->template->assign_block_vars('outer[1].middle[0].inner', array()); + + $expect = 'outer - 0[outer|3]middle - 0[middle|2]middle - 1 - test[middle|2]outer - 1[outer|3]middle - 0[middle|2]inner - 0[inner|1]middle - 1[middle|2]outer - 2[outer|3]middle - 0[middle|3]middle - 1[middle|3]middle - 2[middle|3]'; + $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Creating an inner block at the first middle block in the second outer block'); + + $this->template->assign_block_vars('outer[1].middle[0].inner', array()); + + $expect = 'outer - 0[outer|3]middle - 0[middle|2]middle - 1 - test[middle|2]outer - 1[outer|3]middle - 0[middle|2]inner - 0[inner|2]inner - 1[inner|2]middle - 1[middle|2]outer - 2[outer|3]middle - 0[middle|3]middle - 1[middle|3]middle - 2[middle|3]'; + $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Inserting another inner block in the same place'); + + $this->template->assign_block_vars('outer.middle[1].inner', array('VARIABLE' => 'test')); + + $expect = 'outer - 0[outer|3]middle - 0[middle|2]middle - 1 - test[middle|2]outer - 1[outer|3]middle - 0[middle|2]inner - 0[inner|2]inner - 1[inner|2]middle - 1[middle|2]outer - 2[outer|3]middle - 0[middle|3]middle - 1[middle|3]inner - 0 - test[inner|1]middle - 2[middle|3]'; + $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Inserting another inner block in the same place'); + } public function assign_block_vars_array_data() { diff --git a/tests/template/templates/loop_nested.html b/tests/template/templates/loop_nested.html index cf099ecc15..5763262781 100644 --- a/tests/template/templates/loop_nested.html +++ b/tests/template/templates/loop_nested.html @@ -2,5 +2,8 @@ outer - {outer.S_ROW_COUNT} - {outer.VARIABLE}[{outer.S_BLOCK_NAME}|{outer.S_NUM_ROWS}] middle - {outer.middle.S_ROW_COUNT} - {outer.middle.VARIABLE}[{outer.middle.S_BLOCK_NAME}|{outer.middle.S_NUM_ROWS}] + +inner - {outer.middle.inner.S_ROW_COUNT} - {outer.middle.inner.VARIABLE}[{outer.middle.inner.S_BLOCK_NAME}|{outer.middle.inner.S_NUM_ROWS}] + diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index b7386e9a3e..606c40a623 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -142,9 +142,86 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test $manager->database_synchronisation($table_column_map); } + /** + * Create xml data set for insertion into database + * + * @param string $path Path to fixture XML + * @return PHPUnit_Extensions_Database_DataSet_DefaultDataSet|PHPUnit_Extensions_Database_DataSet_XmlDataSet + */ public function createXMLDataSet($path) { $this->fixture_xml_data = parent::createXMLDataSet($path); + + // Extend XML data set on MSSQL + if (strpos($this->get_database_config()['dbms'], 'mssql') !== false) + { + $newXmlData = new PHPUnit_Extensions_Database_DataSet_DefaultDataSet(); + $db = $this->new_dbal(); + foreach ($this->fixture_xml_data as $key => $value) + { + /** @var \PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData $tableMetaData */ + $tableMetaData = $value->getTableMetaData(); + $columns = $tableMetaData->getColumns(); + $primaryKeys = $tableMetaData->getPrimaryKeys(); + + $sql = "SELECT COLUMN_NAME AS identity_column + FROM INFORMATION_SCHEMA.COLUMNS + WHERE COLUMNPROPERTY(object_id(TABLE_SCHEMA + '.' + TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1 + AND TABLE_NAME = '$key' + ORDER BY TABLE_NAME"; + $result = $db->sql_query($sql); + $identity_columns = $db->sql_fetchrowset($result); + $has_default_identity = false; + $add_primary_keys = false; + + // Iterate over identity columns to check for missing primary + // keys in data set and special identity column 'mssqlindex' + // that might have been added when no default identity column + // exists in the current table. + foreach ($identity_columns as $column) + { + if (in_array($column['identity_column'], $columns) && !in_array($column['identity_column'], $primaryKeys)) + { + $primaryKeys[] = $column['identity_column']; + $add_primary_keys = true; + } + + if ($column['identity_column'] === 'mssqlindex') + { + $has_default_identity = true; + break; + } + } + + if ($has_default_identity || $add_primary_keys) + { + // Add default identity column to columns list + if ($has_default_identity) + { + $columns[] = 'mssqlindex'; + } + + $newMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($key, $columns, $primaryKeys); + $newTable = new PHPUnit_Extensions_Database_DataSet_DefaultTable($newMetaData); + for ($i = 0; $i < $value->getRowCount(); $i++) + { + $dataRow = $value->getRow($i); + if ($has_default_identity) + { + $dataRow['mssqlindex'] = $i + 1; + } + $newTable->addRow($dataRow); + } + $newXmlData->addTable($newTable); + } + else + { + $newXmlData->addTable($value); + } + } + + $this->fixture_xml_data = $newXmlData; + } return $this->fixture_xml_data; } @@ -229,7 +306,7 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test { // http://stackoverflow.com/questions/3838288/phpunit-assert-two-arrays-are-equal-but-order-of-elements-not-important // but one array_diff is not enough! - if (sizeof(array_diff($one, $two)) || sizeof(array_diff($two, $one))) + if (count(array_diff($one, $two)) || count(array_diff($two, $one))) { // get a nice error message $this->assertEquals($one, $two); diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index 147029d699..f3adbefc1b 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -222,6 +222,14 @@ class phpbb_database_test_connection_manager $this->purge_extras(); break; + case 'phpbb\db\driver\mssql': + case 'phpbb\db\driver\mssqlnative': + $this->connect(); + // Drop all tables + $this->pdo->exec("EXEC sp_MSforeachtable 'DROP TABLE ?'"); + $this->purge_extras(); + break; + default: $this->connect(false); @@ -621,7 +629,7 @@ class phpbb_database_test_connection_manager } // Combine all of the SETVALs into one query - if (sizeof($setval_queries)) + if (count($setval_queries)) { $queries[] = 'SELECT ' . implode(', ', $setval_queries); } diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index eb56049515..4d294fd523 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -397,6 +397,14 @@ class phpbb_functional_test_case extends phpbb_test_case global $phpbb_container; $phpbb_container->reset(); + // Purge cache to remove cached files + $phpbb_container = new phpbb_mock_container_builder(); + $phpbb_container->setParameter('core.environment', PHPBB_ENVIRONMENT); + $phpbb_container->setParameter('core.cache_dir', $phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT . '/'); + + $cache = new \phpbb\cache\driver\file; + $cache->purge(); + $blacklist = ['phpbb_class_loader_mock', 'phpbb_class_loader_ext', 'phpbb_class_loader']; foreach (array_keys($GLOBALS) as $key) @@ -425,7 +433,7 @@ class phpbb_functional_test_case extends phpbb_test_case $meta_refresh = $crawler->filter('meta[http-equiv="refresh"]'); // Wait for extension to be fully enabled - while (sizeof($meta_refresh)) + while (count($meta_refresh)) { preg_match('#url=.+/(adm+.+)#', $meta_refresh->attr('content'), $match); $url = $match[1]; @@ -509,7 +517,6 @@ class phpbb_functional_test_case extends phpbb_test_case else { $db->sql_multi_insert(STYLES_TABLE, array(array( - 'style_id' => $style_id, 'style_name' => $style_path, 'style_copyright' => '', 'style_active' => 1, @@ -551,9 +558,10 @@ class phpbb_functional_test_case extends phpbb_test_case * Creates a new user with limited permissions * * @param string $username Also doubles up as the user's password + * @param string $email User email (defaults to nobody@example.com) * @return int ID of created user */ - protected function create_user($username) + protected function create_user($username, $email = 'nobody@example.com') { // Required by unique_id global $config; @@ -572,6 +580,9 @@ class phpbb_functional_test_case extends phpbb_test_case $config['rand_seed'] = ''; $config['rand_seed_last_update'] = time() + 600; + // Prevent new user to have an invalid style + $config['default_style'] = 1; + // Required by user_add global $db, $cache, $phpbb_dispatcher, $phpbb_container; $db = $this->get_db(); @@ -602,7 +613,7 @@ class phpbb_functional_test_case extends phpbb_test_case $user_row = array( 'username' => $username, 'group_id' => 2, - 'user_email' => 'nobody@example.com', + 'user_email' => $email, 'user_type' => 0, 'user_lang' => 'en', 'user_timezone' => 'UTC', @@ -909,10 +920,15 @@ class phpbb_functional_test_case extends phpbb_test_case * status code. This assertion tries to catch that. * * @param int $status_code Expected status code - * @return null + * @return void */ static public function assert_response_status_code($status_code = 200) { + if ($status_code != self::$client->getResponse()->getStatus() && + preg_match('/^5[0-9]{2}/', self::$client->getResponse()->getStatus())) + { + self::fail("Encountered unexpected server error:\n" . self::$client->getResponse()->getContent()); + } self::assertEquals($status_code, self::$client->getResponse()->getStatus(), 'HTTP status code does not match'); } @@ -987,7 +1003,7 @@ class phpbb_functional_test_case extends phpbb_test_case $this->assertEquals( 1, - sizeof($result), + count($result), $message ?: 'Failed asserting that exactly one checkbox with name' . " $name exists in crawler scope." ); @@ -1169,10 +1185,6 @@ class phpbb_functional_test_case extends phpbb_test_case } } - // Bypass time restriction that said that if the lastclick time (i.e. time when the form was opened) - // is not at least 2 seconds before submission, cancel the form - $form_data['lastclick'] = 0; - // I use a request because the form submission method does not allow you to send data that is not // contained in one of the actual form fields that the browser sees (i.e. it ignores "hidden" inputs) // Instead, I send it as a request with the submit button "post" set to true. diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index 7fb9a740b8..c792976b1e 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -385,7 +385,7 @@ class phpbb_test_case_helpers $mb = $this->test_case->getMockBuilder('phpbb\\textformatter\\data_access'); $mb->setMethods(array('get_bbcodes', 'get_censored_words', 'get_smilies', 'get_styles')); $mb->setConstructorArgs(array( - $this->test_case->getMock('phpbb\\db\\driver\\driver'), + $this->test_case->getMockBuilder('phpbb\\db\\driver\\driver')->getMock(), 'phpbb_bbcodes', 'phpbb_smilies', 'phpbb_styles', @@ -489,8 +489,11 @@ class phpbb_test_case_helpers $request = new phpbb_mock_request; } + // Get a log interface + $log = ($container->has('log')) ? $container->get('log') : $this->test_case->getMockBuilder('phpbb\\log\\log_interface')->getMock(); + // Create and register the text_formatter.s9e.factory service - $factory = new \phpbb\textformatter\s9e\factory($dal, $cache, $dispatcher, $config, new \phpbb\textformatter\s9e\link_helper, $cache_dir, $cache_key_parser, $cache_key_renderer); + $factory = new \phpbb\textformatter\s9e\factory($dal, $cache, $dispatcher, $config, new \phpbb\textformatter\s9e\link_helper, $log, $cache_dir, $cache_key_parser, $cache_key_renderer); $container->set('text_formatter.s9e.factory', $factory); // Create a user if none was provided, and add the common lang strings diff --git a/tests/test_framework/phpbb_ui_test_case.php b/tests/test_framework/phpbb_ui_test_case.php index b875d3212b..4d88d7d9cb 100644 --- a/tests/test_framework/phpbb_ui_test_case.php +++ b/tests/test_framework/phpbb_ui_test_case.php @@ -11,6 +11,7 @@ * */ +use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\WebDriverBy; use Facebook\WebDriver\Exception\WebDriverCurlException; use Facebook\WebDriver\Remote\RemoteWebDriver; @@ -79,8 +80,15 @@ class phpbb_ui_test_case extends phpbb_test_case } try { - $capabilities = DesiredCapabilities::firefox(); - self::$webDriver = RemoteWebDriver::create(self::$host . ':' . self::$port, $capabilities); + $capabilities = DesiredCapabilities::chrome(); + $chromeOptions = (new ChromeOptions)->addArguments(['headless', 'disable-gpu']); + $capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); + self::$webDriver = RemoteWebDriver::create( + self::$host . ':' . self::$port, + $capabilities, + 30 * 1000, // 30 seconds connection timeout + 30 * 1000 // 30 seconds request timeout + ); } catch (WebDriverCurlException $e) { self::markTestSkipped('PhantomJS webserver is not running.'); } @@ -192,6 +200,13 @@ class phpbb_ui_test_case extends phpbb_test_case } } + $install_config_file = $phpbb_root_path . 'store/install_config.php'; + + if (file_exists($install_config_file)) + { + unlink($install_config_file); + } + $container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); $container = $container_builder ->with_environment('installer') @@ -205,11 +220,14 @@ class phpbb_ui_test_case extends phpbb_test_case ], 'cache.driver.class' => 'phpbb\cache\driver\file' ]) + ->with_config(new \phpbb\config_php_file($phpbb_root_path, $phpEx)) ->without_compiled_container() ->get_container(); $container->register('installer.install_finish.notify_user')->setSynthetic(true); $container->set('installer.install_finish.notify_user', new phpbb_mock_null_installer_task()); + $container->register('installer.install_finish.install_extensions')->setSynthetic(true); + $container->set('installer.install_finish.install_extensions', new phpbb_mock_null_installer_task()); $container->compile(); $language = $container->get('language'); @@ -317,7 +335,7 @@ class phpbb_ui_test_case extends phpbb_test_case $meta_refresh = $this->find_element('cssSelector', 'meta[http-equiv="refresh"]'); // Wait for extension to be fully enabled - while (sizeof($meta_refresh)) + while (count($meta_refresh)) { preg_match('#url=.+/(adm+.+)#', $meta_refresh->getAttribute('content'), $match); $this->getDriver()->execute(array('method' => 'post', 'url' => $match[1])); @@ -338,6 +356,12 @@ class phpbb_ui_test_case extends phpbb_test_case { if (!$this->cache) { + global $phpbb_container, $phpbb_root_path; + + $phpbb_container = new phpbb_mock_container_builder(); + $phpbb_container->setParameter('core.environment', PHPBB_ENVIRONMENT); + $phpbb_container->setParameter('core.cache_dir', $phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT . '/'); + $this->cache = new \phpbb\cache\driver\file; } @@ -590,4 +614,37 @@ class phpbb_ui_test_case extends phpbb_test_case $this->getDriver()->takeScreenshot($screenshot); } + + /** + * Wait for AJAX. Should be called after an AJAX action is made. + * + * @param string $framework javascript frameworks jquery|prototype|dojo + * @throws \Facebook\WebDriver\Exception\NoSuchElementException + * @throws \Facebook\WebDriver\Exception\TimeOutException + */ + public function waitForAjax($framework = 'jquery') + { + switch ($framework) + { + case 'jquery': + $code = 'return jQuery.active;'; + break; + case 'prototype': + $code = 'return Ajax.activeRequestCount;'; + break; + case 'dojo': + $code = 'return dojo.io.XMLHTTPTransport.inFlight.length;'; + break; + default: + throw new \RuntimeException('Unsupported framework'); + break; + } + // wait for at most 30s, retry every 2000ms (2s) + $driver = $this->getDriver(); + $driver->wait(30, 2000)->until( + function () use ($driver, $code) { + return !$driver->executeScript($code); + } + ); + } } diff --git a/tests/text_formatter/s9e/bbcode_merger_test.php b/tests/text_formatter/s9e/bbcode_merger_test.php new file mode 100644 index 0000000000..815539056b --- /dev/null +++ b/tests/text_formatter/s9e/bbcode_merger_test.php @@ -0,0 +1,280 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +class phpbb_textformatter_s9e_bbcode_merger_test extends phpbb_test_case +{ + /** + * @dataProvider get_merge_bbcodes_tests + */ + public function test_merge_bbcodes($usage_without, $template_without, $usage_with, $template_with, $expected_usage, $expected_template) + { + $container = $this->get_test_case_helpers()->set_s9e_services(); + $factory = $container->get('text_formatter.s9e.factory'); + $bbcode_merger = new \phpbb\textformatter\s9e\bbcode_merger($factory); + + $without = ['usage' => $usage_without, 'template' => $template_without]; + $with = ['usage' => $usage_with, 'template' => $template_with]; + $merged = $bbcode_merger->merge_bbcodes($without, $with); + + // Normalize the expected template's whitespace to match the default indentation + $expected_template = str_replace("\n\t\t\t\t", "\n", $expected_template); + $expected_template = str_replace("\t", ' ', $expected_template); + + $this->assertSame($expected_usage, $merged['usage']); + $this->assertSame($expected_template, $merged['template']); + } + + public function get_merge_bbcodes_tests() + { + return [ + [ + '[x]{TEXT}[/x]', + '{TEXT}', + + '[x={TEXT1}]{TEXT}[/x]', + '{TEXT}', + + '[x={TEXT1?}]{TEXT}[/x]', + ' + + + + + + + ' + ], + [ + // The tokens' numbering differs between versions + '[x]{TEXT}[/x]', + '{TEXT}', + + '[x={TEXT1}]{TEXT2}[/x]', + '{TEXT2}', + + '[x={TEXT1?}]{TEXT2}[/x]', + ' + + + + + + + ' + ], + [ + '[x]{URL}[/x]', + '{URL}', + + '[x={URL}]{TEXT}[/x]', + '{TEXT}', + + '[x={URL;useContent}]{TEXT}[/x]', + ' + + ' + ], + [ + '[x]{URL}[/x]', + '{L_GO_TO}: {URL}', + + '[x={URL}]{TEXT}[/x]', + '{L_GO_TO}: {TEXT}', + + '[x={URL;useContent}]{TEXT}[/x]', + '{L_GO_TO}: ' + ], + [ + // Test that unsafe BBCodes can still be merged + '[script]{TEXT}[/script]', + '', + + '[script={TEXT1}]{TEXT2}[/script]', + '', + + '[script={TEXT1?}]{TEXT2}[/script]', + '' + ], + [ + // https://www.phpbb.com/community/viewtopic.php?p=14848281#p14848281 + '[note]{TEXT}[/note]', + '{TEXT}', + + '[note={TEXT1}]{TEXT2}[/note]', + '{TEXT1}{TEXT2}', + + '[note={TEXT1?}]{TEXT2}[/note]', + ' + + + + + + + + ' + ], + [ + // https://www.phpbb.com/community/viewtopic.php?p=14768441#p14768441 + '[MI]{TEXT}[/MI]', + 'MI: {TEXT}', + + '[MI={TEXT2}]{TEXT1}[/MI]', + 'MI for: "{TEXT2}": {TEXT1}', + + '[MI={TEXT2?}]{TEXT1}[/MI]', + 'MI for: "": + + + + ' + ], + [ + // https://www.phpbb.com/community/viewtopic.php?p=14700506#p14700506 + '[spoiler]{TEXT}[/spoiler]', + ' {TEXT}', + + '[spoiler={TEXT1}]{TEXT2}[/spoiler]', + '
    {TEXT1}{TEXT2}
    ', + + '[spoiler={TEXT1?}]{TEXT2}[/spoiler]', + ' + +
    + + + + + +
    +
    + + + + + + +
    ' + ], + [ + // https://www.phpbb.com/community/viewtopic.php?p=14859676#p14859676 + '[AE]{TEXT}[/AE]', + '
    + +
    + + + + +
    + + + + + + + + +
    +  ACTIVE EFFECTS & CONDITIONS  
    + + + + +
    + {TEXT} +
    +
    +
    +
    +

     

    ', + + '[AE={TEXT1}]{TEXT2}[/AE]', + ' + +
    + + + + +
    + + + + + + + + +
    +   {TEXT1}  
    + + + + +
    + {TEXT2} +
    +
    +
    +
    +

     

    ', + + '[AE={TEXT1?}]{TEXT2}[/AE]', + ' + + + +
    + + + + +
    + + + + + + + + +
    + + +   ACTIVE EFFECTS & CONDITIONS  + + +  
    + + + + +
    + +
    +
    +
    +
    +

     

    ' + ], + ]; + } +} diff --git a/tests/text_formatter/s9e/default_formatting_test.php b/tests/text_formatter/s9e/default_formatting_test.php index a0c57214e4..a35c9138a5 100644 --- a/tests/text_formatter/s9e/default_formatting_test.php +++ b/tests/text_formatter/s9e/default_formatting_test.php @@ -50,27 +50,27 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case return array( array( '[b]bold[/b]', - 'bold' + 'bold' ), array( '[u]underlined[/u]', - 'underlined' + 'underlined' ), array( '[i]italic[/i]', - 'italic' + 'italic' ), array( '[color=#FF0000]colored[/color]', - 'colored' + 'colored' ), array( '[color=red]colored[/color]', - 'colored' + 'colored' ), array( '[size=75]smaller[/size]', - 'smaller' + 'smaller' ), array( '[quote]quoted[/quote]', @@ -102,31 +102,31 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case ), array( '[list=1][*]item[/list]', - '
    1. item
    ' + '
    1. item
    ' ), array( '[list=a][*]item[/list]', - '
    1. item
    ' + '
    1. item
    ' ), array( '[list=i][*]item[/list]', - '
    1. item
    ' + '
    1. item
    ' ), array( '[list=I][*]item[/list]', - '
    1. item
    ' + '
    1. item
    ' ), array( '[list=disc][*]item[/list]', - '
    • item
    ' + '
    • item
    ' ), array( '[list=circle][*]item[/list]', - '
    • item
    ' + '
    • item
    ' ), array( '[list=square][*]item[/list]', - '
    • item
    ' + '
    • item
    ' ), array( '[img]https://area51.phpbb.com/images/area51.png[/img]', @@ -180,17 +180,17 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case array( // Allow textual bbcodes in textual bbcodes '[b]bold [i]bold + italic[/i][/b]', - 'bold bold + italic' + 'bold bold + italic' ), array( // Allow textual bbcodes in url with description '[url=https://area51.phpbb.com/]Area51 [i]italic[/i][/url]', - 'Area51 italic' + 'Area51 italic' ), array( // Allow url with description in textual bbcodes '[i]italic [url=https://area51.phpbb.com/]Area51[/url][/i]', - 'italic Area51' + 'italic Area51' ), array( // Do not parse textual bbcodes in code @@ -205,7 +205,7 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case array( // Textual bbcode nesting into textual bbcode '[b]bold [i]bold + italic[/b] italic[/i]', - 'bold bold + italic italic' + 'bold bold + italic italic' ), array( "[code]\tline1\n line2[/code]", @@ -253,6 +253,10 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case '[url=http://example.org/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[/url]', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' ), + array( + '[url=http://example.org/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]http://example.org/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[/url]', + 'http://example.org/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' + ), array( '[quote="[url=http://example.org]xxx[/url]"]...[/quote]', '
    xxx wrote:...
    ' @@ -298,7 +302,7 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case ), array( "Emoji: \xF0\x9F\x98\x80", - 'Emoji: ' . ' + 'Emoji: ' . ' ), array( "Emoji: \xF0\x9F\x98\x80", diff --git a/tests/text_formatter/s9e/factory_test.php b/tests/text_formatter/s9e/factory_test.php index fd9b4e4c09..0d780a19a9 100644 --- a/tests/text_formatter/s9e/factory_test.php +++ b/tests/text_formatter/s9e/factory_test.php @@ -56,6 +56,7 @@ class phpbb_textformatter_s9e_factory_test extends phpbb_database_test_case $this->dispatcher, new \phpbb\config\config(array('allowed_schemes_links' => 'http,https,ftp')), new \phpbb\textformatter\s9e\link_helper, + $this->getMockBuilder('phpbb\\log\\log_interface')->getMock(), $this->get_cache_dir(), '_foo_parser', '_foo_renderer' @@ -247,6 +248,39 @@ class phpbb_textformatter_s9e_factory_test extends phpbb_database_test_case $this->assertSame($expected, $renderer->render($parser->parse($original))); } + /** + * @testdox Accepts unsafe default BBCodes + */ + public function test_unsafe_default_bbcodes() + { + $fixture = __DIR__ . '/fixtures/unsafe_default_bbcodes.xml'; + $style_dir = __DIR__ . '/fixtures/styles/'; + $container = $this->get_test_case_helpers()->set_s9e_services(null, $fixture, $style_dir); + $parser = $container->get('text_formatter.parser'); + $renderer = $container->get('text_formatter.renderer'); + + $original = '[b]alert(1)[/b]'; + $expected = ''; + $this->assertSame($expected, $renderer->render($parser->parse($original))); + } + + /** + * @testdox Logs malformed BBCodes + */ + public function test_malformed_bbcodes() + { + $log = $this->getMockBuilder('phpbb\\log\\log_interface')->getMock(); + $log->expects($this->once()) + ->method('add') + ->with('critical', null, null, 'LOG_BBCODE_CONFIGURATION_ERROR', false, ['[x !x]{TEXT}[/x]', 'Cannot interpret the BBCode definition']); + + $container = new phpbb_mock_container_builder; + $container->set('log', $log); + + $fixture = __DIR__ . '/fixtures/malformed_bbcode.xml'; + $this->get_test_case_helpers()->set_s9e_services($container, $fixture); + } + /** * @testdox get_configurator() triggers events before and after configuration */ diff --git a/tests/text_formatter/s9e/fixtures/malformed_bbcode.xml b/tests/text_formatter/s9e/fixtures/malformed_bbcode.xml new file mode 100644 index 0000000000..7e7aa1a39c --- /dev/null +++ b/tests/text_formatter/s9e/fixtures/malformed_bbcode.xml @@ -0,0 +1,28 @@ + + + + bbcode_id + bbcode_tag + bbcode_helpline + display_on_posting + bbcode_match + bbcode_tpl + first_pass_match + first_pass_replace + second_pass_match + second_pass_replace + + + 13 + x + + 1 + [x !x]{TEXT}[/x] + ... + + + + + +
    +
    diff --git a/tests/text_formatter/s9e/fixtures/styles/unsafe/template/bbcode.html b/tests/text_formatter/s9e/fixtures/styles/unsafe/template/bbcode.html new file mode 100644 index 0000000000..f3932f9b78 --- /dev/null +++ b/tests/text_formatter/s9e/fixtures/styles/unsafe/template/bbcode.html @@ -0,0 +1,40 @@ +
      +
        +
      + +
        +
      + +
    • +
    • + +
      {USERNAME} {L_WROTE}{L_COLON} +
      +
      + +

      {L_CODE}{L_COLON} {L_SELECT_ALL_CODE}

      +
      + +
      +
      + + + + + + + + + +{TEXT} + +{TEXT} + +{L_IMAGE} + +{DESCRIPTION} + +{DESCRIPTION} + + diff --git a/tests/text_formatter/s9e/fixtures/unsafe_default_bbcodes.xml b/tests/text_formatter/s9e/fixtures/unsafe_default_bbcodes.xml new file mode 100644 index 0000000000..06524a13cc --- /dev/null +++ b/tests/text_formatter/s9e/fixtures/unsafe_default_bbcodes.xml @@ -0,0 +1,24 @@ + + + + style_id + style_name + style_copyright + style_active + style_path + bbcode_bitfield + style_parent_id + style_parent_tree + + + 1 + unsafe + + 1 + unsafe + QA== + 0 + + +
      +
      diff --git a/tests/text_processing/tickets_data/PHPBB3-10122.html b/tests/text_processing/tickets_data/PHPBB3-10122.html index f0fb6115b2..0803c895a8 100644 --- a/tests/text_processing/tickets_data/PHPBB3-10122.html +++ b/tests/text_processing/tickets_data/PHPBB3-10122.html @@ -1 +1 @@ -
      • This is my indented text
      \ No newline at end of file +
      • This is my indented text
      \ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-10268.html b/tests/text_processing/tickets_data/PHPBB3-10268.html index c89e63f9a3..13b71b4823 100644 --- a/tests/text_processing/tickets_data/PHPBB3-10268.html +++ b/tests/text_processing/tickets_data/PHPBB3-10268.html @@ -1,4 +1,4 @@
      -http://phpbb.com
      - http://phpbb.com
      +http://phpbb.com
      + http://phpbb.com
      diff --git a/tests/text_processing/tickets_data/PHPBB3-13641.html b/tests/text_processing/tickets_data/PHPBB3-13641.html index 1bd1c06dbb..2646bc0ea5 100644 --- a/tests/text_processing/tickets_data/PHPBB3-13641.html +++ b/tests/text_processing/tickets_data/PHPBB3-13641.html @@ -1 +1 @@ -[color=#FF0000] - red \ No newline at end of file +[color=#FF0000] - red \ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-13921.html b/tests/text_processing/tickets_data/PHPBB3-13921.html index 6a9dc7f504..690668ef28 100644 --- a/tests/text_processing/tickets_data/PHPBB3-13921.html +++ b/tests/text_processing/tickets_data/PHPBB3-13921.html @@ -1 +1 @@ -
      xxx
      \ No newline at end of file +
      xxx
      \ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-14706.html b/tests/text_processing/tickets_data/PHPBB3-14706.html index b8f74c9e93..23b3304485 100644 --- a/tests/text_processing/tickets_data/PHPBB3-14706.html +++ b/tests/text_processing/tickets_data/PHPBB3-14706.html @@ -1 +1 @@ -
        1. a
        2. b
        3. c
        4. d
        5. e
      • outer
      \ No newline at end of file +
        1. a
        2. b
        3. c
        4. d
        5. e
      • outer
      \ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-14790.html b/tests/text_processing/tickets_data/PHPBB3-14790.html index 7624b2d36c..5384098e1b 100644 --- a/tests/text_processing/tickets_data/PHPBB3-14790.html +++ b/tests/text_processing/tickets_data/PHPBB3-14790.html @@ -1,4 +1,4 @@ -
      • text
      • -
      • text
      • -
      • text
      • -
      • text
      \ No newline at end of file +
      • text
      • +
      • text
      • +
      • text
      • +
      • text
      \ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-14846.html b/tests/text_processing/tickets_data/PHPBB3-14846.html index 461ca25bc6..bd4455781b 100644 --- a/tests/text_processing/tickets_data/PHPBB3-14846.html +++ b/tests/text_processing/tickets_data/PHPBB3-14846.html @@ -1 +1 @@ -
      moderator text
      - Mickroz
      \ No newline at end of file +
      moderator text
      - Mickroz
      \ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-15348.html b/tests/text_processing/tickets_data/PHPBB3-15348.html index e65925ec28..1794232d08 100644 --- a/tests/text_processing/tickets_data/PHPBB3-15348.html +++ b/tests/text_processing/tickets_data/PHPBB3-15348.html @@ -1 +1 @@ -:o k: :ok: \ No newline at end of file +:o k: :ok: \ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-16053.html b/tests/text_processing/tickets_data/PHPBB3-16053.html new file mode 100644 index 0000000000..af70ddf7eb --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-16053.html @@ -0,0 +1 @@ +Test \ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-16053.txt b/tests/text_processing/tickets_data/PHPBB3-16053.txt new file mode 100644 index 0000000000..c786665eb9 --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-16053.txt @@ -0,0 +1 @@ +[test=http://ea117.com]Test[/test] \ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-16053.xml b/tests/text_processing/tickets_data/PHPBB3-16053.xml new file mode 100644 index 0000000000..25f7c9e34e --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-16053.xml @@ -0,0 +1,28 @@ + + + + bbcode_id + bbcode_tag + bbcode_helpline + display_on_posting + bbcode_match + bbcode_tpl + first_pass_match + first_pass_replace + second_pass_match + second_pass_replace + + + 13 + test + + 1 + [test={URL}]{TEXT}[/test] + {TEXT}]]> + ((?!)) + + ((?!)) + + +
      +
      diff --git a/tests/text_processing/tickets_data/PHPBB3-16074.html b/tests/text_processing/tickets_data/PHPBB3-16074.html new file mode 100644 index 0000000000..b588e2ac47 --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-16074.html @@ -0,0 +1 @@ +:man_judge: 👨‍⚖️ \ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-16074.txt b/tests/text_processing/tickets_data/PHPBB3-16074.txt new file mode 100644 index 0000000000..f067a7294d --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-16074.txt @@ -0,0 +1 @@ +:man_judge: 👨‍⚖️ \ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-8419.html b/tests/text_processing/tickets_data/PHPBB3-8419.html index 38df626a94..df91e9df50 100644 --- a/tests/text_processing/tickets_data/PHPBB3-8419.html +++ b/tests/text_processing/tickets_data/PHPBB3-8419.html @@ -1 +1 @@ -przykład \ No newline at end of file +przykład \ No newline at end of file diff --git a/tests/text_reparser/base_test.php b/tests/text_reparser/base_test.php index af2d56ea51..2c6844b063 100644 --- a/tests/text_reparser/base_test.php +++ b/tests/text_reparser/base_test.php @@ -66,4 +66,19 @@ class phpbb_textreparser_base_test extends phpbb_database_test_case $this->get_rows(array(1)) ); } + + public function test_reparse_case_insensitive() + { + $this->get_reparser()->reparse_range(2, 2); + + $this->assertEquals( + [ + [ + 'id' => '2', + 'text' => '[IMG]img.png[/IMG]' + ] + ], + $this->get_rows([2]) + ); + } } diff --git a/tests/text_reparser/fixtures/base.xml b/tests/text_reparser/fixtures/base.xml index a4921a8823..532a19a8a9 100644 --- a/tests/text_reparser/fixtures/base.xml +++ b/tests/text_reparser/fixtures/base.xml @@ -15,5 +15,13 @@ abcd1234 + + 2 + 1 + 1 + 1 + [IMG]img.png[/IMG]]]> + + diff --git a/tests/text_reparser/plugins/fixtures/polls.xml b/tests/text_reparser/plugins/fixtures/polls.xml index 2960d640a9..5247fb906d 100644 --- a/tests/text_reparser/plugins/fixtures/polls.xml +++ b/tests/text_reparser/plugins/fixtures/polls.xml @@ -44,55 +44,66 @@ topic_id topic_first_post_id poll_title + poll_start 1 1 This row should be [b]ignored[/b] + 1 2 1 [b]Not bold[/b] :) http://example.org + 1 3 2 [b:abcd1234]Bold[/b:abcd1234] :) http://example.org + 1 4 3 :) http://example.org]]> + 1 5 4 http://example.org]]> + 1 6 2 + 1 7 1 + 1 8 2 + 1 9 1 + 1 1000 1 This row should be [b]ignored[/b] + 1 diff --git a/tests/tree/nestedset_forum_base.php b/tests/tree/nestedset_forum_base.php index 3daa75b2e4..498c6a69a2 100644 --- a/tests/tree/nestedset_forum_base.php +++ b/tests/tree/nestedset_forum_base.php @@ -69,7 +69,7 @@ class phpbb_tests_tree_nestedset_forum_base extends phpbb_database_test_case static $forums; if (empty($forums)) - { + { $this->create_forum('Parent with two flat children'); $this->create_forum('Flat child #1', 1); $this->create_forum('Flat child #2', 1); @@ -86,7 +86,7 @@ class phpbb_tests_tree_nestedset_forum_base extends phpbb_database_test_case // Updating forum_parents column here so it's not empty // This is required, so we can see whether the methods - // correctly clear the values. + // correctly clear the values. $sql = "UPDATE phpbb_forums SET forum_parents = 'a:0:{}'"; $this->db->sql_query($sql); @@ -100,6 +100,13 @@ class phpbb_tests_tree_nestedset_forum_base extends phpbb_database_test_case } else { + // Turn on identity insert on mssql to be able to insert into + // identity columns (e.g. forum_id) + if (strpos($this->db->sql_layer, 'mssql') !== false) + { + $sql = 'SET IDENTITY_INSERT phpbb_forums ON'; + $this->db->sql_query($sql); + } $buffer = new \phpbb\db\sql_insert_buffer($this->db, 'phpbb_forums'); $buffer->insert_all($forums); $buffer->flush(); @@ -107,7 +114,14 @@ class phpbb_tests_tree_nestedset_forum_base extends phpbb_database_test_case $this->database_synchronisation(array( 'phpbb_forums' => array('forum_id'), )); - } + + // Disable identity insert on mssql again + if (strpos($this->db->sql_layer, 'mssql') !== false) + { + $sql = 'SET IDENTITY_INSERT phpbb_forums OFF'; + $this->db->sql_query($sql); + } + } } protected function create_forum($name, $parent_id = 0) diff --git a/tests/upload/filespec_test.php b/tests/upload/filespec_test.php index 18b6deed1f..b41b95d925 100644 --- a/tests/upload/filespec_test.php +++ b/tests/upload/filespec_test.php @@ -79,7 +79,7 @@ class phpbb_filespec_test extends phpbb_test_case $this->phpbb_root_path = $phpbb_root_path; } - private function set_reflection_property(&$class, $property_name, $value) + private function set_reflection_property($class, $property_name, $value) { $property = new ReflectionProperty($class, $property_name); $property->setAccessible(true); diff --git a/tests/upload/fileupload_test.php b/tests/upload/fileupload_test.php index fb72823f08..5b3357237d 100644 --- a/tests/upload/fileupload_test.php +++ b/tests/upload/fileupload_test.php @@ -173,7 +173,7 @@ class phpbb_fileupload_test extends phpbb_test_case ->set_max_filesize(1000); $file = $this->gen_valid_filespec(); $upload->common_checks($file); - $this->assertEquals(0, sizeof($file->error)); + $this->assertEquals(0, count($file->error)); } public function test_local_upload() @@ -184,7 +184,7 @@ class phpbb_fileupload_test extends phpbb_test_case copy($this->path . 'jpg', $this->path . 'jpg.jpg'); $file = $upload->handle_upload('files.types.local', $this->path . 'jpg.jpg'); - $this->assertEquals(0, sizeof($file->error)); + $this->assertEquals(0, count($file->error)); $this->assertFalse($file->additional_checks()); $this->assertTrue($file->move_file('../tests/upload/fixture/copies', true)); $file->remove(); @@ -198,10 +198,10 @@ class phpbb_fileupload_test extends phpbb_test_case copy($this->path . 'jpg', $this->path . 'jpg.jpg'); $file = $upload->handle_upload('files.types.local', $this->path . 'jpg.jpg'); - $this->assertEquals(0, sizeof($file->error)); + $this->assertEquals(0, count($file->error)); $this->assertFalse($file->move_file('../tests/upload/fixture')); $this->assertFalse($file->get('file_moved')); - $this->assertEquals(1, sizeof($file->error)); + $this->assertEquals(1, count($file->error)); } public function test_move_existent_file_overwrite() @@ -213,9 +213,9 @@ class phpbb_fileupload_test extends phpbb_test_case copy($this->path . 'jpg', $this->path . 'jpg.jpg'); copy($this->path . 'jpg', $this->path . 'copies/jpg.jpg'); $file = $upload->handle_upload('files.types.local', $this->path . 'jpg.jpg'); - $this->assertEquals(0, sizeof($file->error)); + $this->assertEquals(0, count($file->error)); $file->move_file('../tests/upload/fixture/copies', true); - $this->assertEquals(0, sizeof($file->error)); + $this->assertEquals(0, count($file->error)); unlink($this->path . 'copies/jpg.jpg'); } diff --git a/tests/wrapper/version_compare_test.php b/tests/wrapper/version_compare_test.php index 8260d99504..ee23fe779c 100644 --- a/tests/wrapper/version_compare_test.php +++ b/tests/wrapper/version_compare_test.php @@ -66,7 +66,7 @@ class phpbb_wrapper_version_compare_test extends phpbb_test_case '3.2-A1', ); - for ($i = 0, $size = sizeof($releases); $i < $size - 1; ++$i) + for ($i = 0, $size = count($releases); $i < $size - 1; ++$i) { $version1 = $releases[$i]; $version2 = $releases[$i + 1]; diff --git a/travis/setup-mariadb.sh b/travis/setup-mariadb.sh index 9bc487915d..95445dcc55 100755 --- a/travis/setup-mariadb.sh +++ b/travis/setup-mariadb.sh @@ -12,7 +12,7 @@ set -e set -x # MariaDB Series -VERSION='5.5' +VERSION='10.0' # Operating system codename, e.g. "precise" OS_CODENAME=$(lsb_release --codename --short) diff --git a/travis/setup-php-extensions.sh b/travis/setup-php-extensions.sh index d9544858b7..de27965e39 100755 --- a/travis/setup-php-extensions.sh +++ b/travis/setup-php-extensions.sh @@ -46,13 +46,26 @@ php_ini_file=$(find_php_ini) if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.5.0-dev', '<');"` == "1" ] then echo 'Enabling APC PHP extension' - register_php_extension 'apc' "$php_ini_file" + printf "\n" | pecl install apc echo 'apc.enable_cli=1' >> "$php_ini_file" else echo 'Disabling Opcache' echo 'opcache.enable=0' >> "$php_ini_file" fi +# APCu +if [ `php -r "echo (int) (version_compare(PHP_VERSION, '7.0.0-dev', '>=') && version_compare(PHP_VERSION, '7.3.0-dev', '<'));"` == "1" ] +then + if ! [ "$(pecl info pecl/apcu)" ] + then + echo 'Enabling APCu PHP extension' + printf "\n" | pecl install apcu + echo 'apc.enabled=1' >> "$php_ini_file" + echo 'apc.enable_cli=1' >> "$php_ini_file" + fi +fi + + # redis # Disabled redis for now as it causes travis to fail # git clone git://github.com/nicolasff/phpredis.git redis diff --git a/travis/setup-phpbb.sh b/travis/setup-phpbb.sh index f9fd9522ca..be9eb703d5 100755 --- a/travis/setup-phpbb.sh +++ b/travis/setup-phpbb.sh @@ -26,7 +26,7 @@ then travis/setup-mariadb.sh fi -if [ "$NOTESTS" != '1' -a "$TRAVIS_PHP_VERSION" != "hhvm" ] +if [ "$NOTESTS" != '1' ] then travis/setup-php-extensions.sh fi diff --git a/travis/setup-webserver.sh b/travis/setup-webserver.sh index 3369d740fe..fd87d97449 100755 --- a/travis/setup-webserver.sh +++ b/travis/setup-webserver.sh @@ -19,42 +19,30 @@ sudo service nginx stop DIR=$(dirname "$0") USER=$(whoami) PHPBB_ROOT_PATH=$(realpath "$DIR/../phpBB") -NGINX_CONF="/etc/nginx/sites-enabled/default" +NGINX_SITE_CONF="/etc/nginx/sites-enabled/default" +NGINX_CONF="/etc/nginx/nginx.conf" APP_SOCK=$(realpath "$DIR")/php-app.sock -if [ "$TRAVIS_PHP_VERSION" = 'hhvm' ] -then - HHVM_LOG=$(realpath "$DIR")/hhvm.log +# php-fpm +PHP_FPM_BIN="$HOME/.phpenv/versions/$TRAVIS_PHP_VERSION/sbin/php-fpm" +PHP_FPM_CONF="$DIR/php-fpm.conf" - sudo service hhvm stop - sudo hhvm \ - --mode daemon \ - --user "$USER" \ - -vServer.Type=fastcgi \ - -vServer.FileSocket="$APP_SOCK" \ - -vLog.File="$HHVM_LOG" -else - # php-fpm - PHP_FPM_BIN="$HOME/.phpenv/versions/$TRAVIS_PHP_VERSION/sbin/php-fpm" - PHP_FPM_CONF="$DIR/php-fpm.conf" +echo " + [global] - echo " - [global] + [travis] + user = $USER + group = $USER + listen = $APP_SOCK + listen.mode = 0666 + pm = static + pm.max_children = 2 - [travis] - user = $USER - group = $USER - listen = $APP_SOCK - listen.mode = 0666 - pm = static - pm.max_children = 2 + php_admin_value[memory_limit] = 128M +" > $PHP_FPM_CONF - php_admin_value[memory_limit] = 128M - " > $PHP_FPM_CONF - - sudo $PHP_FPM_BIN \ - --fpm-config "$DIR/php-fpm.conf" -fi +sudo $PHP_FPM_BIN \ + --fpm-config "$DIR/php-fpm.conf" # nginx cat $DIR/../phpBB/docs/nginx.sample.conf \ @@ -63,6 +51,7 @@ cat $DIR/../phpBB/docs/nginx.sample.conf \ | sed -e '/If running php as fastcgi/,$d' \ | sed -e "s/fastcgi_pass php;/fastcgi_pass unix:$(echo $APP_SOCK | sed -e 's/\\/\\\\/g' -e 's/\//\\\//g' -e 's/&/\\\&/g');/g" \ | sed -e 's/#listen 80/listen 80/' \ -| sudo tee $NGINX_CONF +| sudo tee $NGINX_SITE_CONF +sudo sed -i "s/user www-data;/user $USER;/g" $NGINX_CONF sudo service nginx start