feat(通知模板): 支持缺字段按空值渲染与空行省略
Motivation: 统一 crypto-strategy 与 trade-signal 两类交易信号的模板字段,使同一套通知模板可复用;字段缺失或为空时不再导致渲染报错或输出空行,通知内容更整洁。 Changes: * 渲染器缺失字段改为按空值处理,新增 line 函数实现空值整行省略 * crypto-strategy 信号补充止盈价、止损价、平均价、收益额等模板字段 * trade-signal 信号保留原始报文中的额外字段以适配统一模板 * 修复结构化日志将 error 作为值直接输出导致的格式问题
This commit is contained in:
@@ -3,6 +3,8 @@ package cryptostrategy
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"aiaa-notification-service/internal/engine"
|
||||
)
|
||||
|
||||
const sampleBody = `{
|
||||
@@ -124,6 +126,37 @@ func TestConvertPayloadObject(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertRendersSharedSignalTemplate(t *testing.T) {
|
||||
body := []byte(`{
|
||||
"eventType": "SIGNAL_RECEIVED",
|
||||
"correlationId": "0_0_0",
|
||||
"symbol": "ICP",
|
||||
"direction": "LONG",
|
||||
"payload": "{\"strategyCode\":\"ai-crypto-signals\",\"period\":\"1h\",\"currency\":\"ICP\",\"isSale\":false,\"isClose\":true,\"isGain\":true,\"gainTarget\":1,\"price\":2.273,\"remark\":\"{\\\"orderId\\\":\\\"uJs3zQI8IaRV16n8NERq\\\",\\\"revenue\\\":\\\"14.1088%\\\"}\",\"totalGainTarget\":5}",
|
||||
"eventTime": 1786808929754
|
||||
}`)
|
||||
_, data, err := Convert(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, key := range []string{"totalAvgPx", "takeProfitPrice", "stopLossPrice", "side", "action", "symbol", "period", "price"} {
|
||||
if _, ok := data[key]; !ok {
|
||||
t.Fatalf("missing template key %q in %v", key, data)
|
||||
}
|
||||
}
|
||||
if data["orderId"] != "uJs3zQI8IaRV16n8NERq" || data["revenue"] != "14.1088%" {
|
||||
t.Fatalf("remark=%v", data)
|
||||
}
|
||||
tmpl := "### {{.symbol}} {{.action}}\n币种:{{.symbol}}\n周期:{{.period}}\n方向:{{.side}}\n价格:{{.price}}\n平均价:{{.totalAvgPx}}\n止盈价:{{.takeProfitPrice}}\n止损价:{{.stopLossPrice}}"
|
||||
out, err := engine.NewRenderer().Render(tmpl, data)
|
||||
if err != nil {
|
||||
t.Fatalf("render: %v", err)
|
||||
}
|
||||
if !strings.Contains(out, "ICP") || !strings.Contains(out, "CLOSE") {
|
||||
t.Fatalf("out=%s", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertInvalidJSON(t *testing.T) {
|
||||
_, _, err := Convert([]byte(`{not json`))
|
||||
if err == nil {
|
||||
|
||||
Reference in New Issue
Block a user