package response import ( "encoding/json" "net/http/httptest" "testing" ) // Eine leere Liste muss als [] herauskommen, nicht als null. Jede // Oberfläche, die über die Antwort läuft, bricht sonst ab – so ist die // Kalenderansicht bei einem Konto ohne Kalender weiß geblieben. func TestJSONLeereListeWirdZuLeeremArray(t *testing.T) { type eintrag struct { Name string `json:"name"` } var leer []eintrag w := httptest.NewRecorder() JSON(w, 200, leer) if got := w.Body.String(); !contains(got, `"data":[]`) { t.Fatalf("erwartet \"data\":[], bekam %s", got) } } func TestJSONBefuellteListeBleibtUnveraendert(t *testing.T) { w := httptest.NewRecorder() JSON(w, 200, []string{"a", "b"}) var out struct { Data []string `json:"data"` } if err := json.Unmarshal(w.Body.Bytes(), &out); err != nil { t.Fatal(err) } if len(out.Data) != 2 || out.Data[0] != "a" { t.Fatalf("Inhalt verändert: %v", out.Data) } } // Einzelne Objekte und nil dürfen davon nicht berührt werden – sonst // verwandelte die Regel jede fehlende Antwort in eine leere Liste. func TestJSONObjekteBleibenObjekte(t *testing.T) { w := httptest.NewRecorder() JSON(w, 200, map[string]int{"n": 1}) if got := w.Body.String(); !contains(got, `"n":1`) { t.Fatalf("Objekt verändert: %s", got) } w = httptest.NewRecorder() JSON(w, 200, nil) if got := w.Body.String(); contains(got, "[]") { t.Fatalf("nil sollte keine Liste werden: %s", got) } } func contains(s, sub string) bool { return len(s) >= len(sub) && (s == sub || len(sub) == 0 || indexOf(s, sub) >= 0) } func indexOf(s, sub string) int { for i := 0; i+len(sub) <= len(s); i++ { if s[i:i+len(sub)] == sub { return i } } return -1 }