From f15f33c9206f33e143d69e2bbc410c6cafd43041 Mon Sep 17 00:00:00 2001 From: Luca Tumedei Date: Wed, 29 Nov 2023 10:03:08 +0100 Subject: [PATCH] feat(WPLoader) add support for the skipInstall parameter --- docs/modules/WPLoader.md | 1 + includes/core-phpunit/wp-tests-config.php | 9 +- src/Module/WPLoader.php | 138 +++-- src/Process/StderrStream.php | 2 +- src/Process/StderrStream/TraceEntry.php | 24 + src/WordPress/Database/MysqlDatabase.php | 9 +- .../Traits/MainInstallationAccess.php | 25 +- .../WPBrowser/Events/Module/WPLoaderTest.php | 474 ++++++++++++------ 8 files changed, 463 insertions(+), 219 deletions(-) diff --git a/docs/modules/WPLoader.md b/docs/modules/WPLoader.md index a92cf1d0a..6cbe58227 100644 --- a/docs/modules/WPLoader.md +++ b/docs/modules/WPLoader.md @@ -86,6 +86,7 @@ When used in this mode, the module supports the following configuration paramete * `backupGlobalsExcludeList` - a list of global variables to exclude from the global environment backup. The list must be in the form of array, and it will be merged to the list of globals excluded by default. * `backupStaticAttributes` - a boolean value to indicate if static attributes of classes should be backed up before each test. Defaults to `true`. The static attributes' backup involves serialization of the global state, plugins or themes that define classes developed to prevent serialization of the global state will cause the tests to fail. Set this parameter to `false` to disable the static attributes backup, or use a more refined approanch setting the `backupStaticAttributesExcludeList` parameter below. Note that a test case that is explicitly setting the `backupStaticAttributes` property will override this configuration parameter. * `backupStaticAttributesExcludeList` - a list of classes to exclude from the static attributes backup. The list must be in the form of map from class names to the array of method names to exclude from the backup. See an example below. +* `skipInstall` - a boolean value to indicate if the WordPress installation should be skipped between runs, when already installed. Defaults to `false`. During boot, the `WPLoader` module will re-install WordPress and activate, on top of the fresh installation, any plugin and theme specified in the `plugins` and `theme` configuration parameters: this can be a time-consuming operation. Set this parameter to `true` to run the WordPress installation once and just load it on the following runs. To force the installation to run again, rerun the suite using the WPLoader module using the `--debug` flag or delete the `_wploader-state.sql` file in the suite directory. This configuration parameter is ignored when the `loadOnly` parameter is set to `true`. This is an example of an integration suite configured to use the module: diff --git a/includes/core-phpunit/wp-tests-config.php b/includes/core-phpunit/wp-tests-config.php index 9e58925d5..0e64ab9b4 100644 --- a/includes/core-phpunit/wp-tests-config.php +++ b/includes/core-phpunit/wp-tests-config.php @@ -99,13 +99,8 @@ * The `WP_MULTISITE` constant should not be defined at this stage: it will be picked up by the scripts from * environment variables and defined in the tests bootstrap scripts. */ -foreach ([ - 'WP_MULTISITE' => (int)$wpLoaderConfig['multisite'], - 'WP_TESTS_SKIP_INSTALL' => 0 - ] as $envVar => $value) { - putenv($envVar . '=' . $value); -} -unset($envVar); +$value = (int)$wpLoaderConfig['multisite']; +putenv('WP_MULTISITE' . '=' . $value); /* * This file will be included a first time by the Core PHPUnit suite bootstrap file, and then diff --git a/src/Module/WPLoader.php b/src/Module/WPLoader.php index f02687f68..ec9ceee9b 100644 --- a/src/Module/WPLoader.php +++ b/src/Module/WPLoader.php @@ -124,6 +124,7 @@ class WPLoader extends Module * backupGlobalsExcludeList?: string[], * backupStaticAttributes?: bool, * backupStaticAttributesExcludeList?: array, + * skipInstall?: bool, * } */ protected array $config = [ @@ -160,6 +161,7 @@ class WPLoader extends Module 'backupGlobalsExcludeList' => [], 'backupStaticAttributes' => true, 'backupStaticAttributesExcludeList' => [], + 'skipInstall' => false ]; private string $wpBootstrapFile; @@ -169,6 +171,7 @@ class WPLoader extends Module private string $installationOutput = ''; private bool $earlyExit = true; private ?DatabaseInterface $db = null; + private ?CodeExecutionFactory $codeExecutionFactory = null; public function _getBootstrapOutput(): string { @@ -271,6 +274,14 @@ protected function validateConfig(): void ); } + if (isset($this->config['skipInstall']) + && !is_bool($this->config['skipInstall'])) { + throw new ModuleConfigException( + __CLASS__, + 'The `skipInstall` configuration parameter must be a boolean.' + ); + } + parent::validateConfig(); } @@ -330,6 +341,7 @@ public function _initialize(): void * backupGlobalsExcludeList: string[], * backupStaticAttributes: bool, * backupStaticAttributesExcludeList: array, + * skipInstall: bool * } $config */ $config = $this->config; @@ -526,16 +538,16 @@ private function loadWordPress(bool $loadOnly = false): void * The value will first look at the `WP_PLUGIN_DIR` constant, then the `pluginsFolder` configuration parameter * and will, finally, look in the default path from the WordPress root directory. * - * @param string $path A relative path to append to te plugins directory absolute path. - * - * @return string The absolute path to the `pluginsFolder` path or the same with a relative path appended if `$path` - * is provided. * @example * ```php * $plugins = $this->getPluginsFolder(); * $hello = $this->getPluginsFolder('hello.php'); * ``` * + * @param string $path A relative path to append to te plugins directory absolute path. + * + * @return string The absolute path to the `pluginsFolder` path or the same with a relative path appended if `$path` + * is provided. */ public function getPluginsFolder(string $path = ''): string { @@ -545,16 +557,16 @@ public function getPluginsFolder(string $path = ''): string /** * Returns the absolute path to the themes directory. * - * @param string $path A relative path to append to te themes directory absolute path. - * - * @return string The absolute path to the `themesFolder` path or the same with a relative path appended if `$path` - * is provided. * @example * ```php * $themes = $this->getThemesFolder(); * $twentytwenty = $this->getThemesFolder('/twentytwenty'); * ``` * + * @param string $path A relative path to append to te themes directory absolute path. + * + * @return string The absolute path to the `themesFolder` path or the same with a relative path appended if `$path` + * is provided. */ public function getThemesFolder(string $path = ''): string { @@ -573,30 +585,39 @@ private function installAndBootstrapInstallation(): void { $GLOBALS['wpLoaderConfig'] = $this->config; + $skipInstall = ($this->config['skipInstall'] ?? false) + && !Debug::isEnabled() + && $this->isWordPressInstalled(); + Dispatcher::dispatch(self::EVENT_BEFORE_INSTALL, $this); - $isMultisite = $this->config['multisite']; - $plugins = (array)$this->config['plugins']; + if (!$skipInstall) { + putenv('WP_TESTS_SKIP_INSTALL=0'); + $isMultisite = $this->config['multisite']; + $plugins = (array)$this->config['plugins']; - /* - * The bootstrap file will load the `wp-settings.php` one that will load plugins and the theme. - * Hook on the option to get the the active plugins to run the plugins' and theme activation - * in a separate process. - */ - if ($isMultisite) { - // Activate plugins and enable theme network-wide. - $activate = function () use (&$activate, $plugins): array { - remove_filter('pre_site_option_active_sitewide_plugins', $activate); - return $this->muActivatePluginsTheme($plugins); - }; - PreloadFilters::addFilter('pre_site_option_active_sitewide_plugins', $activate); + /* + * The bootstrap file will load the `wp-settings.php` one that will load plugins and the theme. + * Hook on the option to get the the active plugins to run the plugins' and theme activation + * in a separate process. + */ + if ($isMultisite) { + // Activate plugins and enable theme network-wide. + $activate = function () use (&$activate, $plugins): array { + remove_filter('pre_site_option_active_sitewide_plugins', $activate); + return $this->muActivatePluginsTheme($plugins); + }; + PreloadFilters::addFilter('pre_site_option_active_sitewide_plugins', $activate); + } else { + // Activate plugins and theme. + $activate = function () use (&$activate, $plugins): array { + remove_filter('pre_option_active_plugins', $activate); + return $this->activatePluginsTheme($plugins); + }; + PreloadFilters::addFilter('pre_option_active_plugins', $activate); + } } else { - // Activate plugins and theme. - $activate = function () use (&$activate, $plugins): array { - remove_filter('pre_option_active_plugins', $activate); - return $this->activatePluginsTheme($plugins); - }; - PreloadFilters::addFilter('pre_option_active_plugins', $activate); + putenv('WP_TESTS_SKIP_INSTALL=1'); } $this->includeCorePHPUniteSuiteBootstrapFile(); @@ -605,7 +626,9 @@ private function installAndBootstrapInstallation(): void $this->disableUpdates(); - $this->importDumps(); + if (!$skipInstall) { + $this->importDumps(); + } Dispatcher::dispatch(self::EVENT_AFTER_BOOTSTRAP, $this); @@ -623,7 +646,7 @@ private function activatePluginsSwitchThemeInSeparateProcess(): void /** @var array $plugins */ $plugins = (array)($this->config['plugins'] ?: []); $multisite = (bool)($this->config['multisite'] ?? false); - $closuresFactory = $this->getClosuresFactory(); + $closuresFactory = $this->getCodeExecutionFactory(); $jobs = array_combine( array_map(static fn(string $plugin): string => 'plugin::' . $plugin, $plugins), @@ -696,15 +719,15 @@ private function runBootstrapActions(): void * This method gives access to the same factories provided by the * [Core test suite](https://make.wordpress.org/core/handbook/testing/automated-testing/writing-phpunit-tests/). * - * @return FactoryStore A factory store, proxy to get hold of the Core suite object - * factories. - * * @example * ```php * $postId = $I->factory()->post->create(); * $userId = $I->factory()->user->create(['role' => 'administrator']); * ``` * + * @return FactoryStore A factory store, proxy to get hold of the Core suite object + * factories. + * * @link https://make.wordpress.org/core/handbook/testing/automated-testing/writing-phpunit-tests/ */ public function factory(): FactoryStore @@ -742,9 +765,6 @@ private function loadConfigFiles(): void /** * Returns the absolute path to the WordPress content directory. * - * @param string $path An optional path to append to the content directory absolute path. - * - * @return string The content directory absolute path, or a path in it. * @example * ```php * $content = $this->getContentFolder(); @@ -752,20 +772,27 @@ private function loadConfigFiles(): void * $twentytwenty = $this->getContentFolder('themes/twentytwenty'); * ``` * + * @param string $path An optional path to append to the content directory absolute path. + * + * @return string The content directory absolute path, or a path in it. */ public function getContentFolder(string $path = ''): string { return $this->installation->getContentDir($path); } - private function getClosuresFactory(): CodeExecutionFactory + private function getCodeExecutionFactory(): CodeExecutionFactory { + if ($this->codeExecutionFactory !== null) { + return $this->codeExecutionFactory; + } + $installationState = $this->installation->getState(); $wpConfigFilePath = $installationState instanceof Scaffolded ? $installationState->getWpRootDir('/wp-config.php') : $installationState->getWpConfigPath(); - return new CodeExecutionFactory( + $this->codeExecutionFactory = new CodeExecutionFactory( $this->getWpRootFolder(), $this->config['domain'] ?: 'localhost', [$wpConfigFilePath => CorePHPUnit::path('/wp-tests-config.php')], @@ -774,6 +801,8 @@ private function getClosuresFactory(): CodeExecutionFactory 'wpLoaderConfig' => $this->config ] ); + + return $this->codeExecutionFactory; } public function getInstallation(): Installation @@ -940,20 +969,18 @@ private function activatePluginsTheme(array $plugins): array { $this->activatePluginsSwitchThemeInSeparateProcess(); - /** @var DatabaseInterface $database */ $database = $this->db; - if ($this->config['theme']) { - // Refresh the theme related options. - if ($database === null) { - throw new ModuleException( - __CLASS__, - 'Could not get database instance from installation.' - ); - } + if ($database === null) { + throw new ModuleException( + __CLASS__, + 'Could not get database instance from installation.' + ); + } - update_option('template', $database->getOption('template')); - update_option('stylesheet', $database->getOption('stylesheet')); + if ($this->config['theme']) { + $database->updateOption('template', $database->getOption('template')); + $database->updateOption('stylesheet', $database->getOption('stylesheet')); } // Flush the cache to force the refetch of the options' value. @@ -995,4 +1022,17 @@ private function muActivatePluginsTheme(array $plugins): array // Format for site-wide active plugins is `[ 'plugin-slug/plugin.php' => timestamp ]`. return array_combine($plugins, array_fill(0, count($plugins), time())); } + + private function isWordPressInstalled(): bool + { + if (!$this->db instanceof DatabaseInterface) { + return false; + } + + try { + return !empty($this->db->getOption('siteurl')); + } catch (Throwable) { + return false; + } + } } diff --git a/src/Process/StderrStream.php b/src/Process/StderrStream.php index cd0deb861..20559af55 100644 --- a/src/Process/StderrStream.php +++ b/src/Process/StderrStream.php @@ -288,7 +288,7 @@ public function getThrowable(): ?Throwable 'message' => $sourceError->message, 'file' => $sourceError->file, 'line' => $sourceError->line, - 'trace' => $sourceError->trace, + 'trace' => array_map(static fn(TraceEntry $t)=> $t->toArray(), $sourceError->trace), 'code' => 0, // The code is not available in the error log. ]); diff --git a/src/Process/StderrStream/TraceEntry.php b/src/Process/StderrStream/TraceEntry.php index 93b6c4299..6f684f70c 100644 --- a/src/Process/StderrStream/TraceEntry.php +++ b/src/Process/StderrStream/TraceEntry.php @@ -11,4 +11,28 @@ class TraceEntry public string $args = ''; public string $file = ''; public int $line = 0; + + /** + * @return array{ + * date: string, + * time: string, + * timezone: string, + * call: string, + * args: string, + * file: string, + * line: int + * } + */ + public function toArray(): array + { + return [ + 'date' => $this->date, + 'time' => $this->time, + 'timezone' => $this->timezone, + 'call' => $this->call, + 'args' => $this->args, + 'file' => $this->file, + 'line' => $this->line, + ]; + } } diff --git a/src/WordPress/Database/MysqlDatabase.php b/src/WordPress/Database/MysqlDatabase.php index 5b9bcd7fa..c56198b70 100644 --- a/src/WordPress/Database/MysqlDatabase.php +++ b/src/WordPress/Database/MysqlDatabase.php @@ -330,7 +330,14 @@ public function import(string $dumpFilePath): int public function dump(string $dumpFile): void { try { - $dump = new Mysqldump($this->dsn, $this->dbUser, $this->dbPassword); + $dump = new class($this->dsn, $this->dbUser, $this->dbPassword) extends Mysqldump { + public function start($filename = '') + { + $this->dumpSettings['add-drop-table'] = true; + $this->dumpSettings['add-drop-database'] = true; + return parent::start($filename); + } + }; $dump->start($dumpFile); } catch (\Exception $e) { throw new DbException("Failed to dump database: " . $e->getMessage(), DbException::FAILED_DUMP); diff --git a/tests/_support/Traits/MainInstallationAccess.php b/tests/_support/Traits/MainInstallationAccess.php index eb7ab026e..b97ed29b6 100644 --- a/tests/_support/Traits/MainInstallationAccess.php +++ b/tests/_support/Traits/MainInstallationAccess.php @@ -9,22 +9,27 @@ trait MainInstallationAccess { - protected function copyOverContentFromTheMainInstallation(Installation $installation): void + protected function copyOverContentFromTheMainInstallation(Installation $installation, array $options = []): void { $mainWPInstallationRootDir = Env::get('WORDPRESS_ROOT_DIR'); - foreach ([ - 'hello-dolly', - 'akismet', - 'woocommerce', - ] as $plugin) { - if (!FS::recurseCopy($mainWPInstallationRootDir . '/wp-content/plugins/' . $plugin, - $installation->getPluginsDir($plugin))) { + $plugins = $options['plugins'] ?? [ + 'hello-dolly', + 'akismet', + 'woocommerce', + ]; + foreach ($plugins as $plugin) { + if (!FS::recurseCopy( + $mainWPInstallationRootDir . '/wp-content/plugins/' . $plugin, + $installation->getPluginsDir($plugin) + )) { throw new RuntimeException(sprintf('Could not copy plugin %s', $plugin)); } } // Copy over theme from the main installation. - if (!FS::recurseCopy($mainWPInstallationRootDir . '/wp-content/themes/twentytwenty', - $installation->getThemesDir('twentytwenty'))) { + if (!FS::recurseCopy( + $mainWPInstallationRootDir . '/wp-content/themes/twentytwenty', + $installation->getThemesDir('twentytwenty') + )) { throw new RuntimeException('Could not copy theme twentytwenty'); } } diff --git a/tests/unit/lucatume/WPBrowser/Events/Module/WPLoaderTest.php b/tests/unit/lucatume/WPBrowser/Events/Module/WPLoaderTest.php index 711ad000d..516f43b45 100644 --- a/tests/unit/lucatume/WPBrowser/Events/Module/WPLoaderTest.php +++ b/tests/unit/lucatume/WPBrowser/Events/Module/WPLoaderTest.php @@ -7,13 +7,12 @@ use Codeception\Exception\ModuleException; use Codeception\Lib\Di; use Codeception\Lib\ModuleContainer; -use Codeception\Test\TestCaseWrapper; use Codeception\Test\Unit; +use Codeception\Util\Debug; use Exception; use Generator; use lucatume\WPBrowser\Events\Dispatcher; use lucatume\WPBrowser\Module\WPLoader\FactoryStore; -use lucatume\WPBrowser\TestCase\WPTestCase; use lucatume\WPBrowser\Tests\FSTemplates\BedrockProject; use lucatume\WPBrowser\Tests\Traits\DatabaseAssertions; use lucatume\WPBrowser\Tests\Traits\LoopIsolation; @@ -29,17 +28,18 @@ use lucatume\WPBrowser\WordPress\InstallationException; use lucatume\WPBrowser\WordPress\InstallationState\InstallationStateInterface; use lucatume\WPBrowser\WordPress\InstallationState\Scaffolded; -use PHPUnit\Framework\Assert; use PHPUnit\Framework\TestResult; -use RuntimeException; use stdClass; use tad\Codeception\SnapshotAssertions\SnapshotAssertions; use UnitTester; use WP_Theme; -use WP_UnitTestCase; - use function PHPUnit\Framework\assertEquals; +use function PHPUnit\Framework\assertFalse; +use function PHPUnit\Framework\assertFileExists; +use function PHPUnit\Framework\assertInstanceOf; +use function PHPUnit\Framework\assertNotEquals; +use function PHPUnit\Framework\assertTrue; use const ABSPATH; use const WP_DEBUG; @@ -133,10 +133,10 @@ public function unsetEnvVars(): void /** * @return WPLoader */ - private function module(): WPLoader + private function module(array $moduleContainerConfig = [], ?array $moduleConfig = null): WPLoader { - $this->mockModuleContainer = new ModuleContainer(new Di(), []); - return new WPLoader($this->mockModuleContainer, $this->config); + $this->mockModuleContainer = new ModuleContainer(new Di(), $moduleContainerConfig); + return new WPLoader($this->mockModuleContainer, ($moduleConfig ?? $this->config)); } /** @@ -203,8 +203,8 @@ public function should_allow_specifying_the_wp_root_folder_as_a_relative_path_to $this->assertInIsolation(static function () use ($rootDir, $wpLoader1) { chdir($rootDir); $wpLoader1->_initialize(); - Assert::assertEquals($rootDir . '/test/wordpress/', $wpLoader1->_getConfig('wpRootFolder')); - Assert::assertEquals($rootDir . '/test/wordpress/', $wpLoader1->getWpRootFolder()); + assertEquals($rootDir . '/test/wordpress/', $wpLoader1->_getConfig('wpRootFolder')); + assertEquals($rootDir . '/test/wordpress/', $wpLoader1->getWpRootFolder()); }, $rootDir); $this->config = [ @@ -220,8 +220,8 @@ public function should_allow_specifying_the_wp_root_folder_as_a_relative_path_to $this->assertInIsolation(static function () use ($rootDir, $wpLoader2) { chdir($rootDir); $wpLoader2->_initialize(); - Assert::assertEquals($rootDir . '/test/wordpress/', $wpLoader2->_getConfig('wpRootFolder')); - Assert::assertEquals($rootDir . '/test/wordpress/', $wpLoader2->getWpRootFolder()); + assertEquals($rootDir . '/test/wordpress/', $wpLoader2->_getConfig('wpRootFolder')); + assertEquals($rootDir . '/test/wordpress/', $wpLoader2->getWpRootFolder()); }, $rootDir); } @@ -250,8 +250,8 @@ public function should_allow_specifying_the_wp_root_folder_including_the_home_sy $_SERVER['HOME'] = $homeDir; $wpLoader->_initialize(); - Assert::assertEquals($homeDir . '/projects/work/acme/wordpress/', $wpLoader->_getConfig('wpRootFolder')); - Assert::assertEquals($homeDir . '/projects/work/acme/wordpress/', $wpLoader->getWpRootFolder()); + assertEquals($homeDir . '/projects/work/acme/wordpress/', $wpLoader->_getConfig('wpRootFolder')); + assertEquals($homeDir . '/projects/work/acme/wordpress/', $wpLoader->getWpRootFolder()); }); } @@ -277,8 +277,8 @@ public function should_allow_specifying_the_wp_root_folder_as_an_absolute_path() $this->assertInIsolation(static function () use ($wpRootDir, $wpLoader) { $wpLoader->_initialize(); - Assert::assertEquals($wpRootDir . '/', $wpLoader->_getConfig('wpRootFolder')); - Assert::assertEquals($wpRootDir . '/', $wpLoader->getWpRootFolder()); + assertEquals($wpRootDir . '/', $wpLoader->_getConfig('wpRootFolder')); + assertEquals($wpRootDir . '/', $wpLoader->getWpRootFolder()); }); } @@ -304,8 +304,8 @@ public function should_allow_specifying_the_wp_root_folder_as_absolute_path_with $this->assertInIsolation(static function () use ($wpRootDir, $wpLoader) { $wpLoader->_initialize(); - Assert::assertEquals($wpRootDir . '/Word Press/', $wpLoader->_getConfig('wpRootFolder')); - Assert::assertEquals($wpRootDir . '/Word Press/', $wpLoader->getWpRootFolder()); + assertEquals($wpRootDir . '/Word Press/', $wpLoader->_getConfig('wpRootFolder')); + assertEquals($wpRootDir . '/Word Press/', $wpLoader->getWpRootFolder()); }); } @@ -330,7 +330,7 @@ public function should_scaffold_the_installation_if_the_wp_root_folder_is_empty( $this->assertInIsolation(static function () use ($wpLoader) { $wpLoader->_initialize(); - Assert::assertInstanceOf(Scaffolded::class, $wpLoader->getInstallation()->getState()); + assertInstanceOf(Scaffolded::class, $wpLoader->getInstallation()->getState()); }); } @@ -362,14 +362,14 @@ public function should_read_salts_from_configured_installation(): void $wpLoader->_initialize(); $installation = $wpLoader->getInstallation(); - Assert::assertEquals($installation->getAuthKey(), $wpLoader->_getConfig('AUTH_KEY')); - Assert::assertEquals($installation->getSecureAuthKey(), $wpLoader->_getConfig('SECURE_AUTH_KEY')); - Assert::assertEquals($installation->getLoggedInKey(), $wpLoader->_getConfig('LOGGED_IN_KEY')); - Assert::assertEquals($installation->getNonceKey(), $wpLoader->_getConfig('NONCE_KEY')); - Assert::assertEquals($installation->getAuthSalt(), $wpLoader->_getConfig('AUTH_SALT')); - Assert::assertEquals($installation->getSecureAuthSalt(), $wpLoader->_getConfig('SECURE_AUTH_SALT')); - Assert::assertEquals($installation->getLoggedInSalt(), $wpLoader->_getConfig('LOGGED_IN_SALT')); - Assert::assertEquals($installation->getNonceSalt(), $wpLoader->_getConfig('NONCE_SALT')); + assertEquals($installation->getAuthKey(), $wpLoader->_getConfig('AUTH_KEY')); + assertEquals($installation->getSecureAuthKey(), $wpLoader->_getConfig('SECURE_AUTH_KEY')); + assertEquals($installation->getLoggedInKey(), $wpLoader->_getConfig('LOGGED_IN_KEY')); + assertEquals($installation->getNonceKey(), $wpLoader->_getConfig('NONCE_KEY')); + assertEquals($installation->getAuthSalt(), $wpLoader->_getConfig('AUTH_SALT')); + assertEquals($installation->getSecureAuthSalt(), $wpLoader->_getConfig('SECURE_AUTH_SALT')); + assertEquals($installation->getLoggedInSalt(), $wpLoader->_getConfig('LOGGED_IN_SALT')); + assertEquals($installation->getNonceSalt(), $wpLoader->_getConfig('NONCE_SALT')); }); } @@ -395,9 +395,9 @@ public function should_allow_getting_paths_from_the_wp_root_folder(): void $this->assertInIsolation(static function () use ($wpRootDir, $wpLoader) { $wpLoader->_initialize(); - Assert::assertEquals($wpRootDir . '/foo-bar', $wpLoader->getWpRootFolder('foo-bar')); - Assert::assertEquals($wpRootDir . '/foo-bar/baz', $wpLoader->getWpRootFolder('foo-bar/baz')); - Assert::assertEquals($wpRootDir . '/wp-config.php', $wpLoader->getWpRootFolder('wp-config.php')); + assertEquals($wpRootDir . '/foo-bar', $wpLoader->getWpRootFolder('foo-bar')); + assertEquals($wpRootDir . '/foo-bar/baz', $wpLoader->getWpRootFolder('foo-bar/baz')); + assertEquals($wpRootDir . '/wp-config.php', $wpLoader->getWpRootFolder('wp-config.php')); }); } @@ -434,9 +434,9 @@ public function should_set_some_default_values_for_salt_keys(): void ]; foreach ($var as $i => $key) { if ($i > 0) { - Assert::assertNotEquals($var[$i - 1], $wpLoader->_getConfig($key)); + assertNotEquals($var[$i - 1], $wpLoader->_getConfig($key)); } - Assert::assertEquals(64, strlen($wpLoader->_getConfig($key))); + assertEquals(64, strlen($wpLoader->_getConfig($key))); } }); } @@ -462,7 +462,7 @@ public function should_load_config_files_if_set(): void $this->assertInIsolation(static function () use ($wpLoader) { $wpLoader->_initialize(); - Assert::assertEquals('test_file_001.php', getenv('LOADED')); + assertEquals('test_file_001.php', getenv('LOADED')); }); $this->config = [ @@ -482,8 +482,8 @@ public function should_load_config_files_if_set(): void $this->assertInIsolation(static function () use ($wpLoader) { $wpLoader->_initialize(); - Assert::assertEquals(getenv('LOADED_2'), 'test_file_002.php'); - Assert::assertEquals(getenv('LOADED_3'), 'test_file_003.php'); + assertEquals(getenv('LOADED_2'), 'test_file_002.php'); + assertEquals(getenv('LOADED_3'), 'test_file_003.php'); }); } @@ -511,10 +511,10 @@ public function should_throw_if_config_files_do_not_exist(): void try { $wpLoader->_initialize(); } catch (Exception $e) { - Assert::assertInstanceOf(ModuleConfigException::class, $e); + assertInstanceOf(ModuleConfigException::class, $e); $captured = true; } - Assert::assertTrue($captured); + assertTrue($captured); }); $this->config = [ @@ -699,8 +699,8 @@ public function should_load_word_press_before_suite_if_load_only_w_config_files( $this->assertInIsolation(static function () use ($wpRootDir, $wpLoader) { $wpLoader->_initialize(); - Assert::assertEquals('', getenv('LOADED_2')); - Assert::assertFalse(defined('ABSPATH')); + assertEquals('', getenv('LOADED_2')); + assertFalse(defined('ABSPATH')); $actions = []; Dispatcher::addListener(WPLoader::EVENT_BEFORE_LOADONLY, static function () use (&$actions) { @@ -712,13 +712,13 @@ public function should_load_word_press_before_suite_if_load_only_w_config_files( Dispatcher::dispatch(Events::SUITE_BEFORE); - Assert::assertEquals('test_file_002.php', getenv('LOADED_2')); - Assert::assertEquals($wpRootDir . '/', ABSPATH); - Assert::assertEquals([ + assertEquals('test_file_002.php', getenv('LOADED_2')); + assertEquals($wpRootDir . '/', ABSPATH); + assertEquals([ WPLoader::EVENT_BEFORE_LOADONLY, WPLoader::EVENT_AFTER_LOADONLY, ], $actions); - Assert::assertInstanceOf(FactoryStore::class, $wpLoader->factory()); + assertInstanceOf(FactoryStore::class, $wpLoader->factory()); }); } @@ -802,7 +802,7 @@ public function should_not_throw_when_load_only_true_and_using_db_module( Dispatcher::dispatch(Events::SUITE_BEFORE); - Assert::assertEquals($wpRootDir . '/', ABSPATH); + assertEquals($wpRootDir . '/', ABSPATH); }); } @@ -943,11 +943,11 @@ public function should_should_install_and_bootstrap_single_site_using_constants_ $this->assertInIsolation(static function () use ($wpLoader, $wpRootDir) { $wpLoader->_initialize(); - Assert::assertEquals('test_file_001.php', getenv('LOADED')); - Assert::assertEquals('test_file_002.php', getenv('LOADED_2')); - Assert::assertEquals($wpRootDir . '/', ABSPATH); - Assert::assertTrue(defined('WP_DEBUG')); - Assert::assertTrue(WP_DEBUG); + assertEquals('test_file_001.php', getenv('LOADED')); + assertEquals('test_file_002.php', getenv('LOADED_2')); + assertEquals($wpRootDir . '/', ABSPATH); + assertTrue(defined('WP_DEBUG')); + assertTrue(WP_DEBUG); }); } @@ -1019,7 +1019,7 @@ public function should_install_and_bootstrap_single_installation(): void $this->copyOverContentFromTheMainInstallation($installation); $wpLoader = $this->module(); - $installationOutput = $this->assertInIsolation(static function () use ($wpLoader, $wpRootDir) { + $this->assertInIsolation(static function () use ($wpLoader, $wpRootDir) { $actions = []; Dispatcher::addListener(WPLoader::EVENT_BEFORE_INSTALL, function () use (&$actions) { $actions[] = 'before_install'; @@ -1037,31 +1037,31 @@ public function should_install_and_bootstrap_single_installation(): void if (PHP_VERSION >= 7.4) { $expectedActivePlugins[] = 'woocommerce/woocommerce.php'; } - Assert::assertEquals($expectedActivePlugins, get_option('active_plugins')); - Assert::assertEquals([ + assertEquals($expectedActivePlugins, get_option('active_plugins')); + assertEquals([ 'before_install', 'after_install', ], $actions); - Assert::assertEquals('twentytwenty', get_option('template')); - Assert::assertEquals('twentytwenty', get_option('stylesheet')); - Assert::assertEquals('test_file_001.php', getenv('LOADED')); - Assert::assertEquals('test_file_002.php', getenv('LOADED_2')); - Assert::assertEquals($wpRootDir . '/', ABSPATH); - Assert::assertTrue(defined('WP_DEBUG')); - Assert::assertTrue(WP_DEBUG); - Assert::assertInstanceOf(\wpdb::class, $GLOBALS['wpdb']); - Assert::assertFalse(is_multisite()); - Assert::assertEquals($wpRootDir . '/wp-content/', $wpLoader->getContentFolder()); - Assert::assertEquals($wpRootDir . '/wp-content/some/path', $wpLoader->getContentFolder('some/path')); - Assert::assertEquals( + assertEquals('twentytwenty', get_option('template')); + assertEquals('twentytwenty', get_option('stylesheet')); + assertEquals('test_file_001.php', getenv('LOADED')); + assertEquals('test_file_002.php', getenv('LOADED_2')); + assertEquals($wpRootDir . '/', ABSPATH); + assertTrue(defined('WP_DEBUG')); + assertTrue(WP_DEBUG); + assertInstanceOf(\wpdb::class, $GLOBALS['wpdb']); + assertFalse(is_multisite()); + assertEquals($wpRootDir . '/wp-content/', $wpLoader->getContentFolder()); + assertEquals($wpRootDir . '/wp-content/some/path', $wpLoader->getContentFolder('some/path')); + assertEquals( $wpRootDir . '/wp-content/some/path/some-file.php', $wpLoader->getContentFolder('some/path/some-file.php') ); - Assert::assertEquals( + assertEquals( $wpRootDir . '/wp-content/plugins/some-file.php', $wpLoader->getPluginsFolder('/some-file.php') ); - Assert::assertEquals( + assertEquals( $wpRootDir . '/wp-content/themes/some-file.php', $wpLoader->getThemesFolder('/some-file.php') ); @@ -1070,14 +1070,7 @@ public function should_install_and_bootstrap_single_installation(): void WPAssert::assertTableExists('woocommerce_order_items'); } WPAssert::assertUpdatesDisabled(); - - return [ - 'bootstrapOutput' => $wpLoader->_getBootstrapOutput(), - 'installationOutput' => $wpLoader->_getInstallationOutput(), - ]; }); - - codecept_debug($installationOutput); } /** @@ -1135,32 +1128,32 @@ public function should_install_and_bootstrap_multisite_installation(): void if (PHP_VERSION >= 7.4) { $expectedActivePlugins[] = 'woocommerce/woocommerce.php'; } - Assert::assertEquals($expectedActivePlugins, array_keys(get_site_option('active_sitewide_plugins'))); - Assert::assertEquals([ + assertEquals($expectedActivePlugins, array_keys(get_site_option('active_sitewide_plugins'))); + assertEquals([ 'before_install', 'after_install', ], $actions); - Assert::assertEquals('twentytwenty', get_option('template')); - Assert::assertEquals('twentytwenty', get_option('stylesheet')); - Assert::assertEquals(['twentytwenty' => true], WP_Theme::get_allowed()); - Assert::assertEquals('test_file_001.php', getenv('LOADED')); - Assert::assertEquals('test_file_002.php', getenv('LOADED_2')); - Assert::assertEquals($wpRootDir . '/', ABSPATH); - Assert::assertTrue(defined('WP_DEBUG')); - Assert::assertTrue(WP_DEBUG); - Assert::assertInstanceOf(\wpdb::class, $GLOBALS['wpdb']); - Assert::assertTrue(is_multisite()); - Assert::assertEquals($wpRootDir . '/wp-content/', $wpLoader->getContentFolder()); - Assert::assertEquals($wpRootDir . '/wp-content/some/path', $wpLoader->getContentFolder('some/path')); - Assert::assertEquals( + assertEquals('twentytwenty', get_option('template')); + assertEquals('twentytwenty', get_option('stylesheet')); + assertEquals(['twentytwenty' => true], WP_Theme::get_allowed()); + assertEquals('test_file_001.php', getenv('LOADED')); + assertEquals('test_file_002.php', getenv('LOADED_2')); + assertEquals($wpRootDir . '/', ABSPATH); + assertTrue(defined('WP_DEBUG')); + assertTrue(WP_DEBUG); + assertInstanceOf(\wpdb::class, $GLOBALS['wpdb']); + assertTrue(is_multisite()); + assertEquals($wpRootDir . '/wp-content/', $wpLoader->getContentFolder()); + assertEquals($wpRootDir . '/wp-content/some/path', $wpLoader->getContentFolder('some/path')); + assertEquals( $wpRootDir . '/wp-content/some/path/some-file.php', $wpLoader->getContentFolder('some/path/some-file.php') ); - Assert::assertEquals( + assertEquals( $wpRootDir . '/wp-content/plugins/some-file.php', $wpLoader->getPluginsFolder('/some-file.php') ); - Assert::assertEquals( + assertEquals( $wpRootDir . '/wp-content/themes/some-file.php', $wpLoader->getThemesFolder('/some-file.php') ); @@ -1175,8 +1168,6 @@ public function should_install_and_bootstrap_multisite_installation(): void 'installationOutput' => $wpLoader->_getInstallationOutput(), ]; }); - - codecept_debug($installationOutput); } public function singleSiteAndMultisite(): array @@ -1428,16 +1419,14 @@ public function should_correctly_activate_child_theme_in_single_installation(): $installationOutput = $this->assertInIsolation(static function () use ($wpLoader, $wpRootDir) { $wpLoader->_initialize(); - Assert::assertEquals('twentytwenty', get_option('template')); - Assert::assertEquals('some-child-theme', get_option('stylesheet')); + assertEquals('twentytwenty', get_option('template')); + assertEquals('some-child-theme', get_option('stylesheet')); return [ 'bootstrapOutput' => $wpLoader->_getBootstrapOutput(), 'installationOutput' => $wpLoader->_getInstallationOutput(), ]; }); - - codecept_debug($installationOutput); } /** @@ -1498,16 +1487,14 @@ public function should_correctly_activate_child_theme_in_multisite_installation( $installationOutput = $this->assertInIsolation(static function () use ($wpLoader, $wpRootDir) { $wpLoader->_initialize(); - Assert::assertEquals('twentytwenty', get_option('template')); - Assert::assertEquals('twentytwenty-child', get_option('stylesheet')); + assertEquals('twentytwenty', get_option('template')); + assertEquals('twentytwenty-child', get_option('stylesheet')); return [ 'bootstrapOutput' => $wpLoader->_getBootstrapOutput(), 'installationOutput' => $wpLoader->_getInstallationOutput(), ]; }); - - codecept_debug($installationOutput); } /** @@ -1632,7 +1619,7 @@ public function should_allow_loading_a_database_dump_before_tests(): void $this->assertInIsolation(static function () use ($wpLoader) { $wpLoader->_initialize(); - Assert::assertEquals('value_1', get_option('option_1')); + assertEquals('value_1', get_option('option_1')); }); } @@ -1667,9 +1654,9 @@ public function should_allow_loading_multiple_database_dumps_before_the_tests(): $this->assertInIsolation(static function () use ($wpLoader) { $wpLoader->_initialize(); - Assert::assertEquals('value_1', get_option('option_1')); - Assert::assertEquals('value_2', get_option('option_2')); - Assert::assertEquals('value_3', get_option('option_3')); + assertEquals('value_1', get_option('option_1')); + assertEquals('value_2', get_option('option_2')); + assertEquals('value_3', get_option('option_3')); }); } @@ -1735,7 +1722,7 @@ public function should_place_sq_lite_dropin_if_using_sq_lite_database_for_tests( $this->assertInIsolation(static function () use ($wpRootDir, $wpLoader) { $wpLoader->_initialize(); - Assert::assertFileExists($wpRootDir . '/wp-content/db.php'); + assertFileExists($wpRootDir . '/wp-content/db.php'); }); } @@ -1762,8 +1749,8 @@ public function should_initialize_correctly_with_sqlite_database(): void $this->assertInIsolation(static function () use ($wpLoader) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); - Assert::assertInstanceOf(\WP_User::class, wp_get_current_user()); + assertTrue(function_exists('do_action')); + assertInstanceOf(\WP_User::class, wp_get_current_user()); }); } @@ -1800,8 +1787,8 @@ public function should_initialize_correctly_with_sqlite_database_in_load_only_mo $wpLoader->_initialize(); Dispatcher::dispatch(Events::SUITE_BEFORE); - Assert::assertTrue(function_exists('do_action')); - Assert::assertInstanceOf(\WP_User::class, wp_get_current_user()); + assertTrue(function_exists('do_action')); + assertInstanceOf(\WP_User::class, wp_get_current_user()); }); } @@ -1873,12 +1860,12 @@ function plugin_2_canary() {} $this->assertInIsolation(static function () use ($wpLoader) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); - Assert::assertTrue(function_exists('plugin_1_canary')); - Assert::assertTrue(is_plugin_active('plugin-1/plugin.php')); - Assert::assertTrue(function_exists('plugin_2_canary')); - Assert::assertTrue(is_plugin_active('plugin-2/plugin.php')); - Assert::assertEquals('theme-1', wp_get_theme()->get_stylesheet()); + assertTrue(function_exists('do_action')); + assertTrue(function_exists('plugin_1_canary')); + assertTrue(is_plugin_active('plugin-1/plugin.php')); + assertTrue(function_exists('plugin_2_canary')); + assertTrue(is_plugin_active('plugin-2/plugin.php')); + assertEquals('theme-1', wp_get_theme()->get_stylesheet()); }); } @@ -1929,8 +1916,8 @@ public function should_correctly_load_with_different_database_names(string $dbNa $this->assertInIsolation(static function () use ($wpLoader) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); - Assert::assertInstanceOf(\WP_User::class, wp_get_current_user()); + assertTrue(function_exists('do_action')); + assertInstanceOf(\WP_User::class, wp_get_current_user()); return $wpLoader->getInstallation()->getDb()->getDbName(); }) @@ -1974,7 +1961,7 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); + assertTrue(function_exists('do_action')); require_once $testcaseFile; @@ -1982,7 +1969,7 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w /** @var TestResult $result */ $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + assertTrue($result->wasSuccessful()); }); // Set `WPLoader.backupGlobals` to `true`. @@ -1996,7 +1983,7 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); + assertTrue(function_exists('do_action')); require_once $testcaseFile; @@ -2004,7 +1991,7 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w /** @var TestResult $result */ $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + assertTrue($result->wasSuccessful()); }); // Do not set `WPLoader.backupGlobals`, but use the default value. @@ -2018,7 +2005,7 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); + assertTrue(function_exists('do_action')); require_once $testcaseFile; @@ -2026,7 +2013,7 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w /** @var TestResult $result */ $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + assertTrue($result->wasSuccessful()); }); // Set `WPLoader.backupGlobals` to `true`, but use a use-case that sets it explicitly to `false`. @@ -2040,7 +2027,7 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w $this->assertInIsolation(static function () use ($wpLoader, $overridingTestCaseFile) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); + assertTrue(function_exists('do_action')); require_once $overridingTestCaseFile; @@ -2048,7 +2035,7 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w /** @var TestResult $result */ $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + assertTrue($result->wasSuccessful()); }); $this->config = [ @@ -2061,7 +2048,7 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); + assertTrue(function_exists('do_action')); // Set the initial value of the global variable. global $_wpbrowser_test_global_var; @@ -2073,10 +2060,10 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w /** @var TestResult $result */ $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + assertTrue($result->wasSuccessful()); // Check that the value of the global variable has been updated. - Assert::assertEquals('initial_value', $_wpbrowser_test_global_var); + assertEquals('initial_value', $_wpbrowser_test_global_var); }); $this->config = [ @@ -2090,7 +2077,7 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); + assertTrue(function_exists('do_action')); // Set the initial value of the global variable. global $_wpbrowser_test_global_var; @@ -2102,10 +2089,10 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w /** @var TestResult $result */ $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + assertTrue($result->wasSuccessful()); // Check that the value of the global variable has been updated. - Assert::assertEquals('updated_value', $_wpbrowser_test_global_var); + assertEquals('updated_value', $_wpbrowser_test_global_var); }); } @@ -2146,7 +2133,7 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); + assertTrue(function_exists('do_action')); require_once $testcaseFile; @@ -2154,9 +2141,9 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ /** @var TestResult $result */ $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + assertTrue($result->wasSuccessful()); - Assert::assertEquals('updated_value', \BackupControlTestCaseStore::$staticAttribute); + assertEquals('updated_value', \BackupControlTestCaseStore::$staticAttribute); }); // Don't set`WPLoader.backupStaticAttributes`, it should be `true` by default. @@ -2169,7 +2156,7 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); + assertTrue(function_exists('do_action')); require_once $testcaseFile; @@ -2177,9 +2164,9 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ /** @var TestResult $result */ $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + assertTrue($result->wasSuccessful()); - Assert::assertEquals('initial_value', \BackupControlTestCaseStore::$staticAttribute); + assertEquals('initial_value', \BackupControlTestCaseStore::$staticAttribute); }); // Set the value of `WPLoader.backupStaticAttributes` to `true`, but use a use-case that sets it explicitly to `false`. @@ -2193,7 +2180,7 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ $this->assertInIsolation(static function () use ($wpLoader, $overridingTestCaseFile) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); + assertTrue(function_exists('do_action')); require_once $overridingTestCaseFile; @@ -2201,9 +2188,9 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ /** @var TestResult $result */ $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + assertTrue($result->wasSuccessful()); - Assert::assertEquals('updated_value', \BackupControlTestCaseOverridingStore::$staticAttribute); + assertEquals('updated_value', \BackupControlTestCaseOverridingStore::$staticAttribute); }); // Set the value of the `WPLoader.backupStaticAttributesExcludeList` to not back up the static attribute. @@ -2221,7 +2208,7 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ static function () use ($wpLoader, $testcaseFile) { $wpLoader->_initialize(); - Assert::assertTrue(function_exists('do_action')); + assertTrue(function_exists('do_action')); require_once $testcaseFile; @@ -2229,16 +2216,16 @@ static function () use ($wpLoader, $testcaseFile) { /** @var TestResult $result */ $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + assertTrue($result->wasSuccessful()); - Assert::assertEquals('updated_value', \BackupControlTestCaseStore::$staticAttribute); - Assert::assertEquals('initial_value', \BackupControlTestCaseStore::$staticAttributeTwo); - Assert::assertEquals('updated_value', \BackupControlTestCaseStore::$staticAttributeThree); - Assert::assertEquals('initial_value', \BackupControlTestCaseStore::$staticAttributeFour); - Assert::assertEquals('initial_value', \BackupControlTestCaseStoreTwo::$staticAttribute); - Assert::assertEquals('initial_value', \BackupControlTestCaseStoreTwo::$staticAttributeTwo); - Assert::assertEquals('initial_value', \BackupControlTestCaseStoreTwo::$staticAttributeThree); - Assert::assertEquals('updated_value', \BackupControlTestCaseStoreTwo::$staticAttributeFour); + assertEquals('updated_value', \BackupControlTestCaseStore::$staticAttribute); + assertEquals('initial_value', \BackupControlTestCaseStore::$staticAttributeTwo); + assertEquals('updated_value', \BackupControlTestCaseStore::$staticAttributeThree); + assertEquals('initial_value', \BackupControlTestCaseStore::$staticAttributeFour); + assertEquals('initial_value', \BackupControlTestCaseStoreTwo::$staticAttribute); + assertEquals('initial_value', \BackupControlTestCaseStoreTwo::$staticAttributeTwo); + assertEquals('initial_value', \BackupControlTestCaseStoreTwo::$staticAttributeThree); + assertEquals('updated_value', \BackupControlTestCaseStoreTwo::$staticAttributeFour); } ); } @@ -2367,4 +2354,189 @@ public function should_throw_if_backup_static_attributes_exclude_list_is_not_in_ $this->module(); } + + /** + * It should throw if skipInstall is not a boolean + * + * @test + * @dataProvider notABooleanProvider + */ + public function should_throw_if_skip_install_is_not_a_boolean($input): void + { + $wpRootDir = Env::get('WORDPRESS_ROOT_DIR'); + $db = (new Installation($wpRootDir))->getDb(); + $this->config = [ + 'wpRootFolder' => $wpRootDir, + 'dbUrl' => $db->getDbUrl(), + 'skipInstall' => $input, + ]; + + $this->expectException(ModuleConfigException::class); + + $this->module(); + } + + /** + * It should skip installation when skipInstall is true + * + * @test + */ + public function should_skip_installation_when_skip_install_is_true(): void + { + $wpRootDir = FS::tmpDir('wploader_'); + $installation = Installation::scaffold($wpRootDir); + $dbName = Random::dbName(); + $dbHost = Env::get('WORDPRESS_DB_HOST'); + $dbUser = Env::get('WORDPRESS_DB_USER'); + $dbPassword = Env::get('WORDPRESS_DB_PASSWORD'); + $installationDb = new MysqlDatabase($dbName, $dbUser, $dbPassword, $dbHost, 'wp_'); + $installation->configure($installationDb); + $this->copyOverContentFromTheMainInstallation($installation, [ + 'plugins' => [ + 'woocommerce' + ] + ]); + if (!mkdir($wpRootDir . '/tests/some_test_suite', 0777, true)) { + throw new \RuntimeException('Failed to create the test suite folder.'); + } + $moduleContainerConfig = [ + 'config' => [ + 'suite' => 'some_test_suite', + 'path' => $wpRootDir . '/tests/some_test_suite' + ] + ]; + $moduleConfig = [ + 'wpRootFolder' => $wpRootDir, + 'dbUrl' => $installationDb->getDbUrl(), + 'tablePrefix' => 'test_', + 'skipInstall' => true, + 'plugins' => ['woocommerce/woocommerce.php'], + 'theme' => 'twentytwenty' + ]; + + // Run the module a first time: it should create the flag file indicating the database was installed. + $wpLoader = $this->module($moduleContainerConfig, $moduleConfig); + $moduleSplObjectHash = spl_object_hash($wpLoader); + $this->assertInIsolation( + static function () use ($wpLoader, $moduleSplObjectHash) { + $beforeInstallCalled = false; + $afterInstallCalled = false; + $afterBootstrapCalled = false; + Dispatcher::addListener(WPLoader::EVENT_BEFORE_INSTALL, function () use (&$beforeInstallCalled) { + $beforeInstallCalled = true; + }); + Dispatcher::addListener(WPLoader::EVENT_AFTER_INSTALL, function () use (&$afterInstallCalled) { + $afterInstallCalled = true; + }); + Dispatcher::addListener(WPLoader::EVENT_AFTER_BOOTSTRAP, function () use (&$afterBootstrapCalled) { + $afterBootstrapCalled = true; + }); + + $wpLoader->_initialize(); + + // Check the value directly in the database to skip the `pre_option_` filter. + global $wpdb; + $activePlugins = $wpdb->get_var( + "SELECT option_value FROM {$wpdb->options} WHERE option_name = 'active_plugins'" + ); + assertEquals(['woocommerce/woocommerce.php'], unserialize($activePlugins)); + assertNotEquals('1', getenv('WP_TESTS_SKIP_INSTALL')); + assertTrue(function_exists('do_action')); + assertTrue($beforeInstallCalled); + assertTrue($afterInstallCalled); + assertTrue($afterBootstrapCalled); + assertTrue(function_exists('wc_get_product')); + assertEquals('twentytwenty', wp_get_theme()->get_stylesheet()); + + // Set a canary value. + update_option('canary', $moduleSplObjectHash); + } + ); + + $checkDb = new MysqlDatabase($dbName, $dbUser, $dbPassword, $dbHost, 'test_'); + $checkDb->useDb($dbName); + $this->assertEquals( + ['woocommerce/woocommerce.php'], + $checkDb->getOption('active_plugins'), + 'After the first run, WordPress should be installed and the plugins activated.' + ); + $this->assertEquals('twentytwenty', $checkDb->getOption('stylesheet')); + + // Run a second time, this time the installation should be skipped. + $wpLoader = $this->module($moduleContainerConfig, $moduleConfig); + $this->assertInIsolation( + static function () use ($moduleSplObjectHash, $wpLoader) { + $beforeInstallCalled = false; + $afterInstallCalled = false; + $afterBootstrapCalled = false; + Dispatcher::addListener(WPLoader::EVENT_BEFORE_INSTALL, function () use (&$beforeInstallCalled) { + $beforeInstallCalled = true; + }); + Dispatcher::addListener(WPLoader::EVENT_AFTER_INSTALL, function () use (&$afterInstallCalled) { + $afterInstallCalled = true; + }); + Dispatcher::addListener(WPLoader::EVENT_AFTER_BOOTSTRAP, function () use (&$afterBootstrapCalled) { + $afterBootstrapCalled = true; + }); + + $wpLoader->_initialize(); + + // Check the value directly in the database to skip the `pre_option_` filter. + global $wpdb; + $activePlugins = $wpdb->get_var( + "SELECT option_value FROM {$wpdb->options} WHERE option_name = 'active_plugins'" + ); + assertEquals(['woocommerce/woocommerce.php'], unserialize($activePlugins)); + assertEquals('1', getenv('WP_TESTS_SKIP_INSTALL')); + assertTrue(function_exists('do_action')); + assertTrue($beforeInstallCalled); + assertTrue($afterInstallCalled); + assertTrue($afterBootstrapCalled); + assertTrue(function_exists('wc_get_product')); + assertEquals('twentytwenty', wp_get_theme()->get_stylesheet()); + assertEquals($moduleSplObjectHash, get_option('canary')); + } + ); + + // Now run in --debug mode, the installation should run again. + $wpLoader = $this->module($moduleContainerConfig, $moduleConfig); + $this->assertInIsolation( + static function () use ($moduleSplObjectHash, $wpLoader) { + $beforeInstallCalled = false; + $afterInstallCalled = false; + $afterBootstrapCalled = false; + Dispatcher::addListener(WPLoader::EVENT_BEFORE_INSTALL, function () use (&$beforeInstallCalled) { + $beforeInstallCalled = true; + }); + Dispatcher::addListener(WPLoader::EVENT_AFTER_INSTALL, function () use (&$afterInstallCalled) { + $afterInstallCalled = true; + }); + Dispatcher::addListener(WPLoader::EVENT_AFTER_BOOTSTRAP, function () use (&$afterBootstrapCalled) { + $afterBootstrapCalled = true; + }); + uopz_set_return(Debug::class, 'isEnabled', true); + + $wpLoader->_initialize(); + + // Check the value directly in the database to skip the `pre_option_` filter. + global $wpdb; + $activePlugins = $wpdb->get_var( + "SELECT option_value FROM {$wpdb->options} WHERE option_name = 'active_plugins'" + ); + assertEquals(['woocommerce/woocommerce.php'], unserialize($activePlugins)); + assertNotEquals('1', getenv('WP_TESTS_SKIP_INSTALL')); + assertTrue(function_exists('do_action')); + assertTrue($beforeInstallCalled); + assertTrue($afterInstallCalled); + assertTrue($afterBootstrapCalled); + assertTrue(function_exists('wc_get_product')); + assertEquals('twentytwenty', wp_get_theme()->get_stylesheet()); + assertEquals( + '', + get_option('canary'), + 'The value set in the previous installation should be gone.' + ); + } + ); + } }