From 0b657c0b4c0a0fff3b588917d65f555619d2a929 Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Sat, 20 Dec 2014 16:56:46 +1030 Subject: [PATCH 01/68] Restore Initial Meaningful Test Infrastructure This testing package was initially a part of flarum/core, but was extracted during the 0.1.0-beta.16 release cycle. The extraction was made through git's filter-branch tool to preserve some useful history in the repository. --- php-packages/testing/.editorconfig | 19 +++++ php-packages/testing/.gitattributes | 13 +++ php-packages/testing/.gitignore | 9 +++ php-packages/testing/.styleci.yml | 18 +++++ php-packages/testing/LICENSE | 21 +++++ .../integration/RetrievesAuthorizedUsers.php | 70 ++++++++++++++++ .../testing/tests/integration/TestCase.php | 81 +++++++++++++++++++ .../integration/tmp/public/assets/.gitkeep | 0 .../tests/integration/tmp/storage/.gitkeep | 0 .../tmp/storage/formatter/.gitkeep | 0 .../integration/tmp/storage/sessions/.gitkeep | 0 .../tmp/vendor/composer/installed.json | 1 + 12 files changed, 232 insertions(+) create mode 100644 php-packages/testing/.editorconfig create mode 100644 php-packages/testing/.gitattributes create mode 100644 php-packages/testing/.gitignore create mode 100644 php-packages/testing/.styleci.yml create mode 100755 php-packages/testing/LICENSE create mode 100644 php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php create mode 100644 php-packages/testing/tests/integration/TestCase.php create mode 100644 php-packages/testing/tests/integration/tmp/public/assets/.gitkeep create mode 100644 php-packages/testing/tests/integration/tmp/storage/.gitkeep create mode 100644 php-packages/testing/tests/integration/tmp/storage/formatter/.gitkeep create mode 100644 php-packages/testing/tests/integration/tmp/storage/sessions/.gitkeep create mode 100644 php-packages/testing/tests/integration/tmp/vendor/composer/installed.json diff --git a/php-packages/testing/.editorconfig b/php-packages/testing/.editorconfig new file mode 100644 index 000000000..658a43499 --- /dev/null +++ b/php-packages/testing/.editorconfig @@ -0,0 +1,19 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 2 + +[*.{diff,md}] +trim_trailing_whitespace = false + +[*.{php,xml}] +indent_size = 4 diff --git a/php-packages/testing/.gitattributes b/php-packages/testing/.gitattributes new file mode 100644 index 000000000..ccbdf6188 --- /dev/null +++ b/php-packages/testing/.gitattributes @@ -0,0 +1,13 @@ +.gitattributes export-ignore +.gitignore export-ignore +.gitmodules export-ignore +.github export-ignore +.travis export-ignore +.travis.yml export-ignore +.editorconfig export-ignore +.styleci.yml export-ignore + +phpunit.xml export-ignore +tests export-ignore + +js/dist/* -diff diff --git a/php-packages/testing/.gitignore b/php-packages/testing/.gitignore new file mode 100644 index 000000000..56b9aaf7d --- /dev/null +++ b/php-packages/testing/.gitignore @@ -0,0 +1,9 @@ +/vendor +composer.lock +composer.phar +node_modules +.DS_Store +Thumbs.db +/tests/integration/tmp +.vagrant +.idea/* diff --git a/php-packages/testing/.styleci.yml b/php-packages/testing/.styleci.yml new file mode 100644 index 000000000..5d07e31ea --- /dev/null +++ b/php-packages/testing/.styleci.yml @@ -0,0 +1,18 @@ +preset: recommended + +enabled: + - logical_not_operators_with_successor_space + +disabled: + - align_double_arrow + - blank_line_after_opening_tag + - multiline_array_trailing_comma + - new_with_braces + - phpdoc_align + - phpdoc_order + - phpdoc_separation + - phpdoc_types + +finder: + exclude: + - "stubs" diff --git a/php-packages/testing/LICENSE b/php-packages/testing/LICENSE new file mode 100755 index 000000000..4bc2a96d2 --- /dev/null +++ b/php-packages/testing/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Stichting Flarum (Flarum Foundation) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php b/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php new file mode 100644 index 000000000..135ef7bec --- /dev/null +++ b/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Tests\integration; + +trait RetrievesAuthorizedUsers +{ + protected function adminGroup(): array + { + return [ + 'id' => 1, + 'name_singular' => 'Admin', + 'name_plural' => 'Admins', + 'color' => '#B72A2A', + 'icon' => 'fas fa-wrench', + ]; + } + + protected function guestGroup(): array + { + return [ + 'id' => 2, + 'name_singular' => 'Guest', + 'name_plural' => 'Guests', + 'color' => null, + 'icon' => null, + ]; + } + + protected function memberGroup(): array + { + return [ + 'id' => 3, + 'name_singular' => 'Member', + 'name_plural' => 'Members', + 'color' => null, + 'icon' => null, + ]; + } + + protected function adminUser(): array + { + return [ + 'id' => 1, + 'username' => 'admin', + 'password' => '$2y$10$HMOAe.XaQjOimA778VmFue1OCt7tj5j0wk5vfoL/CMSJq2BQlfBV2', // BCrypt hash for "password" + 'email' => 'admin@machine.local', + 'is_email_confirmed' => 1, + ]; + } + + protected function normalUser(): array + { + return [ + 'id' => 2, + 'username' => 'normal', + 'password' => '$2y$10$LO59tiT7uggl6Oe23o/O6.utnF6ipngYjvMvaxo1TciKqBttDNKim', // BCrypt hash for "too-obscure" + 'email' => 'normal@machine.local', + 'is_email_confirmed' => 1, + ]; + } +} diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php new file mode 100644 index 000000000..9d199564e --- /dev/null +++ b/php-packages/testing/tests/integration/TestCase.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Tests\integration; + +use Flarum\Foundation\InstalledSite; +use Illuminate\Database\ConnectionInterface; + +abstract class TestCase extends \PHPUnit\Framework\TestCase +{ + public function setUp() + { + parent::setUp(); + + // Boot the Flarum app + $this->app(); + } + + protected $app; + + /** + * @return \Flarum\Foundation\InstalledApp + */ + protected function app() + { + if (! is_null($this->app)) { + return $this->app; + } + + $site = new InstalledSite( + [ + 'base' => __DIR__.'/tmp', + 'public' => __DIR__.'/tmp/public', + 'storage' => __DIR__.'/tmp/storage', + ], + include __DIR__.'/tmp/config.php' + ); + + return $this->app = $site->bootApp(); + } + + protected $database; + + protected function database(): ConnectionInterface + { + if (is_null($this->database)) { + $this->database = $this->app()->getContainer()->make( + ConnectionInterface::class + ); + } + + return $this->database; + } + + protected function prepareDatabase(array $tableData) + { + // We temporarily disable foreign key checks to simplify this process. + $this->database()->getSchemaBuilder()->disableForeignKeyConstraints(); + + // First, truncate all referenced tables so that they are empty. + foreach (array_keys($tableData) as $table) { + $this->database()->table($table)->truncate(); + } + + // Then, insert all rows required for this test case. + foreach ($tableData as $table => $rows) { + $this->database()->table($table)->insert($rows); + } + + // And finally, turn on foreign key checks again. + $this->database()->getSchemaBuilder()->enableForeignKeyConstraints(); + } +} diff --git a/php-packages/testing/tests/integration/tmp/public/assets/.gitkeep b/php-packages/testing/tests/integration/tmp/public/assets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/php-packages/testing/tests/integration/tmp/storage/.gitkeep b/php-packages/testing/tests/integration/tmp/storage/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/php-packages/testing/tests/integration/tmp/storage/formatter/.gitkeep b/php-packages/testing/tests/integration/tmp/storage/formatter/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/php-packages/testing/tests/integration/tmp/storage/sessions/.gitkeep b/php-packages/testing/tests/integration/tmp/storage/sessions/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/php-packages/testing/tests/integration/tmp/vendor/composer/installed.json b/php-packages/testing/tests/integration/tmp/vendor/composer/installed.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/php-packages/testing/tests/integration/tmp/vendor/composer/installed.json @@ -0,0 +1 @@ +{} From d90b77073ee2c718ed819fd8c379b573ff66158b Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Wed, 30 Jan 2019 21:16:25 +0100 Subject: [PATCH 02/68] Setup Composer commands for testing and setup --- .../testing/tests/integration/setup.php | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 php-packages/testing/tests/integration/setup.php diff --git a/php-packages/testing/tests/integration/setup.php b/php-packages/testing/tests/integration/setup.php new file mode 100644 index 000000000..e207e29d0 --- /dev/null +++ b/php-packages/testing/tests/integration/setup.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Flarum\Install\AdminUser; +use Flarum\Install\DatabaseConfig; +use Flarum\Install\Installation; + +require __DIR__.'/../../vendor/autoload.php'; + +/* + * Setup installation configuration + */ + +$installation = new Installation( + __DIR__.'/tmp', + __DIR__.'/tmp/public', + __DIR__.'/tmp/storage' +); + +$pipeline = $installation + ->configPath('config.php') + ->debugMode(true) + ->baseUrl('http://localhost') + ->databaseConfig(new DatabaseConfig( + 'mysql', + env('DB_HOST', 'localhost'), + intval(env('DB_PORT', 3306)), + env('DB_DATABASE', 'flarum_test'), + env('DB_USERNAME', 'root'), + env('DB_PASSWORD', ''), + env('DB_PREFIX', '') + )) + ->adminUser(new AdminUser( + 'admin', + 'secret', + 'admin@flarum.email' + )) + ->settings(['mail_driver' => 'log']) + ->build(); + +/* + * Run the actual configuration + */ + +$pipeline->run(); From cc3d0d6d0a30a43d2945c1e3e06ee38d26916572 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Thu, 31 Jan 2019 21:30:16 +0100 Subject: [PATCH 03/68] Add helpful (?) output to test setup script --- .../testing/tests/integration/setup.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/php-packages/testing/tests/integration/setup.php b/php-packages/testing/tests/integration/setup.php index e207e29d0..590538f2b 100644 --- a/php-packages/testing/tests/integration/setup.php +++ b/php-packages/testing/tests/integration/setup.php @@ -15,6 +15,25 @@ use Flarum\Install\Installation; require __DIR__.'/../../vendor/autoload.php'; +$host = env('DB_HOST', 'localhost'); +$port = intval(env('DB_PORT', 3306)); +$name = env('DB_DATABASE', 'flarum_test'); +$user = env('DB_USERNAME', 'root'); +$pass = env('DB_PASSWORD', ''); +$pref = env('DB_PREFIX', ''); + +echo "Connecting to database $name at $host:$port.\n"; +echo "Logging in as $user with password '$pass'.\n"; +echo "Table prefix: '$pref'\n"; + +echo "\n\nCancel now if that's not what you want...\n"; +echo "Use the following environment variables for configuration:\n"; +echo "DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD, DB_PREFIX\n"; + +sleep(5); + +echo "\nOff we go...\n"; + /* * Setup installation configuration */ @@ -51,3 +70,5 @@ $pipeline = $installation */ $pipeline->run(); + +echo "Installation complete\n"; From e20961dabc8f0137230305fb48f90bddf3c28740 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Thu, 13 Jun 2019 00:13:38 +0200 Subject: [PATCH 04/68] Integration tests: Fix test setup --- php-packages/testing/tests/integration/setup.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php-packages/testing/tests/integration/setup.php b/php-packages/testing/tests/integration/setup.php index 590538f2b..45f0a382d 100644 --- a/php-packages/testing/tests/integration/setup.php +++ b/php-packages/testing/tests/integration/setup.php @@ -41,7 +41,8 @@ echo "\nOff we go...\n"; $installation = new Installation( __DIR__.'/tmp', __DIR__.'/tmp/public', - __DIR__.'/tmp/storage' + __DIR__.'/tmp/storage', + __DIR__.'/../../vendor' ); $pipeline = $installation From e6d4c66933b4f002d1acc8ba65117c795b0f558d Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Tue, 4 Jun 2019 23:50:38 +0200 Subject: [PATCH 05/68] Integration tests: Memoize request handler as well This is useful to send HTTP requests (or their PSR-7 equivalents) through the entire application's middleware stack (instead of talking to specific controllers, which should be considered implementation detail). --- .../testing/tests/integration/TestCase.php | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 9d199564e..8785f8669 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -24,27 +24,36 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase $this->app(); } + /** + * @var \Flarum\Foundation\InstalledApp + */ protected $app; + /** + * @var \Psr\Http\Server\RequestHandlerInterface + */ + protected $server; + /** * @return \Flarum\Foundation\InstalledApp */ protected function app() { - if (! is_null($this->app)) { - return $this->app; + if (is_null($this->app)) { + $site = new InstalledSite( + [ + 'base' => __DIR__.'/tmp', + 'public' => __DIR__.'/tmp/public', + 'storage' => __DIR__.'/tmp/storage', + ], + include __DIR__.'/tmp/config.php' + ); + + $this->app = $site->bootApp(); + $this->server = $this->app->getRequestHandler(); } - $site = new InstalledSite( - [ - 'base' => __DIR__.'/tmp', - 'public' => __DIR__.'/tmp/public', - 'storage' => __DIR__.'/tmp/storage', - ], - include __DIR__.'/tmp/config.php' - ); - - return $this->app = $site->bootApp(); + return $this->app; } protected $database; From 05b4d8076bdc826b8eb9e475d984d08701892fe4 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Wed, 12 Jun 2019 23:46:15 +0200 Subject: [PATCH 06/68] Integration tests: Configure vendor path Now that this is possible, make the easy change... --- php-packages/testing/tests/integration/TestCase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 8785f8669..2d295d11d 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -43,6 +43,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase $site = new InstalledSite( [ 'base' => __DIR__.'/tmp', + 'vendor' => __DIR__.'/../../vendor', 'public' => __DIR__.'/tmp/public', 'storage' => __DIR__.'/tmp/storage', ], From c5d042929f873f5184598b45e759fe89095a8762 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Wed, 12 Jun 2019 22:57:38 +0200 Subject: [PATCH 07/68] Refactor tests to shorten HTTP requests Multiple tests now provide JSON request bodies, and others copy cookies from previous responses, so let's provide convenient helpers for these. --- .../testing/tests/integration/TestCase.php | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 2d295d11d..9fa641df0 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -11,8 +11,13 @@ namespace Flarum\Tests\integration; +use Dflydev\FigCookies\SetCookie; use Flarum\Foundation\InstalledSite; use Illuminate\Database\ConnectionInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Zend\Diactoros\CallbackStream; +use Zend\Diactoros\ServerRequest; abstract class TestCase extends \PHPUnit\Framework\TestCase { @@ -88,4 +93,69 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase // And finally, turn on foreign key checks again. $this->database()->getSchemaBuilder()->enableForeignKeyConstraints(); } + + /** + * Send a full HTTP request through Flarum's middleware stack. + */ + protected function send(ServerRequestInterface $request): ResponseInterface + { + return $this->server->handle($request); + } + + /** + * Build a HTTP request that can be passed through middleware. + * + * This method simplifies building HTTP request for use in our HTTP-level + * integration tests. It provides options for all features repeatedly being + * used in those tests. + * + * @param string $method + * @param string $path + * @param array $options + * An array of optional request properties. + * Currently supported: + * - "json" should point to a JSON-serializable object that will be + * serialized and used as request body. The corresponding Content-Type + * header will be set automatically. + * - "cookiesFrom" should hold a response object from a previous HTTP + * interaction. All cookies returned from the server in that response + * (via the "Set-Cookie" header) will be copied to the cookie params of + * the new request. + * @return ServerRequestInterface + */ + protected function request(string $method, string $path, array $options = []): ServerRequestInterface + { + $request = new ServerRequest([], [], $path, $method); + + // Do we want a JSON request body? + if (isset($options['json'])) { + $request = $request + ->withHeader('Content-Type', 'application/json') + ->withBody( + new CallbackStream(function () use ($options) { + return json_encode($options['json']); + }) + ); + } + + // Let's copy the cookies from a previous response + if (isset($options['cookiesFrom'])) { + /** @var ResponseInterface $previousResponse */ + $previousResponse = $options['cookiesFrom']; + + $cookies = array_reduce( + $previousResponse->getHeader('Set-Cookie'), + function ($memo, $setCookieString) { + $setCookie = SetCookie::fromSetCookieString($setCookieString); + $memo[$setCookie->getName()] = $setCookie->getValue(); + return $memo; + }, + [] + ); + + $request = $request->withCookieParams($cookies); + } + + return $request; + } } From f686fd3e570025d2bbd5f183ea5dbf41f44d24ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Klabbers?= Date: Tue, 18 Jun 2019 17:22:23 +0200 Subject: [PATCH 08/68] Fixed issue with tmp/storage/views not existing, this caused tmpname to notice. Fixed csrf test that assumed an access token allows application access, which is actually api token. Improved return type hinting in the StartSession middleware --- php-packages/testing/tests/integration/tmp/storage/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 php-packages/testing/tests/integration/tmp/storage/.gitkeep diff --git a/php-packages/testing/tests/integration/tmp/storage/.gitkeep b/php-packages/testing/tests/integration/tmp/storage/.gitkeep deleted file mode 100644 index e69de29bb..000000000 From f47d739aacdd2524efc5fdb3e0c6c7adaa6cc16f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Klabbers?= Date: Tue, 18 Jun 2019 17:45:29 +0200 Subject: [PATCH 09/68] Using a different setting key now, so that it won't break tests whenever you re-run them once smtp is set. Fixed, badly, the test to create users etc caused by the prepareDatabase flushing all settings by default. --- .../testing/tests/integration/TestCase.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 9fa641df0..e705a8967 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -82,12 +82,26 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase // First, truncate all referenced tables so that they are empty. foreach (array_keys($tableData) as $table) { - $this->database()->table($table)->truncate(); + if ($table !== 'settings') { + $this->database()->table($table)->truncate(); + } } // Then, insert all rows required for this test case. foreach ($tableData as $table => $rows) { - $this->database()->table($table)->insert($rows); + foreach ($rows as $row) { + if ($table === 'settings') { + $this->database()->table($table)->updateOrInsert( + ['key' => $row['key']], + $row + ); + } else { + $this->database()->table($table)->updateOrInsert( + isset($row['id']) ? ['id' => $row['id']] : $row, + $row + ); + } + } } // And finally, turn on foreign key checks again. From c772029af923ddbebd2707b4e44e36a1cac89ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Klabbers?= Date: Mon, 24 Jun 2019 09:15:15 +0200 Subject: [PATCH 10/68] Apply fixes from StyleCI (#1800) [ci skip] [skip ci] --- php-packages/testing/tests/integration/TestCase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index e705a8967..8cd255949 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -162,6 +162,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase function ($memo, $setCookieString) { $setCookie = SetCookie::fromSetCookieString($setCookieString); $memo[$setCookie->getName()] = $setCookie->getValue(); + return $memo; }, [] From 93d6b235e30ebdaf9eeb83e8bf40f9c2385d1244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Klabbers?= Date: Mon, 24 Jun 2019 13:00:36 +0200 Subject: [PATCH 11/68] fixed tests on master, missing views directory and suppressing notices from tempnam when storing files in tmp --- php-packages/testing/tests/integration/tmp/storage/views/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 php-packages/testing/tests/integration/tmp/storage/views/.gitkeep diff --git a/php-packages/testing/tests/integration/tmp/storage/views/.gitkeep b/php-packages/testing/tests/integration/tmp/storage/views/.gitkeep new file mode 100644 index 000000000..e69de29bb From 3decf1b658d7406bb1003c73eac017af6f69be76 Mon Sep 17 00:00:00 2001 From: Stefan Totev Date: Mon, 23 Sep 2019 23:26:51 +0100 Subject: [PATCH 12/68] Normalize Base URL during installation - Fix base url when is appended with a script filename - Add default base url http://flarum.local when CLI wizard used - Remove some code duplication - Add minor improvement to the UX when CLI wizard used - Add tests - Extract base url normalisation into its own value object --- php-packages/testing/tests/integration/setup.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php-packages/testing/tests/integration/setup.php b/php-packages/testing/tests/integration/setup.php index 45f0a382d..8678b522f 100644 --- a/php-packages/testing/tests/integration/setup.php +++ b/php-packages/testing/tests/integration/setup.php @@ -10,6 +10,7 @@ */ use Flarum\Install\AdminUser; +use Flarum\Install\BaseUrl; use Flarum\Install\DatabaseConfig; use Flarum\Install\Installation; @@ -48,7 +49,7 @@ $installation = new Installation( $pipeline = $installation ->configPath('config.php') ->debugMode(true) - ->baseUrl('http://localhost') + ->baseUrl(BaseUrl::fromString('http://localhost')) ->databaseConfig(new DatabaseConfig( 'mysql', env('DB_HOST', 'localhost'), From c869417759952654c3918b1f096c07bdaa4c9966 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Thu, 21 Nov 2019 00:51:11 +0100 Subject: [PATCH 13/68] Automatically set up Mockery for unit tests - Use provided PhpUnit listener to enforce verification of expectations. - Include Mockery's trait to auto-close Mockery after each test. --- php-packages/testing/tests/unit/TestCase.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 php-packages/testing/tests/unit/TestCase.php diff --git a/php-packages/testing/tests/unit/TestCase.php b/php-packages/testing/tests/unit/TestCase.php new file mode 100644 index 000000000..8c87018b6 --- /dev/null +++ b/php-packages/testing/tests/unit/TestCase.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Tests\unit; + +use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; + +abstract class TestCase extends \PHPUnit\Framework\TestCase +{ + // Ensure Mockery is always torn down automatically after each test. + use MockeryPHPUnitIntegration; +} From 48d996d9489e562d37221ea927de2585465e35cd Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Thu, 28 Nov 2019 00:16:50 +0000 Subject: [PATCH 14/68] Apply fixes from StyleCI [ci skip] [skip ci] --- .../testing/tests/integration/RetrievesAuthorizedUsers.php | 6 ++---- php-packages/testing/tests/integration/TestCase.php | 6 ++---- php-packages/testing/tests/integration/setup.php | 6 ++---- php-packages/testing/tests/unit/TestCase.php | 6 ++---- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php b/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php index 135ef7bec..df2f80e87 100644 --- a/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php +++ b/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php @@ -3,10 +3,8 @@ /* * This file is part of Flarum. * - * (c) Toby Zerner - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. + * For detailed copyright and license information, please view the + * LICENSE file that was distributed with this source code. */ namespace Flarum\Tests\integration; diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 8cd255949..6c26a6245 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -3,10 +3,8 @@ /* * This file is part of Flarum. * - * (c) Toby Zerner - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. + * For detailed copyright and license information, please view the + * LICENSE file that was distributed with this source code. */ namespace Flarum\Tests\integration; diff --git a/php-packages/testing/tests/integration/setup.php b/php-packages/testing/tests/integration/setup.php index 8678b522f..8403acf5c 100644 --- a/php-packages/testing/tests/integration/setup.php +++ b/php-packages/testing/tests/integration/setup.php @@ -3,10 +3,8 @@ /* * This file is part of Flarum. * - * (c) Toby Zerner - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. + * For detailed copyright and license information, please view the + * LICENSE file that was distributed with this source code. */ use Flarum\Install\AdminUser; diff --git a/php-packages/testing/tests/unit/TestCase.php b/php-packages/testing/tests/unit/TestCase.php index 8c87018b6..63214ce19 100644 --- a/php-packages/testing/tests/unit/TestCase.php +++ b/php-packages/testing/tests/unit/TestCase.php @@ -3,10 +3,8 @@ /* * This file is part of Flarum. * - * (c) Toby Zerner - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. + * For detailed copyright and license information, please view the + * LICENSE file that was distributed with this source code. */ namespace Flarum\Tests\unit; From 924a2e5efaae4bb281206d4b71c54f4f14277449 Mon Sep 17 00:00:00 2001 From: Matt Kilgore Date: Mon, 6 Jan 2020 16:29:34 -0500 Subject: [PATCH 15/68] Change Zend namespace to Laminas (#1963) Also ensure backwards compatibility for extensions that use the Zend framework but don't explicitly require it. --- php-packages/testing/tests/integration/TestCase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 6c26a6245..c6928812e 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -12,10 +12,10 @@ namespace Flarum\Tests\integration; use Dflydev\FigCookies\SetCookie; use Flarum\Foundation\InstalledSite; use Illuminate\Database\ConnectionInterface; +use Laminas\Diactoros\CallbackStream; +use Laminas\Diactoros\ServerRequest; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; -use Zend\Diactoros\CallbackStream; -use Zend\Diactoros\ServerRequest; abstract class TestCase extends \PHPUnit\Framework\TestCase { From 1ca610d96a8f061826e2ca488ce74a0c9a12db49 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Fri, 7 Feb 2020 23:22:22 +0100 Subject: [PATCH 16/68] Integration tests: Create app lazily when needed This will allow registering extenders in test scenarios. Previously, this would not have had any effect as the app would have booted already. --- php-packages/testing/tests/integration/TestCase.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index c6928812e..31d14199a 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -19,14 +19,6 @@ use Psr\Http\Message\ServerRequestInterface; abstract class TestCase extends \PHPUnit\Framework\TestCase { - public function setUp() - { - parent::setUp(); - - // Boot the Flarum app - $this->app(); - } - /** * @var \Flarum\Foundation\InstalledApp */ From 23ad5bcc6b0f8159686808bc24f5f4d241aca240 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Fri, 7 Feb 2020 23:28:37 +0100 Subject: [PATCH 17/68] Integration tests: Add lazy server helper This allows sending requests directly in an integration test, without having *explicitly* booted the app. --- .../testing/tests/integration/TestCase.php | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 31d14199a..cdb3fdc9a 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -16,6 +16,7 @@ use Laminas\Diactoros\CallbackStream; use Laminas\Diactoros\ServerRequest; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Server\RequestHandlerInterface; abstract class TestCase extends \PHPUnit\Framework\TestCase { @@ -24,11 +25,6 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase */ protected $app; - /** - * @var \Psr\Http\Server\RequestHandlerInterface - */ - protected $server; - /** * @return \Flarum\Foundation\InstalledApp */ @@ -52,6 +48,20 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase return $this->app; } + /** + * @var RequestHandlerInterface + */ + protected $server; + + protected function server(): RequestHandlerInterface + { + if (is_null($this->server)) { + $this->server = $this->app()->getRequestHandler(); + } + + return $this->server; + } + protected $database; protected function database(): ConnectionInterface @@ -103,7 +113,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase */ protected function send(ServerRequestInterface $request): ResponseInterface { - return $this->server->handle($request); + return $this->server()->handle($request); } /** From b0711b18c70b34aa7b9a1a2a77494db1310d7e50 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Fri, 7 Feb 2020 23:29:14 +0100 Subject: [PATCH 18/68] Integration tests: Allow registering extenders --- .../testing/tests/integration/TestCase.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index cdb3fdc9a..687023dbe 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -10,6 +10,7 @@ namespace Flarum\Tests\integration; use Dflydev\FigCookies\SetCookie; +use Flarum\Extend\ExtenderInterface; use Flarum\Foundation\InstalledSite; use Illuminate\Database\ConnectionInterface; use Laminas\Diactoros\CallbackStream; @@ -41,13 +42,24 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase include __DIR__.'/tmp/config.php' ); + $site->extendWith($this->extenders); + $this->app = $site->bootApp(); - $this->server = $this->app->getRequestHandler(); } return $this->app; } + /** + * @var ExtenderInterface[] + */ + protected $extenders = []; + + protected function extend(ExtenderInterface $extender) + { + $this->extenders[] = $extender; + } + /** * @var RequestHandlerInterface */ From 232a431b50c8d01bebfab1d2a0b99b59f2faff19 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Fri, 20 Mar 2020 17:16:29 +0100 Subject: [PATCH 19/68] Add Authenticated Test Case utility --- .../integration/AuthenticatedTestCase.php | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 php-packages/testing/tests/integration/AuthenticatedTestCase.php diff --git a/php-packages/testing/tests/integration/AuthenticatedTestCase.php b/php-packages/testing/tests/integration/AuthenticatedTestCase.php new file mode 100644 index 000000000..3f2ce4e5f --- /dev/null +++ b/php-packages/testing/tests/integration/AuthenticatedTestCase.php @@ -0,0 +1,72 @@ +firstOrCreate([ + 'key' => Str::random(), + 'user_id' => $user_id, + 'created_at' => Carbon::now() + ]); + }); + } + + /** + * Build an authenticated HTTP request that can be passed through middleware. + * + * This method simplifies building HTTP request for use in our HTTP-level + * integration tests. It provides options for all features repeatedly being + * used in those tests. + * + * @param string $method + * @param string $path + * @param array $options + * An array of optional request properties. + * Currently supported: + * - "json" should point to a JSON-serializable object that will be + * serialized and used as request body. The corresponding Content-Type + * header will be set automatically. + * - "cookiesFrom" should hold a response object from a previous HTTP + * interaction. All cookies returned from the server in that response + * (via the "Set-Cookie" header) will be copied to the cookie params of + * the new request. + * @param int $userId Which user should be emulated? User ID 1 will return a + * user with admin perms unless this has been modified in your test case. + * @return ServerRequestInterface + */ + protected function authenticatedRequest(string $method, string $path, array $options = [], int $userId = 1): ServerRequestInterface + { + $request = $this->request($method, $path, $options); + + $this->prepareDatabase([ + 'users' => [ + $this->adminUser(), + $this->normalUser(), + ], + ]); + + if (! isset($this->key)) { + $this->key = $this->genKey(); + } + + return $request->withAddedHeader('Authorization', "Token {$this->key->key}; userId=$userId"); + } +} From 0c4ab20b50a4db93b699f24394a9941a22d9a2f3 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Fri, 20 Mar 2020 17:48:39 +0100 Subject: [PATCH 20/68] Tests: Extract trait for building requests --- .../tests/integration/BuildsHttpRequests.php | 48 +++++++++++++++++++ .../testing/tests/integration/TestCase.php | 32 ++++--------- 2 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 php-packages/testing/tests/integration/BuildsHttpRequests.php diff --git a/php-packages/testing/tests/integration/BuildsHttpRequests.php b/php-packages/testing/tests/integration/BuildsHttpRequests.php new file mode 100644 index 000000000..d0a21b61c --- /dev/null +++ b/php-packages/testing/tests/integration/BuildsHttpRequests.php @@ -0,0 +1,48 @@ +withHeader('Content-Type', 'application/json') + ->withBody( + new CallbackStream(function () use ($json) { + return json_encode($json); + }) + ); + } + + protected function requestWithCookiesFrom(Request $req, Response $previous): Request + { + $cookies = array_reduce( + $previous->getHeader('Set-Cookie'), + function ($memo, $setCookieString) { + $setCookie = SetCookie::fromSetCookieString($setCookieString); + $memo[$setCookie->getName()] = $setCookie->getValue(); + + return $memo; + }, + [] + ); + + return $req->withCookieParams($cookies); + } +} diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 687023dbe..65af8cdca 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -9,11 +9,9 @@ namespace Flarum\Tests\integration; -use Dflydev\FigCookies\SetCookie; use Flarum\Extend\ExtenderInterface; use Flarum\Foundation\InstalledSite; use Illuminate\Database\ConnectionInterface; -use Laminas\Diactoros\CallbackStream; use Laminas\Diactoros\ServerRequest; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -21,6 +19,8 @@ use Psr\Http\Server\RequestHandlerInterface; abstract class TestCase extends \PHPUnit\Framework\TestCase { + use BuildsHttpRequests; + /** * @var \Flarum\Foundation\InstalledApp */ @@ -131,7 +131,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase /** * Build a HTTP request that can be passed through middleware. * - * This method simplifies building HTTP request for use in our HTTP-level + * This method simplifies building HTTP requests for use in our HTTP-level * integration tests. It provides options for all features repeatedly being * used in those tests. * @@ -155,32 +155,16 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase // Do we want a JSON request body? if (isset($options['json'])) { - $request = $request - ->withHeader('Content-Type', 'application/json') - ->withBody( - new CallbackStream(function () use ($options) { - return json_encode($options['json']); - }) - ); + $request = $this->requestWithJsonBody( + $request, $options['json'] + ); } // Let's copy the cookies from a previous response if (isset($options['cookiesFrom'])) { - /** @var ResponseInterface $previousResponse */ - $previousResponse = $options['cookiesFrom']; - - $cookies = array_reduce( - $previousResponse->getHeader('Set-Cookie'), - function ($memo, $setCookieString) { - $setCookie = SetCookie::fromSetCookieString($setCookieString); - $memo[$setCookie->getName()] = $setCookie->getValue(); - - return $memo; - }, - [] + $request = $this->requestWithCookiesFrom( + $request, $options['cookiesFrom'] ); - - $request = $request->withCookieParams($cookies); } return $request; From 30450687b92c17d0fa3d73588e04b87f5bee5f74 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Fri, 20 Mar 2020 18:22:52 +0100 Subject: [PATCH 21/68] Replace authenticatedRequest() by request() option I feel this makes the parameters a bit more clear, does not rely on inheritance (you can only inherit from one class, but we might want more of these helpers in the future), and has less side effects (e.g. no creation and, more importantly, deletion of users in the database). Refs #2052. --- .../integration/AuthenticatedTestCase.php | 72 ------------------- .../tests/integration/BuildsHttpRequests.php | 9 +++ .../testing/tests/integration/TestCase.php | 10 +++ 3 files changed, 19 insertions(+), 72 deletions(-) delete mode 100644 php-packages/testing/tests/integration/AuthenticatedTestCase.php diff --git a/php-packages/testing/tests/integration/AuthenticatedTestCase.php b/php-packages/testing/tests/integration/AuthenticatedTestCase.php deleted file mode 100644 index 3f2ce4e5f..000000000 --- a/php-packages/testing/tests/integration/AuthenticatedTestCase.php +++ /dev/null @@ -1,72 +0,0 @@ -firstOrCreate([ - 'key' => Str::random(), - 'user_id' => $user_id, - 'created_at' => Carbon::now() - ]); - }); - } - - /** - * Build an authenticated HTTP request that can be passed through middleware. - * - * This method simplifies building HTTP request for use in our HTTP-level - * integration tests. It provides options for all features repeatedly being - * used in those tests. - * - * @param string $method - * @param string $path - * @param array $options - * An array of optional request properties. - * Currently supported: - * - "json" should point to a JSON-serializable object that will be - * serialized and used as request body. The corresponding Content-Type - * header will be set automatically. - * - "cookiesFrom" should hold a response object from a previous HTTP - * interaction. All cookies returned from the server in that response - * (via the "Set-Cookie" header) will be copied to the cookie params of - * the new request. - * @param int $userId Which user should be emulated? User ID 1 will return a - * user with admin perms unless this has been modified in your test case. - * @return ServerRequestInterface - */ - protected function authenticatedRequest(string $method, string $path, array $options = [], int $userId = 1): ServerRequestInterface - { - $request = $this->request($method, $path, $options); - - $this->prepareDatabase([ - 'users' => [ - $this->adminUser(), - $this->normalUser(), - ], - ]); - - if (! isset($this->key)) { - $this->key = $this->genKey(); - } - - return $request->withAddedHeader('Authorization', "Token {$this->key->key}; userId=$userId"); - } -} diff --git a/php-packages/testing/tests/integration/BuildsHttpRequests.php b/php-packages/testing/tests/integration/BuildsHttpRequests.php index d0a21b61c..09704de8b 100644 --- a/php-packages/testing/tests/integration/BuildsHttpRequests.php +++ b/php-packages/testing/tests/integration/BuildsHttpRequests.php @@ -10,6 +10,7 @@ namespace Flarum\Tests\integration; use Dflydev\FigCookies\SetCookie; +use Flarum\Http\AccessToken; use Laminas\Diactoros\CallbackStream; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; @@ -30,6 +31,14 @@ trait BuildsHttpRequests ); } + protected function requestAsUser(Request $req, int $userId): Request + { + $token = AccessToken::generate($userId); + $token->save(); + + return $req->withAddedHeader('Authorization', "Token {$token->token}"); + } + protected function requestWithCookiesFrom(Request $req, Response $previous): Request { $cookies = array_reduce( diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 65af8cdca..6e99a778e 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -143,6 +143,9 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase * - "json" should point to a JSON-serializable object that will be * serialized and used as request body. The corresponding Content-Type * header will be set automatically. + * - "authenticatedAs" should identify an *existing* user by ID. This will + * cause an access token to be created for this user, which will be used + * to authenticate the request via the "Authorization" header. * - "cookiesFrom" should hold a response object from a previous HTTP * interaction. All cookies returned from the server in that response * (via the "Set-Cookie" header) will be copied to the cookie params of @@ -160,6 +163,13 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase ); } + // Authenticate as a given user + if (isset($options['authenticatedAs'])) { + $request = $this->requestAsUser( + $request, $options['authenticatedAs'] + ); + } + // Let's copy the cookies from a previous response if (isset($options['cookiesFrom'])) { $request = $this->requestWithCookiesFrom( From 21f4c3f6dd809eeeedc96ef2fb74ede12fb6a583 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Fri, 20 Mar 2020 17:28:58 +0000 Subject: [PATCH 22/68] Apply fixes from StyleCI [ci skip] [skip ci] --- php-packages/testing/tests/integration/TestCase.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 6e99a778e..ea22a5a42 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -159,21 +159,24 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase // Do we want a JSON request body? if (isset($options['json'])) { $request = $this->requestWithJsonBody( - $request, $options['json'] + $request, + $options['json'] ); } // Authenticate as a given user if (isset($options['authenticatedAs'])) { $request = $this->requestAsUser( - $request, $options['authenticatedAs'] + $request, + $options['authenticatedAs'] ); } // Let's copy the cookies from a previous response if (isset($options['cookiesFrom'])) { $request = $this->requestWithCookiesFrom( - $request, $options['cookiesFrom'] + $request, + $options['cookiesFrom'] ); } From 915a428973366e81ca524c0c7963fb22e36bd1b4 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com> Date: Fri, 3 Apr 2020 13:38:54 -0400 Subject: [PATCH 23/68] Add console extender (#2057) * Made the console command system extender-friendly * Added console extender * Added ConsoleTestCase to integration tests * Added integration tests for console extender * Marked event-based console extension system as deprecated * Moved trimming command output of whitespace into superclass * Renamed 'add' to 'command' * Added special processing for laravel commands * Code style fixes * More style fixes * Fixed $this->container --- .../tests/integration/ConsoleTestCase.php | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 php-packages/testing/tests/integration/ConsoleTestCase.php diff --git a/php-packages/testing/tests/integration/ConsoleTestCase.php b/php-packages/testing/tests/integration/ConsoleTestCase.php new file mode 100644 index 000000000..80d907a2e --- /dev/null +++ b/php-packages/testing/tests/integration/ConsoleTestCase.php @@ -0,0 +1,44 @@ +console)) { + $this->console = new ConsoleApplication('Flarum', Application::VERSION); + $this->console->setAutoExit(false); + + foreach ($this->app()->getConsoleCommands() as $command) { + $this->console->add($command); + } + } + + return $this->console; + } + + protected function runCommand(array $inputArray) + { + $input = new ArrayInput($inputArray); + $output = new BufferedOutput(); + + $this->console()->run($input, $output); + + return trim($output->fetch()); + } +} From f45a1608dfcf358b12b233821d1f25be6173de31 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Fri, 1 May 2020 09:53:55 +0000 Subject: [PATCH 24/68] Split up Application and Container - Stop trying to implement Laravel's Application contract, which has no value for us. - Stop inheriting from the Container, injecting one works equally well and does not clutter up the interfaces. - Inject the Paths collection instead of unwrapping it again, for better encapsulation. This brings us one step closer toward upgrading our Laravel components (#2055), because we no longer need to adopt the changes to the Application contract. --- php-packages/testing/tests/integration/TestCase.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index ea22a5a42..cf35bbcf1 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -11,6 +11,7 @@ namespace Flarum\Tests\integration; use Flarum\Extend\ExtenderInterface; use Flarum\Foundation\InstalledSite; +use Flarum\Foundation\Paths; use Illuminate\Database\ConnectionInterface; use Laminas\Diactoros\ServerRequest; use Psr\Http\Message\ResponseInterface; @@ -33,12 +34,12 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase { if (is_null($this->app)) { $site = new InstalledSite( - [ + new Paths([ 'base' => __DIR__.'/tmp', 'vendor' => __DIR__.'/../../vendor', 'public' => __DIR__.'/tmp/public', 'storage' => __DIR__.'/tmp/storage', - ], + ]), include __DIR__.'/tmp/config.php' ); From fe0159ecd1a7a87cec11c5e66d2ba2fe0921fd35 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Fri, 8 May 2020 22:15:55 +0200 Subject: [PATCH 25/68] Test setup: Do not use env() helper Not needed, and not working without a full Laravel installation. --- .../testing/tests/integration/setup.php | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/php-packages/testing/tests/integration/setup.php b/php-packages/testing/tests/integration/setup.php index 8403acf5c..afe5a6063 100644 --- a/php-packages/testing/tests/integration/setup.php +++ b/php-packages/testing/tests/integration/setup.php @@ -14,12 +14,12 @@ use Flarum\Install\Installation; require __DIR__.'/../../vendor/autoload.php'; -$host = env('DB_HOST', 'localhost'); -$port = intval(env('DB_PORT', 3306)); -$name = env('DB_DATABASE', 'flarum_test'); -$user = env('DB_USERNAME', 'root'); -$pass = env('DB_PASSWORD', ''); -$pref = env('DB_PREFIX', ''); +$host = getenv('DB_HOST') ?: 'localhost'; +$port = intval(getenv('DB_PORT') ?: 3306); +$name = getenv('DB_DATABASE') ?: 'flarum_test'; +$user = getenv('DB_USERNAME') ?: 'root'; +$pass = getenv('DB_PASSWORD') ?: ''; +$pref = getenv('DB_PREFIX') ?: ''; echo "Connecting to database $name at $host:$port.\n"; echo "Logging in as $user with password '$pass'.\n"; @@ -48,15 +48,9 @@ $pipeline = $installation ->configPath('config.php') ->debugMode(true) ->baseUrl(BaseUrl::fromString('http://localhost')) - ->databaseConfig(new DatabaseConfig( - 'mysql', - env('DB_HOST', 'localhost'), - intval(env('DB_PORT', 3306)), - env('DB_DATABASE', 'flarum_test'), - env('DB_USERNAME', 'root'), - env('DB_PASSWORD', ''), - env('DB_PREFIX', '') - )) + ->databaseConfig( + new DatabaseConfig('mysql', $host, $port, $name, $user, $pass, $pref) + ) ->adminUser(new AdminUser( 'admin', 'secret', From 3224aeabac7f40117f7a92434540507109180985 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Sat, 23 May 2020 02:00:25 +0200 Subject: [PATCH 26/68] Tests: Actually accept multiple extenders We did pass multiple extenders to this method in the tests for the `Model` extender - now this actually has the desired effect. --- php-packages/testing/tests/integration/TestCase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index cf35bbcf1..d7253f45c 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -56,9 +56,9 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase */ protected $extenders = []; - protected function extend(ExtenderInterface $extender) + protected function extend(ExtenderInterface ...$extenders) { - $this->extenders[] = $extender; + $this->extenders = array_merge($this->extenders, $extenders); } /** From 99eeaf0be5965a378380e6f1e32a8c9d1403006d Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Fri, 19 Jun 2020 22:16:03 +0200 Subject: [PATCH 27/68] Clean up usages / deprecate path helpers (#2155) * Write source map without creating temp file Less I/O, and one less place where we access the global path helpers. * Drop useless app_path() helper This was probably taken straight from Laravel. There is no equivalent concept in Flarum, so this should be safe to remove. * Deprecate global path helpers Developers using these helpers can inject the `Paths` class instead. * Stop storing paths as strings in container * Avoid using path helpers from Application class * Deprecate path helpers from Application class * Avoid using public_path() in prerequisite check a) The comparison was already outdated, as a different path was passed. b) We're trying to get rid of these global helpers. --- php-packages/testing/tests/integration/setup.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/php-packages/testing/tests/integration/setup.php b/php-packages/testing/tests/integration/setup.php index afe5a6063..2a18ca4a6 100644 --- a/php-packages/testing/tests/integration/setup.php +++ b/php-packages/testing/tests/integration/setup.php @@ -7,6 +7,7 @@ * LICENSE file that was distributed with this source code. */ +use Flarum\Foundation\Paths; use Flarum\Install\AdminUser; use Flarum\Install\BaseUrl; use Flarum\Install\DatabaseConfig; @@ -38,10 +39,12 @@ echo "\nOff we go...\n"; */ $installation = new Installation( - __DIR__.'/tmp', - __DIR__.'/tmp/public', - __DIR__.'/tmp/storage', - __DIR__.'/../../vendor' + new Paths([ + 'base' => __DIR__.'/tmp', + 'public' => __DIR__.'/tmp/public', + 'storage' => __DIR__.'/tmp/storage', + 'vendor' => __DIR__.'/../../vendor', + ]) ); $pipeline = $installation From d1462571edbf82c829553a65b35622999785526b Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Fri, 21 Aug 2020 18:21:33 +0200 Subject: [PATCH 28/68] Use Config class for data from config.php --- php-packages/testing/tests/integration/TestCase.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index d7253f45c..16a65f07e 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -10,6 +10,7 @@ namespace Flarum\Tests\integration; use Flarum\Extend\ExtenderInterface; +use Flarum\Foundation\Config; use Flarum\Foundation\InstalledSite; use Flarum\Foundation\Paths; use Illuminate\Database\ConnectionInterface; @@ -40,7 +41,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase 'public' => __DIR__.'/tmp/public', 'storage' => __DIR__.'/tmp/storage', ]), - include __DIR__.'/tmp/config.php' + new Config(include __DIR__.'/tmp/config.php') ); $site->extendWith($this->extenders); From eaf5358defdf288119fa55e535d5433867b9e781 Mon Sep 17 00:00:00 2001 From: Wadim Kalmykov <36057469+w-4@users.noreply.github.com> Date: Tue, 29 Sep 2020 01:04:08 +0700 Subject: [PATCH 29/68] Improve developer experience by forcing LF line endings (#2321) --- php-packages/testing/.gitattributes | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php-packages/testing/.gitattributes b/php-packages/testing/.gitattributes index ccbdf6188..61036520c 100644 --- a/php-packages/testing/.gitattributes +++ b/php-packages/testing/.gitattributes @@ -11,3 +11,5 @@ phpunit.xml export-ignore tests export-ignore js/dist/* -diff + +* text=auto eol=lf From 8675e76c92d40709ffe702bcd45141e1426d309b Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Thu, 7 Jan 2021 23:27:32 -0500 Subject: [PATCH 30/68] Add vscode config to gitignore --- php-packages/testing/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/php-packages/testing/.gitignore b/php-packages/testing/.gitignore index 56b9aaf7d..e79d4cf73 100644 --- a/php-packages/testing/.gitignore +++ b/php-packages/testing/.gitignore @@ -7,3 +7,4 @@ Thumbs.db /tests/integration/tmp .vagrant .idea/* +.vscode From 31028e0bf968c8f1d270d8ec4f410a564cde0c5d Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Tue, 19 May 2020 23:12:08 +0200 Subject: [PATCH 31/68] Run integration tests in a transaction --- .../testing/tests/integration/TestCase.php | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 16a65f07e..916b1c06f 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -23,6 +23,20 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase { use BuildsHttpRequests; + protected function setUp(): void + { + parent::setUp(); + + $this->database()->beginTransaction(); + } + + protected function tearDown(): void + { + parent::tearDown(); + + $this->database()->rollBack(); + } + /** * @var \Flarum\Foundation\InstalledApp */ @@ -94,13 +108,6 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase // We temporarily disable foreign key checks to simplify this process. $this->database()->getSchemaBuilder()->disableForeignKeyConstraints(); - // First, truncate all referenced tables so that they are empty. - foreach (array_keys($tableData) as $table) { - if ($table !== 'settings') { - $this->database()->table($table)->truncate(); - } - } - // Then, insert all rows required for this test case. foreach ($tableData as $table => $rows) { foreach ($rows as $row) { From b1a18971cab4db5336645639b0564b27bf6af293 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Wed, 20 May 2020 00:18:00 +0200 Subject: [PATCH 32/68] Tests: Rely on admin user, groups, permissions from test setup script --- .../integration/RetrievesAuthorizedUsers.php | 44 ------------------- .../testing/tests/integration/setup.php | 4 +- 2 files changed, 2 insertions(+), 46 deletions(-) diff --git a/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php b/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php index df2f80e87..a4bd58a98 100644 --- a/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php +++ b/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php @@ -11,50 +11,6 @@ namespace Flarum\Tests\integration; trait RetrievesAuthorizedUsers { - protected function adminGroup(): array - { - return [ - 'id' => 1, - 'name_singular' => 'Admin', - 'name_plural' => 'Admins', - 'color' => '#B72A2A', - 'icon' => 'fas fa-wrench', - ]; - } - - protected function guestGroup(): array - { - return [ - 'id' => 2, - 'name_singular' => 'Guest', - 'name_plural' => 'Guests', - 'color' => null, - 'icon' => null, - ]; - } - - protected function memberGroup(): array - { - return [ - 'id' => 3, - 'name_singular' => 'Member', - 'name_plural' => 'Members', - 'color' => null, - 'icon' => null, - ]; - } - - protected function adminUser(): array - { - return [ - 'id' => 1, - 'username' => 'admin', - 'password' => '$2y$10$HMOAe.XaQjOimA778VmFue1OCt7tj5j0wk5vfoL/CMSJq2BQlfBV2', // BCrypt hash for "password" - 'email' => 'admin@machine.local', - 'is_email_confirmed' => 1, - ]; - } - protected function normalUser(): array { return [ diff --git a/php-packages/testing/tests/integration/setup.php b/php-packages/testing/tests/integration/setup.php index 2a18ca4a6..95739eaac 100644 --- a/php-packages/testing/tests/integration/setup.php +++ b/php-packages/testing/tests/integration/setup.php @@ -56,8 +56,8 @@ $pipeline = $installation ) ->adminUser(new AdminUser( 'admin', - 'secret', - 'admin@flarum.email' + 'password', + 'admin@machine.local' )) ->settings(['mail_driver' => 'log']) ->build(); From 663f7a5d3220298ccb16998e5814dfc93a8a1e91 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Thu, 21 May 2020 22:34:01 +0200 Subject: [PATCH 33/68] Tests: Stop using Eloquent models for seeding data --- .../tests/integration/BuildsHttpRequests.php | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/php-packages/testing/tests/integration/BuildsHttpRequests.php b/php-packages/testing/tests/integration/BuildsHttpRequests.php index 09704de8b..410d67b56 100644 --- a/php-packages/testing/tests/integration/BuildsHttpRequests.php +++ b/php-packages/testing/tests/integration/BuildsHttpRequests.php @@ -9,8 +9,9 @@ namespace Flarum\Tests\integration; +use Carbon\Carbon; use Dflydev\FigCookies\SetCookie; -use Flarum\Http\AccessToken; +use Illuminate\Support\Str; use Laminas\Diactoros\CallbackStream; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; @@ -33,10 +34,21 @@ trait BuildsHttpRequests protected function requestAsUser(Request $req, int $userId): Request { - $token = AccessToken::generate($userId); - $token->save(); + $token = Str::random(40); - return $req->withAddedHeader('Authorization', "Token {$token->token}"); + /** + * We insert this directly instead of via `prepareDatabase` + * so that requests can be created/sent after the app is booted. + */ + $this->database()->table('access_tokens')->insert([ + 'token' => $token, + 'user_id' => $userId, + 'created_at' => Carbon::now()->toDateTimeString(), + 'last_activity_at' => Carbon::now()->toDateTimeString(), + 'lifetime_seconds' => 3600 + ]); + + return $req->withAddedHeader('Authorization', "Token {$token}"); } protected function requestWithCookiesFrom(Request $req, Response $previous): Request From 6ca9191f427c98527fb9fad127c89819d4a76bfd Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Thu, 21 May 2020 22:35:06 +0200 Subject: [PATCH 34/68] Tests: Always start transaction before seeding --- .../testing/tests/integration/TestCase.php | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 916b1c06f..5c8c5526c 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -23,13 +23,6 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase { use BuildsHttpRequests; - protected function setUp(): void - { - parent::setUp(); - - $this->database()->beginTransaction(); - } - protected function tearDown(): void { parent::tearDown(); @@ -61,6 +54,10 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase $site->extendWith($this->extenders); $this->app = $site->bootApp(); + + $this->database()->beginTransaction(); + + $this->populateDatabase(); } return $this->app; @@ -103,13 +100,23 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase return $this->database; } + protected $databaseContent = []; + protected function prepareDatabase(array $tableData) + { + $this->databaseContent = array_merge_recursive( + $this->databaseContent, + $tableData + ); + } + + protected function populateDatabase() { // We temporarily disable foreign key checks to simplify this process. $this->database()->getSchemaBuilder()->disableForeignKeyConstraints(); // Then, insert all rows required for this test case. - foreach ($tableData as $table => $rows) { + foreach ($this->databaseContent as $table => $rows) { foreach ($rows as $row) { if ($table === 'settings') { $this->database()->table($table)->updateOrInsert( From ab43c31ff588fe1f0e02155bfe2af0c7a359ca00 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Wed, 6 Jan 2021 22:16:26 -0500 Subject: [PATCH 35/68] Add @inheritDoc to all setUp and tearDown methods --- php-packages/testing/tests/integration/TestCase.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 5c8c5526c..1bf515a41 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -23,6 +23,9 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase { use BuildsHttpRequests; + /** + * @inheritDoc + */ protected function tearDown(): void { parent::tearDown(); From 1afbb070371489b0b2c9a3bb9cba6ca7a0684126 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Thu, 7 Jan 2021 14:10:53 -0500 Subject: [PATCH 36/68] Tests: purge settings cache Some tests need to change settings, but since MemoryCacheSettingsRepository caches settings in-memory, those changes aren't reflected. The new `purgeSettingsCache` removes it from the container, eliminating that cache. For UserTest, we also need to regenerate the display name driver, since that's set statically on boot, before we'll get a change to clear the settings cache. --- .../tests/integration/UsesSettings.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 php-packages/testing/tests/integration/UsesSettings.php diff --git a/php-packages/testing/tests/integration/UsesSettings.php b/php-packages/testing/tests/integration/UsesSettings.php new file mode 100644 index 000000000..d37aa0f7b --- /dev/null +++ b/php-packages/testing/tests/integration/UsesSettings.php @@ -0,0 +1,25 @@ +app()->getContainer()->forgetInstance(SettingsRepositoryInterface::class); + } +} From ba0fbd71e6f33b2bcb5d91b9161a4dc871e1cbe3 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Wed, 13 Jan 2021 01:16:59 -0500 Subject: [PATCH 37/68] Move test infrastructure to Testing namespace in src directory --- .../testing/{tests => src}/integration/BuildsHttpRequests.php | 2 +- .../testing/{tests => src}/integration/ConsoleTestCase.php | 2 +- .../{tests => src}/integration/RetrievesAuthorizedUsers.php | 2 +- php-packages/testing/{tests => src}/integration/TestCase.php | 2 +- .../testing/{tests => src}/integration/UsesSettings.php | 2 +- php-packages/testing/{tests => src}/integration/setup.php | 0 .../{tests => src}/integration/tmp/public/assets/.gitkeep | 0 .../{tests => src}/integration/tmp/storage/formatter/.gitkeep | 0 .../{tests => src}/integration/tmp/storage/sessions/.gitkeep | 0 .../{tests => src}/integration/tmp/storage/views/.gitkeep | 0 .../integration/tmp/vendor/composer/installed.json | 0 php-packages/testing/{tests => src}/unit/TestCase.php | 2 +- 12 files changed, 6 insertions(+), 6 deletions(-) rename php-packages/testing/{tests => src}/integration/BuildsHttpRequests.php (98%) rename php-packages/testing/{tests => src}/integration/ConsoleTestCase.php (96%) rename php-packages/testing/{tests => src}/integration/RetrievesAuthorizedUsers.php (93%) rename php-packages/testing/{tests => src}/integration/TestCase.php (99%) rename php-packages/testing/{tests => src}/integration/UsesSettings.php (93%) rename php-packages/testing/{tests => src}/integration/setup.php (100%) rename php-packages/testing/{tests => src}/integration/tmp/public/assets/.gitkeep (100%) rename php-packages/testing/{tests => src}/integration/tmp/storage/formatter/.gitkeep (100%) rename php-packages/testing/{tests => src}/integration/tmp/storage/sessions/.gitkeep (100%) rename php-packages/testing/{tests => src}/integration/tmp/storage/views/.gitkeep (100%) rename php-packages/testing/{tests => src}/integration/tmp/vendor/composer/installed.json (100%) rename php-packages/testing/{tests => src}/unit/TestCase.php (92%) diff --git a/php-packages/testing/tests/integration/BuildsHttpRequests.php b/php-packages/testing/src/integration/BuildsHttpRequests.php similarity index 98% rename from php-packages/testing/tests/integration/BuildsHttpRequests.php rename to php-packages/testing/src/integration/BuildsHttpRequests.php index 410d67b56..111be7637 100644 --- a/php-packages/testing/tests/integration/BuildsHttpRequests.php +++ b/php-packages/testing/src/integration/BuildsHttpRequests.php @@ -7,7 +7,7 @@ * LICENSE file that was distributed with this source code. */ -namespace Flarum\Tests\integration; +namespace Flarum\Testing\integration; use Carbon\Carbon; use Dflydev\FigCookies\SetCookie; diff --git a/php-packages/testing/tests/integration/ConsoleTestCase.php b/php-packages/testing/src/integration/ConsoleTestCase.php similarity index 96% rename from php-packages/testing/tests/integration/ConsoleTestCase.php rename to php-packages/testing/src/integration/ConsoleTestCase.php index 80d907a2e..a29db0895 100644 --- a/php-packages/testing/tests/integration/ConsoleTestCase.php +++ b/php-packages/testing/src/integration/ConsoleTestCase.php @@ -7,7 +7,7 @@ * LICENSE file that was distributed with this source code. */ -namespace Flarum\Tests\integration; +namespace Flarum\Testing\integration; use Flarum\Foundation\Application; use Symfony\Component\Console\Application as ConsoleApplication; diff --git a/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php b/php-packages/testing/src/integration/RetrievesAuthorizedUsers.php similarity index 93% rename from php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php rename to php-packages/testing/src/integration/RetrievesAuthorizedUsers.php index a4bd58a98..8eefc75f6 100644 --- a/php-packages/testing/tests/integration/RetrievesAuthorizedUsers.php +++ b/php-packages/testing/src/integration/RetrievesAuthorizedUsers.php @@ -7,7 +7,7 @@ * LICENSE file that was distributed with this source code. */ -namespace Flarum\Tests\integration; +namespace Flarum\Testing\integration; trait RetrievesAuthorizedUsers { diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/src/integration/TestCase.php similarity index 99% rename from php-packages/testing/tests/integration/TestCase.php rename to php-packages/testing/src/integration/TestCase.php index 1bf515a41..60fb2b38b 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/src/integration/TestCase.php @@ -7,7 +7,7 @@ * LICENSE file that was distributed with this source code. */ -namespace Flarum\Tests\integration; +namespace Flarum\Testing\integration; use Flarum\Extend\ExtenderInterface; use Flarum\Foundation\Config; diff --git a/php-packages/testing/tests/integration/UsesSettings.php b/php-packages/testing/src/integration/UsesSettings.php similarity index 93% rename from php-packages/testing/tests/integration/UsesSettings.php rename to php-packages/testing/src/integration/UsesSettings.php index d37aa0f7b..66b49cf9e 100644 --- a/php-packages/testing/tests/integration/UsesSettings.php +++ b/php-packages/testing/src/integration/UsesSettings.php @@ -7,7 +7,7 @@ * LICENSE file that was distributed with this source code. */ -namespace Flarum\Tests\integration; +namespace Flarum\Testing\integration; use Flarum\Settings\SettingsRepositoryInterface; diff --git a/php-packages/testing/tests/integration/setup.php b/php-packages/testing/src/integration/setup.php similarity index 100% rename from php-packages/testing/tests/integration/setup.php rename to php-packages/testing/src/integration/setup.php diff --git a/php-packages/testing/tests/integration/tmp/public/assets/.gitkeep b/php-packages/testing/src/integration/tmp/public/assets/.gitkeep similarity index 100% rename from php-packages/testing/tests/integration/tmp/public/assets/.gitkeep rename to php-packages/testing/src/integration/tmp/public/assets/.gitkeep diff --git a/php-packages/testing/tests/integration/tmp/storage/formatter/.gitkeep b/php-packages/testing/src/integration/tmp/storage/formatter/.gitkeep similarity index 100% rename from php-packages/testing/tests/integration/tmp/storage/formatter/.gitkeep rename to php-packages/testing/src/integration/tmp/storage/formatter/.gitkeep diff --git a/php-packages/testing/tests/integration/tmp/storage/sessions/.gitkeep b/php-packages/testing/src/integration/tmp/storage/sessions/.gitkeep similarity index 100% rename from php-packages/testing/tests/integration/tmp/storage/sessions/.gitkeep rename to php-packages/testing/src/integration/tmp/storage/sessions/.gitkeep diff --git a/php-packages/testing/tests/integration/tmp/storage/views/.gitkeep b/php-packages/testing/src/integration/tmp/storage/views/.gitkeep similarity index 100% rename from php-packages/testing/tests/integration/tmp/storage/views/.gitkeep rename to php-packages/testing/src/integration/tmp/storage/views/.gitkeep diff --git a/php-packages/testing/tests/integration/tmp/vendor/composer/installed.json b/php-packages/testing/src/integration/tmp/vendor/composer/installed.json similarity index 100% rename from php-packages/testing/tests/integration/tmp/vendor/composer/installed.json rename to php-packages/testing/src/integration/tmp/vendor/composer/installed.json diff --git a/php-packages/testing/tests/unit/TestCase.php b/php-packages/testing/src/unit/TestCase.php similarity index 92% rename from php-packages/testing/tests/unit/TestCase.php rename to php-packages/testing/src/unit/TestCase.php index 63214ce19..ae04b4cac 100644 --- a/php-packages/testing/tests/unit/TestCase.php +++ b/php-packages/testing/src/unit/TestCase.php @@ -7,7 +7,7 @@ * LICENSE file that was distributed with this source code. */ -namespace Flarum\Tests\unit; +namespace Flarum\Testing\unit; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; From b392b85f1782e0b33461041f2c7d4f6bd10e07da Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Wed, 13 Jan 2021 01:20:59 -0500 Subject: [PATCH 38/68] Add composer.json --- php-packages/testing/composer.json | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 php-packages/testing/composer.json diff --git a/php-packages/testing/composer.json b/php-packages/testing/composer.json new file mode 100644 index 000000000..c9d5c7650 --- /dev/null +++ b/php-packages/testing/composer.json @@ -0,0 +1,24 @@ +{ + "name": "flarum/testing", + "description": "Automated testing infrastructure for Flarum core and extensions.", + "keywords": ["forum", "discussion"], + "homepage": "https://flarum.org/", + "license": "MIT", + "require": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.0" + }, + "require-dev": { + "flarum/core": "^0.1.0-beta" + }, + "autoload": { + "psr-4": { + "Flarum\\Testing\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "0.1.x-dev" + } + } +} From 0dba5af52d8e87c631739f75131fb2a1827cdfeb Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Wed, 13 Jan 2021 01:28:08 -0500 Subject: [PATCH 39/68] Move setup script to importable class --- .../src/integration/Setup/SetupScript.php | 114 ++++++++++++++++++ .../testing/src/integration/setup.php | 71 ----------- 2 files changed, 114 insertions(+), 71 deletions(-) create mode 100644 php-packages/testing/src/integration/Setup/SetupScript.php delete mode 100644 php-packages/testing/src/integration/setup.php diff --git a/php-packages/testing/src/integration/Setup/SetupScript.php b/php-packages/testing/src/integration/Setup/SetupScript.php new file mode 100644 index 000000000..1c23e8689 --- /dev/null +++ b/php-packages/testing/src/integration/Setup/SetupScript.php @@ -0,0 +1,114 @@ +host = getenv('DB_HOST') ?: 'localhost'; + $this->port = intval(getenv('DB_PORT') ?: 3306); + $this->name = getenv('DB_DATABASE') ?: 'flarum_test'; + $this->user = getenv('DB_USERNAME') ?: 'root'; + $this->pass = getenv('DB_PASSWORD') ?: 'root'; + $this->pref = getenv('DB_PREFIX') ?: ''; + } + + public function run() + { + echo "Connecting to database $this->name at $this->host:$this->port.\n"; + echo "Logging in as $this->user with password '$this->pass'.\n"; + echo "Table prefix: '$this->pref'\n"; + + echo "\n\nCancel now if that's not what you want...\n"; + echo "Use the following environment variables for configuration:\n"; + echo "DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD, DB_PREFIX\n"; + + sleep(4); + + echo "\nOff we go...\n"; + $installation = new Installation( + new Paths([ + 'base' => __DIR__.'/../tmp', + 'public' => __DIR__.'/../tmp/public', + 'storage' => __DIR__.'/../tmp/storage', + 'vendor' => __DIR__.'/../../../../../', + ]) + ); + + $pipeline = $installation + ->configPath('config.php') + ->debugMode(true) + ->baseUrl(BaseUrl::fromString('http://localhost')) + ->databaseConfig( + new DatabaseConfig('mysql', $this->host, $this->port, $this->name, $this->user, $this->pass, $this->pref) + ) + ->adminUser(new AdminUser( + 'admin', + 'password', + 'admin@machine.local' + )) + ->settings(['mail_driver' => 'log']) + ->build(); + + // Run the actual configuration + $pipeline->run(); + + echo "Installation complete\n"; + } +} diff --git a/php-packages/testing/src/integration/setup.php b/php-packages/testing/src/integration/setup.php deleted file mode 100644 index 95739eaac..000000000 --- a/php-packages/testing/src/integration/setup.php +++ /dev/null @@ -1,71 +0,0 @@ - __DIR__.'/tmp', - 'public' => __DIR__.'/tmp/public', - 'storage' => __DIR__.'/tmp/storage', - 'vendor' => __DIR__.'/../../vendor', - ]) -); - -$pipeline = $installation - ->configPath('config.php') - ->debugMode(true) - ->baseUrl(BaseUrl::fromString('http://localhost')) - ->databaseConfig( - new DatabaseConfig('mysql', $host, $port, $name, $user, $pass, $pref) - ) - ->adminUser(new AdminUser( - 'admin', - 'password', - 'admin@machine.local' - )) - ->settings(['mail_driver' => 'log']) - ->build(); - -/* - * Run the actual configuration - */ - -$pipeline->run(); - -echo "Installation complete\n"; From 167ffced5d0d68abc0afff997a2777f364394102 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Wed, 13 Jan 2021 16:49:39 -0500 Subject: [PATCH 40/68] Fix vendor path --- php-packages/testing/src/integration/TestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-packages/testing/src/integration/TestCase.php b/php-packages/testing/src/integration/TestCase.php index 60fb2b38b..ad6986a83 100644 --- a/php-packages/testing/src/integration/TestCase.php +++ b/php-packages/testing/src/integration/TestCase.php @@ -47,7 +47,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase $site = new InstalledSite( new Paths([ 'base' => __DIR__.'/tmp', - 'vendor' => __DIR__.'/../../vendor', + 'vendor' => __DIR__.'/../../../../', 'public' => __DIR__.'/tmp/public', 'storage' => __DIR__.'/tmp/storage', ]), From 6eafce06604c719d68d36767eacb6b1799c69675 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com> Date: Sun, 24 Jan 2021 12:13:27 -0500 Subject: [PATCH 41/68] If current package is an extension, add it to the extension manager (#1) Core's ExtensionManager only looks for extensions in the vendor directory, which makes sense for a Flarum instance, but is problematic if used in the context of a test suite for an extension. This PR: - Adds a class extending ExtensionManager to include the current package - Adds an extender that replaces ExtensionManager with this new class in container bindings Effectively, this package can now be used to test extensions. --- .../OverrideExtensionManagerForTests.php | 35 ++++++++++++++++ .../ExtensionManagerIncludeCurrent.php | 42 +++++++++++++++++++ .../testing/src/integration/TestCase.php | 19 ++++++++- 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php create mode 100644 php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php diff --git a/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php b/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php new file mode 100644 index 000000000..a975cdab7 --- /dev/null +++ b/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php @@ -0,0 +1,35 @@ +extensions = $extensions; + } + + public function extend(Container $container, Extension $extension = null) + { + if (count($this->extensions)) { + $container->bind(ExtensionManager::class, ExtensionManagerIncludeCurrent::class); + $extensionManager = $container->make(ExtensionManager::class); + + foreach ($this->extensions as $extension) { + $extensionManager->enable($extension); + } + + $extensionManager->extend($container); + } + } +} diff --git a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php new file mode 100644 index 000000000..0d869b8d8 --- /dev/null +++ b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php @@ -0,0 +1,42 @@ +filesystem->get($this->paths->vendor . '/../composer.json'), true); + + if (Arr::get($package, 'type') === 'flarum-extension') { + $current = new Extension($this->paths->vendor . '/../', $package); + $current->setInstalled(true); + $current->setVersion(Arr::get($package, 'version')); + $current->calculateDependencies([]); + + $extensions->put($current->getId(), $current); + + $this->extensions = $extensions->sortBy(function ($extension, $name) { + return $extension->composerJsonAttribute('extra.flarum-extension.title'); + }); + } + + return $this->extensions; + } +} diff --git a/php-packages/testing/src/integration/TestCase.php b/php-packages/testing/src/integration/TestCase.php index ad6986a83..7b385b173 100644 --- a/php-packages/testing/src/integration/TestCase.php +++ b/php-packages/testing/src/integration/TestCase.php @@ -13,6 +13,7 @@ use Flarum\Extend\ExtenderInterface; use Flarum\Foundation\Config; use Flarum\Foundation\InstalledSite; use Flarum\Foundation\Paths; +use Flarum\Testing\integration\Extend\OverrideExtensionManagerForTests; use Illuminate\Database\ConnectionInterface; use Laminas\Diactoros\ServerRequest; use Psr\Http\Message\ResponseInterface; @@ -51,10 +52,14 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase 'public' => __DIR__.'/tmp/public', 'storage' => __DIR__.'/tmp/storage', ]), - new Config(include __DIR__.'/tmp/config.php') + new Config(include __DIR__ . '/tmp/config.php') ); - $site->extendWith($this->extenders); + $extenders = array_merge([ + new OverrideExtensionManagerForTests($this->extensions) + ], $this->extenders); + + $site->extendWith($extenders); $this->app = $site->bootApp(); @@ -76,6 +81,16 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase $this->extenders = array_merge($this->extenders, $extenders); } + /** + * @var string[] + */ + protected $extensions = []; + + protected function extension(string ...$extensions) + { + $this->extensions = array_merge($this->extensions, $extensions); + } + /** * @var RequestHandlerInterface */ From e8f3d23deda2cf4f892c800efb5051877c787b34 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com> Date: Wed, 10 Feb 2021 08:59:08 -0500 Subject: [PATCH 42/68] Configurable Tmp Dir Location (#2) --- .../src/integration/Setup/SetupScript.php | 21 ++++++--- .../testing/src/integration/TestCase.php | 13 +++--- .../testing/src/integration/UsesTmpDir.php | 44 +++++++++++++++++++ .../integration/tmp/public/assets/.gitkeep | 0 .../tmp/storage/formatter/.gitkeep | 0 .../integration/tmp/storage/sessions/.gitkeep | 0 .../integration/tmp/storage/views/.gitkeep | 0 .../tmp/vendor/composer/installed.json | 1 - 8 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 php-packages/testing/src/integration/UsesTmpDir.php delete mode 100644 php-packages/testing/src/integration/tmp/public/assets/.gitkeep delete mode 100644 php-packages/testing/src/integration/tmp/storage/formatter/.gitkeep delete mode 100644 php-packages/testing/src/integration/tmp/storage/sessions/.gitkeep delete mode 100644 php-packages/testing/src/integration/tmp/storage/views/.gitkeep delete mode 100644 php-packages/testing/src/integration/tmp/vendor/composer/installed.json diff --git a/php-packages/testing/src/integration/Setup/SetupScript.php b/php-packages/testing/src/integration/Setup/SetupScript.php index 1c23e8689..15c7cf490 100644 --- a/php-packages/testing/src/integration/Setup/SetupScript.php +++ b/php-packages/testing/src/integration/Setup/SetupScript.php @@ -14,9 +14,12 @@ use Flarum\Install\AdminUser; use Flarum\Install\BaseUrl; use Flarum\Install\DatabaseConfig; use Flarum\Install\Installation; +use Flarum\Testing\integration\UsesTmpDir; class SetupScript { + use UsesTmpDir; + /** * Test database host. * @@ -71,23 +74,31 @@ class SetupScript public function run() { + $tmp = $this->tmpDir(); + echo "Connecting to database $this->name at $this->host:$this->port.\n"; echo "Logging in as $this->user with password '$this->pass'.\n"; echo "Table prefix: '$this->pref'\n"; + echo "\nStoring test config in '$tmp'\n"; echo "\n\nCancel now if that's not what you want...\n"; echo "Use the following environment variables for configuration:\n"; - echo "DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD, DB_PREFIX\n"; + echo "Database: DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD, DB_PREFIX\n"; + echo "Test Config: FLARUM_TEST_TMP_DIR or FLARUM_TEST_TMP_DIR_LOCAL\n"; + sleep(4); echo "\nOff we go...\n"; + + $this->setupTmpDir(); + $installation = new Installation( new Paths([ - 'base' => __DIR__.'/../tmp', - 'public' => __DIR__.'/../tmp/public', - 'storage' => __DIR__.'/../tmp/storage', - 'vendor' => __DIR__.'/../../../../../', + 'base' => $tmp, + 'public' => "$tmp/public", + 'storage' => "$tmp/storage", + 'vendor' => getcwd().'/vendor', ]) ); diff --git a/php-packages/testing/src/integration/TestCase.php b/php-packages/testing/src/integration/TestCase.php index 7b385b173..bba228879 100644 --- a/php-packages/testing/src/integration/TestCase.php +++ b/php-packages/testing/src/integration/TestCase.php @@ -23,6 +23,7 @@ use Psr\Http\Server\RequestHandlerInterface; abstract class TestCase extends \PHPUnit\Framework\TestCase { use BuildsHttpRequests; + use UsesTmpDir; /** * @inheritDoc @@ -45,14 +46,16 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase protected function app() { if (is_null($this->app)) { + $tmp = $this->tmpDir(); + $site = new InstalledSite( new Paths([ - 'base' => __DIR__.'/tmp', - 'vendor' => __DIR__.'/../../../../', - 'public' => __DIR__.'/tmp/public', - 'storage' => __DIR__.'/tmp/storage', + 'base' => $tmp, + 'public' => "$tmp/public", + 'storage' => "$tmp/storage", + 'vendor' => getcwd().'/vendor', ]), - new Config(include __DIR__ . '/tmp/config.php') + new Config(include "$tmp/config.php") ); $extenders = array_merge([ diff --git a/php-packages/testing/src/integration/UsesTmpDir.php b/php-packages/testing/src/integration/UsesTmpDir.php new file mode 100644 index 000000000..23f2eb279 --- /dev/null +++ b/php-packages/testing/src/integration/UsesTmpDir.php @@ -0,0 +1,44 @@ + '{}' + ]; + + $tmpDir = $this->tmpDir(); + + foreach ($DIRS_NEEDED as $path) { + $fullPath = $tmpDir.$path; + if (!file_exists($fullPath)) { + mkdir($fullPath); + } + } + + foreach ($FILES_NEEDED as $path => $contents) { + $fullPath = $tmpDir.$path; + if (!file_exists($fullPath)) { + file_put_contents($fullPath, $contents); + } + } + } +} diff --git a/php-packages/testing/src/integration/tmp/public/assets/.gitkeep b/php-packages/testing/src/integration/tmp/public/assets/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/php-packages/testing/src/integration/tmp/storage/formatter/.gitkeep b/php-packages/testing/src/integration/tmp/storage/formatter/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/php-packages/testing/src/integration/tmp/storage/sessions/.gitkeep b/php-packages/testing/src/integration/tmp/storage/sessions/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/php-packages/testing/src/integration/tmp/storage/views/.gitkeep b/php-packages/testing/src/integration/tmp/storage/views/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/php-packages/testing/src/integration/tmp/vendor/composer/installed.json b/php-packages/testing/src/integration/tmp/vendor/composer/installed.json deleted file mode 100644 index 0967ef424..000000000 --- a/php-packages/testing/src/integration/tmp/vendor/composer/installed.json +++ /dev/null @@ -1 +0,0 @@ -{} From dd6897cb6f6d600c76c2b31047974da0e3fa6f11 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Sat, 6 Mar 2021 18:38:12 -0500 Subject: [PATCH 43/68] Update BuildsHttpRequests for new token system --- php-packages/testing/src/integration/BuildsHttpRequests.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-packages/testing/src/integration/BuildsHttpRequests.php b/php-packages/testing/src/integration/BuildsHttpRequests.php index 111be7637..6b379702a 100644 --- a/php-packages/testing/src/integration/BuildsHttpRequests.php +++ b/php-packages/testing/src/integration/BuildsHttpRequests.php @@ -45,7 +45,7 @@ trait BuildsHttpRequests 'user_id' => $userId, 'created_at' => Carbon::now()->toDateTimeString(), 'last_activity_at' => Carbon::now()->toDateTimeString(), - 'lifetime_seconds' => 3600 + 'type' => 'session' ]); return $req->withAddedHeader('Authorization', "Token {$token}"); From 19763f86417ffe6fb613d6613071d2cbb1ba6f3f Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Sat, 6 Mar 2021 18:38:34 -0500 Subject: [PATCH 44/68] Update PHPUnit to v9 --- php-packages/testing/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-packages/testing/composer.json b/php-packages/testing/composer.json index c9d5c7650..05b6da07c 100644 --- a/php-packages/testing/composer.json +++ b/php-packages/testing/composer.json @@ -6,7 +6,7 @@ "license": "MIT", "require": { "mockery/mockery": "^1.0", - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^9.0" }, "require-dev": { "flarum/core": "^0.1.0-beta" From ce0e5c99a625bf2925853b3bc936bd3897533018 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Sat, 6 Mar 2021 18:58:07 -0500 Subject: [PATCH 45/68] Use mockery 1.4 --- php-packages/testing/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-packages/testing/composer.json b/php-packages/testing/composer.json index 05b6da07c..721bbcad1 100644 --- a/php-packages/testing/composer.json +++ b/php-packages/testing/composer.json @@ -5,7 +5,7 @@ "homepage": "https://flarum.org/", "license": "MIT", "require": { - "mockery/mockery": "^1.0", + "mockery/mockery": "^1.4", "phpunit/phpunit": "^9.0" }, "require-dev": { From ca8b7424b882685d6d80b78f664d005f939570f5 Mon Sep 17 00:00:00 2001 From: SychO9 Date: Thu, 11 Mar 2021 18:52:41 +0100 Subject: [PATCH 46/68] Add required argument --- .../integration/Extension/ExtensionManagerIncludeCurrent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php index 0d869b8d8..bd127308f 100644 --- a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php +++ b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php @@ -28,7 +28,7 @@ class ExtensionManagerIncludeCurrent extends ExtensionManager $current = new Extension($this->paths->vendor . '/../', $package); $current->setInstalled(true); $current->setVersion(Arr::get($package, 'version')); - $current->calculateDependencies([]); + $current->calculateDependencies([], []); $extensions->put($current->getId(), $current); From c7fdb79ce3c60b04b9baa96251b3512b969d1f46 Mon Sep 17 00:00:00 2001 From: SychO9 Date: Thu, 11 Mar 2021 18:53:27 +0100 Subject: [PATCH 47/68] Ignore generated tmp --- php-packages/testing/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-packages/testing/.gitignore b/php-packages/testing/.gitignore index e79d4cf73..38a8fa98d 100644 --- a/php-packages/testing/.gitignore +++ b/php-packages/testing/.gitignore @@ -4,7 +4,7 @@ composer.phar node_modules .DS_Store Thumbs.db -/tests/integration/tmp +/src/integration/tmp .vagrant .idea/* .vscode From 082a600adfdcada84922604e71ac75fc0c39fffd Mon Sep 17 00:00:00 2001 From: Clark Winkelmann Date: Sat, 20 Mar 2021 23:46:03 +0100 Subject: [PATCH 48/68] Fix variable names (#4) It's not causing any issue because the correct variable name is always used to set and read the value, and PHP is fine setting new attributes on a class dynamically. It's just the explicit variables declared don't match with those actually used later. --- php-packages/testing/src/integration/Setup/SetupScript.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php-packages/testing/src/integration/Setup/SetupScript.php b/php-packages/testing/src/integration/Setup/SetupScript.php index 15c7cf490..ca9b302f9 100644 --- a/php-packages/testing/src/integration/Setup/SetupScript.php +++ b/php-packages/testing/src/integration/Setup/SetupScript.php @@ -32,7 +32,7 @@ class SetupScript * * @var int */ - protected $post; + protected $port; /** * Test database name. @@ -60,7 +60,7 @@ class SetupScript * * @var string */ - protected $prefix; + protected $pref; public function __construct() { From f410f69b36a9b91957df7fbca967d7b3f4d367e0 Mon Sep 17 00:00:00 2001 From: Clark Winkelmann Date: Sun, 21 Mar 2021 19:25:02 +0100 Subject: [PATCH 49/68] Add missing import for ExtensionManager (#6) Replace bind with singleton, otherwise singleton behavior is lost --- .../integration/Extend/OverrideExtensionManagerForTests.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php b/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php index a975cdab7..de3c7abbe 100644 --- a/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php +++ b/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php @@ -4,6 +4,7 @@ namespace Flarum\Testing\integration\Extend; use Flarum\Extend\ExtenderInterface; use Flarum\Extension\Extension; +use Flarum\Extension\ExtensionManager; use Flarum\Testing\integration\Extension\ExtensionManagerIncludeCurrent; use Illuminate\Contracts\Container\Container; @@ -22,7 +23,7 @@ class OverrideExtensionManagerForTests implements ExtenderInterface public function extend(Container $container, Extension $extension = null) { if (count($this->extensions)) { - $container->bind(ExtensionManager::class, ExtensionManagerIncludeCurrent::class); + $container->singleton(ExtensionManager::class, ExtensionManagerIncludeCurrent::class); $extensionManager = $container->make(ExtensionManager::class); foreach ($this->extensions as $extension) { From 3506991d3e46ae1acbe5acb315c56bc87cb8478c Mon Sep 17 00:00:00 2001 From: Clark Winkelmann Date: Sun, 21 Mar 2021 19:26:25 +0100 Subject: [PATCH 50/68] Requirement and formatting fixes (#5) Add ext-json to composer requirements Update editorconfig to match core Update phpdoc to not reference missing import --- php-packages/testing/.editorconfig | 2 +- php-packages/testing/composer.json | 6 +++++- .../Extension/ExtensionManagerIncludeCurrent.php | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/php-packages/testing/.editorconfig b/php-packages/testing/.editorconfig index 658a43499..a61a3ab36 100644 --- a/php-packages/testing/.editorconfig +++ b/php-packages/testing/.editorconfig @@ -15,5 +15,5 @@ indent_size = 2 [*.{diff,md}] trim_trailing_whitespace = false -[*.{php,xml}] +[*.{php,xml,json}] indent_size = 4 diff --git a/php-packages/testing/composer.json b/php-packages/testing/composer.json index 721bbcad1..eb29a6161 100644 --- a/php-packages/testing/composer.json +++ b/php-packages/testing/composer.json @@ -1,10 +1,14 @@ { "name": "flarum/testing", "description": "Automated testing infrastructure for Flarum core and extensions.", - "keywords": ["forum", "discussion"], + "keywords": [ + "forum", + "discussion" + ], "homepage": "https://flarum.org/", "license": "MIT", "require": { + "ext-json": "*", "mockery/mockery": "^1.4", "phpunit/phpunit": "^9.0" }, diff --git a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php index bd127308f..c7a4169f3 100644 --- a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php +++ b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php @@ -16,7 +16,7 @@ use Illuminate\Support\Arr; class ExtensionManagerIncludeCurrent extends ExtensionManager { /** - * @return Collection + * @{@inheritDoc} */ public function getExtensions() { From 1fbf5fd02916b0c3e1d1b0f337ebe84da8d6e69f Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Wed, 7 Apr 2021 15:01:40 -0400 Subject: [PATCH 51/68] Add `setting` method to integration TestCase This allows adding settings before the app is booted. In the past we've used hacky workarounds like manually resetting a binding to override singletons to use custom setting values. It makes sense to support this through `TestCase`. --- .../Extend/SetSettingsBeforeBoot.php | 32 +++++++++++++++ .../testing/src/integration/TestCase.php | 40 ++++++++++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 php-packages/testing/src/integration/Extend/SetSettingsBeforeBoot.php diff --git a/php-packages/testing/src/integration/Extend/SetSettingsBeforeBoot.php b/php-packages/testing/src/integration/Extend/SetSettingsBeforeBoot.php new file mode 100644 index 000000000..51957b19a --- /dev/null +++ b/php-packages/testing/src/integration/Extend/SetSettingsBeforeBoot.php @@ -0,0 +1,32 @@ +settings = $settings; + } + + public function extend(Container $container, Extension $extension = null) + { + if (count($this->settings)) { + $settings = $container->make(SettingsRepositoryInterface::class); + + foreach ($this->settings as $key => $value) { + $settings->set($key, $value); + } + } + } +} diff --git a/php-packages/testing/src/integration/TestCase.php b/php-packages/testing/src/integration/TestCase.php index bba228879..d54a90a37 100644 --- a/php-packages/testing/src/integration/TestCase.php +++ b/php-packages/testing/src/integration/TestCase.php @@ -14,6 +14,7 @@ use Flarum\Foundation\Config; use Flarum\Foundation\InstalledSite; use Flarum\Foundation\Paths; use Flarum\Testing\integration\Extend\OverrideExtensionManagerForTests; +use Flarum\Testing\integration\Extend\SetSettingsBeforeBoot; use Illuminate\Database\ConnectionInterface; use Laminas\Diactoros\ServerRequest; use Psr\Http\Message\ResponseInterface; @@ -59,7 +60,8 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase ); $extenders = array_merge([ - new OverrideExtensionManagerForTests($this->extensions) + new OverrideExtensionManagerForTests($this->extensions), + new SetSettingsBeforeBoot($this->settings), ], $this->extenders); $site->extendWith($extenders); @@ -79,6 +81,13 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase */ protected $extenders = []; + /** + * Each argument should be an instance of an extender that should + * be applied at application boot. + * + * Note that this method will have no effect if called after the + * application is booted. + */ protected function extend(ExtenderInterface ...$extenders) { $this->extenders = array_merge($this->extenders, $extenders); @@ -89,11 +98,40 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase */ protected $extensions = []; + /** + * Each argument should be an ID of an extension to be enabled. + * Extensions other than the one currently being tested must be + * listed in this extension's `composer.json` under `require` or + * `require-dev`. + * + * Note that this method will have no effect if called after the + * application is booted. + */ protected function extension(string ...$extensions) { $this->extensions = array_merge($this->extensions, $extensions); } + /** + * @var string[] + */ + protected $settings = []; + + /** + * Some settings are used during application boot, so setting + * them via `prepareDatabase` will be too late for the desired + * effect. For instance, in core the active display name driver + * is configured based on the `display_name_driver` setting. + * That setting should be registered using this method. + * + * Note that this method will have no effect if called after the + * application is booted. + */ + protected function setting(string $key, string $value) + { + $this->settings[$key] = $value; + } + /** * @var RequestHandlerInterface */ From 9ed29cd35ee9a4d8fc6300ffd7f63634fb35de7b Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Wed, 7 Apr 2021 15:01:55 -0400 Subject: [PATCH 52/68] Add automated tests for `flarum/testing` --- .../testing/.github/workflows/test.yml | 83 +++++++++++++++++++ php-packages/testing/composer.json | 5 ++ php-packages/testing/tests/.gitignore | 1 + php-packages/testing/tests/README.md | 1 + php-packages/testing/tests/composer.json | 35 ++++++++ php-packages/testing/tests/extend.php | 20 +++++ .../testing/tests/tests/.phpunit.result.cache | 1 + .../testing/tests/tests/fixtures/.gitkeep | 0 .../tests/tests/integration/TestCaseTest.php | 30 +++++++ .../testing/tests/tests/integration/setup.php | 16 ++++ .../tests/tests/phpunit.integration.xml | 24 ++++++ .../testing/tests/tests/phpunit.unit.xml | 27 ++++++ .../testing/tests/tests/unit/.gitkeep | 0 13 files changed, 243 insertions(+) create mode 100644 php-packages/testing/.github/workflows/test.yml create mode 100644 php-packages/testing/tests/.gitignore create mode 100644 php-packages/testing/tests/README.md create mode 100644 php-packages/testing/tests/composer.json create mode 100644 php-packages/testing/tests/extend.php create mode 100644 php-packages/testing/tests/tests/.phpunit.result.cache create mode 100644 php-packages/testing/tests/tests/fixtures/.gitkeep create mode 100644 php-packages/testing/tests/tests/integration/TestCaseTest.php create mode 100644 php-packages/testing/tests/tests/integration/setup.php create mode 100644 php-packages/testing/tests/tests/phpunit.integration.xml create mode 100644 php-packages/testing/tests/tests/phpunit.unit.xml create mode 100644 php-packages/testing/tests/tests/unit/.gitkeep diff --git a/php-packages/testing/.github/workflows/test.yml b/php-packages/testing/.github/workflows/test.yml new file mode 100644 index 000000000..b7ba28c30 --- /dev/null +++ b/php-packages/testing/.github/workflows/test.yml @@ -0,0 +1,83 @@ +name: Tests + +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + + defaults: + run: + shell: bash + working-directory: tests + + strategy: + matrix: + php: [7.3, 7.4, '8.0'] + service: ['mysql:5.7', mariadb] + prefix: ['', flarum_] + + include: + - service: 'mysql:5.7' + db: MySQL + - service: mariadb + db: MariaDB + - prefix: flarum_ + prefixStr: (prefix) + + exclude: + - php: 7.3 + service: 'mysql:5.7' + prefix: flarum_ + - php: 7.3 + service: mariadb + prefix: flarum_ + - php: 8.0 + service: 'mysql:5.7' + prefix: flarum_ + - php: 8.0 + service: mariadb + prefix: flarum_ + + services: + mysql: + image: ${{ matrix.service }} + ports: + - 13306:3306 + + name: 'PHP ${{ matrix.php }} / ${{ matrix.db }} ${{ matrix.prefixStr }}' + + steps: + - uses: actions/checkout@master + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: xdebug + extensions: curl, dom, gd, json, mbstring, openssl, pdo_mysql, tokenizer, zip + tools: phpunit, composer:v2 + + # The authentication alter is necessary because newer mysql versions use the `caching_sha2_password` driver, + # which isn't supported prior to PHP7.4 + # When we drop support for PHP7.3, we should remove this from the setup. + - name: Create MySQL Database + run: | + sudo systemctl start mysql + mysql -uroot -proot -e 'CREATE DATABASE flarum_test;' --port 13306 + mysql -uroot -proot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';" --port 13306 + + - name: Install Composer dependencies + run: composer install + + - name: Setup Composer tests + run: composer test:setup + env: + DB_PORT: 13306 + DB_PASSWORD: root + DB_PREFIX: ${{ matrix.prefix }} + + - name: Run Composer tests + run: composer test + env: + COMPOSER_PROCESS_TIMEOUT: 600 diff --git a/php-packages/testing/composer.json b/php-packages/testing/composer.json index eb29a6161..44ea9e07f 100644 --- a/php-packages/testing/composer.json +++ b/php-packages/testing/composer.json @@ -20,6 +20,11 @@ "Flarum\\Testing\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "Flarum\\Testing\\Tests\\": "src/tests/" + } + }, "extra": { "branch-alias": { "dev-master": "0.1.x-dev" diff --git a/php-packages/testing/tests/.gitignore b/php-packages/testing/tests/.gitignore new file mode 100644 index 000000000..208a59913 --- /dev/null +++ b/php-packages/testing/tests/.gitignore @@ -0,0 +1 @@ +vendor/* \ No newline at end of file diff --git a/php-packages/testing/tests/README.md b/php-packages/testing/tests/README.md new file mode 100644 index 000000000..ec93c967f --- /dev/null +++ b/php-packages/testing/tests/README.md @@ -0,0 +1 @@ +A minimal extension skeleton to test the flarum/testing package. \ No newline at end of file diff --git a/php-packages/testing/tests/composer.json b/php-packages/testing/tests/composer.json new file mode 100644 index 000000000..58baed651 --- /dev/null +++ b/php-packages/testing/tests/composer.json @@ -0,0 +1,35 @@ +{ + "name": "flarum/testing-tests", + "description": "Minimal extension to test the flarum/testing package", + "type": "flarum-extension", + "require": { + "flarum/core": "^0.1.0-beta.16" + }, + "require-dev": { + "flarum/testing": "*@dev" + }, + "autoload-dev": { + "psr-4": { + "Flarum\\Testing\\Tests\\": "tests/" + } + }, + "scripts": { + "test": [ + "@test:unit", + "@test:integration" + ], + "test:unit": "phpunit -c tests/phpunit.unit.xml", + "test:integration": "phpunit -c tests/phpunit.integration.xml", + "test:setup": "@php tests/integration/setup.php" + }, + "scripts-descriptions": { + "test": "Runs all tests.", + "test:unit": "Runs all unit tests.", + "test:integration": "Runs all integration tests.", + "test:setup": "Sets up a database for use with integration tests. Execute this only once." + }, + "repositories": [{ + "type": "path", + "url": "../" + }] +} diff --git a/php-packages/testing/tests/extend.php b/php-packages/testing/tests/extend.php new file mode 100644 index 000000000..8ece8c036 --- /dev/null +++ b/php-packages/testing/tests/extend.php @@ -0,0 +1,20 @@ +setting('hello', 'world'); + $this->setting('display_name_driver', 'something_other_than_username'); + + $settings = $this->app()->getContainer()->make(SettingsRepositoryInterface::class); + + $this->assertEquals('world', $settings->get('hello')); + $this->assertEquals('something_other_than_username', $settings->get('display_name_driver')); + } +} \ No newline at end of file diff --git a/php-packages/testing/tests/tests/integration/setup.php b/php-packages/testing/tests/tests/integration/setup.php new file mode 100644 index 000000000..67039c083 --- /dev/null +++ b/php-packages/testing/tests/tests/integration/setup.php @@ -0,0 +1,16 @@ +run(); diff --git a/php-packages/testing/tests/tests/phpunit.integration.xml b/php-packages/testing/tests/tests/phpunit.integration.xml new file mode 100644 index 000000000..23afc237d --- /dev/null +++ b/php-packages/testing/tests/tests/phpunit.integration.xml @@ -0,0 +1,24 @@ + + + + + ../src/ + + + + + ./integration + + + diff --git a/php-packages/testing/tests/tests/phpunit.unit.xml b/php-packages/testing/tests/tests/phpunit.unit.xml new file mode 100644 index 000000000..d3a4a3e3d --- /dev/null +++ b/php-packages/testing/tests/tests/phpunit.unit.xml @@ -0,0 +1,27 @@ + + + + + ../src/ + + + + + ./unit + + + + + + diff --git a/php-packages/testing/tests/tests/unit/.gitkeep b/php-packages/testing/tests/tests/unit/.gitkeep new file mode 100644 index 000000000..e69de29bb From f2101e502ef2d4f63da1082ff01d5485f5a29915 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com> Date: Thu, 8 Apr 2021 18:39:21 -0400 Subject: [PATCH 53/68] Don't enable extensions during installation (#7) --- php-packages/testing/src/integration/Setup/SetupScript.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php-packages/testing/src/integration/Setup/SetupScript.php b/php-packages/testing/src/integration/Setup/SetupScript.php index ca9b302f9..ffde8d9f0 100644 --- a/php-packages/testing/src/integration/Setup/SetupScript.php +++ b/php-packages/testing/src/integration/Setup/SetupScript.php @@ -115,6 +115,7 @@ class SetupScript 'admin@machine.local' )) ->settings(['mail_driver' => 'log']) + ->extensions([]) ->build(); // Run the actual configuration From f13d45f77bc71030bd8857308225b779dd8d7a1b Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Sun, 11 Apr 2021 22:47:09 -0400 Subject: [PATCH 54/68] Test against dev version of core Since we're making changes for the dev version of core, we should test against that too. For now, this fixes issues with the `extensions` method of `Installation` being undefined. --- php-packages/testing/composer.json | 2 +- php-packages/testing/tests/composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php-packages/testing/composer.json b/php-packages/testing/composer.json index 44ea9e07f..212490bc2 100644 --- a/php-packages/testing/composer.json +++ b/php-packages/testing/composer.json @@ -13,7 +13,7 @@ "phpunit/phpunit": "^9.0" }, "require-dev": { - "flarum/core": "^0.1.0-beta" + "flarum/core": "*@dev" }, "autoload": { "psr-4": { diff --git a/php-packages/testing/tests/composer.json b/php-packages/testing/tests/composer.json index 58baed651..cc8ba7bb9 100644 --- a/php-packages/testing/tests/composer.json +++ b/php-packages/testing/tests/composer.json @@ -3,7 +3,7 @@ "description": "Minimal extension to test the flarum/testing package", "type": "flarum-extension", "require": { - "flarum/core": "^0.1.0-beta.16" + "flarum/core": "^0.1.0@dev" }, "require-dev": { "flarum/testing": "*@dev" From 675627ac15588bab1ae6ecfbfcc599bef12ba9e2 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Sun, 11 Apr 2021 23:00:36 -0400 Subject: [PATCH 55/68] Add a few more automated tests --- php-packages/testing/tests/extend.php | 4 +- .../tests/tests/integration/TestCaseTest.php | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/php-packages/testing/tests/extend.php b/php-packages/testing/tests/extend.php index 8ece8c036..075d35db5 100644 --- a/php-packages/testing/tests/extend.php +++ b/php-packages/testing/tests/extend.php @@ -14,7 +14,5 @@ namespace Flarum\Testing; use Flarum\Extend; return [ - - - + (new Extend\Settings)->serializeToForum('notARealSetting', 'not.a.real.setting') ]; diff --git a/php-packages/testing/tests/tests/integration/TestCaseTest.php b/php-packages/testing/tests/tests/integration/TestCaseTest.php index 4aa709da1..374cd5db3 100644 --- a/php-packages/testing/tests/tests/integration/TestCaseTest.php +++ b/php-packages/testing/tests/tests/integration/TestCaseTest.php @@ -9,11 +9,29 @@ namespace Flarum\Testing\Tests\integration; +use Flarum\Extend; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Testing\integration\TestCase; +use Flarum\User\User; class TestCaseTest extends TestCase { + /** + * @test + */ + public function admin_user_created_as_part_of_default_state() + { + $this->app(); + + $this->assertEquals(1, User::query()->count()); + + $user = User::find(1); + + $this->assertEquals('admin', $user->username); + $this->assertEquals('admin@machine.local', $user->email); + $this->assertTrue($user->isAdmin()); + } + /** * @test */ @@ -27,4 +45,46 @@ class TestCaseTest extends TestCase $this->assertEquals('world', $settings->get('hello')); $this->assertEquals('something_other_than_username', $settings->get('display_name_driver')); } + + /** + * @test + */ + public function current_extension_not_applied_by_default() + { + $response = $this->send( + $this->request('GET', '/') + ); + + $this->assertStringNotContainsString('notARealSetting', $response->getBody()->getContents()); + } + + /** + * @test + */ + public function current_extension_applied_if_specified() + { + $this->extension('flarum-testing-tests'); + + $response = $this->send( + $this->request('GET', '/') + ); + + $this->assertStringContainsString('notARealSetting', $response->getBody()->getContents()); + } + + /** + * @test + */ + public function can_apply_extenders() + { + $this->extend( + (new Extend\Settings)->serializeToForum('notARealSetting', 'not.a.real.setting') + ); + + $response = $this->send( + $this->request('GET', '/') + ); + + $this->assertStringContainsString('notARealSetting', $response->getBody()->getContents()); + } } \ No newline at end of file From 76a869a198b7a8573722bb872d55c89fafab31e4 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com> Date: Mon, 12 Apr 2021 10:26:05 -0400 Subject: [PATCH 56/68] Start transactions before the app is fully booted. (#11) This make a cleaner state more likely, and ensures that settings set via `$this->setting` are cleaned up after the test case runs. --- .../Extend/BeginTransactionAndSetDatabase.php | 30 +++++++++++++++++++ .../testing/src/integration/TestCase.php | 11 ++++--- .../tests/tests/integration/TestCaseTest.php | 11 +++++++ 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 php-packages/testing/src/integration/Extend/BeginTransactionAndSetDatabase.php diff --git a/php-packages/testing/src/integration/Extend/BeginTransactionAndSetDatabase.php b/php-packages/testing/src/integration/Extend/BeginTransactionAndSetDatabase.php new file mode 100644 index 000000000..cc088686f --- /dev/null +++ b/php-packages/testing/src/integration/Extend/BeginTransactionAndSetDatabase.php @@ -0,0 +1,30 @@ +setDbOnTestCase = $setDbOnTestCase; + } + + public function extend(Container $container, Extension $extension = null) + { + $db = $container->make(ConnectionInterface::class); + + $db->beginTransaction(); + + ($this->setDbOnTestCase)($db); + } +} diff --git a/php-packages/testing/src/integration/TestCase.php b/php-packages/testing/src/integration/TestCase.php index d54a90a37..68896d443 100644 --- a/php-packages/testing/src/integration/TestCase.php +++ b/php-packages/testing/src/integration/TestCase.php @@ -13,6 +13,7 @@ use Flarum\Extend\ExtenderInterface; use Flarum\Foundation\Config; use Flarum\Foundation\InstalledSite; use Flarum\Foundation\Paths; +use Flarum\Testing\integration\Extend\BeginTransactionAndSetDatabase; use Flarum\Testing\integration\Extend\OverrideExtensionManagerForTests; use Flarum\Testing\integration\Extend\SetSettingsBeforeBoot; use Illuminate\Database\ConnectionInterface; @@ -61,6 +62,9 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase $extenders = array_merge([ new OverrideExtensionManagerForTests($this->extensions), + new BeginTransactionAndSetDatabase(function (ConnectionInterface $db) { + $this->database = $db; + }), new SetSettingsBeforeBoot($this->settings), ], $this->extenders); @@ -150,12 +154,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase protected function database(): ConnectionInterface { - if (is_null($this->database)) { - $this->database = $this->app()->getContainer()->make( - ConnectionInterface::class - ); - } - + // Set in `BeginTransactionAndSetDatabase` extender. return $this->database; } diff --git a/php-packages/testing/tests/tests/integration/TestCaseTest.php b/php-packages/testing/tests/tests/integration/TestCaseTest.php index 374cd5db3..eb4e2f53e 100644 --- a/php-packages/testing/tests/tests/integration/TestCaseTest.php +++ b/php-packages/testing/tests/tests/integration/TestCaseTest.php @@ -46,6 +46,17 @@ class TestCaseTest extends TestCase $this->assertEquals('something_other_than_username', $settings->get('display_name_driver')); } + /** + * @test + */ + public function settings_cleaned_up_from_previous_method() + { + $settings = $this->app()->getContainer()->make(SettingsRepositoryInterface::class); + + $this->assertEquals(null, $settings->get('hello')); + $this->assertEquals(null, $settings->get('display_name_driver')); + } + /** * @test */ From b2ecb8f020461739b74c837f9b2ce1f631fdf08c Mon Sep 17 00:00:00 2001 From: Sami Mazouz Date: Wed, 14 Apr 2021 04:46:04 +0100 Subject: [PATCH 57/68] Remove UsesSettingsTrait (#12) --- .../testing/src/integration/UsesSettings.php | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 php-packages/testing/src/integration/UsesSettings.php diff --git a/php-packages/testing/src/integration/UsesSettings.php b/php-packages/testing/src/integration/UsesSettings.php deleted file mode 100644 index 66b49cf9e..000000000 --- a/php-packages/testing/src/integration/UsesSettings.php +++ /dev/null @@ -1,25 +0,0 @@ -app()->getContainer()->forgetInstance(SettingsRepositoryInterface::class); - } -} From 8fd1cc4f0dd47858daf16e35ef7daf9517c43457 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com> Date: Wed, 14 Apr 2021 16:27:59 -0400 Subject: [PATCH 58/68] TestCase Config method (#13) Similarly to `settings`, this allows setting/overriding config prior to application boot. --- .../testing/src/integration/TestCase.php | 43 +++++++++++++++++-- .../tests/tests/integration/TestCaseTest.php | 29 +++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/php-packages/testing/src/integration/TestCase.php b/php-packages/testing/src/integration/TestCase.php index 68896d443..45bdc6030 100644 --- a/php-packages/testing/src/integration/TestCase.php +++ b/php-packages/testing/src/integration/TestCase.php @@ -17,6 +17,7 @@ use Flarum\Testing\integration\Extend\BeginTransactionAndSetDatabase; use Flarum\Testing\integration\Extend\OverrideExtensionManagerForTests; use Flarum\Testing\integration\Extend\SetSettingsBeforeBoot; use Illuminate\Database\ConnectionInterface; +use Illuminate\Support\Arr; use Laminas\Diactoros\ServerRequest; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -50,6 +51,12 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase if (is_null($this->app)) { $tmp = $this->tmpDir(); + $config = include "$tmp/config.php"; + + foreach ($this->config as $key => $value) { + Arr::set($config, $key, $value); + } + $site = new InstalledSite( new Paths([ 'base' => $tmp, @@ -57,7 +64,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase 'storage' => "$tmp/storage", 'vendor' => getcwd().'/vendor', ]), - new Config(include "$tmp/config.php") + new Config($config) ); $extenders = array_merge([ @@ -117,7 +124,37 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase } /** - * @var string[] + * @var array + */ + protected $config = []; + + /** + * Some Flarum code depends on config.php values. Flarum doesn't + * offer a way to set them at runtime, so this method lets you + * add/override them before boot. + * + * You can use dot-separated syntax to assign values to subarrays. + * + * For example: + * + * `$this->config('a.b.c', 'value');` will result in the following: + * + * [ + * 'a' => [ + * 'b' => ['c' => 'value'] + * ] + * ] + * + * Note that this method will have no effect if called after the + * application is booted. + */ + protected function config(string $key, $value) + { + $this->config[$key] = $value; + } + + /** + * @var array */ protected $settings = []; @@ -131,7 +168,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase * Note that this method will have no effect if called after the * application is booted. */ - protected function setting(string $key, string $value) + protected function setting(string $key, $value) { $this->settings[$key] = $value; } diff --git a/php-packages/testing/tests/tests/integration/TestCaseTest.php b/php-packages/testing/tests/tests/integration/TestCaseTest.php index eb4e2f53e..f301b77c3 100644 --- a/php-packages/testing/tests/tests/integration/TestCaseTest.php +++ b/php-packages/testing/tests/tests/integration/TestCaseTest.php @@ -10,6 +10,7 @@ namespace Flarum\Testing\Tests\integration; use Flarum\Extend; +use Flarum\Foundation\Config; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Testing\integration\TestCase; use Flarum\User\User; @@ -57,6 +58,34 @@ class TestCaseTest extends TestCase $this->assertEquals(null, $settings->get('display_name_driver')); } + /** + * @test + */ + public function can_add_config_via_method() + { + $this->config('hello', 'world'); + $this->config('url', 'https://flarum.org'); + $this->config('level1.level2', 'value'); + + $config = $this->app()->getContainer()->make(Config::class); + + $this->assertEquals('world', $config['hello']); + $this->assertEquals('https://flarum.org', $config['url']); + $this->assertEquals('value', $config['level1']['level2']); + } + + /** + * @test + */ + public function config_cleaned_up_from_previous_method() + { + $config = $this->app()->getContainer()->make(Config::class); + + $this->assertEquals(null, $config['hello']); + $this->assertEquals('http://localhost', $config['url']); + $this->assertFalse(isset($config['level1']['level2'])); + } + /** * @test */ From 0569da23e163c78d88edec77a5245f5b48d3bf2c Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com> Date: Tue, 20 Apr 2021 14:47:07 -0400 Subject: [PATCH 59/68] Drop all DB tables before installation during setup. (#9) This ensures a clean state for the extension currently being tested. The alternative requires the user to create and keep track of multiple test databases, or manually delete/re-recreate the database every time they switch between extensions being tested. Now, a simple `composer test:setup` will always reset the test environment to the original state. --- .../src/integration/Setup/SetupScript.php | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/php-packages/testing/src/integration/Setup/SetupScript.php b/php-packages/testing/src/integration/Setup/SetupScript.php index ffde8d9f0..931a6af12 100644 --- a/php-packages/testing/src/integration/Setup/SetupScript.php +++ b/php-packages/testing/src/integration/Setup/SetupScript.php @@ -14,6 +14,7 @@ use Flarum\Install\AdminUser; use Flarum\Install\BaseUrl; use Flarum\Install\DatabaseConfig; use Flarum\Install\Installation; +use Flarum\Install\Steps\ConnectToDatabase; use Flarum\Testing\integration\UsesTmpDir; class SetupScript @@ -62,6 +63,11 @@ class SetupScript */ protected $pref; + /** + * @var DatabaseConfig + */ + private $dbConfig; + public function __construct() { $this->host = getenv('DB_HOST') ?: 'localhost'; @@ -77,6 +83,7 @@ class SetupScript $tmp = $this->tmpDir(); echo "Connecting to database $this->name at $this->host:$this->port.\n"; + echo "Warning: all tables will be dropped to ensure clean state. DO NOT use your production database!\n"; echo "Logging in as $this->user with password '$this->pass'.\n"; echo "Table prefix: '$this->pref'\n"; echo "\nStoring test config in '$tmp'\n"; @@ -91,6 +98,12 @@ class SetupScript echo "\nOff we go...\n"; + $this->dbConfig = new DatabaseConfig('mysql', $this->host, $this->port, $this->name, $this->user, $this->pass, $this->pref); + + echo "\nWiping DB to ensure clean state\n"; + $this->wipeDb(); + echo "Success! Proceeding to installation...\n"; + $this->setupTmpDir(); $installation = new Installation( @@ -98,7 +111,7 @@ class SetupScript 'base' => $tmp, 'public' => "$tmp/public", 'storage' => "$tmp/storage", - 'vendor' => getcwd().'/vendor', + 'vendor' => getcwd() . '/vendor', ]) ); @@ -106,9 +119,7 @@ class SetupScript ->configPath('config.php') ->debugMode(true) ->baseUrl(BaseUrl::fromString('http://localhost')) - ->databaseConfig( - new DatabaseConfig('mysql', $this->host, $this->port, $this->name, $this->user, $this->pass, $this->pref) - ) + ->databaseConfig($this->dbConfig) ->adminUser(new AdminUser( 'admin', 'password', @@ -123,4 +134,16 @@ class SetupScript echo "Installation complete\n"; } + + protected function wipeDb() + { + // Reuse the connection step to include version checks + (new ConnectToDatabase($this->dbConfig, function ($db) { + // Inspired by Laravel's db:wipe + $builder = $db->getSchemaBuilder(); + + $builder->dropAllTables(); + $builder->dropAllViews(); + }))->run(); + } } From 04b04f3635d7d670892ad84c785872cebe004496 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Fri, 23 Apr 2021 15:20:29 -0400 Subject: [PATCH 60/68] Ensure app is booted when getting database --- php-packages/testing/src/integration/TestCase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php-packages/testing/src/integration/TestCase.php b/php-packages/testing/src/integration/TestCase.php index 45bdc6030..ae1315d99 100644 --- a/php-packages/testing/src/integration/TestCase.php +++ b/php-packages/testing/src/integration/TestCase.php @@ -191,6 +191,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase protected function database(): ConnectionInterface { + $this->app(); // Set in `BeginTransactionAndSetDatabase` extender. return $this->database; } From 148f810d960f8b4b3ddd638a20890c05b2a99ec9 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Fri, 23 Apr 2021 18:26:41 -0400 Subject: [PATCH 61/68] Don't resolve routes early. In normal Flarum, extensions are only enabled during requests. Here, however, we enable some during boot. This resolves the FilesystemManager early, which resolves the Url Generator early. To fix this, we directly provide a filesystem disk for assets instead of getting it from the filesystem manager. --- .../ExtensionManagerIncludeCurrent.php | 14 +++++ php-packages/testing/tests/extend.php | 3 +- .../tests/tests/integration/TestCaseTest.php | 57 +++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php index c7a4169f3..75fa63a27 100644 --- a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php +++ b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php @@ -11,7 +11,11 @@ namespace Flarum\Testing\integration\Extension; use Flarum\Extension\Extension; use Flarum\Extension\ExtensionManager; +use Illuminate\Contracts\Filesystem\Cloud; +use Illuminate\Filesystem\FilesystemAdapter; use Illuminate\Support\Arr; +use League\Flysystem\Adapter\Local; +use League\Flysystem\Filesystem; class ExtensionManagerIncludeCurrent extends ExtensionManager { @@ -39,4 +43,14 @@ class ExtensionManagerIncludeCurrent extends ExtensionManager return $this->extensions; } + + /** + * Get an instance of the assets filesystem. + * This is resolved dynamically because Flarum's filesystem configuration + * might not be booted yet when the ExtensionManager singleton initializes. + */ + protected function getAssetsFilesystem(): Cloud + { + return new FilesystemAdapter(new Filesystem(new Local($this->paths->public.'/assets'), ['url' => resolve('flarum.config')->url().'/assets'])); + } } diff --git a/php-packages/testing/tests/extend.php b/php-packages/testing/tests/extend.php index 075d35db5..9c49c556f 100644 --- a/php-packages/testing/tests/extend.php +++ b/php-packages/testing/tests/extend.php @@ -14,5 +14,6 @@ namespace Flarum\Testing; use Flarum\Extend; return [ - (new Extend\Settings)->serializeToForum('notARealSetting', 'not.a.real.setting') + (new Extend\Settings)->serializeToForum('notARealSetting', 'not.a.real.setting'), + (new Extend\Frontend('forum'))->route('/added-by-extension', 'added-by-extension') ]; diff --git a/php-packages/testing/tests/tests/integration/TestCaseTest.php b/php-packages/testing/tests/tests/integration/TestCaseTest.php index f301b77c3..9efd32302 100644 --- a/php-packages/testing/tests/tests/integration/TestCaseTest.php +++ b/php-packages/testing/tests/tests/integration/TestCaseTest.php @@ -127,4 +127,61 @@ class TestCaseTest extends TestCase $this->assertStringContainsString('notARealSetting', $response->getBody()->getContents()); } + + /** + * @test + */ + public function can_apply_route_extenders() + { + $this->extend( + (new Extend\Frontend('forum'))->route('/arbitrary', 'arbitrary') + ); + + $response = $this->send( + $this->request('GET', '/arbitrary') + ); + + $this->assertEquals(200, $response->getStatusCode()); + } + + /** + * @test + */ + public function routes_added_by_current_extension_not_accessible_by_default() + { + $response = $this->send( + $this->request('GET', '/added-by-extension') + ); + + $this->assertEquals(404, $response->getStatusCode()); + } + + /** + * @test + */ + public function routes_added_by_current_extension_accessible() + { + $this->extension('flarum-testing-tests'); + + $response = $this->send( + $this->request('GET', '/added-by-extension') + ); + + $this->assertEquals(200, $response->getStatusCode()); + } + + /** + * @test + */ + public function extension_url_correct() + { + $this->extension('flarum-testing-tests'); + $expected = $this->app()->getContainer()->make('filesystem')->disk('flarum-assets')->url('/flarum-testing-tests/'); + // We need to test this since we override it. + $extensions = $this->app()->getContainer()->make('flarum.extensions'); + $currExtension = $extensions->getExtension('flarum-testing-tests'); + $baseAssetsUrl = $extensions->getAsset($currExtension, ''); + + $this->assertEquals($expected, $baseAssetsUrl); + } } \ No newline at end of file From bd613ba70c760f7443d5b89a3d1a0af3bbdb2021 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Mon, 3 May 2021 01:27:06 -0400 Subject: [PATCH 62/68] Remove second beginTransaction The transaction is already started in the proper `BeginTransactionAndSetDatabase` extender. --- php-packages/testing/src/integration/TestCase.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/php-packages/testing/src/integration/TestCase.php b/php-packages/testing/src/integration/TestCase.php index ae1315d99..034db0f3f 100644 --- a/php-packages/testing/src/integration/TestCase.php +++ b/php-packages/testing/src/integration/TestCase.php @@ -79,8 +79,6 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase $this->app = $site->bootApp(); - $this->database()->beginTransaction(); - $this->populateDatabase(); } From 5febbf8fb15a4a5f6b63517c8aeea8df441b43ce Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Tue, 11 May 2021 16:24:27 -0400 Subject: [PATCH 63/68] get/set enabled extensions from test case, not DB --- .../OverrideExtensionManagerForTests.php | 1 + .../ExtensionManagerIncludeCurrent.php | 44 ++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php b/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php index de3c7abbe..49bc5ac86 100644 --- a/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php +++ b/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php @@ -22,6 +22,7 @@ class OverrideExtensionManagerForTests implements ExtenderInterface public function extend(Container $container, Extension $extension = null) { + $container->when(ExtensionManagerIncludeCurrent::class)->needs('$enabledIds')->give($this->extensions); if (count($this->extensions)) { $container->singleton(ExtensionManager::class, ExtensionManagerIncludeCurrent::class); $extensionManager = $container->make(ExtensionManager::class); diff --git a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php index 75fa63a27..cfc00d71e 100644 --- a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php +++ b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php @@ -9,16 +9,41 @@ namespace Flarum\Testing\integration\Extension; +use Flarum\Database\Migrator; use Flarum\Extension\Extension; use Flarum\Extension\ExtensionManager; +use Flarum\Foundation\Paths; +use Flarum\Settings\SettingsRepositoryInterface; +use Illuminate\Contracts\Container\Container; +use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Filesystem\Cloud; +use Illuminate\Filesystem\Filesystem; use Illuminate\Filesystem\FilesystemAdapter; use Illuminate\Support\Arr; use League\Flysystem\Adapter\Local; -use League\Flysystem\Filesystem; +use League\Flysystem\Filesystem as FlysystemFilesystem; class ExtensionManagerIncludeCurrent extends ExtensionManager { + /** + * @var array + */ + protected $enabledIds; + + public function __construct( + SettingsRepositoryInterface $config, + Paths $paths, + Container $container, + Migrator $migrator, + Dispatcher $dispatcher, + Filesystem $filesystem, + array $enabledIds + ) { + parent::__construct($config, $paths, $container, $migrator, $dispatcher, $filesystem); + + $this->enabledIds = $enabledIds; + } + /** * @{@inheritDoc} */ @@ -44,6 +69,21 @@ class ExtensionManagerIncludeCurrent extends ExtensionManager return $this->extensions; } + /** + * In test cases, enabled extensions are determined by the test case, not the database. + */ + public function getEnabled() + { + return $this->enabledIds; + } + + /** + * Enabled extensions must be specified by the test case, so this should do nothing. + */ + protected function setEnabledExtensions(array $enabledExtensions) + { + } + /** * Get an instance of the assets filesystem. * This is resolved dynamically because Flarum's filesystem configuration @@ -51,6 +91,6 @@ class ExtensionManagerIncludeCurrent extends ExtensionManager */ protected function getAssetsFilesystem(): Cloud { - return new FilesystemAdapter(new Filesystem(new Local($this->paths->public.'/assets'), ['url' => resolve('flarum.config')->url().'/assets'])); + return new FilesystemAdapter(new FlysystemFilesystem(new Local($this->paths->public . '/assets'), ['url' => resolve('flarum.config')->url() . '/assets'])); } } From d68d551e1632594c5763eadb13b551a9bc2f3520 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Tue, 11 May 2021 17:15:11 -0400 Subject: [PATCH 64/68] Ensure that migrations run --- .../Extension/ExtensionManagerIncludeCurrent.php | 8 ++++++++ ...00000_create_table_so_we_can_check_existence.php | 10 ++++++++++ .../tests/tests/integration/TestCaseTest.php | 13 +++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 php-packages/testing/tests/migrations/2021_05_11_000000_create_table_so_we_can_check_existence.php diff --git a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php index cfc00d71e..8031d20f9 100644 --- a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php +++ b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php @@ -69,6 +69,14 @@ class ExtensionManagerIncludeCurrent extends ExtensionManager return $this->extensions; } + /** + * Since we enable every time, we always assume it's not enabled. + */ + public function isEnabled($extension) + { + return false; + } + /** * In test cases, enabled extensions are determined by the test case, not the database. */ diff --git a/php-packages/testing/tests/migrations/2021_05_11_000000_create_table_so_we_can_check_existence.php b/php-packages/testing/tests/migrations/2021_05_11_000000_create_table_so_we_can_check_existence.php new file mode 100644 index 000000000..649dff1b9 --- /dev/null +++ b/php-packages/testing/tests/migrations/2021_05_11_000000_create_table_so_we_can_check_existence.php @@ -0,0 +1,10 @@ +string('id', 100)->primary(); +}); \ No newline at end of file diff --git a/php-packages/testing/tests/tests/integration/TestCaseTest.php b/php-packages/testing/tests/tests/integration/TestCaseTest.php index 9efd32302..af7f6252b 100644 --- a/php-packages/testing/tests/tests/integration/TestCaseTest.php +++ b/php-packages/testing/tests/tests/integration/TestCaseTest.php @@ -14,6 +14,8 @@ use Flarum\Foundation\Config; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Testing\integration\TestCase; use Flarum\User\User; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Schema\Builder; class TestCaseTest extends TestCase { @@ -112,6 +114,17 @@ class TestCaseTest extends TestCase $this->assertStringContainsString('notARealSetting', $response->getBody()->getContents()); } + /** + * @test + */ + public function current_extension_migrations_applied_if_specified() + { + $this->extension('flarum-testing-tests'); + + $tableExists = $this->app()->getContainer()->make(Builder::class)->hasTable('testing_table'); + $this->assertTrue($tableExists); + } + /** * @test */ From ce7484e2c86541d74d52d30e4f37b0b20190ef0c Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Tue, 11 May 2021 19:31:35 -0400 Subject: [PATCH 65/68] Extensions should be considered enabled after boot. Before boot, we consider them "disabled" so they get migrated. --- .../Extend/OverrideExtensionManagerForTests.php | 2 ++ .../Extension/ExtensionManagerIncludeCurrent.php | 13 +++++++++++-- .../tests/tests/integration/TestCaseTest.php | 11 +++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php b/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php index 49bc5ac86..8d66e7319 100644 --- a/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php +++ b/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php @@ -31,6 +31,8 @@ class OverrideExtensionManagerForTests implements ExtenderInterface $extensionManager->enable($extension); } + $extensionManager->booted = true; + $extensionManager->extend($container); } } diff --git a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php index 8031d20f9..1a3dbc8f0 100644 --- a/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php +++ b/php-packages/testing/src/integration/Extension/ExtensionManagerIncludeCurrent.php @@ -30,6 +30,11 @@ class ExtensionManagerIncludeCurrent extends ExtensionManager */ protected $enabledIds; + /** + * @var bool + */ + public $booted = false; + public function __construct( SettingsRepositoryInterface $config, Paths $paths, @@ -70,11 +75,15 @@ class ExtensionManagerIncludeCurrent extends ExtensionManager } /** - * Since we enable every time, we always assume it's not enabled. + * We assume it's not enabled during boot. + * However, since some logic needs this, as soon as we enable extensions + * we'll switch booted to on. */ public function isEnabled($extension) { - return false; + if (!$this->booted) return false; + + return parent::isEnabled($extension); } /** diff --git a/php-packages/testing/tests/tests/integration/TestCaseTest.php b/php-packages/testing/tests/tests/integration/TestCaseTest.php index af7f6252b..2b7c3814e 100644 --- a/php-packages/testing/tests/tests/integration/TestCaseTest.php +++ b/php-packages/testing/tests/tests/integration/TestCaseTest.php @@ -125,6 +125,17 @@ class TestCaseTest extends TestCase $this->assertTrue($tableExists); } + /** + * @test + */ + public function current_extension_considered_enabled_after_boot() + { + $this->extension('flarum-testing-tests'); + + $enabled = $this->app()->getContainer()->make('flarum.extensions')->isEnabled('flarum-testing-tests'); + $this->assertTrue($enabled); + } + /** * @test */ From f2398017a7f4a3b698483f9ad6e08af36bc85a32 Mon Sep 17 00:00:00 2001 From: David Wheatley Date: Sat, 15 May 2021 00:58:25 +0100 Subject: [PATCH 66/68] Update copyright year --- php-packages/testing/LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-packages/testing/LICENSE b/php-packages/testing/LICENSE index 4bc2a96d2..9fe7ef1c7 100755 --- a/php-packages/testing/LICENSE +++ b/php-packages/testing/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2020 Stichting Flarum (Flarum Foundation) +Copyright (c) 2020-2021 Stichting Flarum (Flarum Foundation) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 8eb5cfd062d9146ee2aed11c2a8d0530d8aed86e Mon Sep 17 00:00:00 2001 From: Daniel Klabbers Date: Tue, 25 May 2021 22:59:06 +0200 Subject: [PATCH 67/68] fix branch alias --- php-packages/testing/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-packages/testing/composer.json b/php-packages/testing/composer.json index 212490bc2..831dcd88c 100644 --- a/php-packages/testing/composer.json +++ b/php-packages/testing/composer.json @@ -27,7 +27,7 @@ }, "extra": { "branch-alias": { - "dev-master": "0.1.x-dev" + "dev-master": "1.x-dev" } } } From 23dc0d718248270ee8be8d664dfba52ef160a2b7 Mon Sep 17 00:00:00 2001 From: Daniel Klabbers Date: Mon, 21 Jun 2021 09:32:27 +0200 Subject: [PATCH 68/68] allow empty db password "" again --- php-packages/testing/src/integration/Setup/SetupScript.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-packages/testing/src/integration/Setup/SetupScript.php b/php-packages/testing/src/integration/Setup/SetupScript.php index 931a6af12..0767db596 100644 --- a/php-packages/testing/src/integration/Setup/SetupScript.php +++ b/php-packages/testing/src/integration/Setup/SetupScript.php @@ -74,7 +74,7 @@ class SetupScript $this->port = intval(getenv('DB_PORT') ?: 3306); $this->name = getenv('DB_DATABASE') ?: 'flarum_test'; $this->user = getenv('DB_USERNAME') ?: 'root'; - $this->pass = getenv('DB_PASSWORD') ?: 'root'; + $this->pass = getenv('DB_PASSWORD') ?? 'root'; $this->pref = getenv('DB_PREFIX') ?: ''; }