Skip to content

Commit

Permalink
transpile #755
Browse files Browse the repository at this point in the history
  • Loading branch information
lucatume committed Sep 11, 2024
1 parent 1cb05aa commit a1eb010
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 10 deletions.
4 changes: 3 additions & 1 deletion src/Module/WPLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -647,11 +647,13 @@ public function _loadWordPress(?bool $loadOnly = null): void
$this->loadConfigFiles();

if ($loadOnly) {
putenv('WPBROWSER_LOAD_ONLY=1');
Dispatcher::dispatch(self::EVENT_BEFORE_LOADONLY, $this);
$loadSandbox = new LoadSandbox($this->installation->getWpRootDir(), $this->config['domain']);
$loadSandbox->load();
$loadSandbox->load($this->db);
Dispatcher::dispatch(self::EVENT_AFTER_LOADONLY, $this);
} else {
putenv('WPBROWSER_LOAD_ONLY=0');
$this->installAndBootstrapInstallation();
}

Expand Down
24 changes: 23 additions & 1 deletion src/WordPress/LoadSandbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

namespace lucatume\WPBrowser\WordPress;

use lucatume\WPBrowser\Utils\MonkeyPatch;
use lucatume\WPBrowser\Utils\Property;
use lucatume\WPBrowser\WordPress\Database\DatabaseInterface;
use lucatume\WPBrowser\WordPress\Database\MysqlDatabase;

