Eliminates repeated marshal-set-header-write boilerplate in handlers.
WriteError produces consistent {"error": "..."} JSON responses.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
73 lines
1.6 KiB
Go
73 lines
1.6 KiB
Go
package server_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"git.codelab.vc/pkg/httpx/server"
|
|
)
|
|
|
|
func TestWriteJSON(t *testing.T) {
|
|
t.Run("writes JSON with status and content type", func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
|
|
type resp struct {
|
|
ID int `json:"id"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
err := server.WriteJSON(w, 201, resp{ID: 1, Name: "Alice"})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
if w.Code != 201 {
|
|
t.Fatalf("got status %d, want %d", w.Code, 201)
|
|
}
|
|
if ct := w.Header().Get("Content-Type"); ct != "application/json" {
|
|
t.Fatalf("Content-Type = %q, want %q", ct, "application/json")
|
|
}
|
|
|
|
var decoded resp
|
|
if err := json.Unmarshal(w.Body.Bytes(), &decoded); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
if decoded.ID != 1 || decoded.Name != "Alice" {
|
|
t.Fatalf("got %+v, want {ID:1 Name:Alice}", decoded)
|
|
}
|
|
})
|
|
|
|
t.Run("returns error for unmarshalable input", func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
|
|
err := server.WriteJSON(w, 200, make(chan int))
|
|
if err == nil {
|
|
t.Fatal("expected error for channel type")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestWriteError(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
|
|
err := server.WriteError(w, 404, "not found")
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
if w.Code != 404 {
|
|
t.Fatalf("got status %d, want %d", w.Code, 404)
|
|
}
|
|
|
|
var body struct {
|
|
Error string `json:"error"`
|
|
}
|
|
if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
if body.Error != "not found" {
|
|
t.Fatalf("error = %q, want %q", body.Error, "not found")
|
|
}
|
|
}
|