package web import ( "strings" "testing" ) // R-252 / R-253 — A REFUSAL ON THE RECOVERY PATH NAMES A REASON A PERSON CAN ACT ON, AND THE WAY TO // ACT ON IT. // // Both of these were met on the fifth walk (2026-08-07) at the LAST step of a successful recovery — // the customer had entered their recovery code, seen their data listed, and pressed through. Neither // needed a shell to clear, which is why the walk's journey half passed; both required knowing // something the product never said, which is why they are filed. // // These assert the RENDERED page, not the state that feeds it: the defect in both cases was copy // that disagreed with behaviour, and only the rendered bytes can show that. // restoreData is the healthy fixture — app in the store, installed here, drives registered. Every // test below overlays exactly one field, so what it proves is attributable. func restoreData() map[string]interface{} { d := splitTestData() d["NoRestoreDestination"] = false d["OffsiteRestoreRows"] = []OffsiteRestoreRow{ {App: "calibre-web", DisplayName: "Calibre-Web", InStore: true, Installed: true, Enabled: true}, } return d } // ── SCENARIO C — a refusal for a missing drive says what to do ────────────────────────────────── // RED-PROOF: restore the old copy — delete the `{{if .NoRestoreDestination}}` block from // backups_restore.html — and this fails on both assertions: the customer is left with a page that // looks normal and a button that will refuse with a message naming no next step. func TestRestorePage_NoRegisteredDrive_NamesTheReasonAndTheRoute(t *testing.T) { d := restoreData() d["NoRestoreDestination"] = true html := renderBackupPage(t, "backups_restore", d) if !strings.Contains(html, "csatold vissza az adatmeghajtót") { t.Error("R-252: the restore page says nothing about the drives being unregistered — the " + "customer presses through and gets a refusal that names no next step") } if !strings.Contains(html, `href="/storage"`) { t.Error("R-252: the notice does not ROUTE to the place that fixes it — a reason without a " + "route is what made this an obstacle rather than a message") } // It must say the data is safe. „nincs elérhető adatmeghajtó" reads like data loss; it is not. if !strings.Contains(html, "megvannak") { t.Error("R-252: the notice does not say the backups and the drives are both still there") } } // ── SCENARIO E — a healthy box is unchanged ───────────────────────────────────────────────────── // RED-PROOF: make the notice unconditional (drop the `{{if .NoRestoreDestination}}` guard) and this // fails — a box with every precondition satisfied is warned about a problem it does not have, which // is the R-215 shape (a screen about a situation the customer is not in). func TestRestorePage_HealthyBox_HasNoPreconditionNotice(t *testing.T) { html := renderBackupPage(t, "backups_restore", restoreData()) if strings.Contains(html, "csatold vissza az adatmeghajtót") { t.Error("the drive notice rendered on a box whose drives ARE registered") } if strings.Contains(html, "előbb") && strings.Contains(html, "telepítsd újra") { t.Error("the not-installed copy rendered for an app that IS installed") } } // ── SCENARIO D — the page and the handler agree about reinstalling ────────────────────────────── // RED-PROOF: restore the old string „Nincs telepítve — a visszaállítás előbb újratelepíti." and this // fails on the first assertion — the page promises a reinstall the reconstitute path refuses to do, // which is the contradiction R-253 filed. func TestRestorePage_NotInstalled_DoesNotPromiseAReinstall(t *testing.T) { d := restoreData() d["OffsiteRestoreRows"] = []OffsiteRestoreRow{ {App: "calibre-web", DisplayName: "Calibre-Web", InStore: true, Installed: false, Enabled: true}, } html := renderBackupPage(t, "backups_restore", d) if strings.Contains(html, "a visszaállítás előbb újratelepíti") { t.Error("R-253: the page still promises that the restore reinstalls the app — the " + "reconstitute path refuses precisely because it is not installed, and cannot deploy it " + "itself (the destination is the app's own HDD path, a drive the CUSTOMER chooses)") } if !strings.Contains(html, "telepítsd újra") { t.Error("R-253: the page no longer tells the customer to install the app first") } if !strings.Contains(html, `href="/stacks/calibre-web/deploy"`) { t.Error("R-253: the copy names the step but does not route to it") } }