diff --git a/docs/superpowers/plans/2026-08-04-hostnamen-trennung.md b/docs/superpowers/plans/2026-08-04-hostnamen-trennung.md index c1cc719..c19cc89 100644 --- a/docs/superpowers/plans/2026-08-04-hostnamen-trennung.md +++ b/docs/superpowers/plans/2026-08-04-hostnamen-trennung.md @@ -696,6 +696,26 @@ it('schreibt bei --dry-run nichts, sagt aber was geschähe', function () { ->and(glob($this->envPath.'.bak-*'))->toBeEmpty(); }); +it('schreibt einen Wert wörtlich, auch wenn er wie ein Rückverweis aussieht', function () { + // SITE_HOST steht schon leer da — genau das, was .env.example wirklich + // ausliefert, und der Pfad, auf dem apply() eine VORHANDENE Zeile ersetzt + // statt sie nur anzuhängen. Das ist der Unterschied, an dem dieser Test + // hängt: gegen einen fehlenden Schlüssel liefe er über den Anhänge-Zweig + // und wäre auch gegen die fehlerhafte Fassung grün gewesen. + file_put_contents($this->envPath, "APP_URL=https://app.example.test\nSITE_HOST=\n"); + + // `$1` und `\1` sind das, was preg_replace im ERSATZ als Rückverweis deutet + // und still verschluckt. Diese Datei hält jedes Geheimnis der Installation + // — was hier ankommt, muss ankommen wie eingegeben. + $this->artisan('clupilot:bind-hosts', [ + '--site' => 'www.example.test$1,foo\1bar', + '--force' => true, + ])->assertSuccessful(); + + expect(file_get_contents($this->envPath)) + ->toContain('SITE_HOST=www.example.test$1,foo\1bar'); +}); + 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',