package api import ( "context" "encoding/json" "net/http" "net/http/httptest" "testing" ) func TestNewBaseClient(t *testing.T) { client := NewBaseClient("https://api.example.com") if client.BaseURL != "https://api.example.com" { t.Errorf("Expected BaseURL 'https://api.example.com', got '%s'", client.BaseURL) } if client.HTTPClient == nil { t.Error("HTTPClient should not be nil") } } func TestBaseClient_Get(t *testing.T) { expected := map[string]string{"message": "hello"} server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { t.Errorf("Expected GET, got %s", r.Method) } if r.URL.Path != "/test" { t.Errorf("Expected path /test, got %s", r.URL.Path) } if r.Header.Get("Authorization") != "Bearer token123" { t.Errorf("Expected Authorization header") } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(expected) })) defer server.Close() client := BaseClient{HTTPClient: server.Client(), BaseURL: server.URL} var result map[string]string err := client.Get(context.Background(), "/test", map[string]string{"Authorization": "Bearer token123"}, &result) if err != nil { t.Fatalf("Get failed: %v", err) } if result["message"] != "hello" { t.Errorf("Expected message 'hello', got '%s'", result["message"]) } } func TestBaseClient_Get_Error(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("server error")) })) defer server.Close() client := BaseClient{HTTPClient: server.Client(), BaseURL: server.URL} var result map[string]string err := client.Get(context.Background(), "/test", nil, &result) if err == nil { t.Error("Expected error for 500 response") } } func TestBaseClient_Post(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { t.Errorf("Expected POST, got %s", r.Method) } if r.Header.Get("Content-Type") != "application/json" { t.Error("Expected Content-Type application/json") } var body map[string]string json.NewDecoder(r.Body).Decode(&body) if body["name"] != "test" { t.Errorf("Expected name 'test', got '%s'", body["name"]) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]int{"id": 42}) })) defer server.Close() client := BaseClient{HTTPClient: server.Client(), BaseURL: server.URL} var result map[string]int err := client.Post(context.Background(), "/create", nil, map[string]string{"name": "test"}, &result) if err != nil { t.Fatalf("Post failed: %v", err) } if result["id"] != 42 { t.Errorf("Expected id 42, got %d", result["id"]) } } func TestBaseClient_Post_NilBody(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Content-Type") == "application/json" { t.Error("Content-Type should not be set for nil body") } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"status": "ok"}) })) defer server.Close() client := BaseClient{HTTPClient: server.Client(), BaseURL: server.URL} var result map[string]string err := client.Post(context.Background(), "/action", nil, nil, &result) if err != nil { t.Fatalf("Post with nil body failed: %v", err) } } func TestBaseClient_PostForm(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { t.Errorf("Expected POST, got %s", r.Method) } if r.Header.Get("Content-Type") != "application/x-www-form-urlencoded" { t.Error("Expected form-urlencoded Content-Type") } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]bool{"success": true}) })) defer server.Close() client := BaseClient{HTTPClient: server.Client(), BaseURL: server.URL} var result map[string]bool err := client.PostForm(context.Background(), "/submit", nil, "key=value", &result) if err != nil { t.Fatalf("PostForm failed: %v", err) } if !result["success"] { t.Error("Expected success to be true") } } func TestBaseClient_PostEmpty(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { t.Errorf("Expected POST, got %s", r.Method) } if r.Header.Get("X-Custom") != "custom-value" { t.Error("Expected custom header") } w.WriteHeader(http.StatusNoContent) })) defer server.Close() client := BaseClient{HTTPClient: server.Client(), BaseURL: server.URL} err := client.PostEmpty(context.Background(), "/trigger", map[string]string{"X-Custom": "custom-value"}) if err != nil { t.Fatalf("PostEmpty failed: %v", err) } } func TestBaseClient_PostEmpty_Error(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("bad request")) })) defer server.Close() client := BaseClient{HTTPClient: server.Client(), BaseURL: server.URL} err := client.PostEmpty(context.Background(), "/fail", nil) if err == nil { t.Error("Expected error for 400 response") } } func TestBaseClient_Put(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != "PUT" { t.Errorf("Expected PUT, got %s", r.Method) } if r.Header.Get("Content-Type") != "application/x-www-form-urlencoded" { t.Error("Expected form-urlencoded Content-Type") } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"updated": "yes"}) })) defer server.Close() client := BaseClient{HTTPClient: server.Client(), BaseURL: server.URL} var result map[string]string err := client.Put(context.Background(), "/update", nil, "field=value", &result) if err != nil { t.Fatalf("Put failed: %v", err) } if result["updated"] != "yes" { t.Error("Expected updated to be yes") } } func TestBaseClient_doJSON_DecodeError(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Write([]byte("invalid json")) })) defer server.Close() client := BaseClient{HTTPClient: server.Client(), BaseURL: server.URL} var result map[string]string err := client.Get(context.Background(), "/bad-json", nil, &result) if err == nil { t.Error("Expected error for invalid JSON") } }