package api import ( "bytes" "encoding/json" "io" "net/http" "net/http/httptest" "testing" "github.com/isabelroses/quoteit/internal/store" "github.com/labstack/echo/v4" ) func newTestEnv(t *testing.T) (*echo.Echo, *store.Store) { t.Helper() st, err := store.Open(":memory:") if err != nil { t.Fatalf("open store: %v", err) } return New(st).Routes(), st } func do(t *testing.T, e *echo.Echo, method, path string, body any, headers map[string]string) *httptest.ResponseRecorder { t.Helper() var reader io.Reader if body != nil { b, err := json.Marshal(body) if err != nil { t.Fatalf("marshal: %v", err) } reader = bytes.NewReader(b) } req := httptest.NewRequest(method, path, reader) if body != nil { req.Header.Set("Content-Type", "application/json") } for k, v := range headers { req.Header.Set(k, v) } w := httptest.NewRecorder() e.ServeHTTP(w, req) return w } func decodeJSON[T any](t *testing.T, body *bytes.Buffer) T { t.Helper() var v T if err := json.NewDecoder(body).Decode(&v); err != nil { t.Fatalf("decode: %v", err) } return v } func bearer(token string) map[string]string { return map[string]string{"Authorization": "Bearer " + token} } func assertStatus(t *testing.T, w *httptest.ResponseRecorder, want int) { t.Helper() if w.Code != want { t.Fatalf("status: got %d want %d; body=%s", w.Code, want, w.Body.String()) } } // Ensure echo's RealIP fallback doesn't break httptest (RemoteAddr is set by httptest). var _ = http.StatusOK