70 lines
2.0 KiB
Go
70 lines
2.0 KiB
Go
package handler
|
||
|
||
import "testing"
|
||
|
||
// 平台侧 slug/标题不受本侧寻址约束,normalizeAlias 必须把它改写成
|
||
// 能安全出现在 name@path.<alias> 末段的形式。
|
||
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)
|
||
}
|
||
}
|
||
}
|