package handler import "testing" // 平台侧 slug/标题不受本侧寻址约束,normalizeAlias 必须把它改写成 // 能安全出现在 name@path. 末段的形式。 func TestNormalizeAlias(t *testing.T) { cases := []struct{ in, want string }{ // opencode 风格 slug 原样通过 {"jolly-cactus", "jolly-cactus"}, {"fix-memory-leak", "fix-memory-leak"}, // 非法字符统一换 -,连续的压缩成一个 {"fix.memory.leak", "fix-memory-leak"}, {"修复 登录态 丢失", "修复-登录态-丢失"}, {"a//b..c", "a-b-c"}, {"user@host", "user-host"}, // 首尾的分隔符要去掉 {".leading", "leading"}, {"trailing.", "trailing"}, {" spaced ", "spaced"}, // 保留字必须避开,否则会被寻址当成「新建会话」 {"new", "session-new"}, // 全是非法字符 → 空串,交由调用方报错 {"...", ""}, {"", ""}, } for _, c := range cases { if got := normalizeAlias(c.in); got != c.want { t.Errorf("normalizeAlias(%q) = %q, want %q", c.in, got, c.want) } } } // 规范化后的别名必须能通过寻址校验,否则同步会写进一个自己都拒绝的别名。 func TestNormalizeAliasPassesValidation(t *testing.T) { for _, in := range []string{ "jolly-cactus", "fix.memory.leak", "修复 登录态 丢失", "new", "user@host/path", } { norm := normalizeAlias(in) if norm == "" { continue } if err := validateSessionAlias(norm); err != nil { t.Errorf("normalizeAlias(%q) = %q,但未通过 validateSessionAlias: %v", in, norm, err) } } } // 截断长别名时不能切坏多字节字符(session_alias 是 VARCHAR(128))。 func TestNormalizeAliasTruncatesOnValidUTF8(t *testing.T) { long := "" for i := 0; i < 100; i++ { long += "修" // 每个 3 字节,共 300 字节 } got := normalizeAlias(long) if len(got) > 128 { t.Errorf("normalizeAlias 截断后 %d 字节,超过 128", len(got)) } for _, r := range got { if r == '\uFFFD' { t.Fatalf("normalizeAlias 截断产生了非法 UTF-8: %q", got) } } }