package middleware import ( "net/http" "net/http/httptest" "testing" "github.com/QuantumNous/new-api/setting/system_setting" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" ) func TestSyncAuth_Disabled(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() router.Use(SyncAuth()) router.GET("/test", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"success": true}) }) // 未启用区域同步 settings := system_setting.GetRegionSyncSettings() settings.Enabled = false req, _ := http.NewRequest("GET", "/test", nil) req.Header.Set("X-Sync-API-Key", "test-key") req.Header.Set("X-Sync-Node", "slave-1") w := httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusForbidden, w.Code) assert.Contains(t, w.Body.String(), "region sync is not enabled") } func TestSyncAuth_MissingAPIKey(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() router.Use(SyncAuth()) router.GET("/test", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"success": true}) }) settings := system_setting.GetRegionSyncSettings() settings.Enabled = true settings.SyncApiKey = "test-key" req, _ := http.NewRequest("GET", "/test", nil) req.Header.Set("X-Sync-Node", "slave-1") w := httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusUnauthorized, w.Code) assert.Contains(t, w.Body.String(), "missing sync API key") } func TestSyncAuth_InvalidAPIKey(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() router.Use(SyncAuth()) router.GET("/test", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"success": true}) }) settings := system_setting.GetRegionSyncSettings() settings.Enabled = true settings.SyncApiKey = "correct-key" req, _ := http.NewRequest("GET", "/test", nil) req.Header.Set("X-Sync-API-Key", "wrong-key") req.Header.Set("X-Sync-Node", "slave-1") w := httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusUnauthorized, w.Code) assert.Contains(t, w.Body.String(), "invalid sync API key") } func TestSyncAuth_MissingNode(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() router.Use(SyncAuth()) router.GET("/test", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"success": true}) }) settings := system_setting.GetRegionSyncSettings() settings.Enabled = true settings.SyncApiKey = "test-key" req, _ := http.NewRequest("GET", "/test", nil) req.Header.Set("X-Sync-API-Key", "test-key") w := httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusBadRequest, w.Code) assert.Contains(t, w.Body.String(), "missing sync node identifier") } func TestSyncAuth_Valid(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() router.Use(SyncAuth()) router.GET("/test", func(c *gin.Context) { node := GetSyncNode(c) c.JSON(http.StatusOK, gin.H{ "success": true, "node": node, }) }) settings := system_setting.GetRegionSyncSettings() settings.Enabled = true settings.SyncApiKey = "test-key" req, _ := http.NewRequest("GET", "/test", nil) req.Header.Set("X-Sync-API-Key", "test-key") req.Header.Set("X-Sync-Node", "slave-1") w := httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) assert.Contains(t, w.Body.String(), "slave-1") } func TestValidateSyncAPIKey_Single(t *testing.T) { assert.True(t, validateSyncAPIKey("test-key", "test-key")) assert.False(t, validateSyncAPIKey("test-key", "different-key")) assert.False(t, validateSyncAPIKey("", "")) } func TestValidateSyncAPIKey_Multiple(t *testing.T) { // 支持逗号分隔的多个 key assert.True(t, validateSyncAPIKey("key1", "key1,key2,key3")) assert.True(t, validateSyncAPIKey("key2", "key1,key2,key3")) assert.True(t, validateSyncAPIKey("key3", "key1,key2,key3")) assert.False(t, validateSyncAPIKey("key4", "key1,key2,key3")) } func TestValidateSyncAPIKey_TrimSpace(t *testing.T) { // 去除前后空格 assert.True(t, validateSyncAPIKey("test-key", " test-key ")) assert.True(t, validateSyncAPIKey("test-key", " test-key")) assert.True(t, validateSyncAPIKey("test-key", "test-key ")) }