Files
Charon/backend/internal/api/handlers/security_geoip_endpoints_test.go
2026-03-04 18:34:49 +00:00

139 lines
4.0 KiB
Go

package handlers
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/Wikid82/charon/backend/internal/config"
"github.com/Wikid82/charon/backend/internal/services"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSecurityHandler_GetGeoIPStatus_NotInitialized(t *testing.T) {
gin.SetMode(gin.TestMode)
h := NewSecurityHandler(config.SecurityConfig{}, nil, nil)
r := gin.New()
r.GET("/security/geoip/status", h.GetGeoIPStatus)
w := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/security/geoip/status", http.NoBody)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var body map[string]any
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &body))
assert.Equal(t, false, body["loaded"])
assert.Equal(t, "GeoIP service not initialized", body["message"])
}
func TestSecurityHandler_GetGeoIPStatus_Initialized_NotLoaded(t *testing.T) {
gin.SetMode(gin.TestMode)
h := NewSecurityHandler(config.SecurityConfig{}, nil, nil)
h.SetGeoIPService(&services.GeoIPService{})
r := gin.New()
r.GET("/security/geoip/status", h.GetGeoIPStatus)
w := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/security/geoip/status", http.NoBody)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var body map[string]any
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &body))
assert.Equal(t, false, body["loaded"])
assert.Equal(t, "GeoIP service available", body["message"])
}
func TestSecurityHandler_ReloadGeoIP_NotInitialized(t *testing.T) {
gin.SetMode(gin.TestMode)
h := NewSecurityHandler(config.SecurityConfig{}, nil, nil)
r := gin.New()
r.Use(func(c *gin.Context) {
c.Set("role", "admin")
c.Next()
})
r.POST("/security/geoip/reload", h.ReloadGeoIP)
w := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodPost, "/security/geoip/reload", http.NoBody)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusServiceUnavailable, w.Code)
}
func TestSecurityHandler_ReloadGeoIP_LoadError(t *testing.T) {
gin.SetMode(gin.TestMode)
h := NewSecurityHandler(config.SecurityConfig{}, nil, nil)
h.SetGeoIPService(&services.GeoIPService{}) // dbPath empty => Load() will error
r := gin.New()
r.Use(func(c *gin.Context) {
c.Set("role", "admin")
c.Next()
})
r.POST("/security/geoip/reload", h.ReloadGeoIP)
w := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodPost, "/security/geoip/reload", http.NoBody)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusInternalServerError, w.Code)
assert.Contains(t, w.Body.String(), "Failed to reload GeoIP database")
}
func TestSecurityHandler_LookupGeoIP_MissingIPAddress(t *testing.T) {
gin.SetMode(gin.TestMode)
h := NewSecurityHandler(config.SecurityConfig{}, nil, nil)
r := gin.New()
r.Use(func(c *gin.Context) {
c.Set("role", "admin")
c.Next()
})
r.POST("/security/geoip/lookup", h.LookupGeoIP)
payload := []byte(`{}`)
w := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodPost, "/security/geoip/lookup", bytes.NewReader(payload))
req.Header.Set("Content-Type", "application/json")
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusBadRequest, w.Code)
assert.Contains(t, w.Body.String(), "ip_address is required")
}
func TestSecurityHandler_LookupGeoIP_ServiceUnavailable(t *testing.T) {
gin.SetMode(gin.TestMode)
h := NewSecurityHandler(config.SecurityConfig{}, nil, nil)
h.SetGeoIPService(&services.GeoIPService{}) // present but not loaded
r := gin.New()
r.Use(func(c *gin.Context) {
c.Set("role", "admin")
c.Next()
})
r.POST("/security/geoip/lookup", h.LookupGeoIP)
payload, _ := json.Marshal(map[string]string{"ip_address": "8.8.8.8"})
w := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodPost, "/security/geoip/lookup", bytes.NewReader(payload))
req.Header.Set("Content-Type", "application/json")
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusServiceUnavailable, w.Code)
assert.Contains(t, w.Body.String(), "GeoIP service not available")
}