package middleware import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "testing" "github.com/gin-gonic/gin" "github.com/stretchr/testify/require" "portal-mini-go/internal/model/admin" "portal-mini-go/internal/pkg/response" ) // simulateLoader 模拟 PermissionLoader 把角色与权限集写入 context。 func simulateLoader(roles, perms []string) gin.HandlerFunc { return func(c *gin.Context) { c.Set(adminRolesCtxKey, roles) set := make(map[string]struct{}, len(perms)) for _, p := range perms { set[p] = struct{}{} } c.Set(adminPermsCtxKey, set) c.Next() } } func doReq(r *gin.Engine, method, path string) (int, int) { req := httptest.NewRequest(method, path, bytes.NewReader(nil)) w := httptest.NewRecorder() r.ServeHTTP(w, req) var body response.Response _ = json.Unmarshal(w.Body.Bytes(), &body) return w.Code, body.Code } func TestRequirePerm(t *testing.T) { gin.SetMode(gin.TestMode) cases := []struct { name string roles []string perms []string need []string wantCode int // 业务码:0 通过,40300 禁止 }{ {"super_admin 短路", []string{admin.SuperAdminRoleCode}, nil, []string{"any:perm"}, 0}, {"拥有所需权限", nil, []string{"user:view"}, []string{"user:view"}, 0}, {"缺少所需权限", nil, []string{"other"}, []string{"user:view"}, 40300}, {"多权限全部满足", nil, []string{"a", "b"}, []string{"a", "b"}, 0}, {"多权限部分缺失", nil, []string{"a"}, []string{"a", "b"}, 40300}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { r := gin.New() r.Use(ErrorHandler()) g := r.Group("/x") g.Use(simulateLoader(tc.roles, tc.perms)) g.GET("/need", RequirePerm(tc.need...), func(c *gin.Context) { c.Status(http.StatusOK) }) _, code := doReq(r, http.MethodGet, "/x/need") require.Equal(t, tc.wantCode, code) }) } }