Files
MailUI4Agents/server/internal/handler/rename_proposal_test.go

144 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handler
import "testing"
func TestExtractRenameProposal(t *testing.T) {
cases := []struct {
name string
body string
wantAlias string
wantReason string
wantBody string
}{
{
name: "无标记时原样返回",
body: "普通正文。",
wantAlias: "",
wantBody: "普通正文。",
},
{
name: "带理由",
body: "已定位问题。\n\n<!-- agentmail:rename-session alias=\"fix-login-leak\" reason=\"是登录态泄漏\" -->",
wantAlias: "fix-login-leak",
wantReason: "是登录态泄漏",
wantBody: "已定位问题。",
},
{
name: "无理由",
body: "<!-- agentmail:rename-session alias=\"cache-eval\" -->\n\n正文在后。",
wantAlias: "cache-eval",
wantBody: "正文在后。",
},
{
// Agent 在长回复里反复修正措辞,最后写下的才是它的结论
name: "多条只取最后一条",
body: "<!-- agentmail:rename-session alias=\"first\" -->\n中间\n<!-- agentmail:rename-session alias=\"second\" -->",
wantAlias: "second",
wantBody: "中间",
},
{
// 别名含 . / @ 会让三维地址切分歧义normalizeAlias 改写为 -
name: "非法字符被规范化",
body: "<!-- agentmail:rename-session alias=\"fix login.leak/now\" -->",
wantAlias: "fix-login-leak-now",
wantBody: "",
},
{
// "new" 是寻址保留字
name: "保留字被改写",
body: "<!-- agentmail:rename-session alias=\"new\" -->",
wantAlias: "session-new",
wantBody: "",
},
{
// 规范化后为空 → 视为无提议,但标记仍要剥掉
name: "空别名视为无提议且剥掉标记",
body: "正文\n<!-- agentmail:rename-session alias=\"\" -->",
wantAlias: "",
wantBody: "正文",
},
{
name: "多余空格容错",
body: "<!-- agentmail:rename-session alias=\"ok-name\" -->",
wantAlias: "ok-name",
wantBody: "",
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
p, body := extractRenameProposal(c.body)
gotAlias := ""
gotReason := ""
if p != nil {
gotAlias, gotReason = p.Alias, p.Reason
}
if gotAlias != c.wantAlias {
t.Errorf("alias = %q期望 %q", gotAlias, c.wantAlias)
}
if gotReason != c.wantReason {
t.Errorf("reason = %q期望 %q", gotReason, c.wantReason)
}
if body != c.wantBody {
t.Errorf("剥标记后正文 = %q期望 %q", body, c.wantBody)
}
})
}
}
// 标记必须从入库正文里彻底消失react-markdown 不解析 raw HTML
// 留着会被转义成一行可见的乱码文本,而不是被渲染器吞掉。
func TestProposalMarkerNeverSurvivesInBody(t *testing.T) {
bodies := []string{
"<!-- agentmail:rename-session alias=\"a\" -->",
"前\n<!-- agentmail:rename-session alias=\"a\" reason=\"r\" -->\n后",
"<!-- agentmail:rename-session alias=\"\" -->", // 无效提议也要剥
}
for _, b := range bodies {
_, out := extractRenameProposal(b)
if renameProposalRe.MatchString(out) {
t.Errorf("正文里仍残留标记:%q", out)
}
}
}
// 提议出来的别名必须能直接通过 PUT alias 的校验,
// 否则前端点「接受」时会拿到 400 —— 系统自己造出了自己拒绝的值。
func TestProposedAliasPassesValidation(t *testing.T) {
inputs := []string{
"fix login.leak",
"new",
"a@b/c",
" spaced name ",
"正常中文别名",
}
for _, in := range inputs {
p, _ := extractRenameProposal("<!-- agentmail:rename-session alias=\"" + in + "\" -->")
if p == nil {
continue // 规范化后为空,已按无提议处理
}
if err := validateSessionAlias(p.Alias); err != nil {
t.Errorf("提议 %q → %q 未通过 validateSessionAlias: %v", in, p.Alias, err)
}
}
}
func TestReasonTruncatedOnUTF8Boundary(t *testing.T) {
long := ""
for i := 0; i < 100; i++ {
long += "很长的理由"
}
p, _ := extractRenameProposal("<!-- agentmail:rename-session alias=\"x\" reason=\"" + long + "\" -->")
if p == nil {
t.Fatal("应当解析出提议")
}
if len(p.Reason) > 210 { // 200 + "..."
t.Errorf("理由未截断:%d 字节", len(p.Reason))
}
for _, r := range p.Reason {
if r == 0xFFFD {
t.Fatal("截断产生了替换符,说明切在多字节字符中间")
}
}
}