fix(account): seed a fresh guest's interface language from the client locale

A guest was provisioned with only its detected time zone; its PreferredLanguage
fell to the 'en' column default. The client already sends its locale in the guest
login (GuestLoginRequest.locale), but the gateway dropped it and ProvisionGuest
took no language — so a Russian user's brand-new native guest got English
language-dependent server content (the ad banner, bot messages) until the client's
later language reconcile. Read the locale in the gateway guest handler, thread it
through GuestAuth -> ProvisionGuest, and seed PreferredLanguage from it (validated;
an unsupported/absent value keeps the 'en' default). Wire field already present —
no schema change.
This commit is contained in:
Ilia Denisov
2026-07-15 00:06:23 +02:00
parent b5fe61279b
commit f8aeec8008
9 changed files with 48 additions and 19 deletions
+18 -3
View File
@@ -229,21 +229,36 @@ func TestProvisionSeedsTimeZone(t *testing.T) {
t.Errorf("TimeZone = %q, want UTC fallback for a malformed offset", bad.TimeZone)
}
// A guest is seeded its detected offset; an empty one keeps the UTC default.
guest, err := store.ProvisionGuest(ctx, "-05:30")
// A guest is seeded its detected offset and interface language; an empty offset keeps the
// UTC default and an empty/unsupported language keeps the 'en' default.
guest, err := store.ProvisionGuest(ctx, "-05:30", "ru")
if err != nil {
t.Fatalf("provision guest: %v", err)
}
if guest.TimeZone != "-05:30" {
t.Errorf("guest TimeZone = %q, want the seeded -05:30", guest.TimeZone)
}
plainGuest, err := store.ProvisionGuest(ctx, "")
if guest.PreferredLanguage != "ru" {
t.Errorf("guest PreferredLanguage = %q, want the seeded ru", guest.PreferredLanguage)
}
plainGuest, err := store.ProvisionGuest(ctx, "", "")
if err != nil {
t.Fatalf("provision plain guest: %v", err)
}
if plainGuest.TimeZone != "UTC" {
t.Errorf("plain guest TimeZone = %q, want UTC default", plainGuest.TimeZone)
}
if plainGuest.PreferredLanguage != "en" {
t.Errorf("plain guest PreferredLanguage = %q, want en default", plainGuest.PreferredLanguage)
}
// An unsupported locale falls back to the 'en' default rather than persisting a junk value.
frGuest, err := store.ProvisionGuest(ctx, "", "fr-FR")
if err != nil {
t.Fatalf("provision fr guest: %v", err)
}
if frGuest.PreferredLanguage != "en" {
t.Errorf("unsupported-locale guest PreferredLanguage = %q, want en default", frGuest.PreferredLanguage)
}
}
// TestProvisionTelegramUnknownLanguageDefaults checks an unsupported Telegram
+1 -1
View File
@@ -216,7 +216,7 @@ func TestConfirmCodeClearsGuest(t *testing.T) {
mailer := &capturingMailer{}
svc := account.NewEmailService(store, mailer, "https://erudit-game.ru")
guest, err := store.ProvisionGuest(ctx, "")
guest, err := store.ProvisionGuest(ctx, "", "")
if err != nil {
t.Fatalf("provision guest: %v", err)
}
+1 -1
View File
@@ -431,7 +431,7 @@ func TestConfirmByTokenLinkClearsGuest(t *testing.T) {
store := account.NewStore(testDB)
mailer := &capturingMailer{}
svc := account.NewEmailService(store, mailer, "https://erudit-game.ru")
guest, err := store.ProvisionGuest(ctx, "")
guest, err := store.ProvisionGuest(ctx, "", "")
if err != nil {
t.Fatalf("provision guest: %v", err)
}
+1 -1
View File
@@ -154,7 +154,7 @@ func provisionAccount(t *testing.T) uuid.UUID {
// provisionGuest creates a fresh ephemeral guest account and returns its id.
func provisionGuest(t *testing.T) uuid.UUID {
t.Helper()
acc, err := account.NewStore(testDB).ProvisionGuest(context.Background(), "")
acc, err := account.NewStore(testDB).ProvisionGuest(context.Background(), "", "")
if err != nil {
t.Fatalf("provision guest: %v", err)
}
+1 -1
View File
@@ -26,7 +26,7 @@ func TestUserListFilter(t *testing.T) {
if err != nil {
t.Fatalf("provision robot: %v", err)
}
guest, err := st.ProvisionGuest(ctx, "")
guest, err := st.ProvisionGuest(ctx, "", "")
if err != nil {
t.Fatalf("provision guest: %v", err)
}