forgejo-tickets/internal/middleware/middleware_test.go

133 lines
2.8 KiB
Go

package middleware
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
)
func init() {
gin.SetMode(gin.TestMode)
}
func TestRequestID_SetsHeader(t *testing.T) {
r := gin.New()
r.Use(RequestID)
r.GET("/", func(c *gin.Context) {
c.Status(http.StatusOK)
})
req := httptest.NewRequest(http.MethodGet, "/", nil)
rr := httptest.NewRecorder()
r.ServeHTTP(rr, req)
reqID := rr.Header().Get("X-Request-ID")
if reqID == "" {
t.Fatal("expected X-Request-ID header to be set, but it was empty")
}
// 8 random bytes = 16 hex characters
if len(reqID) != 16 {
t.Errorf("expected X-Request-ID length 16, got %d (%q)", len(reqID), reqID)
}
}
func TestRequestID_UniquePerRequest(t *testing.T) {
r := gin.New()
r.Use(RequestID)
r.GET("/", func(c *gin.Context) {
c.Status(http.StatusOK)
})
req1 := httptest.NewRequest(http.MethodGet, "/", nil)
rr1 := httptest.NewRecorder()
r.ServeHTTP(rr1, req1)
req2 := httptest.NewRequest(http.MethodGet, "/", nil)
rr2 := httptest.NewRecorder()
r.ServeHTTP(rr2, req2)
id1 := rr1.Header().Get("X-Request-ID")
id2 := rr2.Header().Get("X-Request-ID")
if id1 == id2 {
t.Errorf("expected unique request IDs, but both were %q", id1)
}
}
func TestLogging_DoesNotPanic(t *testing.T) {
r := gin.New()
r.Use(Logging)
r.GET("/test-path", func(c *gin.Context) {
c.Status(http.StatusOK)
})
req := httptest.NewRequest(http.MethodGet, "/test-path", nil)
rr := httptest.NewRecorder()
// Should not panic
r.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Errorf("expected status 200, got %d", rr.Code)
}
}
func TestLogging_RecordsStatus(t *testing.T) {
r := gin.New()
r.Use(Logging)
r.GET("/missing", func(c *gin.Context) {
c.Status(http.StatusNotFound)
})
req := httptest.NewRequest(http.MethodGet, "/missing", nil)
rr := httptest.NewRecorder()
r.ServeHTTP(rr, req)
if rr.Code != http.StatusNotFound {
t.Errorf("expected status 404, got %d", rr.Code)
}
}
func TestRecovery_CatchesPanics(t *testing.T) {
r := gin.New()
r.Use(Recovery)
r.GET("/", func(c *gin.Context) {
panic("something went wrong")
})
req := httptest.NewRequest(http.MethodGet, "/", nil)
rr := httptest.NewRecorder()
// Should not propagate the panic
r.ServeHTTP(rr, req)
if rr.Code != http.StatusInternalServerError {
t.Errorf("expected status 500, got %d", rr.Code)
}
}
func TestRecovery_PassesThroughNormally(t *testing.T) {
r := gin.New()
r.Use(Recovery)
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "ok")
})
req := httptest.NewRequest(http.MethodGet, "/", nil)
rr := httptest.NewRecorder()
r.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Errorf("expected status 200, got %d", rr.Code)
}
if rr.Body.String() != "ok" {
t.Errorf("expected body %q, got %q", "ok", rr.Body.String())
}
}