Files
sm-user-plugin/mail_locale_test.go
Jakub Zych 6bf219f50a fix(quick-261029-d9j): pick the mail language from Accept-Language, add mail.fallback_locale, Polish subjects
- preferred_locale and the request locale are normalised (comma lists,
  q-weights, region subtags, case) to pl or en by NormalizeMailLocale, so a
  raw Accept-Language such as en-GB,en;q=0.9 selects the -en templates
- new golem15.user.mail.fallback_locale (default pl) is used when neither
  names a supported language; ResolveMailLocaleFor applies it, and Boot
  rejects any value other than pl or en
- activate, reactivate and restore Polish templates get Polish subjects
- no template, route or payload changes; MailTemplate and
  ResolveMailLocale keep their signatures
2026-10-29 09:47:42 +01:00

115 lines
4.0 KiB
Go

package user
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"git.golem15.com/golem15/sm-user-plugin/classes"
"git.golem15.com/golem15/sm-user-plugin/controllers"
"git.golem15.com/golem15/summercms/modules/backpack"
"git.golem15.com/golem15/summercms/modules/towel"
)
const mailFallbackKey = "golem15.user.mail.fallback_locale"
// TestMailFallbackLocaleConfig reads golem15.user.mail.fallback_locale from
// the plugin's config.yaml default and from overrides.
func TestMailFallbackLocaleConfig(t *testing.T) {
app := bareApp(t)
if err := app.Config.MergePlugin("golem15.user", configFS); err != nil {
t.Fatal(err)
}
if v, ok := app.Config.Lookup(mailFallbackKey); !ok || v != "pl" {
t.Fatalf("config.yaml default = %#v (set %v), want pl", v, ok)
}
if got, err := classes.MailFallbackLocale(app); got != "pl" || err != nil {
t.Fatalf("default: %q %v", got, err)
}
for _, tc := range []struct{ value, want string }{{"en", "en"}, {"EN-gb", "en"}} {
if err := app.Config.Set(mailFallbackKey, tc.value); err != nil {
t.Fatal(err)
}
if got, err := classes.MailFallbackLocale(app); got != tc.want || err != nil {
t.Errorf("%q: %q %v", tc.value, got, err)
}
}
if err := app.Config.Set(mailFallbackKey, "de"); err != nil {
t.Fatal(err)
}
if _, err := classes.MailFallbackLocale(app); err == nil || !strings.Contains(err.Error(), mailFallbackKey) {
t.Errorf("de: %v", err)
}
}
// TestMailFallbackLocaleBoot fails Boot on an unsupported fallback before
// anything is started, and leaves an unset key alone.
func TestMailFallbackLocaleBoot(t *testing.T) {
withSecret := func(t *testing.T) *backpack.App {
app := bareApp(t)
if err := app.Config.Set("golem15.user.jwt.secret", "mail-locale-boot-secret"); err != nil {
t.Fatal(err)
}
return app
}
app := withSecret(t)
if err := app.Config.Set(mailFallbackKey, "de"); err != nil {
t.Fatal(err)
}
if err := (&Plugin{}).Boot(app); err == nil || !strings.Contains(err.Error(), mailFallbackKey) {
t.Fatalf("Boot with fallback de: %v", err)
}
if err := (&Plugin{}).Boot(withSecret(t)); err != nil && strings.Contains(err.Error(), mailFallbackKey) {
t.Fatalf("Boot with the key unset: %v", err)
}
}
// TestMailLocaleFromRequest sends the reset mail through POST
// /forgot-password with the request locale the router stores when no
// translate plugin is installed: the raw Accept-Language header.
func TestMailLocaleFromRequest(t *testing.T) {
if testing.Short() {
t.Skip("Postgres (testcontainers)")
}
app, gdb := sessionApp(t, "0s")
rec, _ := publishMemoryMail(t, app)
forgot := func(t *testing.T, email, locale string) {
t.Helper()
req := httptest.NewRequest(http.MethodPost, "/_user/api/v1/forgot-password", strings.NewReader(`{"email":"`+email+`"}`))
req.Host = "example.com"
req.Header.Set("Content-Type", "application/json")
if locale != "" {
req = req.WithContext(towel.WithLocale(req.Context(), locale))
}
w := httptest.NewRecorder()
controllers.ForgotPassword(app)(w, req)
if w.Code >= 300 {
t.Fatalf("forgot-password %s: %d %s", email, w.Code, w.Body.String())
}
}
insertUser(t, gdb, "locale-header@example.test", "correct-horse")
forgot(t, "locale-header@example.test", "en-GB,en;q=0.9")
assertTemplate(t, rec, "golem15.user::mail.restore-en", "locale-header@example.test")
insertUser(t, gdb, "locale-none@example.test", "correct-horse")
forgot(t, "locale-none@example.test", "")
assertTemplate(t, rec, "golem15.user::mail.restore", "locale-none@example.test")
if err := app.Config.Set(mailFallbackKey, "en"); err != nil {
t.Fatal(err)
}
insertUser(t, gdb, "locale-fallback@example.test", "correct-horse")
forgot(t, "locale-fallback@example.test", "")
assertTemplate(t, rec, "golem15.user::mail.restore-en", "locale-fallback@example.test")
saved := insertUser(t, gdb, "locale-saved@example.test", "correct-horse")
if err := gdb.Model(saved).Update("preferred_locale", "en-GB").Error; err != nil {
t.Fatal(err)
}
forgot(t, "locale-saved@example.test", "pl")
assertTemplate(t, rec, "golem15.user::mail.restore-en", "locale-saved@example.test")
}