faef8f8a91
Operator ruling 2026-10-12 (S27, 09 §3 decision 222). The operator approves the Hungarian text before release. A box whose first ingestion failed now serves one bilingual waiting page and retries every minute instead of the wizard. Own commit so the lead can hold it back. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
69 lines
2.4 KiB
Go
69 lines
2.4 KiB
Go
package recovery
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// R-554 (`09` §3 decision 222): recovery-info.txt points at the dashboard's Restore page and the recovery
|
|
// code — never at the deleted first-boot wizard (docker-setup.sh, :8081, „Visszaállítás mentésből").
|
|
//
|
|
// RED-PROOF (REPORT): the old text (docker-setup.sh … http://<ip>:8081 … varázsló) fails every
|
|
// "must carry" line and every "must not carry" line.
|
|
func TestRecoveryInfo_PointsAtDashboardNotWizard(t *testing.T) {
|
|
info := Info{
|
|
CustomerID: "c-123", RetrievalPassword: "TESTONLY-retrieval-pw", HubURL: "https://hub.example",
|
|
SupportEmail: "support@felhom.eu", SupportURL: "https://felhom.eu/kapcsolat",
|
|
DashboardURL: "https://felhom.example.hu/",
|
|
}
|
|
at := time.Date(2026, 10, 12, 15, 4, 5, 0, time.UTC)
|
|
for _, tc := range []struct {
|
|
lang string
|
|
must []string
|
|
}{
|
|
{"hu", []string{"Biztonsági mentés → Visszaállítás", "helyreállítási kód", "Adatok visszaszerzése"}},
|
|
{"en", []string{"Backup → Restore", "recovery code", "Retrieve data"}},
|
|
} {
|
|
info.Lang = tc.lang
|
|
got, err := Render(info, "0.308.0", at)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, want := range append(tc.must,
|
|
"https://felhom.example.hu/backups/restore", "https://felhom.example.hu/recovery",
|
|
"c-123", "https://hub.example", "TESTONLY-retrieval-pw", "2026-10-12 15:04:05", "0.308.0") {
|
|
if !strings.Contains(got, want) {
|
|
t.Errorf("%s: the file does not carry %q", tc.lang, want)
|
|
}
|
|
}
|
|
for _, gone := range []string{"docker-setup.sh", ":8081", "Visszaállítás mentésből", "varázsló", "wizard", "%!"} {
|
|
if strings.Contains(got, gone) {
|
|
t.Errorf("%s: the file still carries %q", tc.lang, gone)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// The file is written 0600 (it holds the retrieval password) and in the box's language.
|
|
func TestGenerateRecoveryFile_WritesPrivateFile(t *testing.T) {
|
|
dir := t.TempDir()
|
|
if err := GenerateRecoveryFile(Info{CustomerID: "c-1", DashboardURL: "https://felhom.x.hu", Lang: "en"}, "0.308.0", dir); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
p := filepath.Join(dir, "recovery-info.txt")
|
|
fi, err := os.Stat(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if fi.Mode().Perm() != 0o600 {
|
|
t.Errorf("mode = %v, want 0600", fi.Mode().Perm())
|
|
}
|
|
b, _ := os.ReadFile(p)
|
|
if !strings.Contains(string(b), "Emergency information") {
|
|
t.Errorf("an English box's file is not in English")
|
|
}
|
|
}
|