Files
t 18c9354095 refactor: 将客服后端重构为宿主可嵌入模块
- 注入数据库、运行时配置、统一响应、文件存储和平台 AI 能力,补充业务读写工具与客户快捷操作契约。

- 移除模块内重复的组织、客户、工单、标签、技能、旧工作流、MCP 和迁移实现,将身份权限与业务主体交由宿主管理。

- 使用 libSQL 重构向量存储,并完善图片消息、访客身份、排队调度、企业微信和支持聊天页面。

- 统一 HTTP、DTO 与 WebSocket 的 snake_case 协议,补齐模块初始化、业务动作和公共载荷等回归测试。
2026-08-28 22:23:13 +08:00

85 lines
3.8 KiB
Go

package runtime
import (
"strings"
"testing"
)
func TestEnforceVerifiedPackageReplyReplacesBasicRecommendation(t *testing.T) {
results := map[string]string{
"business/device_diagnosis": `{"network_diagnosis":{"required_package_type":"addon"}}`,
"business/device_package_catalog": `[
{"sequence":1,"name":"20G加油包","package_type":"addon","price":"20.00","can_purchase":true,"recommended":true},
{"sequence":2,"name":"200G加油包","package_type":"addon","price":"200.00","can_purchase":true,"recommended":true}
]`,
}
got := enforceVerifiedPackageReply("推荐操作:订购一个立即生效的独立套餐(如12.9元30G),最快恢复。", results)
for _, expected := range []string{"当前只能购买加油包", "1. 20G加油包 - ¥20.00", "2. 200G加油包 - ¥200.00"} {
if !strings.Contains(got, expected) {
t.Fatalf("missing %q in guarded reply: %s", expected, got)
}
}
if strings.Contains(got, "12.9") || strings.Contains(got, "订购一个立即生效的独立套餐") {
t.Fatalf("unsafe basic package recommendation survived: %s", got)
}
}
func TestEnforceVerifiedPackageReplyDoesNotTrustDiagnosisAlone(t *testing.T) {
results := map[string]string{
"business/card_diagnosis": `{"required_package_type":"addon"}`,
}
want := "当前不能购买基础套餐,应购买加油包。"
if got := enforceVerifiedPackageReply(want, results); got != want {
t.Fatalf("correct answer was unexpectedly replaced: %s", got)
}
}
func TestEnforceVerifiedPackageReplyRendersAddonCatalogDeterministically(t *testing.T) {
results := map[string]string{
"business/card_package_catalog": `{"items":[{"sequence":8,"name":"20G加油包","package_type":"addon","price":"20.00","can_purchase":true,"recommended":true}]}`,
}
got := enforceVerifiedPackageReply("模型自由发挥的正确加油包回答", results)
for _, expected := range []string{"当前只能购买加油包", "8. 20G加油包 - ¥20.00", "请回复加油包序号"} {
if !strings.Contains(got, expected) {
t.Fatalf("missing %q in deterministic reply: %s", expected, got)
}
}
}
func TestEnforceVerifiedPackageReplyIgnoresUnrelatedNestedAddonField(t *testing.T) {
want := "这是普通售后回答。"
results := map[string]string{
"business/device_status": `{"metadata":{"required_package_type":"addon"}}`,
}
if got := enforceVerifiedPackageReply(want, results); got != want {
t.Fatalf("unrelated tool result changed answer: %s", got)
}
}
func TestEnforceVerifiedPackageReplyKeepsBasicCatalogReply(t *testing.T) {
want := "当前可以购买基础套餐。"
results := map[string]string{
"business/device_package_catalog": `[{"sequence":1,"name":"30G月包","package_type":"basic","can_purchase":true,"recommended":true},{"sequence":2,"name":"20G加油包","package_type":"addon","can_purchase":false}]`,
}
if got := enforceVerifiedPackageReply(want, results); got != want {
t.Fatalf("mixed/basic catalog unexpectedly forced add-on: %s", got)
}
}
func TestEnforceVerifiedPackageReplyRequiresVerifiedAddonState(t *testing.T) {
want := "您可以购买基础套餐。"
if got := enforceVerifiedPackageReply(want, map[string]string{"business/card_diagnosis": `{"required_package_type":"basic"}`}); got != want {
t.Fatalf("answer changed without verified add-on requirement: %s", got)
}
}
func TestEnforceVerifiedPackageReplyExplainsInsufficientBalance(t *testing.T) {
results := map[string]string{
"business/card_package_catalog": `[{"sequence":1,"name":"20G加油包","package_type":"addon","price":"20.00","can_purchase":false,"reason_code":"insufficient_balance","unavailable_reason":"当前余额不足"}]`,
}
got := enforceVerifiedPackageReply("我推荐您购买基础套餐。", results)
if !strings.Contains(got, "请先充值余额") || !strings.Contains(got, "再购买加油包") {
t.Fatalf("insufficient balance guidance missing: %s", got)
}
}