From 5929d774f0631bc791be120eaf3c59362f7d8b92 Mon Sep 17 00:00:00 2001 From: long-agent Date: Thu, 9 Apr 2026 10:18:31 +0800 Subject: [PATCH] test: add TraceID, ErrorHandler, Recover middleware tests - TestTraceID_GeneratesAndAttachesTraceID - TestTraceID_ExtractsExistingTraceID - TestErrorHandler_HandlesErrors - TestRecover_HandlesPanic Fix test to use errors.New instead of gin.Error{Err: nil} --- internal/api/middleware/runtime_test.go | 79 +++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/internal/api/middleware/runtime_test.go b/internal/api/middleware/runtime_test.go index f69bf47..79e65bf 100644 --- a/internal/api/middleware/runtime_test.go +++ b/internal/api/middleware/runtime_test.go @@ -1,6 +1,7 @@ package middleware import ( + "errors" "net/http" "net/http/httptest" "strings" @@ -137,3 +138,81 @@ func TestNoStoreSensitiveResponses_DoesNotAttachHeadersToNonAuthRoutes(t *testin t.Fatalf("did not expect cache-control header, got %q", got) } } + +// ---------- TraceID middleware ---------- + +func TestTraceID_GeneratesAndAttachesTraceID(t *testing.T) { + gin.SetMode(gin.TestMode) + + recorder := httptest.NewRecorder() + c, _ := gin.CreateTestContext(recorder) + c.Request = httptest.NewRequest(http.MethodGet, "/api/v1/users", nil) + + TraceID()(c) + + traceID := c.GetString("trace_id") + if traceID == "" { + t.Fatal("expected trace_id to be set") + } + if len(traceID) < 8 { + t.Fatalf("trace_id should be reasonably long, got %q", traceID) + } + + if got := recorder.Header().Get("X-Trace-ID"); got != traceID { + t.Fatalf("expected X-Trace-ID header to match trace_id, got %q", got) + } +} + +func TestTraceID_ExtractsExistingTraceID(t *testing.T) { + gin.SetMode(gin.TestMode) + + existingTraceID := "existing-trace-id-12345" + recorder := httptest.NewRecorder() + c, _ := gin.CreateTestContext(recorder) + c.Request = httptest.NewRequest(http.MethodGet, "/api/v1/users", nil) + c.Request.Header.Set("X-Trace-ID", existingTraceID) + + TraceID()(c) + + traceID := c.GetString("trace_id") + if traceID != existingTraceID { + t.Fatalf("expected trace_id to be extracted from header, got %q", traceID) + } +} + +// ---------- Error handling middleware ---------- + +func TestErrorHandler_HandlesErrors(t *testing.T) { + gin.SetMode(gin.TestMode) + + recorder := httptest.NewRecorder() + c, _ := gin.CreateTestContext(recorder) + c.Request = httptest.NewRequest(http.MethodGet, "/api/v1/users", nil) + + c.Error(errors.New("test error")) + + ErrorHandler()(c) + + if recorder.Code != http.StatusInternalServerError { + t.Fatalf("expected status 500, got %d", recorder.Code) + } +} + +func TestRecover_HandlesPanic(t *testing.T) { + gin.SetMode(gin.TestMode) + + recorder := httptest.NewRecorder() + c, router := gin.CreateTestContext(recorder) + c.Request = httptest.NewRequest(http.MethodGet, "/panic", nil) + + router.Use(Recover()) + router.GET("/panic", func(c *gin.Context) { + panic("test panic") + }) + + router.ServeHTTP(recorder, c.Request) + + if recorder.Code != http.StatusInternalServerError { + t.Fatalf("expected status 500 after panic, got %d", recorder.Code) + } +}