package middleware import ( "net/http" "net/http/httptest" "testing" "github.com/gin-gonic/gin" "github.com/perfect-panel/server/pkg/constant" ) // TestAdminMetaMiddleware_PopulatesCtx asserts the middleware pins ClientIP // and User-Agent onto the request context under the typed constant keys, so // downstream audit writers can pick them up without gin.Context threading. func TestAdminMetaMiddleware_PopulatesCtx(t *testing.T) { gin.SetMode(gin.TestMode) var ( gotIP string gotUA string ) r := gin.New() r.Use(AdminMetaMiddleware()) r.GET("/ping", func(c *gin.Context) { ctx := c.Request.Context() gotIP, _ = ctx.Value(constant.CtxKeyIP).(string) gotUA, _ = ctx.Value(constant.CtxKeyUserAgent).(string) c.String(http.StatusOK, "ok") }) req := httptest.NewRequest(http.MethodGet, "/ping", nil) req.RemoteAddr = "10.99.99.7:54321" req.Header.Set("User-Agent", "qa-audit-probe") w := httptest.NewRecorder() r.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("status = %d, want 200", w.Code) } if gotUA != "qa-audit-probe" { t.Fatalf("user_agent = %q, want %q", gotUA, "qa-audit-probe") } // Gin resolves ClientIP() from RemoteAddr when no forwarded headers are // trusted. It strips the port, so we assert the exact host we set. if gotIP != "10.99.99.7" { t.Fatalf("ip = %q, want %q", gotIP, "10.99.99.7") } } // TestAdminMetaMiddleware_UsesTypedKey guards against the regression that // motivated PR D: reader and writer must share the typed CtxKey, not a bare // string. A ctx.Value("ip") lookup (bare string) MUST miss even though the // typed CtxKey "ip" is present. func TestAdminMetaMiddleware_UsesTypedKey(t *testing.T) { gin.SetMode(gin.TestMode) var ( typedIP string bareStrIP any ) r := gin.New() r.Use(AdminMetaMiddleware()) r.GET("/ping", func(c *gin.Context) { ctx := c.Request.Context() typedIP, _ = ctx.Value(constant.CtxKeyIP).(string) bareStrIP = ctx.Value("ip") // bare string key — must MISS c.String(http.StatusOK, "ok") }) req := httptest.NewRequest(http.MethodGet, "/ping", nil) req.RemoteAddr = "10.1.2.3:80" w := httptest.NewRecorder() r.ServeHTTP(w, req) if typedIP == "" { t.Fatalf("typed CtxKeyIP lookup must succeed") } if bareStrIP != nil { t.Fatalf("bare-string \"ip\" lookup MUST miss (got %v); F2 regression risk", bareStrIP) } }