class LoadSandbox
{
/**
Expand Down Expand Up @@ -30,7 +35,7 @@ public function __construct(string $wpRootDir, string $domain)
/**
* @throws InstallationException
*/
public function load(): void
public function load(?DatabaseInterface $db = null): void
{
$this->setUpServerVars();
PreloadFilters::addFilter('wp_fatal_error_handler_enabled', [$this, 'returnFalse'], 100);
Expand All @@ -39,9 +44,26 @@ public function load(): void
// Setting the `chunk_size` to `0` means the function will only be called when the output buffer is closed.
ob_start([$this, 'obCallback'], 0);

if ($db instanceof MysqlDatabase) {
define('DB_NAME', $db->getDbName());
define('DB_USER', $db->getDbUser());
define('DB_PASSWORD', $db->getDbPassword());
define('DB_HOST', $db->getDbHost());

// Silence errors about the redeclaration of the above `DB_` constants.
$previousErrorHandler = set_error_handler(static function ($errno, $errstr) {
return $errno === E_WARNING
&& preg_match('/^Constant DB_(NAME|USER|PASSWORD|HOST) already defined/i', $errstr);
});
}

// Exceptions thrown during loading are not wrapped on purpose to remove debug overhead.
include_once $this->wpRootDir . '/wp-load.php';

if (!empty($previousErrorHandler)) {
set_error_handler($previousErrorHandler);
}

ob_end_clean();
// If this is reached, then WordPress has loaded correctly.
remove_filter('wp_fatal_error_handler_enabled', [$this, 'returnFalse'], 100);
Expand Down
21 changes: 13 additions & 8 deletions tests/_support/Traits/InstallationMocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@ trait InstallationMocks
/**
* @return array{0: string, 1: string}
*/
private function makeMockConfiguredInstallation(string $phpExtra = ''): array
private function makeMockConfiguredInstallation(string $phpExtra = '', array $overrides = []): array
{
$dbUser = Env::get('WORDPRESS_DB_USER');
$dbPassword = Env::get('WORDPRESS_DB_PASSWORD');
$dbLocalhostPort = Env::get('WORDPRESS_DB_LOCALHOST_PORT');
$dbName = Env::get('WORDPRESS_DB_NAME');
$dbUser = $overrides['dbUser'] ?? Env::get('WORDPRESS_DB_USER');
$dbPassword = $overrides['dbPassword'] ?? Env::get('WORDPRESS_DB_PASSWORD');
if(!isset($overrides['dbHost'])){
$dbLocalhostPort = $overrides['dbLocalhostPort'] ?? Env::get('WORDPRESS_DB_LOCALHOST_PORT');
$dbHost = '127.0.0.1:' . $dbLocalhostPort;
} else {
$dbHost = $overrides['dbHost'];
}
$dbName = $overrides['dbName'] ?? Env::get('WORDPRESS_DB_NAME');
$wpRootFolder = FS::tmpDir('wploader_', [
'wp-includes' => [
'version.php' => <<<PHP
Expand All @@ -35,7 +40,7 @@ private function makeMockConfiguredInstallation(string $phpExtra = ''): array
define('DB_NAME', '{$dbName}');
define('DB_USER', '{$dbUser}');
define('DB_PASSWORD', '{$dbPassword}');
define('DB_HOST', '127.0.0.1:{$dbLocalhostPort}');
define('DB_HOST', '{$dbHost}');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
global \$table_prefix;
Expand All @@ -55,10 +60,10 @@ private function makeMockConfiguredInstallation(string $phpExtra = ''): array
'wp-load.php' => '<?php do_action("wp_loaded");',
]);
$dbUrl = sprintf(
'mysql://%s:%s@127.0.0.1:%d/%s',
'mysql://%s:%s@%s/%s',
$dbUser,
$dbPassword,
$dbLocalhostPort,
$dbHost,
$dbName
);

Expand Down
126 changes: 126 additions & 0 deletions tests/unit/lucatume/WPBrowser/Module/WPLoaderLoadOnlyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Codeception\Test\Unit;
use lucatume\WPBrowser\Tests\Traits\Fork;
use lucatume\WPBrowser\Tests\Traits\InstallationMocks;
use lucatume\WPBrowser\Utils\Env;
use lucatume\WPBrowser\Utils\Filesystem as FS;

class WPLoaderLoadOnlyTest extends Unit
{
Expand Down Expand Up @@ -79,4 +81,128 @@ public function testWillLoadWordPressInInitializeWhenLoadOnlyIsFalse(): void
$this->assertTrue($module->_didLoadWordPress());
});
}

public function testWillDefineDBConstantsWhenLoadOnlyTrue(): void{
[$wpRootFolder] = $this->makeMockConfiguredInstallation('', [
'dbUser' => 'production_user',
'dbPassword' => 'production_password',
'dbHost' => '10.0.0.1:8876',
'dbName' => 'test_db',
]);
file_put_contents($wpRootFolder . '/wp-load.php', '<?php include_once __DIR__ . "/wp-config.php"; do_action("wp_loaded");');
$testDbUser = Env::get('WORDPRESS_DB_USER');
$testDbPassword = Env::get('WORDPRESS_DB_PASSWORD');
$testDbHost = '127.0.0.1:' . Env::get('WORDPRESS_DB_LOCALHOST_PORT');
$testDbName = Env::get('WORDPRESS_DB_NAME');
$testDbUrl = sprintf(
'mysql://%s:%s@%s/%s',
$testDbUser,
$testDbPassword,
$testDbHost,
$testDbName
);
$moduleContainer = new ModuleContainer(new Di(), []);
$module = new WPLoader($moduleContainer, [
'dbUrl' => $testDbUrl,
'wpRootFolder' => $wpRootFolder,
'loadOnly' => true,
]);

Fork::executeClosure(function () use ($testDbName, $testDbHost, $testDbPassword, $testDbUser, $module) {
// WordPress' functions are stubbed by wordpress-stubs in unit tests: override them to do something.
$did_actions = [];
uopz_set_return('do_action', static function ($action) use (&$did_actions) {
$did_actions[$action] = true;
}, true);
uopz_set_return('did_action', static function ($action) use (&$did_actions) {
return isset($did_actions[$action]);
}, true);
// Partial mocking the function that would load WordPress.
uopz_set_return(WPLoader::class, 'installAndBootstrapInstallation', function () {
return true;
}, true);

$module->_initialize();
$module->_beforeSuite();

$this->assertTrue($module->_didLoadWordPress());
$this->assertEquals($testDbUser, DB_USER);
$this->assertEquals($testDbPassword, DB_PASSWORD);
$this->assertEquals($testDbHost, DB_HOST);
$this->assertEquals($testDbName, DB_NAME);
$this->assertEquals('1', getenv('WPBROWSER_LOAD_ONLY'));
});
}

public function testWillLoadConfigFileWhenLoadOnlyTrue(): void{
[$wpRootFolder, $dbUrl] = $this->makeMockConfiguredInstallation();
$configDir = FS::tmpDir('config_', [
'test-config.php' => '<?php define("TEST_CONFIG", true);'
]);
$moduleContainer = new ModuleContainer(new Di(), []);
$module = new WPLoader($moduleContainer, [
'dbUrl' => $dbUrl,
'wpRootFolder' => $wpRootFolder,
'loadOnly' => true,
'configFile' => $configDir . '/test-config.php'
]);

Fork::executeClosure(function () use ($module) {
// WordPress' functions are stubbed by wordpress-stubs in unit tests: override them to do something.
$did_actions = [];
uopz_set_return('do_action', static function ($action) use (&$did_actions) {
$did_actions[$action] = true;
}, true);
uopz_set_return('did_action', static function ($action) use (&$did_actions) {
return isset($did_actions[$action]);
}, true);
// Partial mocking the function that would load WordPress.
uopz_set_return(WPLoader::class, 'installAndBootstrapInstallation', function () {
return true;
}, true);

$module->_initialize();
$module->_beforeSuite();

$this->assertTrue($module->_didLoadWordPress());
$this->assertTrue(defined('TEST_CONFIG'));
});
}

public function testWillLoadMultipleConfigFilesWhenLoadOnlyTrue(): void{
[$wpRootFolder, $dbUrl] = $this->makeMockConfiguredInstallation();
$configDir = FS::tmpDir('config_', [
'test-config.php' => '<?php define("TEST_CONFIG", true);',
'test-config2.php' => '<?php define("TEST_CONFIG2", true);'
]);
$moduleContainer = new ModuleContainer(new Di(), []);
$module = new WPLoader($moduleContainer, [
'dbUrl' => $dbUrl,
'wpRootFolder' => $wpRootFolder,
'loadOnly' => true,
'configFile' => [$configDir . '/test-config.php', $configDir . '/test-config2.php']
]);

Fork::executeClosure(function () use ($module) {
// WordPress' functions are stubbed by wordpress-stubs in unit tests: override them to do something.
$did_actions = [];
uopz_set_return('do_action', static function ($action) use (&$did_actions) {
$did_actions[$action] = true;
}, true);
uopz_set_return('did_action', static function ($action) use (&$did_actions) {
return isset($did_actions[$action]);
}, true);
// Partial mocking the function that would load WordPress.
uopz_set_return(WPLoader::class, 'installAndBootstrapInstallation', function () {
return true;
}, true);

$module->_initialize();
$module->_beforeSuite();

$this->assertTrue($module->_didLoadWordPress());
$this->assertTrue(defined('TEST_CONFIG'));
$this->assertTrue(defined('TEST_CONFIG2'));
});
}
}

0 comments on commit a1eb010

Please sign in to comment.