mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
composer.json, phpunit.xml and the ruby runner were already in place and had never run a single test, so 24 php and 20 ruby files shipped with nothing but php -l and ruby -c behind them. The two joomla scripts are pure file-in/file-out driven by env, which is testable without Joomla: the tests drive the real script against a temporary configuration.php. They pin what the code silently does today — apostrophe escaping in the error level and in the db password, the two repair regexes for malformed public lines, a missing key that is left absent rather than added, and the asymmetry that toggle_debug exits 1 on a missing file while configure_db exits 0. The mastodon initializer is an env gate that downgrades URL building to http. The test pins the security-relevant half: with OIDC off, with an https issuer and with no issuer at all, SWD stays undefined. The http case proves the branch is taken. The three nocheck markers had to go with it: the mirrored-unit-test lint fails a file that carries both a test and an exemption. package_plugin.php keeps its marker, it is a build step. vendor/ and .phpunit.result.cache were not ignored; composer install drops 25 packages into the tree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
122 lines
3.6 KiB
PHP
122 lines
3.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class ConfigureDbTest extends TestCase
|
|
{
|
|
/**
|
|
* Run the script against a throwaway configuration.php.
|
|
*
|
|
* @param array<string, string> $env extra environment for the child
|
|
* @param string|null $contents fixture content, null to omit the file
|
|
* @return array{0: string, 1: int, 2: string|null}
|
|
* stdout, exit code and the file content afterwards
|
|
*/
|
|
private function runScript(array $env, ?string $contents): array
|
|
{
|
|
$file = tempnam(sys_get_temp_dir(), 'jcfg');
|
|
if ($contents === null) {
|
|
unlink($file);
|
|
} else {
|
|
file_put_contents($file, $contents);
|
|
}
|
|
|
|
$script = dirname(__DIR__, 6) . '/roles/web-app-joomla/files/php/configure_db.php';
|
|
$process = proc_open(
|
|
[PHP_BINARY, $script],
|
|
[1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
|
|
$pipes,
|
|
null,
|
|
$env + ['J_CONFIG_FILE' => $file, 'PATH' => (string) getenv('PATH')]
|
|
);
|
|
$stdout = (string) stream_get_contents($pipes[1]);
|
|
fclose($pipes[1]);
|
|
fclose($pipes[2]);
|
|
$code = proc_close($process);
|
|
|
|
$after = is_file($file) ? (string) file_get_contents($file) : null;
|
|
if (is_file($file)) {
|
|
unlink($file);
|
|
}
|
|
|
|
return [$stdout, $code, $after];
|
|
}
|
|
|
|
private const CONFIG = <<<'PHP'
|
|
<?php
|
|
class JConfig {
|
|
public $dbtype = 'mysqli';
|
|
public $host = 'old-host';
|
|
public $user = 'joomla';
|
|
public $password = 'old-secret';
|
|
public $db = 'joomla';
|
|
}
|
|
PHP;
|
|
|
|
/** @return array<string, string> */
|
|
private function env(string $host, string $password): array
|
|
{
|
|
return [
|
|
'J_DBTYPE' => 'mysqli',
|
|
'J_DBHOST' => $host,
|
|
'J_DBUSER' => 'joomla',
|
|
'J_DBPASS' => $password,
|
|
'J_DBNAME' => 'joomla',
|
|
];
|
|
}
|
|
|
|
public function testOnlyDifferingValuesAreRewritten(): void
|
|
{
|
|
[$stdout, $code, $after] = $this->runScript(
|
|
$this->env('new-host', 'old-secret'),
|
|
self::CONFIG
|
|
);
|
|
|
|
$this->assertSame(0, $code);
|
|
$this->assertSame('changed', $stdout);
|
|
$this->assertStringContainsString("public \$host = 'new-host';", (string) $after);
|
|
$this->assertStringContainsString("public \$user = 'joomla';", (string) $after);
|
|
}
|
|
|
|
public function testMatchingConfigIsReportedAsOkAndLeftAlone(): void
|
|
{
|
|
[$stdout, , $after] = $this->runScript(
|
|
$this->env('old-host', 'old-secret'),
|
|
self::CONFIG
|
|
);
|
|
|
|
$this->assertSame('ok', $stdout);
|
|
$this->assertSame(self::CONFIG, $after);
|
|
}
|
|
|
|
public function testPasswordWithApostropheIsEscaped(): void
|
|
{
|
|
[, , $after] = $this->runScript(
|
|
$this->env('old-host', "pa'ss"),
|
|
self::CONFIG
|
|
);
|
|
|
|
$this->assertStringContainsString("public \$password = 'pa\\'ss';", (string) $after);
|
|
}
|
|
|
|
public function testAbsentKeyIsNotAdded(): void
|
|
{
|
|
[, , $after] = $this->runScript(
|
|
$this->env('new-host', 'old-secret'),
|
|
"<?php\nclass JConfig {\n\tpublic \$host = 'old-host';\n}\n"
|
|
);
|
|
|
|
$this->assertStringNotContainsString('$dbtype', (string) $after);
|
|
}
|
|
|
|
public function testMissingConfigFileIsAcceptedSilently(): void
|
|
{
|
|
[$stdout, $code] = $this->runScript($this->env('new-host', 'x'), null);
|
|
|
|
$this->assertSame(0, $code);
|
|
$this->assertSame('', $stdout);
|
|
}
|
|
}
|