72 lines
3.0 KiB
Go
72 lines
3.0 KiB
Go
package scenario
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestValidateContractInput(t *testing.T) {
|
|
valid := contractInput{
|
|
OutputSchema: map[string]interface{}{"fields": []interface{}{
|
|
map[string]interface{}{"key": "matched_topics", "source": "derived", "source_field": "topics"},
|
|
}},
|
|
ResultSchema: map[string]interface{}{"fields": []interface{}{
|
|
map[string]interface{}{"key": "selected_products", "name": "成交商品", "type": "array", "items": map[string]interface{}{"type": "string"}},
|
|
}},
|
|
Rules: []ruleInput{{
|
|
RuleKey: "match_topic", Name: "匹配主题",
|
|
Condition: map[string]interface{}{"field": "product_tags", "operator": "contains", "value": "hot"},
|
|
Actions: []map[string]interface{}{{"operation": "append", "field": "topics", "value": "topic_hot"}},
|
|
}},
|
|
AllowedOrigins: []string{"https://crm.example.com"},
|
|
}
|
|
if err := validateContractInput(valid); err != nil {
|
|
t.Fatalf("valid contract rejected: %v", err)
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
edit func(*contractInput)
|
|
want string
|
|
}{
|
|
{name: "duplicate output", edit: func(input *contractInput) {
|
|
input.OutputSchema["fields"] = append(input.OutputSchema["fields"].([]interface{}), map[string]interface{}{"key": "matched_topics"})
|
|
}, want: "输出字段标识"},
|
|
{name: "invalid source", edit: func(input *contractInput) {
|
|
input.OutputSchema["fields"].([]interface{})[0].(map[string]interface{})["source"] = "script"
|
|
}, want: "不支持的来源"},
|
|
{name: "invalid condition", edit: func(input *contractInput) { input.Rules[0].Condition = map[string]interface{}{"all": []interface{}{}} }, want: "非空数组"},
|
|
{name: "invalid action", edit: func(input *contractInput) { input.Rules[0].Actions[0]["operation"] = "execute" }, want: "不支持的动作"},
|
|
{name: "invalid origin", edit: func(input *contractInput) { input.AllowedOrigins = []string{"crm.example.com"} }, want: "完整的 http/https Origin"},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
input := cloneContractInput(valid)
|
|
test.edit(&input)
|
|
if err := validateContractInput(input); err == nil || !strings.Contains(err.Error(), test.want) {
|
|
t.Fatalf("error = %v, want containing %q", err, test.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func cloneContractInput(input contractInput) contractInput {
|
|
field := input.OutputSchema["fields"].([]interface{})[0].(map[string]interface{})
|
|
fieldCopy := map[string]interface{}{}
|
|
for key, value := range field {
|
|
fieldCopy[key] = value
|
|
}
|
|
rule := input.Rules[0]
|
|
condition := map[string]interface{}{}
|
|
for key, value := range rule.Condition {
|
|
condition[key] = value
|
|
}
|
|
action := map[string]interface{}{}
|
|
for key, value := range rule.Actions[0] {
|
|
action[key] = value
|
|
}
|
|
rule.Condition = condition
|
|
rule.Actions = []map[string]interface{}{action}
|
|
return contractInput{OutputSchema: map[string]interface{}{"fields": []interface{}{fieldCopy}}, ResultSchema: input.ResultSchema, Rules: []ruleInput{rule}, AllowedOrigins: append([]string{}, input.AllowedOrigins...)}
|
|
}
|