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)
}
}