package httpapi import ( "encoding/json" "net/http" "net/http/httptest" "testing" ) func TestErrorLocalizesWithAcceptLanguage(t *testing.T) { t.Parallel() rec := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/x", nil) req.Header.Set("Accept-Language", "nl") Locale(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { Error(w, http.StatusUnauthorized, "unauthorized") })).ServeHTTP(rec, req) if rec.Code != http.StatusUnauthorized { t.Fatalf("status=%d", rec.Code) } var body map[string]string if err := json.NewDecoder(rec.Body).Decode(&body); err != nil { t.Fatal(err) } if body["error"] != "niet geautoriseerd" { t.Fatalf("error=%q", body["error"]) } if got := rec.Header().Get("Vary"); got != "Accept-Language" { t.Fatalf("Vary=%q", got) } } func TestErrorKeepsStableMachineCodes(t *testing.T) { t.Parallel() rec := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/x", nil) req.Header.Set("Accept-Language", "fr") Locale(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { Error(w, http.StatusForbidden, "password_not_set") })).ServeHTTP(rec, req) var body map[string]string if err := json.NewDecoder(rec.Body).Decode(&body); err != nil { t.Fatal(err) } if body["error"] != "password_not_set" { t.Fatalf("stable code changed: %q", body["error"]) } } func TestCodedErrorLocalizesMessageOnly(t *testing.T) { t.Parallel() rec := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/x", nil) req.Header.Set("Accept-Language", "de") Locale(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { CodedError(w, http.StatusUnauthorized, "invalid_api_key", "invalid api key") })).ServeHTTP(rec, req) var body map[string]any if err := json.NewDecoder(rec.Body).Decode(&body); err != nil { t.Fatal(err) } errObj, ok := body["error"].(map[string]any) if !ok { t.Fatalf("shape=%#v", body) } if errObj["code"] != "invalid_api_key" { t.Fatalf("code=%v", errObj["code"]) } if errObj["message"] != "ungültiger API-Schlüssel" { t.Fatalf("message=%v", errObj["message"]) } } func TestFieldErrorLocalizesWithAcceptLanguage(t *testing.T) { t.Parallel() rec := httptest.NewRecorder() req := httptest.NewRequest(http.MethodPost, "/x", nil) req.Header.Set("Accept-Language", "nl") Locale(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { FieldError(w, http.StatusUnauthorized, "unauthorized", "invalid_credentials", map[string]string{ "email": "unauthorized", "password": "unauthorized", }) })).ServeHTTP(rec, req) if rec.Code != http.StatusUnauthorized { t.Fatalf("status=%d", rec.Code) } var body struct { Error string `json:"error"` Code string `json:"code"` Fields map[string]string `json:"fields"` } if err := json.NewDecoder(rec.Body).Decode(&body); err != nil { t.Fatal(err) } if body.Error != "niet geautoriseerd" { t.Fatalf("error=%q", body.Error) } if body.Code != "invalid_credentials" { t.Fatalf("code=%q (must stay stable)", body.Code) } if body.Fields["email"] != "niet geautoriseerd" || body.Fields["password"] != "niet geautoriseerd" { t.Fatalf("fields=%v", body.Fields) } if got := rec.Header().Get("Vary"); got != "Accept-Language" { t.Fatalf("Vary=%q", got) } }