- mapping.BuildFromMirror:由镜像 active 用户/部门构造期望 LLDAP 状态(纯函数), 组名/DN 直接复用快照落库时算好的拍平拼音,用户 DN 固定 ou=people、去掉离职 OU - Feat: FlatDeptInfo 已在本阶段完成测试覆盖(拍平拼音父子/空拼音回落/重名消歧/DN 稳定) - 移除已被目标架构取代的旧「嵌套 CN」测试断言 - 旧 Build(OpenLDAP 单阶段)暂留保证过渡期编译,阶段6退役
98 lines
3.4 KiB
Go
98 lines
3.4 KiB
Go
package mapping
|
|
|
|
// BuildFromMirror(镜像 → 期望状态)的单测。
|
|
//
|
|
// 覆盖:用户 DN 固定 ou=people、组名直接复用镜像拍平 DN、成员关系按用户所属部门
|
|
// 归集、分组按层级父先于子排序。
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"idsync/internal/store"
|
|
)
|
|
|
|
func mirrorUser(uid, email, deptID string) *store.MirrorUser {
|
|
return &store.MirrorUser{
|
|
UID: uid,
|
|
Email: email,
|
|
DisplayName: uid,
|
|
SN: uid,
|
|
GivenName: uid,
|
|
DepartmentIDs: []string{deptID},
|
|
}
|
|
}
|
|
|
|
func mirrorDept(id, name, pinyin, dn string, level int, parent string) *store.MirrorDepartment {
|
|
return &store.MirrorDepartment{
|
|
DeptID: id, Name: name, PinyinName: pinyin, DN: dn, Level: level, ParentID: parent,
|
|
}
|
|
}
|
|
|
|
// TestBuildFromMirrorUserDN 验证用户 DN 固定挂在 ou=people 下,不再有离职 OU。
|
|
func TestBuildFromMirrorUserDN(t *testing.T) {
|
|
depts := []*store.MirrorDepartment{
|
|
mirrorDept("od-root", "Acme", "Acme", "cn=Acme,ou=groups,dc=example,dc=com", 0, ""),
|
|
}
|
|
users := []*store.MirrorUser{mirrorUser("alice", "alice@example.com", "od-root")}
|
|
|
|
st := BuildFromMirror(users, depts, "dc=example,dc=com")
|
|
if len(st.Users) != 1 {
|
|
t.Fatalf("期望 1 个用户,实际 %d", len(st.Users))
|
|
}
|
|
u := st.Users[0]
|
|
if u.DN != "uid=alice,ou=people,dc=example,dc=com" {
|
|
t.Errorf("用户 DN = %q, 期望固定 ou=people", u.DN)
|
|
}
|
|
if u.Mail != "alice@example.com" {
|
|
t.Errorf("mail = %q", u.Mail)
|
|
}
|
|
}
|
|
|
|
// TestBuildFromMirrorGroupMembers 验证成员关系按用户所属部门归集到对应的组。
|
|
func TestBuildFromMirrorGroupMembers(t *testing.T) {
|
|
depts := []*store.MirrorDepartment{
|
|
mirrorDept("od-root", "Acme", "Acme", "cn=Acme,ou=groups,dc=example,dc=com", 0, ""),
|
|
mirrorDept("od-rd", "研发部", "Acme.yanfabu", "cn=Acme.yanfabu,ou=groups,dc=example,dc=com", 1, "od-root"),
|
|
}
|
|
users := []*store.MirrorUser{
|
|
mirrorUser("alice", "alice@example.com", "od-rd"),
|
|
// lisi 属多部门
|
|
{UID: "lisi", Email: "lisi@example.com", DisplayName: "lisi", SN: "lisi",
|
|
GivenName: "lisi", DepartmentIDs: []string{"od-root", "od-rd"}},
|
|
}
|
|
|
|
st := BuildFromMirror(users, depts, "dc=example,dc=com")
|
|
|
|
rd := st.GroupByDeptID["od-rd"]
|
|
if _, ok := rd.Members["uid=alice,ou=people,dc=example,dc=com"]; !ok {
|
|
t.Errorf("alice 未加入 %s", rd.DN)
|
|
}
|
|
if _, ok := rd.Members["uid=lisi,ou=people,dc=example,dc=com"]; !ok {
|
|
t.Errorf("lisi 未加入 %s", rd.DN)
|
|
}
|
|
root := st.GroupByDeptID["od-root"]
|
|
if _, ok := root.Members["uid=alice,ou=people,dc=example,dc=com"]; ok {
|
|
t.Errorf("alice 只属研发部,不应出现在根部门")
|
|
}
|
|
if _, ok := root.Members["uid=lisi,ou=people,dc=example,dc=com"]; !ok {
|
|
t.Errorf("lisi 属根部门,应出现")
|
|
}
|
|
}
|
|
|
|
// TestBuildFromMirrorGroupOrderIsParentFirst 验证分组输出按层级父先于子排序。
|
|
func TestBuildFromMirrorGroupOrderIsParentFirst(t *testing.T) {
|
|
depts := []*store.MirrorDepartment{
|
|
// 刻意让子部门先给出,验证 BuildFromMirror 内部仍按 Level 排回父先于子。
|
|
mirrorDept("od-rd", "研发部", "Acme.yanfabu", "cn=Acme.yanfabu,ou=groups,dc=example,dc=com", 1, "od-root"),
|
|
mirrorDept("od-root", "Acme", "Acme", "cn=Acme,ou=groups,dc=example,dc=com", 0, ""),
|
|
}
|
|
|
|
st := BuildFromMirror(nil, depts, "dc=example,dc=com")
|
|
seen := map[string]int{}
|
|
for i, g := range st.Groups {
|
|
seen[g.DeptID] = i
|
|
}
|
|
if seen["od-root"] > seen["od-rd"] {
|
|
t.Errorf("父部门应排在子部门之前:%v", seen)
|
|
}
|
|
} |