53200cbc0d
Nuevas funciones Go con tests en tres dominios: - core: parse_cron_expr, next_cron_time, join_by_key, validate_struct_fields + tipo CronSchedule - datascience: pivot (tabla dinámica), diff_entities (comparación de entidades) - infra: http_get_json, http_post_json, http_download_file, cache_to_sqlite, cron_ticker Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
81 lines
2.2 KiB
Go
81 lines
2.2 KiB
Go
package infra
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestHttpGetJSON(t *testing.T) {
|
|
t.Run("httptest.Server con respuesta JSON", func(t *testing.T) {
|
|
payload := map[string]any{"ok": true, "value": float64(42)}
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(payload)
|
|
}))
|
|
defer srv.Close()
|
|
|
|
result, err := HttpGetJSON(srv.URL, nil, 5*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if result["ok"] != true {
|
|
t.Errorf("got ok=%v, want true", result["ok"])
|
|
}
|
|
})
|
|
|
|
t.Run("Status 404 → error", func(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
http.Error(w, "not found", http.StatusNotFound)
|
|
}))
|
|
defer srv.Close()
|
|
|
|
_, err := HttpGetJSON(srv.URL, nil, 5*time.Second)
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
if !strings.Contains(err.Error(), "404") {
|
|
t.Errorf("error should contain 404, got: %v", err)
|
|
}
|
|
})
|
|
|
|
t.Run("Timeout → error", func(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// No responde — bloquea hasta que el cliente cancela
|
|
<-r.Context().Done()
|
|
}))
|
|
defer srv.Close()
|
|
|
|
_, err := HttpGetJSON(srv.URL, nil, 50*time.Millisecond)
|
|
if err == nil {
|
|
t.Fatal("expected timeout error, got nil")
|
|
}
|
|
})
|
|
|
|
t.Run("Headers custom", func(t *testing.T) {
|
|
receivedHeaders := make(chan http.Header, 1)
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
receivedHeaders <- r.Header.Clone()
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(`{}`))
|
|
}))
|
|
defer srv.Close()
|
|
|
|
headers := map[string]string{"X-Api-Key": "mytoken"}
|
|
_, err := HttpGetJSON(srv.URL, headers, 5*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
h := <-receivedHeaders
|
|
if h.Get("X-Api-Key") != "mytoken" {
|
|
t.Errorf("X-Api-Key not sent, got: %v", h.Get("X-Api-Key"))
|
|
}
|
|
if h.Get("Accept") != "application/json" {
|
|
t.Errorf("Accept header missing, got: %v", h.Get("Accept"))
|
|
}
|
|
})
|
|
}
|