package httpclient import ( "encoding/json" "net/http" "net/http/httptest" "testing" "time" ) func TestPostJSON(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Content-Type") != "application/json" { t.Error("Content-Type not set") } var in map[string]any if err := json.NewDecoder(r.Body).Decode(&in); err != nil { t.Fatal(err) } if v, _ := in["key"].(string); v != "value" { t.Errorf(`key = %q, want "value"`, v) } _, _ = w.Write([]byte(`{"ok":true}`)) })) defer srv.Close() var out struct { OK bool `json:"ok"` } c := New() if err := c.PostJSON(t.Context(), srv.URL, nil, map[string]string{"key": "value"}, &out); err != nil { t.Fatalf("PostJSON: %v", err) } if !out.OK { t.Error("OK = false, want true") } } func TestPostJSONHTTPError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "boom", http.StatusInternalServerError) })) defer srv.Close() c := New() if err := c.PostJSON(t.Context(), srv.URL, nil, nil, nil); err == nil { t.Error("PostJSON(500) succeeded, want error") } } func TestPostJSONCustomHeaders(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if got := r.Header.Get("X-Custom"); got != "abc" { t.Errorf("X-Custom = %q, want abc", got) } _, _ = w.Write([]byte(`{"x":1}`)) })) defer srv.Close() var out map[string]int c := New() if err := c.PostJSON(t.Context(), srv.URL, map[string]string{"X-Custom": "abc"}, nil, &out); err != nil { t.Fatalf("PostJSON: %v", err) } } func TestWithTimeout(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { time.Sleep(200 * time.Millisecond) _, _ = w.Write([]byte(`{}`)) })) defer srv.Close() c := New(WithTimeout(10 * time.Millisecond)) if err := c.PostJSON(t.Context(), srv.URL, nil, nil, nil); err == nil { t.Error("PostJSON with short timeout succeeded, want error") } }