chore: 并入 iotlcm-bot 历史到 bot/(原提交 31dbc1d)
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
package render
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAlertCardIsInteractiveWithRedHeader(t *testing.T) {
|
||||
body, err := AlertCard(Alert{
|
||||
Environment: "preview",
|
||||
Title: "归档目录不可用",
|
||||
Summary: "正在重启以重新挂载",
|
||||
Reason: "宿主机上的归档目录已被删除,容器仍指向旧目录(挂载失效)。",
|
||||
Path: "/data/full-sync",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var decoded map[string]any
|
||||
if err := json.Unmarshal(body, &decoded); err != nil {
|
||||
t.Fatalf("alert card must be valid JSON: %v", err)
|
||||
}
|
||||
if decoded["msg_type"] != "interactive" {
|
||||
t.Fatalf("alert must be an interactive card, got %v", decoded["msg_type"])
|
||||
}
|
||||
card := decoded["card"].(map[string]any)
|
||||
header := card["header"].(map[string]any)
|
||||
if header["template"] != "red" {
|
||||
t.Fatalf("alert header should be red so it stands out, got %v", header["template"])
|
||||
}
|
||||
title := header["title"].(map[string]any)["content"].(string)
|
||||
if !strings.Contains(title, "预演") || !strings.Contains(title, "归档目录不可用") {
|
||||
t.Fatalf("unexpected title: %q", title)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlertCardShowsPathAndRepeatCount(t *testing.T) {
|
||||
body, err := AlertCard(Alert{
|
||||
Environment: "dev",
|
||||
Title: "归档目录不可用",
|
||||
Summary: "正在重启以重新挂载",
|
||||
Reason: "目录不存在。",
|
||||
Path: "/data/full-sync",
|
||||
ExitCount: 3,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
text := string(body)
|
||||
if !strings.Contains(text, "/data/full-sync") {
|
||||
t.Fatal("card should show the path")
|
||||
}
|
||||
if !strings.Contains(text, "已重复 3 次") {
|
||||
t.Fatal("card should warn about repeated exits")
|
||||
}
|
||||
}
|
||||
|
||||
// 单次故障时不该出现「已重复」这种话,避免误导。
|
||||
func TestAlertCardOmitsRepeatNoticeOnFirstOccurrence(t *testing.T) {
|
||||
body, err := AlertCard(Alert{Environment: "dev", Title: "归档目录不可用", ExitCount: 1})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Contains(string(body), "已重复") {
|
||||
t.Fatal("first occurrence must not claim repeats")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFriendlyReasonTranslatesKnownErrors(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"archive directory was deleted on the host (nlink=0); recreate this container": "宿主机上的归档目录已被删除",
|
||||
"stat /data/x: no such file or directory": "目录不存在。",
|
||||
"open /data/x: permission denied": "没有读取权限。",
|
||||
}
|
||||
for input, want := range cases {
|
||||
if got := FriendlyReason(input); !strings.Contains(got, want) {
|
||||
t.Fatalf("FriendlyReason(%q) = %q, want it to contain %q", input, got, want)
|
||||
}
|
||||
}
|
||||
// 未知错误原样保留,便于排查
|
||||
unknown := "some unexpected failure"
|
||||
if got := FriendlyReason(unknown); got != unknown {
|
||||
t.Fatalf("unknown reason must be preserved, got %q", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user