70 lines
1.8 KiB
Go
70 lines
1.8 KiB
Go
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)
|
|
})
|
|
}
|
|
}
|