chore: 并入 iotlcm-admin-svr 历史到 admin-svr/(原提交 49818c6)
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
_ "github.com/gogf/gf/contrib/drivers/sqlite/v2"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcfg"
|
||||
|
||||
_ "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/logic/memorydb"
|
||||
_ "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/logic/system"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/contexts"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model"
|
||||
)
|
||||
|
||||
// 复现生产形态:dept 100 同时存在模板角色 18(is_pass=1)和普通角色 79(运营人员,is_pass=0)。
|
||||
// 给 79 勾权限保存时,旧逻辑强制把 in.IsPass 置 1 再查重,必然报
|
||||
// 「每个机构只能配置一个下级管理员角色」,导致普通角色永远改不了。
|
||||
func TestSaveTemplateRoleAllowsOrdinaryRoleWithTemplateConfigured(t *testing.T) {
|
||||
setupRoleSaveTestDB(t)
|
||||
ctx := contexts.Set(context.Background(), &model.Context{User: &model.Identity{BaseClaims: model.BaseClaims{
|
||||
ID: 1,
|
||||
TenantId: "000000",
|
||||
DeptId: 100,
|
||||
Roles: []model.Role{{RoleId: 1}},
|
||||
}}})
|
||||
// 模板已配置为 18,机构 100 已有 is_pass=1 的 18
|
||||
mustExecRole(t, ctx, `INSERT INTO sys_dept (dept_id, tenant_id, parent_id, dept_type, status, dept_role) VALUES (100,'000000',0,1,'0',1)`)
|
||||
mustExecRole(t, ctx, `INSERT INTO sys_role (role_id, tenant_id, dept_id, role_name, role_key, status, data_scope, is_pass, created_dept) VALUES
|
||||
(1,'000000',100,'超级管理员','admin','0','1',0,100),
|
||||
(18,'000000',100,'代理商','dl','0','4',1,100),
|
||||
(79,'000000',100,'运营人员','yunying','0','4',0,100)`)
|
||||
mustExecRole(t, ctx, `INSERT INTO sys_role_menu (tenant_id, role_id, menu_id, data_scope) VALUES ('000000',18,100,'0')`)
|
||||
mustExecRole(t, ctx, `INSERT INTO sys_config (config_id, tenant_id, config_key, config_value) VALUES (1,'000000','agent.role.template.role_id','18')`)
|
||||
|
||||
// 编辑普通角色 79:勾一个菜单
|
||||
_, err := NewAgentRole().saveTemplateRole(ctx, &model.AgentRoleSaveParam{
|
||||
RoleId: 79,
|
||||
DeptId: 100,
|
||||
RoleName: "运营人员",
|
||||
RoleKey: "yunying",
|
||||
Status: "0",
|
||||
DataScope: "4",
|
||||
MenuIds: []int64{100},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("已配置模板时普通角色必须能保存,实际报错: %v", err)
|
||||
}
|
||||
|
||||
// 关键断言:79 不能被悄悄改成 is_pass=1
|
||||
var isPass int
|
||||
v, qErr := g.DB().GetValue(ctx, `SELECT is_pass FROM sys_role WHERE role_id = 79`)
|
||||
if qErr != nil {
|
||||
t.Fatalf("query is_pass failed: %v", qErr)
|
||||
}
|
||||
isPass = v.Int()
|
||||
if isPass != 0 {
|
||||
t.Fatalf("普通角色 79 的 is_pass 被改成了 %d,应保持 0", isPass)
|
||||
}
|
||||
// 模板 18 的 is_pass 也不能被动到
|
||||
v18, _ := g.DB().GetValue(ctx, `SELECT is_pass FROM sys_role WHERE role_id = 18`)
|
||||
if v18.Int() != 1 {
|
||||
t.Fatalf("模板角色 18 的 is_pass 变成了 %d,应保持 1", v18.Int())
|
||||
}
|
||||
}
|
||||
|
||||
// 未配置平台模板时,原有「本级唯一 is_pass=1 角色」限制必须保留。
|
||||
func TestSaveTemplateRoleKeepsLegacyUniquenessWithoutTemplate(t *testing.T) {
|
||||
setupRoleSaveTestDB(t)
|
||||
ctx := contexts.Set(context.Background(), &model.Context{User: &model.Identity{BaseClaims: model.BaseClaims{
|
||||
ID: 1, TenantId: "000000", DeptId: 200,
|
||||
}}})
|
||||
mustExecRole(t, ctx, `INSERT INTO sys_dept (dept_id, tenant_id, parent_id, dept_type, status, dept_role) VALUES (200,'000000',0,1,'0',1)`)
|
||||
mustExecRole(t, ctx, `INSERT INTO sys_role (role_id, tenant_id, dept_id, role_name, role_key, status, data_scope, is_pass, created_dept) VALUES
|
||||
(1,'000000',200,'超级管理员','admin','0','1',0,200),
|
||||
(90,'000000',200,'已有的下发角色','dl','0','4',1,200)`)
|
||||
// 没有 sys_config 模板参数 → 走 legacy 分支
|
||||
_, err := NewAgentRole().saveTemplateRole(ctx, &model.AgentRoleSaveParam{
|
||||
RoleId: 0,
|
||||
DeptId: 200,
|
||||
RoleName: "第二个下发角色",
|
||||
RoleKey: "dl2",
|
||||
Status: "0",
|
||||
DataScope: "4",
|
||||
MenuIds: []int64{},
|
||||
IsPass: 1,
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("未配置模板时,第二个 is_pass=1 角色必须被拒绝")
|
||||
}
|
||||
if err.Error() != "每个机构只能配置一个下级管理员角色" {
|
||||
t.Fatalf("错误信息不符,实际: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func setupRoleSaveTestDB(t *testing.T) {
|
||||
t.Helper()
|
||||
if err := gdb.SetConfig(gdb.Config{
|
||||
"default": gdb.ConfigGroup{
|
||||
{Type: "sqlite", Link: "sqlite::@file(:memory:)", Debug: false},
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatalf("configure sqlite failed: %v", err)
|
||||
}
|
||||
_ = g.Cfg().GetAdapter().(*gcfg.AdapterFile).Set("database.memorydb.link", "")
|
||||
ctx := context.Background()
|
||||
t.Cleanup(func() { _ = g.DB().Close(ctx) })
|
||||
mustExecRole(t, ctx, `CREATE TABLE sys_dept (dept_id INTEGER PRIMARY KEY, tenant_id TEXT, parent_id INTEGER, dept_type INTEGER, status TEXT DEFAULT '0', dept_role INTEGER, order_num INTEGER DEFAULT 0, ancestors TEXT, dept_name TEXT, deleted_at DATETIME)`)
|
||||
mustExecRole(t, ctx, `CREATE TABLE sys_config (config_id INTEGER PRIMARY KEY, tenant_id TEXT, config_name TEXT, config_key TEXT, config_value TEXT, config_type TEXT, created_dept INTEGER, created_by INTEGER, created_at DATETIME, updated_by INTEGER, updated_at DATETIME, remark TEXT)`)
|
||||
mustExecRole(t, ctx, `CREATE TABLE sys_role (
|
||||
role_id INTEGER PRIMARY KEY AUTOINCREMENT, tenant_id TEXT, dept_id INTEGER, role_name TEXT, role_key TEXT, role_sort INTEGER, data_scope TEXT,
|
||||
menu_check_strictly INTEGER, dept_check_strictly INTEGER, status TEXT, is_pass INTEGER, created_dept INTEGER, created_by INTEGER, created_at DATETIME, updated_by INTEGER, updated_at DATETIME, deleted_by INTEGER, deleted_at DATETIME, remark TEXT)`)
|
||||
mustExecRole(t, ctx, `CREATE TABLE sys_role_menu (tenant_id TEXT, role_id INTEGER, menu_id INTEGER, data_scope TEXT)`)
|
||||
mustExecRole(t, ctx, `CREATE TABLE sys_role_dept (tenant_id TEXT, role_id INTEGER, dept_id INTEGER)`)
|
||||
mustExecRole(t, ctx, `CREATE TABLE sys_user_role (tenant_id TEXT DEFAULT '000000', user_id INTEGER, role_id INTEGER)`)
|
||||
mustExecRole(t, ctx, `CREATE TABLE sys_menu (menu_id INTEGER PRIMARY KEY, menu_name TEXT, parent_id INTEGER, level INTEGER, tree TEXT, order_num INTEGER DEFAULT 0, path TEXT, component TEXT, query_param TEXT, is_frame INTEGER, is_cache INTEGER, menu_type TEXT, visible TEXT, status TEXT DEFAULT '0', perms TEXT, icon TEXT, created_dept INTEGER, created_by INTEGER, created_at DATETIME, updated_by INTEGER, updated_at DATETIME, remark TEXT)`)
|
||||
mustExecRole(t, ctx, `INSERT INTO sys_menu (menu_id, menu_name, parent_id, status) VALUES (100,'卡片信息',0,'0')`)
|
||||
}
|
||||
|
||||
func mustExecRole(t *testing.T, ctx context.Context, sql string) {
|
||||
t.Helper()
|
||||
if _, err := g.DB().Exec(ctx, sql); err != nil {
|
||||
t.Fatalf("execute sql failed: %v\nsql=%s", err, sql)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user