CluPilotCloud/tests/Feature/BindHostsCommandTest.php

113 lines
4.2 KiB
PHP

<?php
use App\Services\Env\EnvFileEditor;
beforeEach(function () {
// Eine eigene Datei je Test. Der Befehl schreibt sonst die .env dieser
// Entwicklungsmaschine, und ein Test, der das kann, wird irgendwann
// versehentlich scharf ausgeführt.
$this->envPath = sys_get_temp_dir().'/clupilot-env-'.bin2hex(random_bytes(6));
$this->app->instance(EnvFileEditor::class, new EnvFileEditor($this->envPath));
});
afterEach(function () {
foreach (glob($this->envPath.'*') ?: [] as $file) {
@unlink($file);
}
});
it('trägt die fehlenden Hostnamen nach', function () {
file_put_contents($this->envPath, "APP_URL=https://app.example.test\nADMIN_HOSTS=admin.example.test\n");
$this->artisan('clupilot:bind-hosts', [
'--site' => 'www.example.test,example.test',
'--status' => 'status.example.test',
'--files' => 'files.example.test',
'--force' => true,
])->assertSuccessful();
$written = file_get_contents($this->envPath);
// APP_HOST kommt aus dem Host von APP_URL — danach muss niemand gefragt
// werden, die Antwort steht schon in der Datei.
expect($written)->toContain('APP_HOST=app.example.test')
->and($written)->toContain('SITE_HOST=www.example.test,example.test')
->and($written)->toContain('STATUS_HOST=status.example.test')
->and($written)->toContain('FILES_HOST=files.example.test')
// Und nichts Vorhandenes geht verloren.
->and($written)->toContain('APP_URL=https://app.example.test')
->and($written)->toContain('ADMIN_HOSTS=admin.example.test');
});
it('überschreibt niemals einen Wert, den jemand von Hand gesetzt hat', function () {
file_put_contents(
$this->envPath,
"APP_URL=https://app.example.test\nAPP_HOST=eigener.example.test\nSITE_HOST=\n",
);
$this->artisan('clupilot:bind-hosts', [
'--site' => 'www.example.test',
'--force' => true,
])->assertSuccessful();
$written = file_get_contents($this->envPath);
// Gesetzt bleibt gesetzt …
expect($written)->toContain('APP_HOST=eigener.example.test')
->and($written)->not->toContain('APP_HOST=app.example.test')
// … und leer gilt als fehlend, denn genau so liefert .env.example aus.
->and($written)->toContain('SITE_HOST=www.example.test');
});
it('sichert die alte Datei, bevor es schreibt', function () {
file_put_contents($this->envPath, "APP_URL=https://app.example.test\n");
$this->artisan('clupilot:bind-hosts', ['--force' => true])->assertSuccessful();
// EnvFileEditor legt eine Kopie mit Zeitstempel daneben. Diese Datei hält
// jedes Geheimnis der Installation; ein Schreibfehler darf sie nicht
// ersatzlos ersetzen.
expect(glob($this->envPath.'.bak-*'))->not->toBeEmpty();
});
it('tut ohne Bestätigung nichts', function () {
file_put_contents($this->envPath, "APP_URL=https://app.example.test\n");
$this->artisan('clupilot:bind-hosts', ['--site' => 'www.example.test'])
->expectsConfirmation(
'Diese Namen jetzt binden?',
'no',
)
->assertFailed();
expect(file_get_contents($this->envPath))->not->toContain('SITE_HOST');
});
it('schreibt bei --dry-run nichts, sagt aber was geschähe', function () {
file_put_contents($this->envPath, "APP_URL=https://app.example.test\n");
$this->artisan('clupilot:bind-hosts', ['--site' => 'www.example.test', '--dry-run' => true])
->expectsOutputToContain('SITE_HOST=www.example.test')
->assertSuccessful();
expect(file_get_contents($this->envPath))->not->toContain('SITE_HOST')
->and(glob($this->envPath.'.bak-*'))->toBeEmpty();
});
it('sagt es, wenn schon alles steht, statt eine Sicherung anzulegen', function () {
file_put_contents($this->envPath, implode("\n", [
'APP_URL=https://app.example.test',
'APP_HOST=app.example.test',
'SITE_HOST=www.example.test',
'STATUS_HOST=status.example.test',
'FILES_HOST=files.example.test',
'',
]));
$this->artisan('clupilot:bind-hosts', ['--force' => true])
->expectsOutputToContain('Nichts nachzutragen')
->assertSuccessful();
expect(glob($this->envPath.'.bak-*'))->toBeEmpty();
});