package middleware import ( "context" "encoding/json" "fmt" "net/http" "net/http/httptest" "testing" "time" "github.com/gin-gonic/gin" "github.com/redis/go-redis/v9" ) func TestRequireAnyPermission(t *testing.T) { gin.SetMode(gin.TestMode) rdb := redis.NewClient(&redis.Options{ Addr: "127.0.0.1:16379", DB: 14, }) ctx := t.Context() if err := rdb.Ping(ctx).Err(); err != nil { t.Skipf("跳过测试:未检测到测试 Redis: %v", err) } t.Cleanup(func() { _ = rdb.FlushDB(context.Background()).Err() _ = rdb.Close() }) _ = rdb.FlushDB(ctx) adminID := uint64(101) permKey := fmt.Sprintf("admin:perms:%d", adminID) setPerms := func(perms []string) { raw, err := json.Marshal(perms) if err != nil { t.Fatal(err) } if err := rdb.Set(ctx, permKey, string(raw), time.Minute).Err(); err != nil { t.Fatal(err) } } setupRouter := func() *gin.Engine { r := gin.New() r.Use(func(c *gin.Context) { c.Set(ContextAdminID, adminID) c.Next() }) r.GET("/test-any", RequireAnyPermission(rdb, "distribution:site_view", "qrcode:view"), func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"ok": true}) }) return r } router := setupRouter() // 1. 无任何权限 -> 403 setPerms([]string{"dashboard:view"}) req := httptest.NewRequest(http.MethodGet, "/test-any", nil) w := httptest.NewRecorder() router.ServeHTTP(w, req) if w.Code != http.StatusForbidden { t.Fatalf("expected 403, got %d", w.Code) } // 2. 具备 qrcode:view -> 200 setPerms([]string{"qrcode:view"}) req = httptest.NewRequest(http.MethodGet, "/test-any", nil) w = httptest.NewRecorder() router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d", w.Code) } // 3. 具备 distribution:site_view -> 200 setPerms([]string{"distribution:site_view"}) req = httptest.NewRequest(http.MethodGet, "/test-any", nil) w = httptest.NewRecorder() router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d", w.Code) } // 4. 超管通配符 * -> 200 setPerms([]string{"*"}) req = httptest.NewRequest(http.MethodGet, "/test-any", nil) w = httptest.NewRecorder() router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d", w.Code) } }