v0.249.0: i18n slice 1 release B — backup pages in English, Hungarian byte-identical (R-556)
gates / gates (push) Successful in 20s
gates / gates (push) Successful in 20s
Seven backup pages + the restore-progress JS converted against fixtures captured unconverted
(f8ebc47); recovery renders through executeTemplateLang; English retrieval claims registered;
the Fut comparison left unconverted (R-563).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -3,6 +3,8 @@ package web
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
@@ -263,3 +265,68 @@ func huTemplateSource(name string) ([]byte, error) {
|
||||
out, _ := b.Expand(i18n.Default, string(raw))
|
||||
return []byte(out), nil
|
||||
}
|
||||
|
||||
// ── Slice 1: pages rendered OUTSIDE executeTemplate follow the language (executeTemplateLang) ───────
|
||||
//
|
||||
// i18nDirectPages lists them with a parity case and a phrase that must appear in English. Release B adds
|
||||
// recovery; release C adds login, claim, the two guest share pages and the catch-all.
|
||||
var i18nDirectPages = []struct{ tmpl, caseName, enProbe string }{
|
||||
{"recovery", "recovery_locked_can", "Unlock backups"},
|
||||
}
|
||||
|
||||
// TestI18nDirectRenderPagesFollowLanguage — with the household language saved as English the page is
|
||||
// English (`<html lang="en">` and a known English phrase); saved as Hungarian it is byte-identical to the
|
||||
// fixture captured from the unconverted template.
|
||||
func TestI18nDirectRenderPagesFollowLanguage(t *testing.T) {
|
||||
cases := map[string]i18nCase{}
|
||||
for _, c := range i18nCases() {
|
||||
cases[c.name] = c
|
||||
}
|
||||
for _, p := range i18nDirectPages {
|
||||
c, ok := cases[p.caseName]
|
||||
if !ok {
|
||||
t.Fatalf("%s: no parity case %q", p.tmpl, p.caseName)
|
||||
}
|
||||
for _, lang := range []string{"hu", "en"} {
|
||||
s := i18nTestServer(t)
|
||||
if err := s.settings.SetLanguage(lang); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var buf strings.Builder
|
||||
if err := s.executeTemplateLang(&buf, httptest.NewRequest(http.MethodGet, "/x", nil), p.tmpl, c.data()); err != nil {
|
||||
t.Fatalf("%s [%s]: %v", p.tmpl, lang, err)
|
||||
}
|
||||
got := relativeAgeRe.ReplaceAllString(buf.String(), "# $1")
|
||||
if lang == "hu" {
|
||||
want, err := os.ReadFile(filepath.Join("testdata", "i18n_parity", p.caseName+".html"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got != string(want) {
|
||||
t.Errorf("%s: Hungarian render through executeTemplateLang differs from fixture %s", p.tmpl, p.caseName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(got, `<html lang="en"`) || !strings.Contains(got, p.enProbe) {
|
||||
t.Errorf("%s: saved English but the page is not English (lang=en: %v, %q: %v)", p.tmpl,
|
||||
strings.Contains(got, `<html lang="en"`), p.enProbe, strings.Contains(got, p.enProbe))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestRecoveryHandlerFollowsLanguage — the REAL render path (renderRecovery), not the helper: saved
|
||||
// English reaches the recovery page. RED-PROOF: put `s.tmpl.ExecuteTemplate` back in renderRecoveryState.
|
||||
func TestRecoveryHandlerFollowsLanguage(t *testing.T) {
|
||||
s := newDashboardServer(t, time.Time{})
|
||||
if err := s.settings.SetLanguage("en"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rec := httptest.NewRecorder()
|
||||
s.renderRecovery(rec, httptest.NewRequest(http.MethodGet, "/recovery", nil), "", "", nil)
|
||||
body := rec.Body.String()
|
||||
if rec.Code != 200 || !strings.Contains(body, `<html lang="en"`) || !strings.Contains(body, "Unlock backups") {
|
||||
t.Errorf("recovery page with English saved: code %d, lang=en %v, English phrase %v", rec.Code,
|
||||
strings.Contains(body, `<html lang="en"`), strings.Contains(body, "Unlock backups"))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user