R-1278: the install page says when a backup of an earlier install is kept and links the restore page (HU and EN). Red-proved. Commit only.
gates / gates (push) Successful in 1m33s

This commit is contained in:
2026-10-25 23:32:01 +01:00
parent 7ea942a118
commit fbec5cb499
10 changed files with 1368 additions and 0 deletions
+2
View File
@@ -531,9 +531,11 @@ func (s *Server) deployPageData(w http.ResponseWriter, r *http.Request, name str
data["RestoreRecordedAddress"] = ""
data["RestoreRecordedDeclaresPath"] = declaresDataPath
data["RestoreHasRecord"] = false
data["KeptBackups"] = 0 // R-1278: backups of an earlier install the box keeps (set-aside or removed-app units)
// Part 1's visibility line needs the real path, not a literal in a template.
data["SystemDataPath"] = s.cfg.Paths.SystemDataPath
if !alreadyDeployed && s.backupMgr != nil {
data["KeptBackups"] = s.backupMgr.KeptBackupsFor(name)
if place, addr, ok := s.backupMgr.RecordedUnitForStack(name); ok {
prefill := map[string]string{}
if addr.Known() {
@@ -181,6 +181,12 @@ func i18nCasesA() []i18nCase {
{"deploy_new", "deploy", func() map[string]interface{} {
return i18nDeployData(false, stacks.StateNotDeployed, 1)
}},
// R-1278 (2026-10-25 night): a backup of an earlier install is kept — the install page says so.
{"deploy_new_kept_backup_r1278", "deploy", func() map[string]interface{} {
d := i18nDeployData(false, stacks.StateNotDeployed, 1)
d["KeptBackups"] = 1
return d
}},
// R-1125 (v0.327.0, D10 = A): this page shows the same memory sentence — re-captured under this name.
{"deploy_new_blocked_r1125", "deploy", func() map[string]interface{} {
return i18nDeployData(false, stacks.StateNotDeployed, 2)
@@ -0,0 +1,36 @@
package web
import (
"os"
"strings"
"testing"
)
// R-1278: a volume app's reinstall said nothing about the backup of the earlier install the box keeps (set aside by
// D47, or left by „remove — keep backups"). The install page now says the install starts empty and links the restore
// page. One render per branch of the gate (the template-gate rule): kept + not installed → shown; none → not shown;
// installed → not shown.
// RED-PROOF: delete the {{if .KeptBackups}} block → the first case fails.
func TestR1278_TheInstallPageOffersTheKeptBackup(t *testing.T) {
shown := renderDeployWithFields(t, false, map[string]interface{}{"KeptBackups": 2})
if !strings.Contains(shown, `data-kept-backups="2"`) || !strings.Contains(shown, `href="/backups/restore"`) {
t.Fatal("with a kept backup of an earlier install the page must say so and link the restore page")
}
if strings.Contains(renderDeployWithFields(t, false, map[string]interface{}{"KeptBackups": 0}), "kept-backup-offer") {
t.Fatal("no kept backup → no notice")
}
if strings.Contains(renderDeployWithFields(t, false, map[string]interface{}{"KeptBackups": 1, "AlreadyDeployed": true}), "kept-backup-offer") {
t.Fatal("an installed app shows no install-time notice")
}
}
// The page reads the count from the backup manager (seam-built-but-never-wired is a recorded class).
func TestR1278_TheDeployPageAsksTheBackupManager(t *testing.T) {
b, err := os.ReadFile("handlers.go")
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(b), `data["KeptBackups"] = s.backupMgr.KeptBackupsFor(name)`) {
t.Fatal("deployPageData must set KeptBackups from the backup manager")
}
}
@@ -78,6 +78,15 @@
{{T "deploy.ha_most_mashova_szeretned_telepiteni"}}
</div>
{{end}}
{{- if and (not .AlreadyDeployed) .KeptBackups}}{{/* R-1278: a backup of an earlier install is kept (set aside, D47,
or left by „remove — keep backups"). The install starts empty; the backup is loaded afterwards on the
restore page („Megőrzött másolatok"). */}}
<div class="alert alert-info kept-backup-offer" data-kept-backups="{{.KeptBackups}}">
<svg class="ico ico-sm"><use href="#i-info"/></svg>
{{T "deploy.kept_backup_offer"}}
<a href="/backups/restore" class="alert-link">{{T "deploy.kept_backup_offer_link"}}</a>
</div>
{{- end}}
{{/* R-351 / Part 1 — WHERE THE DATA WILL LIVE, before the button is pressed. Measured
2026-08-21: 13 of 53 catalog templates declare a storage field; the other 40 have none and
their data goes to the system drive, which no screen said. This states it. It changes no
File diff suppressed because it is too large Load Diff