chore: directory migration - gateway→server, web→client/electron

This commit is contained in:
2026-09-08 19:16:35 +08:00
parent fd9f99a3f9
commit f9d757b5e5
243 changed files with 5095 additions and 228 deletions

View File

@ -0,0 +1,69 @@
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)
}
}
}