package testutil import ( "encoding/json" "net/http/httptest" "testing" "github.com/stretchr/testify/require" ) // TestResponse wraps a response recorder with assertion methods type TestResponse struct { recorder *httptest.ResponseRecorder } // NewTestResponse creates a new TestResponse from a response recorder func NewTestResponse(recorder *httptest.ResponseRecorder) *TestResponse { return &TestResponse{recorder: recorder} } // AssertStatus asserts the HTTP status code func (r *TestResponse) AssertStatus(t *testing.T, expected int) { t.Helper() require.Equal(t, expected, r.recorder.Code, "Expected status code %d, got %d. Body: %s", expected, r.recorder.Code, r.recorder.Body.String()) } // AssertJSON asserts the JSON response matches the expected value func (r *TestResponse) AssertJSON(t *testing.T, expected any) { t.Helper() var actual any err := json.Unmarshal(r.recorder.Body.Bytes(), &actual) require.NoError(t, err, "Failed to parse JSON response: %s", r.recorder.Body.String()) require.Equal(t, expected, actual) } // AssertJSONContainsKey asserts that the JSON response contains a key and returns its value func (r *TestResponse) AssertJSONContainsKey(t *testing.T, key string) any { t.Helper() var jsonData map[string]any err := json.Unmarshal(r.recorder.Body.Bytes(), &jsonData) require.NoError(t, err, "Failed to parse JSON response: %s", r.recorder.Body.String()) require.Contains(t, jsonData, key, "Response should contain key '%s'. Response: %s", key, r.recorder.Body.String()) return jsonData[key] } // AssertJSONKeyValue asserts that the JSON response contains a key and calls the assert function with its value func (r *TestResponse) AssertJSONKeyValue(t *testing.T, key string, assertFunc func(t *testing.T, value any)) { t.Helper() value := r.AssertJSONContainsKey(t, key) assertFunc(t, value) } // AssertBodyContains asserts that the response body contains the expected string func (r *TestResponse) AssertBodyContains(t *testing.T, expected string) { t.Helper() require.Contains(t, r.recorder.Body.String(), expected, "Response body should contain '%s'. Body: %s", expected, r.recorder.Body.String()) } // GetBody returns the response body as bytes func (r *TestResponse) GetBody() []byte { return r.recorder.Body.Bytes() } // GetBodyString returns the response body as a string func (r *TestResponse) GetBodyString() string { return r.recorder.Body.String() } // GetStatusCode returns the HTTP status code func (r *TestResponse) GetStatusCode() int { return r.recorder.Code }