package metrics_test import ( "encoding/json" "errors" "net/http/httptest" "testing" apierrors "git.yuntuo.hk/k2safe/go-omni/errors" "git.yuntuo.hk/k2safe/go-omni/httpx" "git.yuntuo.hk/k2safe/go-omni/metrics" ) func TestMiddlewareCollectsStatusesAndErrors(t *testing.T) { collector := metrics.New() request := httptest.NewRequest("GET", "/health", nil) first := httptest.NewRecorder() ctx := httpx.NewContext(request, first, nil) if err := collector.Middleware()(func(c *httpx.Context) error { return c.OK("ok") })(ctx); err != nil { t.Fatal(err) } second := httptest.NewRecorder() ctx = httpx.NewContext(request, second, nil) handled := collector.Middleware()(func(*httpx.Context) error { return apierrors.NotFound("MISSING", "missing") }) if err := handled(ctx); err == nil { t.Fatal("expected handler error") } snapshot := collector.Snapshot() if snapshot.Requests != 2 || snapshot.Errors != 1 || snapshot.InFlight != 0 || snapshot.StatusCounts["200"] != 1 || snapshot.StatusCounts["404"] != 1 { t.Fatalf("unexpected snapshot: %+v", snapshot) } } func TestHandlerReturnsJSONSnapshot(t *testing.T) { collector := metrics.New() request := httptest.NewRequest("GET", "/metrics", nil) recorder := httptest.NewRecorder() ctx := httpx.NewContext(request, recorder, nil) if err := collector.Handler()(ctx); err != nil { t.Fatal(err) } var envelope struct { Code string `json:"code"` Data metrics.Snapshot `json:"data"` } if err := json.Unmarshal(recorder.Body.Bytes(), &envelope); err != nil { t.Fatal(err) } if envelope.Code != "OK" || envelope.Data.StatusCounts == nil { t.Fatalf("unexpected metrics response: %s", recorder.Body) } } func TestMiddlewarePreservesApplicationErrors(t *testing.T) { collector := metrics.New() request := httptest.NewRequest("GET", "/", nil) ctx := httpx.NewContext(request, httptest.NewRecorder(), nil) want := errors.New("database unavailable") got := collector.Middleware()(func(*httpx.Context) error { return want })(ctx) if !errors.Is(got, want) { t.Fatalf("middleware replaced error: %v", got) } }