bc278944a3
gates / gates (push) Successful in 25s
app_update_undone / app_update_held events (09 decision 15), on by default and seeded once on existing boxes; R-606 update sentences as key+args rendered per reader; R-646 startup applied-meta backfill for apps current with the catalog; R-620 a disabled notifier WARNs once per event type. Needs hub v0.120.0. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
68 lines
3.0 KiB
Go
68 lines
3.0 KiB
Go
package backup
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// v0.263.0 — a hold after a FAILED UNDO opens with what was tried and what state the data is in, in the
|
|
// box's language; a hold with no undo attempted reads exactly as before (every pre-v0.263.0 hold).
|
|
//
|
|
// COMPANION RED-PROOF (REPORT.md): make RestoreHoldFor ignore h.UndoState (drop undoHoldPrefix) — the
|
|
// three undo cases then read the plain sentence and this test fails on the prefix.
|
|
func TestUndo_HoldSentenceSaysTheUndoWasTriedAndTheDataState(t *testing.T) {
|
|
at := time.Date(2026, 9, 23, 8, 0, 0, 0, time.UTC)
|
|
copyAt := time.Date(2026, 9, 23, 1, 30, 0, 0, time.UTC)
|
|
m := r479Manager(t, false)
|
|
m.logger = log.New(io.Discard, "", 0)
|
|
plain := fmt.Sprintf(UpdateHoldTierFmt, "app", "2026-09-23 10:00", "második meghajtó", "2026-09-23 03:30")
|
|
|
|
if err := m.HoldAfterFailedUpdateHolding("app", at, copyAt, UpdateTierSecondDrive, "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, why := m.RestoreHoldFor("app"); why != plain {
|
|
t.Errorf("no undo attempted: the sentence must be unchanged, got %q", why)
|
|
}
|
|
|
|
for state, clause := range map[string]string{
|
|
"untouched": "Az adatok az új változat által hagyott állapotban vannak.",
|
|
"half": "Az adatok visszamásolása félbeszakadt",
|
|
"not_started": "Az adatok a frissítés előtti állapotba kerültek vissza, de az előző változat nem indult el.",
|
|
} {
|
|
if err := m.HoldAfterFailedUpdateHolding("app", at, copyAt, UpdateTierSecondDrive, "", state); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, why := m.RestoreHoldFor("app")
|
|
if !strings.HasPrefix(why, "A frissítés nem sikerült, és az automatikus visszaállítás sem. "+clause) {
|
|
t.Errorf("%s: the hold must open with the undo prefix and its state, got %q", state, why)
|
|
}
|
|
if !strings.HasSuffix(why, plain) {
|
|
t.Errorf("%s: the hold must still name the copy to restore from, got %q", state, why)
|
|
}
|
|
}
|
|
|
|
// A KNOWN state before the language check — the loop above ranges over a map, so its last state is
|
|
// random (this test read "half" and failed once for exactly that reason, 2026-09-23).
|
|
if err := m.HoldAfterFailedUpdateHolding("app", at, copyAt, UpdateTierSecondDrive, "", "not_started"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := m.settings.SetLanguage("en"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, why := m.RestoreHoldFor("app")
|
|
if !strings.HasPrefix(why, "The update did not succeed, and the automatic undo did not either. The data is back as it was before the update") {
|
|
t.Errorf("an English box gets the English prefix, got %q", why)
|
|
}
|
|
// v0.264.0 (R-606): the WHOLE sentence is English now, not only the prefix.
|
|
if !strings.Contains(why, "The update of app at 2026-09-23 10:00 did not succeed") || !strings.Contains(why, "second drive, 2026-09-23 03:30") {
|
|
t.Errorf("the hold's own sentence must be English on an English box, got %q", why)
|
|
}
|
|
if strings.Contains(why, "automatikus visszaállítás") || strings.Contains(why, "frissítése") || strings.Contains(why, "meghajtó") {
|
|
t.Errorf("no Hungarian may remain on an English box, got %q", why)
|
|
}
|
|
}
|