package handler import ( "context" "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "github.com/multica-ai/multica/server/internal/testutil" ) func TestUpdateMeFrenchLanguageRoundTrip(t *testing.T) { if testHandler == nil || testPool == nil { t.Skip("database not available") } userID := dbfx.User(t, "French user", "lang-fr@multica.ai", testutil.Cols{"language": "en"}) var updated UserResponse testutil.Call(t, testHandler.UpdateMe, newPatchMeRequest(userID, `{"language":"fr"}`)).Want(http.StatusOK).JSON(&updated) if updated.Language == nil || *updated.Language != "fr" { t.Fatalf("updated language = %v, want fr", updated.Language) } // A fresh request after reload must restore French, not the old preference. get := newRequest(http.MethodGet, "/api/me", nil) get.Header.Set("X-User-ID", userID) var reloaded UserResponse testutil.Call(t, testHandler.GetMe, get).Want(http.StatusOK).JSON(&reloaded) if reloaded.Language == nil || *reloaded.Language != "fr" { t.Fatalf("reloaded language = %v, want fr", reloaded.Language) } } func newLanguageTestUser(t *testing.T, email string) string { t.Helper() ctx := context.Background() var userID string if err := testPool.QueryRow(ctx, `INSERT INTO "user" (name, email) VALUES ($1, $2) RETURNING id`, "Language Test", email, ).Scan(&userID); err != nil { t.Fatalf("insert test user: %v", err) } t.Cleanup(func() { testPool.Exec(ctx, `DELETE FROM "user" WHERE id = $1`, userID) }) return userID } func newPatchMeRequest(userID, body string) *http.Request { req := httptest.NewRequest("PATCH", "/api/me", strings.NewReader(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("X-User-ID", userID) return req } func TestUpdateMeAcceptsLanguage(t *testing.T) { userID := newLanguageTestUser(t, "lang-set@multica.ai") w := httptest.NewRecorder() req := newPatchMeRequest(userID, `{"language":"zh-Hans"}`) testHandler.UpdateMe(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String()) } var lang *string if err := testPool.QueryRow(context.Background(), `SELECT language FROM "user" WHERE id = $1`, userID, ).Scan(&lang); err != nil { t.Fatalf("lookup user: %v", err) } if lang == nil || *lang != "zh-Hans" { t.Fatalf("expected language=zh-Hans, got %v", lang) } var resp map[string]any if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("decode response: %v", err) } if got, _ := resp["language"].(string); got != "zh-Hans" { t.Fatalf("expected response language=zh-Hans, got %v", resp["language"]) } } func TestUpdateMeAcceptsKoreanLanguage(t *testing.T) { userID := newLanguageTestUser(t, "lang-ko@multica.ai") w := httptest.NewRecorder() req := newPatchMeRequest(userID, `{"language":"ko"}`) testHandler.UpdateMe(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String()) } var resp map[string]any if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("decode response: %v", err) } if got, _ := resp["language"].(string); got != "ko" { t.Fatalf("expected response language=ko, got %v", resp["language"]) } } func TestUpdateMeAcceptsJapaneseLanguage(t *testing.T) { userID := newLanguageTestUser(t, "lang-ja@multica.ai") w := httptest.NewRecorder() req := newPatchMeRequest(userID, `{"language":"ja"}`) testHandler.UpdateMe(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String()) } var resp map[string]any if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("decode response: %v", err) } if got, _ := resp["language"].(string); got != "ja" { t.Fatalf("expected response language=ja, got %v", resp["language"]) } } func TestUpdateMeRejectsUnsupportedLanguage(t *testing.T) { userID := newLanguageTestUser(t, "lang-reject@multica.ai") w := httptest.NewRecorder() req := newPatchMeRequest(userID, `{"language":"