package services import "testing" // 这些用例只覆盖权限模块中不依赖数据库的纯函数:角色 rights 解析。 // CheckUserPermission 需要查用户/角色/菜单表,属于集成测试范围,此处不覆盖。 func TestParseMenuRights(t *testing.T) { cases := []struct { name string raw string want []uint64 }{ // 规范格式:角色保存接口 json.Marshal([]uint64) 写回的数字数组。 // 曾经只按 []string 反序列化,整体失败后退化成逗号切分, // 首尾元素带上 [ / ] 解析不出数字,第一个和最后一个菜单被静默丢弃。 {"数字数组", "[15,36,37,263]", []uint64{15, 36, 37, 263}}, {"单元素数组", "[7]", []uint64{7}}, {"字符串数组", `["15","36"]`, []uint64{15, 36}}, {"逗号分隔", "15, 36 ,263", []uint64{15, 36, 263}}, {"空数组", "[]", nil}, {"空串", "", nil}, {"脏数据", "abc", nil}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { got := ParseMenuRights(c.raw) if len(got) != len(c.want) { t.Fatalf("rights=%q 期望解析出 %d 个菜单 ID,实际 %d 个:%v", c.raw, len(c.want), len(got), got) } for _, id := range c.want { if !got[id] { t.Fatalf("rights=%q 期望包含菜单 ID %d,实际结果 %v", c.raw, id, got) } } }) } } func TestParseMenuRightsKeepsBoundaryIDs(t *testing.T) { // 单独锁住边界元素:丢首尾是线上真实出现过的故障表现(菜单页渲染成 404) got := ParseMenuRights("[15,36,37,38,263]") for _, id := range []uint64{15, 263} { if !got[id] { t.Fatalf("首尾菜单 ID %d 丢失,解析结果 %v", id, got) } } }