package httputil import ( "encoding/json" "errors" "net/http" "net/http/httptest" "strings" "testing" "sourcecraft.dev/bigbes/huntsman/internal/pkg/apierror" ) func TestJSONStatusAndBody(t *testing.T) { rr := httptest.NewRecorder() JSON(rr, 201, map[string]int{"n": 7}) if rr.Code != 201 { t.Errorf("status = %d", rr.Code) } if got := rr.Header().Get("Content-Type"); got != "application/json" { t.Errorf("content-type = %q", got) } var body map[string]int if err := json.Unmarshal(rr.Body.Bytes(), &body); err != nil { t.Fatalf("decode: %v", err) } if body["n"] != 7 { t.Errorf("body = %+v", body) } } func TestJSONNilDataWritesNoBody(t *testing.T) { rr := httptest.NewRecorder() JSON(rr, 204, nil) if rr.Code != 204 { t.Errorf("status = %d", rr.Code) } if rr.Body.Len() != 0 { t.Errorf("body should be empty, got %q", rr.Body.String()) } } func TestOK(t *testing.T) { rr := httptest.NewRecorder() OK(rr, map[string]string{"hello": "world"}) if rr.Code != 200 { t.Errorf("status = %d", rr.Code) } } func TestErrorMapsClientError(t *testing.T) { rr := httptest.NewRecorder() req := httptest.NewRequestWithContext(t.Context(), "GET", "/foo", http.NoBody) Error(rr, req, apierror.NotFound("widget")) if rr.Code != 404 { t.Errorf("status = %d", rr.Code) } if got := rr.Header().Get("Content-Type"); got != "application/problem+json" { t.Errorf("content-type = %q", got) } } func TestErrorMapsInternalError(t *testing.T) { rr := httptest.NewRecorder() req := httptest.NewRequestWithContext(t.Context(), "GET", "/foo", http.NoBody) Error(rr, req, errors.New("boom")) if rr.Code != 500 { t.Errorf("status = %d", rr.Code) } // Internal detail should not leak in the body. if got := rr.Body.String(); strings.Contains(got, "boom") { t.Errorf("response body leaks internal error: %q", got) } }