Files
felhom-controller/controller/internal/web/r553_stale_note_test.go
T
admin 5270bad76e
gates / gates (push) Successful in 23s
v0.252.0 — the sentences the program builds follow the language (R-557 slice 2 release A)
Slice 1 translated the dashboard's markup. The sentences the program BUILDS were still
Hungarian literals in Go, so an English household clicked an English button and was
answered in Hungarian. 226 of them move into the bundle here.

A flash was the hard part: it travels inside the redirect URL and is rendered by a
DIFFERENT request, so it now carries a bundle key plus its parameters. A link minted by
an older controller carries prose and is shown verbatim — never a raw key, never dropped.

Also converted: page data and view-model text, the internal/api JSON answers, the alert
banners (Alert.MessageKey, rendered on the way out of GetAlerts), 237 country names at
display, and the four page titles built around an app name (R-566 closed).

Hungarian is byte-identical, and that is measured rather than read:
scripts/i18n_go_parity.py freezes every Go literal at the base commit (7 467) and refuses
a key whose Hungarian is not that text, byte for byte. Three decoys, each seen to convict.
Its own first version filtered the capture through an ASCII-Hungarian word list and missed
seven real literals — the R-565 class. The filter is gone.

Nothing on the wire moved, and wire goldens now hold it there: the report's health
warnings and every notify event message stay Hungarian, because the hub MAILS the
controller's sentence when it has no entry of its own. Slice 3 (R-558) owns those.

MinAgent: 0.131.0 (unchanged). No hub release needed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-18 10:15:56 +02:00

100 lines
4.4 KiB
Go

package web
import (
"io"
"log"
"path/filepath"
"strings"
"testing"
"gitea.dooplex.hu/admin/felhom-controller/internal/backup"
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
)
// R-553 — the Távoli mentés page replaces a stale „nothing was selected" run note once apps HAVE been
// selected. It used to find that note by searching the sentence for „nincs mentésre jelölt alkalmazás";
// slice 2 translates the sentence, and the stale note would then come back and stay — telling a
// household that has selected apps that nothing is covered.
//
// RED-PROOF (REPORT): make offboxWarningDisplay decide by the marker again (drop the kind arm) and
// the TRANSLATED row fails: the stale sentence is shown verbatim.
func TestR553_StaleNoteDecisionSurvivesWordingChange(t *testing.T) {
s, _, _ := newOffboxWebServer(t)
// The replacement note is read from the bundle (v0.252.0, R-557): the same sentence the constant
// used to hold, now measured against hu.json rather than restated beside it.
selectionChanged := s.msgLang("hu", offboxSelectionChangedKey)
const hu = "Sikeres — nincs mentésre jelölt alkalmazás"
const en = "Success — no app is selected for backup"
cases := []struct {
name, warning, kind string
toggled int
want string
}{
{"as shipped, apps now selected", hu, backup.OffboxWarnNoAppsSelected, 1, selectionChanged},
{"TRANSLATED, apps now selected", en, backup.OffboxWarnNoAppsSelected, 2, selectionChanged},
{"still nothing selected → the honest note stays", hu, backup.OffboxWarnNoAppsSelected, 0, hu},
{"a quota note passes through", "A tároló a keret 84%-át használja (42/50 GB).", "", 3,
"A tároló a keret 84%-át használja (42/50 GB)."},
// LEGACY: a box upgraded to v0.251.0 still carries the OLD text with no kind until its next
// off-site run rewrites it. Until then the text test is what it has.
{"legacy persisted text, no kind", hu, "", 1, selectionChanged},
{"legacy: any other text without a kind is shown verbatim", "Valami más történt.", "", 1, "Valami más történt."},
}
for _, c := range cases {
if got := s.offboxWarningDisplay(c.warning, c.kind, c.toggled, "hu"); got != c.want {
t.Errorf("%s:\n got %q\nwant %q", c.name, got, c.want)
}
}
}
// The consequence on the page itself: with a TRANSLATED warning that carries the kind, the rendered
// Távoli mentés page shows the selection-changed note and not the stale sentence.
func TestR553_StaleNoteOnTheRenderedPage(t *testing.T) {
s, _, _ := newOffboxWebServer(t)
selectionChanged := s.msgLang("hu", offboxSelectionChangedKey)
const en = "Success — no app is selected for backup"
data := appRowSplitData()
data["Offbox"] = &settings.OffboxTarget{
Enabled: true, Host: "nas.local", LastStatus: "ok", EscrowState: "escrowed",
LastWarning: en, LastWarningKind: backup.OffboxWarnNoAppsSelected,
}
data["OffboxWarningDisplay"] = s.offboxWarningDisplay(en, backup.OffboxWarnNoAppsSelected, 1, "hu")
html := renderBackupPage(t, "backups_remote", data)
if !strings.Contains(html, selectionChanged) {
t.Error("the selection-changed note is missing for a translated warning that carries its kind")
}
if strings.Contains(html, en) {
t.Error("the stale note is still on the page beside its replacement")
}
}
// The kind has to be PERSISTED beside the text and survive an edit of the target, or the page falls
// back to the legacy text test on the next render (settings.json is the only carrier between runs).
func TestR553_WarningKindIsPersistedAndCopied(t *testing.T) {
tgt := settings.OffboxTarget{
Enabled: true, Host: "nas.local", User: "felhom", RepoPath: "/srv/repo",
LastWarning: "Sikeres — nincs mentésre jelölt alkalmazás", LastWarningKind: backup.OffboxWarnNoAppsSelected,
}
dir := t.TempDir()
load := func() *settings.Settings {
s, err := settings.Load(filepath.Join(dir, "settings.json"), log.New(io.Discard, "", 0))
if err != nil {
t.Fatal(err)
}
return s
}
if err := load().SetOffboxTarget(&tgt); err != nil {
t.Fatal(err)
}
reloaded := load().GetOffboxTarget()
if reloaded == nil {
t.Fatal("the target did not survive the reload")
}
if reloaded.LastWarningKind != backup.OffboxWarnNoAppsSelected {
t.Errorf("the warning kind was not persisted: %q", reloaded.LastWarningKind)
}
if reloaded.LastWarning != tgt.LastWarning {
t.Errorf("the warning text changed across the reload: %q", reloaded.LastWarning)
}
}