From 1d0bacc65070c34f5780c92760793dbf7cd2849d Mon Sep 17 00:00:00 2001 From: nexxo Date: Mon, 3 Aug 2026 23:57:42 +0200 Subject: [PATCH] Ein Schritt ohne Namen zeigt bei jeder Bestellung seinen Schluessel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit provisioning.step.configure_instance_mail fehlte in beiden Sprachdateien, waehrend der Schritt in der Pflicht-Pipeline steht: die Konsole zeigte bei JEDER bezahlten Bestellung den rohen Schluessel. Dazu die Pruefung, die danach fragt — fuer jeden Schritt jeder Pipeline, in beiden Sprachen. Sie liest die Sprachdatei selbst und nicht trans($key, [], 'de'): Laravel faellt bei einem fehlenden deutschen Eintrag stumm auf die Ersatzsprache zurueck, und die erste Fassung dieser Pruefung lief genau deshalb gruen, obwohl der deutsche Eintrag geloescht war. Nachgeprueft, nicht angenommen. Und label() des Schrittes selbst statt eines hier nachgebauten Schluessels: Host- und Kundenschritte liegen in verschiedenen Sprachdateien, und ein Test, der die Zusammensetzung nachrechnet, prueft die Zusammensetzung statt den Eintrag. Co-Authored-By: Claude Opus 5 --- lang/de/provisioning.php | 1 + lang/en/provisioning.php | 1 + .../Provisioning/PipelineRegistryTest.php | 40 +++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/lang/de/provisioning.php b/lang/de/provisioning.php index 6cc818c..68fd763 100644 --- a/lang/de/provisioning.php +++ b/lang/de/provisioning.php @@ -11,6 +11,7 @@ return [ 'configure_network' => 'Netzwerk konfigurieren', 'deploy_application_stack' => 'Anwendung ausrollen', 'configure_nextcloud' => 'Nextcloud einrichten', + 'configure_instance_mail' => 'Mailversand einrichten', 'create_customer_admin' => 'Admin-Konto anlegen', 'configure_dns_and_tls' => 'DNS & TLS einrichten', 'register_backup' => 'Backup einrichten', diff --git a/lang/en/provisioning.php b/lang/en/provisioning.php index 2b81849..3afc1ac 100644 --- a/lang/en/provisioning.php +++ b/lang/en/provisioning.php @@ -11,6 +11,7 @@ return [ 'configure_network' => 'Configure network', 'deploy_application_stack' => 'Deploy application stack', 'configure_nextcloud' => 'Set up Nextcloud', + 'configure_instance_mail' => 'Set up mail delivery', 'create_customer_admin' => 'Create admin account', 'configure_dns_and_tls' => 'Configure DNS & TLS', 'register_backup' => 'Register backup', diff --git a/tests/Feature/Provisioning/PipelineRegistryTest.php b/tests/Feature/Provisioning/PipelineRegistryTest.php index 12879aa..5250f16 100644 --- a/tests/Feature/Provisioning/PipelineRegistryTest.php +++ b/tests/Feature/Provisioning/PipelineRegistryTest.php @@ -6,6 +6,7 @@ use App\Provisioning\PipelineRegistry; use App\Provisioning\Steps\Customer\ConfigureDnsAndTls; use App\Provisioning\Steps\Customer\ConfigureNextcloud; use App\Provisioning\WorkInFlight; +use Illuminate\Support\Arr; use Tests\Support\Steps\FakeAdvanceStep; use Tests\Support\Steps\FakeRetryStep; @@ -107,3 +108,42 @@ it('lays the maintenance pipelines out so a half-finished address is a safe one' ->toBeLessThan(array_search($dns, $steps, true)); } }); + +it('gives every step of every pipeline a name a human can read, in both languages', function () { + // `configure_instance_mail` stand in der Pflicht-Pipeline und hatte keinen + // Spracheintrag: die Konsole zeigte bei JEDER bezahlten Bestellung den + // rohen Schlüssel. Ein neuer Schritt ist eine Zeile Code und eine Zeile + // Sprache — die zweite vergisst man, und niemand merkt es, weil kein Test + // je danach gefragt hat. + // + // Gelesen wird die Sprachdatei selbst, NICHT trans($key, [], 'de'): + // Laravel fällt bei einem fehlenden deutschen Eintrag stumm auf die + // Ersatzsprache zurück, und ein Test darauf hätte einen fehlenden + // deutschen Text durchgewunken, solange es den englischen gibt. + // Nachgeprüft, nicht angenommen — die erste Fassung dieses Tests lief + // genau deshalb gruen, obwohl der deutsche Eintrag gelöscht war. + $dateien = []; + $fehlend = []; + + foreach (array_keys((array) config('provisioning.pipelines')) as $pipeline) { + foreach ((array) config('provisioning.pipelines.'.$pipeline) as $step) { + // label() des Schrittes selbst, nicht ein hier nachgebauter + // Schlüssel: Host- und Kundenschritte liegen in verschiedenen + // Sprachdateien (`hosts.step.*` bzw. `provisioning.step.*`), und + // ein Test, der die Zusammensetzung nachrechnet, prüft die + // Zusammensetzung statt den Eintrag (R19). + [$gruppe, $rest] = explode('.', app($step)->label(), 2); + + foreach (['de', 'en'] as $sprache) { + $pfad = lang_path($sprache.'/'.$gruppe.'.php'); + $dateien[$sprache.'/'.$gruppe] ??= is_file($pfad) ? (array) require $pfad : []; + + if (! Arr::has($dateien[$sprache.'/'.$gruppe], $rest)) { + $fehlend[] = $sprache.': '.$gruppe.'.'.$rest; + } + } + } + } + + expect(array_values(array_unique($fehlend)))->toBe([]); +});