hatch-surf/cmd/hatch/main_test.go
SoftwareEngineer 4256d34c27 feat: add one-click replay for captured requests
- Add POST /e/{endpoint}/requests/{id}/replay endpoint
- Replay re-sends captured method, path, headers, query, body to target URL
- Response includes target status code, headers, body (truncated 64KB)
- SSRF guard: denies replay to private/loopback by default
- Opt-in env var HATCH_ALLOW_PRIVATE_REPLAY=true for local dev
- Server-rendered inspect page at GET /e/{endpoint} with replay button UI
- SSE live stream for new requests (EventSource)
- Mock configuration at PUT /e/{endpoint}/mock
- Store: GetRequest, GetMock, SetMock methods added
- Chi router migration from stdlib ServeMux
- 26 passing tests including replay unit tests and E2E capture-to-replay

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 16:58:42 +02:00

78 lines
1.6 KiB
Go

package main
import (
"io"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
"github.com/elfoundation/hatch/internal/handler"
"github.com/elfoundation/hatch/internal/store"
"github.com/go-chi/chi/v5"
)
func TestHealthzViaRouter(t *testing.T) {
repo, err := store.Open(":memory:")
if err != nil {
t.Fatalf("open store: %v", err)
}
defer repo.Close()
r := chi.NewRouter()
h := handler.New(repo)
h.RegisterRoutes(r)
req := httptest.NewRequest(http.MethodGet, "/healthz", nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200 OK, got %d", w.Code)
}
body, _ := io.ReadAll(w.Result().Body)
w.Result().Body.Close()
got := strings.TrimSpace(string(body))
if got != "ok" {
t.Fatalf("expected body 'ok', got %q", got)
}
}
func TestHealthzSmoke(t *testing.T) {
// Smoke: boot server on random port, hit /healthz.
// Use :memory: store so no filesystem dependency.
os.Setenv("HATCH_DB_PATH", ":memory:")
repo, err := store.Open(":memory:")
if err != nil {
t.Fatalf("open store: %v", err)
}
defer repo.Close()
r := chi.NewRouter()
h := handler.New(repo)
h.RegisterRoutes(r)
srv := httptest.NewServer(r)
defer srv.Close()
resp, err := http.Get(srv.URL + "/healthz")
if err != nil {
t.Fatalf("failed to GET /healthz: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatalf("expected 200 OK, got %d", resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatalf("failed to read response body: %v", err)
}
got := strings.TrimSpace(string(body))
if got != "ok" {
t.Fatalf("expected body 'ok', got %q", got)
}
}