package middleware import ( "net/http" "net/http/httptest" "testing" "github.com/gin-gonic/gin" ) func TestRequestID_GeneratesNewID(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() router.Use(RequestID()) router.GET("/test", func(c *gin.Context) { requestID := GetRequestID(c) if requestID == "" { t.Error("Expected request ID to be set") } c.JSON(http.StatusOK, gin.H{"request_id": requestID}) }) req := httptest.NewRequest(http.MethodGet, "/test", nil) w := httptest.NewRecorder() router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Errorf("Expected status 200, got %d", w.Code) } // Check response header requestID := w.Header().Get(RequestIDHeader) if requestID == "" { t.Error("Expected X-Request-ID header in response") } // Check correlation ID header correlationID := w.Header().Get(CorrelationIDHeader) if correlationID == "" { t.Error("Expected X-Correlation-ID header in response") } if requestID != correlationID { t.Error("X-Request-ID and X-Correlation-ID should match") } } func TestRequestID_PropagatesExistingID(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() router.Use(RequestID()) customID := "custom-request-id-12345" router.GET("/test", func(c *gin.Context) { requestID := GetRequestID(c) if requestID != customID { t.Errorf("Expected request ID %s, got %s", customID, requestID) } c.JSON(http.StatusOK, gin.H{"request_id": requestID}) }) req := httptest.NewRequest(http.MethodGet, "/test", nil) req.Header.Set(RequestIDHeader, customID) w := httptest.NewRecorder() router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Errorf("Expected status 200, got %d", w.Code) } responseID := w.Header().Get(RequestIDHeader) if responseID != customID { t.Errorf("Expected response header %s, got %s", customID, responseID) } } func TestRequestID_PropagatesCorrelationID(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() router.Use(RequestID()) correlationID := "correlation-id-67890" router.GET("/test", func(c *gin.Context) { requestID := GetRequestID(c) if requestID != correlationID { t.Errorf("Expected request ID %s, got %s", correlationID, requestID) } c.JSON(http.StatusOK, gin.H{}) }) req := httptest.NewRequest(http.MethodGet, "/test", nil) req.Header.Set(CorrelationIDHeader, correlationID) w := httptest.NewRecorder() router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Errorf("Expected status 200, got %d", w.Code) } // Both headers should be set with the correlation ID if w.Header().Get(RequestIDHeader) != correlationID { t.Error("X-Request-ID should match X-Correlation-ID") } } func TestGetRequestID_ReturnsEmptyWhenNotSet(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() // No RequestID middleware router.GET("/test", func(c *gin.Context) { requestID := GetRequestID(c) if requestID != "" { t.Errorf("Expected empty request ID, got %s", requestID) } c.JSON(http.StatusOK, gin.H{}) }) req := httptest.NewRequest(http.MethodGet, "/test", nil) w := httptest.NewRecorder() router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Errorf("Expected status 200, got %d", w.Code) } } func TestRequestIDFromContext_IsAliasForGetRequestID(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() router.Use(RequestID()) router.GET("/test", func(c *gin.Context) { id1 := GetRequestID(c) id2 := RequestIDFromContext(c) if id1 != id2 { t.Errorf("GetRequestID and RequestIDFromContext should return same value") } c.JSON(http.StatusOK, gin.H{}) }) req := httptest.NewRequest(http.MethodGet, "/test", nil) w := httptest.NewRecorder() router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Errorf("Expected status 200, got %d", w.Code) } }