Files

151 lines
4.6 KiB
Go

package sms
import (
"strings"
"testing"
)
func TestDefaultConfigCoversRegisteredNodes(t *testing.T) {
cfg := DefaultConfig()
if cfg.Enabled {
t.Fatal("默认配置的总开关必须关闭,避免未配置模板就产生短信费用")
}
for _, meta := range NodeMetas() {
node, ok := cfg.Node(meta.Code)
if !ok {
t.Fatalf("默认配置缺少节点 %s", meta.Code)
}
if !node.Enabled {
t.Fatalf("默认配置节点 %s 应默认启用", meta.Code)
}
if node.TemplateCode != "" {
t.Fatalf("默认配置节点 %s 的模板 CODE 应为空,实际 %q", meta.Code, node.TemplateCode)
}
}
if days := cfg.StaleDaysFor(NodeListingStalePriceSuggestion); days != DefaultStaleDays {
t.Fatalf("StaleDaysFor() = %d, want %d", days, DefaultStaleDays)
}
}
func TestParseConfigValueMergesAndFiltersUnknownNodes(t *testing.T) {
cfg, err := ParseConfigValue(`{
"enabled": true,
"nodes": {
"order_handoff_assist": {"enabled": true, "template_code": " SMS_512540945 "},
"listing_stale_price_suggestion": {"enabled": false, "template_code": "SMS_1", "stale_days": 5},
"not_registered_node": {"enabled": true, "template_code": "SMS_BAD"}
}
}`)
if err != nil {
t.Fatalf("ParseConfigValue() error = %v", err)
}
if !cfg.Enabled {
t.Fatal("ParseConfigValue() 应保留总开关")
}
if _, ok := cfg.Node("not_registered_node"); ok {
t.Fatal("ParseConfigValue() 不应保留未登记节点")
}
node, ok := cfg.Node(NodeOrderHandoffAssist)
if !ok || node.TemplateCode != "SMS_512540945" {
t.Fatalf("handoff node = %+v, want template trimmed to SMS_512540945", node)
}
// 未在 JSON 中出现的已登记节点应保留默认值。
rejected, ok := cfg.Node(NodeListingReviewRejected)
if !ok || !rejected.Enabled {
t.Fatalf("未配置节点应保留默认值, got %+v ok=%v", rejected, ok)
}
stale, _ := cfg.Node(NodeListingStalePriceSuggestion)
if stale.StaleDays != 5 {
t.Fatalf("stale_days = %d, want 5", stale.StaleDays)
}
}
func TestParseConfigValueEmptyAndInvalid(t *testing.T) {
cfg, err := ParseConfigValue(" ")
if err != nil {
t.Fatalf("空配置不应报错: %v", err)
}
if cfg.Enabled {
t.Fatal("空配置应回落到默认(总开关关闭)")
}
if _, err := ParseConfigValue("{not json}"); err == nil {
t.Fatal("非法 JSON 应返回错误")
}
}
func TestMarshalConfigNormalizes(t *testing.T) {
raw, err := MarshalConfig(Config{
Enabled: true,
Nodes: map[string]NodeConfig{
NodeListingReviewRejected: {Enabled: true, TemplateCode: " SMS_512520993 ", StaleDays: -3},
"unknown_node": {Enabled: true, TemplateCode: "SMS_X"},
NodeListingStalePriceSuggestion: {Enabled: true, TemplateCode: "SMS_512620985", StaleDays: 0},
},
})
if err != nil {
t.Fatalf("MarshalConfig() error = %v", err)
}
if strings.Contains(raw, "unknown_node") {
t.Fatalf("MarshalConfig() 不应输出未登记节点: %s", raw)
}
parsed, err := ParseConfigValue(raw)
if err != nil {
t.Fatalf("ParseConfigValue() error = %v", err)
}
rejected, _ := parsed.Node(NodeListingReviewRejected)
if rejected.TemplateCode != "SMS_512520993" {
t.Fatalf("template_code = %q, want SMS_512520993", rejected.TemplateCode)
}
if rejected.StaleDays != 0 {
t.Fatalf("负的 stale_days 应被归零, got %d", rejected.StaleDays)
}
if days := parsed.StaleDaysFor(NodeListingStalePriceSuggestion); days != DefaultStaleDays {
t.Fatalf("stale_days=0 时应回落默认值 %d, got %d", DefaultStaleDays, days)
}
}
func TestConfigNodeActive(t *testing.T) {
base := Config{
Enabled: true,
Nodes: map[string]NodeConfig{
NodeListingReviewRejected: {Enabled: true, TemplateCode: "SMS_512520993"},
NodeOrderHandoffAssist: {Enabled: false, TemplateCode: "SMS_512540945"},
NodeListingStalePriceSuggestion: {Enabled: true, TemplateCode: ""},
},
}
if !base.NodeActive(NodeListingReviewRejected) {
t.Fatal("总开关与节点开关都开且模板非空时应可发送")
}
if base.NodeActive(NodeOrderHandoffAssist) {
t.Fatal("节点关闭时不应发送")
}
if base.NodeActive(NodeListingStalePriceSuggestion) {
t.Fatal("模板 CODE 为空时不应发送")
}
if base.NodeActive("unknown_node") {
t.Fatal("未登记节点不应发送")
}
disabled := base
disabled.Enabled = false
if disabled.NodeActive(NodeListingReviewRejected) {
t.Fatal("总开关关闭时不应发送")
}
}
func TestIsKnownNode(t *testing.T) {
for _, code := range []string{
NodeListingReviewRejected,
NodeOrderHandoffAssist,
NodeListingStalePriceSuggestion,
} {
if !IsKnownNode(code) {
t.Fatalf("IsKnownNode(%q) = false, want true", code)
}
}
if IsKnownNode("") || IsKnownNode("nope") {
t.Fatal("未登记节点应为 false")
}
}