Files
qitongxue-api/internal/logic/admin_perm_test.go

115 lines
4.4 KiB
Go
Raw Normal View History

2026-09-29 10:57:01 +08:00
package logic
import (
"net/http"
"testing"
"tool-api/internal/consts"
)
// TestHasPermission 角色 → 权限点判定。
func TestHasPermission(t *testing.T) {
// 空权限点 = 仅需登录 → 任何角色通过
if !HasPermission(consts.AdminRoleReadonly, "") {
t.Fatal("空权限点应对所有角色放行")
}
// 超管:全部
if !HasPermission(consts.AdminRoleSuper, PermAdminManage) ||
!HasPermission(consts.AdminRoleSuper, PermEventWrite) ||
!HasPermission(consts.AdminRoleSuper, PermAuditRead) {
t.Fatal("超管应拥有全部权限")
}
// 运营:有内容写权限,无管理员管理与审计
if !HasPermission(consts.AdminRoleOperator, PermUserWrite) ||
!HasPermission(consts.AdminRoleOperator, PermEventWrite) {
t.Fatal("运营应有内容写权限")
}
if HasPermission(consts.AdminRoleOperator, PermAdminManage) ||
HasPermission(consts.AdminRoleOperator, PermAuditRead) {
t.Fatal("运营不应拥有管理员管理 / 审计权限")
}
// 只读:无任何写权限
if HasPermission(consts.AdminRoleReadonly, PermUserWrite) ||
HasPermission(consts.AdminRoleReadonly, PermAdminManage) {
t.Fatal("只读不应拥有写权限")
}
// 只读:可查看订单,但不可退款
if !HasPermission(consts.AdminRoleReadonly, PermOrderRead) {
t.Fatal("只读应可查看订单")
}
if HasPermission(consts.AdminRoleReadonly, PermOrderWrite) {
t.Fatal("只读不应拥有订单退款权限")
}
// 未知角色:按最小权限,全部拒绝
if HasPermission("ghost", PermUserWrite) {
t.Fatal("未知角色不应拥有权限")
}
}
// TestPermissionsOf 权限点列表稳定且有序。
func TestPermissionsOf(t *testing.T) {
2026-09-30 17:01:18 +08:00
// 迭代-2026-09-29:新增 goods:write / attachment:write(11 → 13)
if n := len(PermissionsOf(consts.AdminRoleSuper)); n != 13 {
t.Fatalf("超管权限点应为 13,得 %d", n)
2026-09-29 10:57:01 +08:00
}
if n := len(PermissionsOf(consts.AdminRoleReadonly)); n != 1 {
t.Fatalf("只读权限点应为 1(仅 order:read),得 %d", n)
}
pos := PermissionsOf(consts.AdminRoleOperator)
2026-09-30 17:01:18 +08:00
// 迭代-2026-09-29:运营同步获得 goods:write / attachment:write(9 → 11)
if len(pos) != 11 {
t.Fatalf("运营权限点应为 11,得 %d", len(pos))
2026-09-29 10:57:01 +08:00
}
for i := 1; i < len(pos); i++ {
if pos[i-1] > pos[i] {
t.Fatalf("权限点未排序: %v", pos)
}
}
}
// TestPermissionForRoute 路由 → 权限点映射。
func TestPermissionForRoute(t *testing.T) {
cases := []struct {
method, path, want string
}{
{http.MethodPost, "/user/set-level", PermUserWrite},
{http.MethodPost, "/user/status", PermUserWrite},
{http.MethodPost, "/user/batch", PermUserWrite},
{http.MethodPost, "/user/quota-period", PermQuotaWrite}, // 额度操作优先于 /user/ 前缀
{http.MethodPost, "/tools/save", PermToolWrite},
{http.MethodPost, "/module/save", PermModuleWrite},
{http.MethodPost, "/level/save", PermLevelWrite},
{http.MethodPost, "/feedback/handle", PermFeedbackWrite},
{http.MethodPost, "/quota/pack/save", PermQuotaWrite},
{http.MethodPost, "/plan/save", PermQuotaWrite},
{http.MethodPost, "/event/admin/status", PermEventWrite},
{http.MethodPost, "/event/employee/import-confirm", PermEventWrite},
{http.MethodPost, "/admin/save", PermAdminManage},
{http.MethodPost, "/audit/record", ""}, // 上报审计仅需登录(≠读取审计)
{http.MethodPost, "/order/refund", PermOrderWrite},
2026-09-30 17:01:18 +08:00
// 迭代-2026-09-29:软件开发服务 / 附件 / 系统配置
{http.MethodPost, "/admin/goods/save", PermGoodsWrite},
{http.MethodPost, "/admin/goods/delete", PermGoodsWrite},
{http.MethodPost, "/admin/upload", PermAttachmentWrite},
{http.MethodPost, "/admin/attachment/delete", PermAttachmentWrite},
{http.MethodPost, "/admin/setting/save", PermAdminManage},
// 服务/附件列表仅需登录(先于 /admin/ 的 admin:manage 兜底命中)
{http.MethodGet, "/admin/goods/list", ""},
{http.MethodGet, "/admin/attachment/list", ""},
{http.MethodGet, "/admin/setting/get", PermAdminManage},
2026-09-29 10:57:01 +08:00
// 只读接口仅需登录
{http.MethodGet, "/user/list", ""},
{http.MethodGet, "/dashboard/stats", ""},
{http.MethodGet, "/tools/all", ""},
// 敏感只读接口需要权限
{http.MethodGet, "/audit/list", PermAuditRead},
{http.MethodGet, "/admin/list", PermAdminManage},
{http.MethodGet, "/order/list", PermOrderRead},
}
for _, c := range cases {
if got := permissionForRoute(c.method, c.path); got != c.want {
t.Errorf("%s %s → %q,期望 %q", c.method, c.path, got, c.want)
}
}
}