Files
artex/notify/markdown_localized_test.go
T
dela 97668dab7e
ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
detections / detections (push) Waiting to run
docs / links (push) Waiting to run
web / web (push) Waiting to run
Localize user-facing UI, agent output, and backend messages to Simplified Chinese
2026-10-09 14:08:31 +08:00

123 lines
4.9 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 notify
import (
"strings"
"testing"
)
// hanFreeItems 는 CJK 한자가 없는 항목(ASCII 제목·유형·요약)만 만든다.
// 라벨이 중국어로 되돌아가면 렌더 결과 전체에 한자가 생기므로, 데이터가
// 한자 0 일 때만 "출력 전체에 한자 0" 단언이 라벨 회귀를 정확히 잡아낸다.
func hanFreeItems(n int) []Item {
items := make([]Item, 0, n)
for i := 0; i < n; i++ {
items = append(items, Item{
FindingID: int64(i + 1),
Name: "login-flaw",
VulnClass: "SQLi",
Severity: "high",
Summary: "SQL injection via q param",
Assets: []string{"a.example.com"},
})
}
return items
}
// TestMarkdownTitleLocalized 는 markdown 계열 채널(dingtalk·wecom)과 제목을
// 공유하는 feishu·html·telegram·webhook 이 함께 쓰는 markdownTitle 이 한국어인지
// 검사한다. 하나라도 중국어로 되돌아가면 이 다섯 채널의 제목이 전부 혼재된다.
func TestMarkdownTitleLocalized(t *testing.T) {
// 다건(汇总): "漏洞汇总 · 共 N 条"
got := markdownTitle(Message{Batch: true, Items: hanFreeItems(3)})
assertChinese(t, "markdownTitle(batch)", got)
if !strings.Contains(got, "漏洞汇总") || !strings.Contains(got, "共 3 条") {
t.Errorf("다건 제목이 '漏洞汇总 · 共 3 条' 형태여야 합니다, 받은 값 %q", got)
}
// 항목 없음: "漏洞通知"
empty := markdownTitle(Message{})
assertChinese(t, "markdownTitle(empty)", empty)
if empty != "漏洞通知" {
t.Errorf("빈 메시지 제목은 '漏洞通知' 이어야 합니다, 받은 값 %q", empty)
}
}
// TestMarkdownBatchIntroLocalized 는 다이제스트 머리말(시간창·건수·초과 안내)이
// 한국어인지 검사한다. 항목 데이터가 한자 0 이므로 출력에 한자가 보이면 머리말
// 문구가 중국어로 회귀한 것이다.
func TestMarkdownBatchIntroLocalized(t *testing.T) {
items := hanFreeItems(3)
// 시간창 있음: "최근 N분간 신규 취약점 N건"
win := markdownBatchIntro(Message{Batch: true, WindowMinutes: 30}, items, 3)
if hasHangul(win) {
t.Errorf("시간창 머리말에 한글이 남았습니다: %q", win)
}
if !strings.Contains(win, "最近 30 分钟") || !strings.Contains(win, "新增漏洞 3 条") {
t.Errorf("시간창 머리말이 '最近 30 分钟新增漏洞 3 条' 형태여야 합니다, 받은 값 %q", win)
}
// 시간창 없음: "新增漏洞 N条"(분간 표기 없음)
noWin := markdownBatchIntro(Message{Batch: true}, items, 3)
if hasHangul(noWin) {
t.Errorf("머리말에 한글이 남았습니다: %q", noWin)
}
if !strings.Contains(noWin, "新增漏洞 3 条") || strings.Contains(noWin, "分钟") {
t.Errorf("시간창 없는 머리말은 '新增漏洞 3 条'(分钟 표기 없음)이어야 합니다, 받은 값 %q", noWin)
}
// 일부만 담겼을 때: "(本条仅显示前 N 条, 其余 N 条将在下一条消息中继续发送)"
trunc := markdownBatchIntro(Message{Batch: true, WindowMinutes: 30}, items, 5)
if hasHangul(trunc) {
t.Errorf("초과 안내에 한글이 남았습니다: %q", trunc)
}
for _, want := range []string{"前 3 条", "其余 2 条", "下一条消息"} {
if !strings.Contains(trunc, want) {
t.Errorf("초과 안내에 %q 가 있어야 합니다, 받은 값 %q", want, trunc)
}
}
}
// TestWriteItemLabelsLocalized 는 단건 상세 렌더(markdown 3채널 공유 경로)의
// 필드 라벨(상태 변경·유형·자산·개요)과 상세 링크가 한국어인지 검사한다.
func TestWriteItemLabelsLocalized(t *testing.T) {
it := Item{
Name: "login-flaw",
VulnClass: "SQLi",
Severity: "high",
Summary: "SQL injection via q param",
Assets: []string{"a.example.com"},
DetailURL: "https://platform.example/finding/1",
FromStatus: "pending",
ToStatus: "fixed",
}
var b strings.Builder
writeItem(&b, it, "", true)
got := b.String()
assertChinese(t, "writeItem(single)", got)
for _, want := range []string{
"**状态变更**:待处理 → 已修复",
"**类型**:SQLi",
"**资产**:a.example.com",
"**概要**:SQL injection via q param",
"[查看详情](https://platform.example/finding/1)",
} {
if !strings.Contains(got, want) {
t.Errorf("단건 렌더에 %q 가 있어야 합니다:\n%s", want, got)
}
}
}
// TestMarkdownBodyFooterLocalized 는 다건 본문 끝의 플랫폼 입구 링크가
// 한국어인지 검사한다(HomeURL 이 있을 때만 붙는다).
func TestMarkdownBodyFooterLocalized(t *testing.T) {
m := Message{Batch: true, HomeURL: "https://platform.example", Items: hanFreeItems(2)}
body, kept := markdownBody(m, 0)
if kept != 2 {
t.Fatalf("한도 없음(0)이면 2건 모두 담겨야 합니다, 받은 값 %d", kept)
}
if !strings.Contains(body, "[在平台查看全部](https://platform.example)") {
t.Errorf("본문 끝에 '在平台查看全部' 링크가 있어야 합니다:\n%s", body)
}
}