97 lines
2.6 KiB
Go
97 lines
2.6 KiB
Go
package testutil
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// NewRequest creates a test HTTP request with JSON body.
|
|
func NewRequest(t *testing.T, method, path string, body any) *http.Request {
|
|
t.Helper()
|
|
var buf bytes.Buffer
|
|
if body != nil {
|
|
if err := json.NewEncoder(&buf).Encode(body); err != nil {
|
|
t.Fatalf("encode request body: %v", err)
|
|
}
|
|
}
|
|
req := httptest.NewRequest(method, path, &buf)
|
|
req.Header.Set("Content-Type", "application/json")
|
|
return req
|
|
}
|
|
|
|
// NewRequestWithAuth creates a test request with API Key auth.
|
|
func NewRequestWithAuth(t *testing.T, method, path, apiKey string, body any) *http.Request {
|
|
t.Helper()
|
|
req := NewRequest(t, method, path, body)
|
|
req.Header.Set("Authorization", "Bearer "+apiKey)
|
|
return req
|
|
}
|
|
|
|
// AssertStatus checks the response status code.
|
|
func AssertStatus(t *testing.T, rr *httptest.ResponseRecorder, want int) {
|
|
t.Helper()
|
|
if rr.Code != want {
|
|
t.Errorf("expected status %d, got %d", want, rr.Code)
|
|
}
|
|
}
|
|
|
|
// AssertJSON checks the response body contains expected JSON fields.
|
|
func AssertJSON(t *testing.T, rr *httptest.ResponseRecorder, expected map[string]any) {
|
|
t.Helper()
|
|
var actual map[string]any
|
|
if err := json.Unmarshal(rr.Body.Bytes(), &actual); err != nil {
|
|
t.Fatalf("unmarshal response: %v\nbody: %s", err, rr.Body.String())
|
|
}
|
|
for k, v := range expected {
|
|
got, ok := actual[k]
|
|
if !ok {
|
|
t.Errorf("expected key %q in response, not found", k)
|
|
continue
|
|
}
|
|
if got != v {
|
|
t.Errorf("expected %q = %v, got %v", k, v, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
// AssertErrorCode checks the error code in the response.
|
|
func AssertErrorCode(t *testing.T, rr *httptest.ResponseRecorder, code string) {
|
|
t.Helper()
|
|
var resp map[string]any
|
|
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
|
|
t.Fatalf("unmarshal error response: %v", err)
|
|
}
|
|
errBody, ok := resp["error"].(map[string]any)
|
|
if !ok {
|
|
t.Fatal("expected error object in response")
|
|
}
|
|
if errBody["code"] != code {
|
|
t.Errorf("expected error code %q, got %v", code, errBody["code"])
|
|
}
|
|
}
|
|
|
|
// RandomID generates a random ID string for testing.
|
|
func RandomID() string {
|
|
return "test-" + randHex(8)
|
|
}
|
|
|
|
func randHex(n int) string {
|
|
const hexChars = "0123456789abcdef"
|
|
b := make([]byte, n)
|
|
for i := range b {
|
|
b[i] = hexChars[time.Now().UnixNano()%int64(len(hexChars))]
|
|
}
|
|
return string(b)
|
|
}
|
|
|
|
// ExecuteRequest executes a request against a handler and returns the response.
|
|
func ExecuteRequest(handler http.Handler, req *http.Request) *httptest.ResponseRecorder {
|
|
rr := httptest.NewRecorder()
|
|
handler.ServeHTTP(rr, req)
|
|
return rr
|
|
}
|