diff --git a/controller/internal/web/handlers.go b/controller/internal/web/handlers.go index 1b88fdb..736d48f 100644 --- a/controller/internal/web/handlers.go +++ b/controller/internal/web/handlers.go @@ -653,10 +653,37 @@ func (s *Server) backupsOffboxData(data map[string]interface{}) { } } data["OffboxToggledCount"] = offboxToggled + // Part E (v0.126.0): the LastWarning DISPLAY pick — never a state mutation. + if offboxTgt != nil { + data["OffboxWarningDisplay"] = offboxWarningDisplay(offboxTgt.LastWarning, offboxToggled) + } else { + data["OffboxWarningDisplay"] = "" + } // SLICE 4 soft-quota usage bar (rendered only when a quota is set — shared model). data["OffboxQuotaPct"] = backup.OffboxQuotaPercent(offboxTgt) } +// offboxStaleWarningMarker is the substring the zero-toggled offbox run writes into +// LastWarning (backup/offbox.go); offboxSelectionChangedLine replaces it once the +// selection has moved on. +const ( + offboxStaleWarningMarker = "nincs mentésre jelölt alkalmazás" + offboxSelectionChangedLine = "A kijelölés módosult az utolsó futás óta — a következő távoli mentés már tartalmazza." +) + +// offboxWarningDisplay picks what the Távoli mentés page shows for the persisted +// Offbox.LastWarning. A zero-toggled run records "Sikeres — nincs mentésre jelölt +// alkalmazás…"; once the customer HAS toggled apps that line is stale and misleading — +// replace it with the honest "selection changed, the next run covers it" note. +// Pure display logic: the persisted LastWarning is never touched, and every other +// warning (quota, partial failure) passes through verbatim. +func offboxWarningDisplay(lastWarning string, toggledCount int) string { + if toggledCount >= 1 && strings.Contains(lastWarning, offboxStaleWarningMarker) { + return offboxSelectionChangedLine + } + return lastWarning +} + // backupsHandler renders the Áttekintés page: storage overview, whole-guest Rendszermentés and // the status stat cards. func (s *Server) backupsHandler(w http.ResponseWriter, r *http.Request) { diff --git a/controller/internal/web/offbox_warning_display_test.go b/controller/internal/web/offbox_warning_display_test.go new file mode 100644 index 0000000..424ff98 --- /dev/null +++ b/controller/internal/web/offbox_warning_display_test.go @@ -0,0 +1,73 @@ +package web + +import ( + "strings" + "testing" + + "gitea.dooplex.hu/admin/felhom-controller/internal/settings" +) + +// v0.126.0 Part E — the stale zero-toggle warning line tells the truth. Display-pick only: +// the persisted LastWarning is never mutated; the page swaps the stale "nincs mentésre +// jelölt alkalmazás" run-result for the selection-changed note once ≥1 app is toggled. +// COMPANION red-proof (recorded in REPORT): make offboxWarningDisplay return lastWarning +// unconditionally → TestOffboxWarningDisplay_Pick's 1-enabled case FAILS. + +const staleZeroToggleWarning = "Sikeres — nincs mentésre jelölt alkalmazás volt a futáskor." + +func TestOffboxWarningDisplay_Pick(t *testing.T) { + // warning + ≥1 enabled → the replacement line + if got := offboxWarningDisplay(staleZeroToggleWarning, 1); got != offboxSelectionChangedLine { + t.Errorf("stale warning + 1 toggled: got %q, want the selection-changed line", got) + } + // warning + 0 enabled → the original line, verbatim (the v0.123.0 honesty stays) + if got := offboxWarningDisplay(staleZeroToggleWarning, 0); got != staleZeroToggleWarning { + t.Errorf("stale warning + 0 toggled: got %q, want the original warning unchanged", got) + } + // any OTHER warning passes through regardless of toggles (quota, partial failure) + quota := "A tároló a keret 84%-át használja (42/50 GB)." + if got := offboxWarningDisplay(quota, 3); got != quota { + t.Errorf("non-stale warning must pass through verbatim, got %q", got) + } + // no warning → no line + if got := offboxWarningDisplay("", 2); got != "" { + t.Errorf("empty warning must stay empty, got %q", got) + } +} + +func TestOffboxWarningDisplay_RemotePageRender(t *testing.T) { + // ≥1 toggled: the page shows the replacement, NOT the stale line. + data := appRowSplitData() + data["Offbox"] = &settings.OffboxTarget{ + Enabled: true, Host: "nas.local", LastStatus: "ok", EscrowState: "escrowed", + LastWarning: staleZeroToggleWarning, + } + data["OffboxWarningDisplay"] = offboxWarningDisplay(staleZeroToggleWarning, 1) + html := renderBackupPage(t, "backups_remote", data) + if !strings.Contains(html, offboxSelectionChangedLine) { + t.Error("selection-changed note missing with 1 app toggled") + } + if strings.Contains(html, staleZeroToggleWarning) { + t.Error("the stale zero-toggle line still renders alongside the replacement") + } + + // 0 toggled: the original warning + the v0.123.0 zero-toggle hint, unchanged. + data = appRowSplitData() + data["OffboxApps"] = []OffboxAppRow{{Name: "calibre-web", DisplayName: "Calibre-Web", Slug: "calibre-web", Enabled: false}} + data["OffboxToggledCount"] = 0 + data["Offbox"] = &settings.OffboxTarget{ + Enabled: true, Host: "nas.local", LastStatus: "ok", EscrowState: "escrowed", + LastWarning: staleZeroToggleWarning, + } + data["OffboxWarningDisplay"] = offboxWarningDisplay(staleZeroToggleWarning, 0) + html = renderBackupPage(t, "backups_remote", data) + if !strings.Contains(html, staleZeroToggleWarning) { + t.Error("0 toggled: the original run warning must render unchanged") + } + if strings.Contains(html, offboxSelectionChangedLine) { + t.Error("0 toggled: the selection-changed note must NOT render") + } + if !strings.Contains(html, "Nincs távoli mentésre jelölt alkalmazás — jelölj ki legalább egyet.") { + t.Error("0 toggled: the v0.123.0 hint must stay") + } +} diff --git a/controller/internal/web/templates/backups_remote.html b/controller/internal/web/templates/backups_remote.html index ae51ecb..21f991e 100644 --- a/controller/internal/web/templates/backups_remote.html +++ b/controller/internal/web/templates/backups_remote.html @@ -50,7 +50,9 @@ {{end}} {{if .Offbox.LastError}}
Utolsó hiba: {{.Offbox.LastError}}
{{end}} - {{if .Offbox.LastWarning}}{{.Offbox.LastWarning}}
{{end}} + {{/* Part E: display pick — a stale zero-toggle warning is replaced once the selection + changed (neutral color: the replacement is reassurance, not a deviation). */}} + {{if .OffboxWarningDisplay}}{{.OffboxWarningDisplay}}
{{end}} {{if and .OffboxConfigured (ne .Offbox.EscrowState "escrowed")}}A távoli mentés a kulcs letétbe helyezésére vár — a mentés addig nem fut (így nem keletkezik visszaállíthatatlan másolat). Futtasd a letéti szertartást, majd erősítsd meg.