f806baf4c7
- backups_remote.html: the status stat carries data-status="{{.Offbox.LastStatus}}"; the poll reads
v.dataset.status === 'running' instead of v.textContent.indexOf('Fut'). The English page could never
see a running backup before this (slice 1 shipped the English page with that word left Hungarian).
- The running label becomes {{T "backups_remote.fut"}} — hu „Fut…" unchanged, en „Running…".
- 12 backups_remote parity fixtures re-captured. Proven (audit switch/fixture diff): each differs from
its predecessor ONLY by the data-status attribute and that one poll line; the other 94 are
byte-identical. The displayed Hungarian is unchanged.
- Tests: TestR563_PollStartsFromAttribute (hu and en), TestR563_AttributeFollowsTheStatus.
Red-proofed twice: poll back on textContent → both languages fail; word back inline → the English
page shows Hungarian.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
81 lines
3.4 KiB
Go
81 lines
3.4 KiB
Go
package web
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
|
|
)
|
|
|
|
// R-563 — the Távoli mentés page starts its progress poll from a MACHINE-READABLE status, not from
|
|
// the word it happens to display.
|
|
//
|
|
// Until v0.251.0 the page did `v.textContent.indexOf('Fut') >= 0`. Two consequences, both measured:
|
|
// the English page (slice 1 shipped it) could never see a running backup, because the English word is
|
|
// „Running…"; and the Hungarian word could not be translated at all while that line existed — it was
|
|
// the ONE word slice 1 had to leave behind.
|
|
//
|
|
// RED-PROOF (REPORT): put the textContent test back in backups_remote.html and the English half fails.
|
|
func TestR563_PollStartsFromAttribute(t *testing.T) {
|
|
statusEl := regexp.MustCompile(`<div class="stat-value" id="offbox-status-value"([^>]*)>([^<]*)</div>`)
|
|
for _, lang := range []string{"hu", "en"} {
|
|
data := appRowSplitData()
|
|
data["Offbox"] = &settings.OffboxTarget{
|
|
Enabled: true, Host: "nas.local", LastStatus: "running", EscrowState: "escrowed",
|
|
}
|
|
html := renderBackupPageLang(t, lang, "backups_remote", data)
|
|
m := statusEl.FindStringSubmatch(html)
|
|
if m == nil {
|
|
t.Fatalf("[%s] the status element is gone — this test no longer reads what it thinks it reads", lang)
|
|
}
|
|
if !strings.Contains(m[1], `data-status="running"`) {
|
|
t.Errorf("[%s] the status element carries no machine-readable status: %q", lang, m[1])
|
|
}
|
|
if !strings.Contains(html, "v.dataset.status === 'running'") {
|
|
t.Errorf("[%s] the poll does not read the attribute", lang)
|
|
}
|
|
if strings.Contains(html, "textContent.indexOf('Fut')") {
|
|
t.Errorf("[%s] the poll reads the displayed Hungarian word again (R-563)", lang)
|
|
}
|
|
// The displayed word itself: Hungarian as always, English on the English page. Before this
|
|
// change the English page showed the Hungarian word here, because it could not be translated.
|
|
word := strings.TrimSpace(m[2])
|
|
want := map[string]string{"hu": "Fut…", "en": "Running…"}[lang]
|
|
if word != want {
|
|
t.Errorf("[%s] status label = %q, want %q", lang, word, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// A state that is NOT running must not claim to be: the attribute follows LastStatus exactly, so the
|
|
// poll cannot be started by a word that merely contains another.
|
|
func TestR563_AttributeFollowsTheStatus(t *testing.T) {
|
|
statusEl := regexp.MustCompile(`id="offbox-status-value" data-status="([a-z]*)"`)
|
|
for _, st := range []string{"ok", "error", "incomplete", "running"} {
|
|
data := appRowSplitData()
|
|
data["Offbox"] = &settings.OffboxTarget{Enabled: true, Host: "nas.local", LastStatus: st, EscrowState: "escrowed"}
|
|
html := renderBackupPage(t, "backups_remote", data)
|
|
m := statusEl.FindStringSubmatch(html)
|
|
if m == nil {
|
|
t.Fatalf("[%s] no data-status attribute on the status element", st)
|
|
}
|
|
if m[1] != st {
|
|
t.Errorf("[%s] data-status = %q — the poll would read the wrong state", st, m[1])
|
|
}
|
|
}
|
|
}
|
|
|
|
// renderBackupPageLang renders a backup page from a chosen language's template set (R-563 needs the
|
|
// English page: it is the one that could never see a running backup).
|
|
func renderBackupPageLang(t *testing.T, lang, page string, data map[string]interface{}) string {
|
|
t.Helper()
|
|
s := testServer(t)
|
|
s.loadTemplates()
|
|
var buf strings.Builder
|
|
if err := s.templatesFor(lang).ExecuteTemplate(&buf, page, data); err != nil {
|
|
t.Fatalf("render %s [%s]: %v", page, lang, err)
|
|
}
|
|
return buf.String()
|
|
}
|