Files
knowledge-governance/internal/qaopsorg/attribution_test.go
T
姚章浩 533db535f1
build / build (push) Successful in 1m12s
feat(qaops): 接入真实模型补缺任务与总表看板
按已确认需求提供独立安全模型配置、真实探测、正式字典字段评估与原问题译中,持久批次支持只补空白、暂停恢复、有限重试、幂等和逐字段依据。覆盖固定规则、本地语言、组织关联与主表有效看板共用治理侧读模型,保留源生产和冻结历史。

验证:完整 make verify 退出0,702项Go与329项前端通过;默认118项外部/隔离集成明确跳过,另跑完整镜像及组织隔离PG竞态。12并发、输入漂移、过期租约、暂停/恢复及有限重试通过。用户授权的百炼 deepseek-v4.1-flash 完成真实后台与浏览器评估/翻译;552行、16列、11块看板及完整PNG、独立配置页测试/保存、重开恢复和零JS异常通过。仅非业务样本外发,自动处理关闭,原payload不变。

上线前治理库已做导出快照原生备份并真实恢复,60表行数与17个QA表内容哈希一致;不修改DobotAI生产或隧道。本提交时尚未部署,线上验收须独立完成。
2026-10-19 14:29:49 +08:00

68 lines
3.4 KiB
Go

package qaopsorg
import (
"context"
"errors"
"testing"
)
func TestAttributionUsesStableIdentityAndKeepsAmbiguitiesExplicit(t *testing.T) {
d := Directory{Departments: []Department{{ID: "root", Name: "fixture"}, {ID: "a", ParentID: "root", Name: "one"}, {ID: "b", ParentID: "root", Name: "two"}}, People: []Person{{ID: "staff-a", UnionID: "union-a", DepartmentIDs: []string{"a", "a"}}, {ID: "staff-cross", UnionID: "union-cross", DepartmentIDs: []string{"a", "b"}}, {ID: "duplicate-one", UnionID: "duplicate", DepartmentIDs: []string{"a"}}, {ID: "duplicate-two", UnionID: "duplicate", DepartmentIDs: []string{"b"}}}}
p, err := BuildAttribution(State{State: "ready", DirectoryID: "d", RevisionID: "r", Rules: []Rule{{DepartmentID: "root", Region: "国内工业"}, {DepartmentID: "b", Region: "APAC"}}}, d)
if err != nil {
t.Fatal(err)
}
for _, key := range [][2]string{{"staff-a", ""}, {"", "union-a"}} {
got := p.Resolve(key[0], key[1])
if got.State != "matched" || got.Region != "国内工业" || len(got.Departments) != 1 || got.PersonID != "staff-a" {
t.Fatalf("stable identity not resolved/deduplicated: %+v", got)
}
}
if got := p.Resolve("staff-cross", ""); got.State != "cross_region" || got.Region != "" || len(got.Departments) != 2 {
t.Fatalf("invented primary region: %+v", got)
}
if got := p.Resolve("", "duplicate"); got.State != "identity_conflict" {
t.Fatalf("duplicate union selected first person: %+v", got)
}
if got := p.Resolve("staff-a", "union-cross"); got.State != "identity_conflict" {
t.Fatalf("contradictory identifiers silently preferred: %+v", got)
}
if got := p.Resolve("absent", ""); got.State != "unmatched" {
t.Fatalf("unknown identity inferred: %+v", got)
}
if got := p.Resolve("", ""); got.State != "no_identity" {
t.Fatalf("anonymous identity inferred: %+v", got)
}
}
func TestLegacyUnionAndUniqueAskerNameResolveWithoutInventingPeople(t *testing.T) {
d := Directory{Departments: []Department{{ID: "r", Name: "示例部门"}}, People: []Person{{ID: "a", UnionID: "ua", Name: "唯一姓名", DepartmentIDs: []string{"r"}}, {ID: "b", UnionID: "ub", Name: "重复姓名", DepartmentIDs: []string{"r"}}, {ID: "c", Name: "重复姓名", DepartmentIDs: []string{"r"}}}}
p, err := BuildAttribution(State{State: "ready", DirectoryID: "d", RevisionID: "v", Rules: []Rule{{DepartmentID: "r", Region: "APAC"}}}, d)
if err != nil {
t.Fatal(err)
}
for _, c := range []struct{ staff, union, asker, raw, want, state string }{
{"", "", "", "{\"name\":\"旧显示姓名\",\"unionId\":\"ua\"}", "a", "matched"},
{"", "", "唯一姓名", "", "a", "matched"},
{"", "", "重复姓名", "", "", "identity_conflict"},
{"", "", "唯一姓名", "{\"unionId\":\"absent\"}", "", "unmatched"},
{"a", "", "", "{\"unionId\":\"ub\"}", "", "identity_conflict"},
{"", "", "唯一姓名", "{bad", "", "identity_conflict"},
} {
got := p.Resolve(c.staff, c.union, c.asker, c.raw)
if got.PersonID != c.want || got.State != c.state {
t.Errorf("got=%+v want person=%q state=%q", got, c.want, c.state)
}
}
}
func TestAttributionDoesNotTreatMissingDirectoryAsPermissionSuccess(t *testing.T) {
p, err := BuildAttribution(State{State: "empty"}, Directory{})
if err != nil || p.Resolve("staff", "").State != "directory_missing" {
t.Fatal("missing directory not explicit")
}
var store *Store
if _, err = store.GetAttribution(context.Background()); !errors.Is(err, ErrUnavailable) {
t.Fatal("unavailable store returned an empty directory")
}
}