Files
inquiry_robot/inquiry-agent/tests/test_land_copy.py
T
jillion886andCursor 378bb892b3 陆运选项不全时改为复制填空清单,方便销售按编号回填。
停发填写样例图,同群只跟当前工单,重量体积统一为 KG/CBM。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-23 17:10:13 +08:00

347 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
陆运核对卡与无产品话术。
"""
from __future__ import annotations
import os
import sys
import unittest
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
if ROOT not in sys.path:
sys.path.insert(0, ROOT)
from agent.policy import inquiry_copy as copy
class LandCopyTest(unittest.TestCase):
def test_domestic_card_no_customs_no_wo(self):
text = copy.land_confirm_card(
{
"运输类型": "国内运输拼车",
"线路类别": "国内长途/零担",
"运输分类": "急件",
"起运港": "广州",
"目的港": "深圳",
"品名": "衣服",
"体积": "100CBM",
"毛重": "50kg",
"报价日期": "2026-09-17",
}
)
self.assertIn("始发站(必填):广州", text)
self.assertNotIn("通关口岸", text)
self.assertNotIn("WO", text)
self.assertIn('请回复“确定”进行TMS查价,内容有误时,请重新发内容。', text)
self.assertIn("运输类型", text)
self.assertIn("国内运输拼车", text)
def test_cross_empty_customs(self):
text = copy.land_confirm_card(
{
"运输类型": "跨境集拼",
"线路类别": "东南亚",
"运输分类": "急件",
"起运港": "广州",
"目的港": "河内",
"品名": "衣服",
"体积": "100CBM",
"毛重": "50kg",
"报价日期": "2026-09-17",
}
)
self.assertIn("通关口岸(非必填):", text)
def test_hk_lcl_shows_vehicle_not_load_field(self):
text = copy.land_confirm_card(
{
"运输类型": "中港零担/集拼",
"线路类别": "东南亚",
"运输分类": "急件",
"起运港": "广州",
"目的港": "香港",
"品名": "衣服",
"车型/数量": "9米6/1",
"报价日期": "2026-09-17",
}
)
self.assertIn("运输类型(必填):中港零担/集拼", text)
self.assertIn("车型/数量(必填):9米6/1", text)
self.assertNotIn("中港装载方式", text)
self.assertIn("通关口岸(非必填)", text)
def test_hk_full_truck_hides_vehicle(self):
text = copy.land_confirm_card(
{
"运输类型": "中港整车",
"线路类别": "东南亚",
"运输分类": "急件",
"起运港": "广州",
"目的港": "香港",
"品名": "衣服",
"报价日期": "2026-09-17",
}
)
self.assertIn("运输类型(必填):中港整车", text)
self.assertNotIn("车型/数量", text)
self.assertNotIn("中港装载方式", text)
def test_domestic_ftl_one_field(self):
text = copy.land_confirm_card(
{
"运输类型": "国内运输整车",
"线路类别": "国内长途/零担",
"运输分类": "急件",
"起运港": "广州",
"目的港": "深圳",
"品名": "衣服",
"车型/数量": "9米6/1",
"报价日期": "2026-09-17",
}
)
self.assertIn("车型/数量(必填):9米6/1", text)
self.assertNotIn("\n数量(必填)", text)
def test_no_staff_copy(self):
self.assertIn("陆运产品岗", copy.land_group_no_staff())
def test_ask_land_fields_marks_required_and_lists_optional(self):
text = copy.ask_land_fields(
facts={
"运输类型": "跨境集拼",
"线路类别": "东南亚",
"运输分类": "急件",
"起运港": "广州",
"目的港": "河内",
"品名": "衣服",
"毛重": "50kg",
},
missing_keys=["体积"],
land_subtype="跨境集拼",
)
self.assertIn("始发站(必填):广州", text)
self.assertIn(copy.CLARIFY_PASTE_HINT, text)
self.assertIn("1.体积(CBM)(必填):\n(如:100CBM)", text)
self.assertIn("2.通关口岸(非必填):\n(如:皇岗)", text)
self.assertNotIn("体积(必填):(如:", text)
self.assertNotIn(copy.LAND_CONFIRM_TAIL, text)
def test_ask_land_fields_domestic_has_no_customs(self):
text = copy.ask_land_fields(
facts={
"运输类型": "国内运输拼车",
"起运港": "广州",
"目的港": "深圳",
"品名": "衣服",
"毛重": "50kg",
},
missing_keys=["体积"],
land_subtype="国内运输拼车",
)
self.assertIn("1.体积(CBM)(必填):\n(如:100CBM)", text)
self.assertNotIn("通关口岸", text)
def test_ask_land_fields_filled_customs_not_pending(self):
text = copy.ask_land_fields(
facts={
"运输类型": "中港整车",
"起运港": "广州",
"目的港": "香港",
"品名": "衣服",
"通关口岸": "皇岗",
},
missing_keys=["起运港"],
land_subtype="中港整车",
)
self.assertIn("通关口岸(非必填):皇岗", text)
pending = text.split(copy.CLARIFY_PASTE_HINT, 1)[1]
self.assertNotIn("通关口岸", pending)
def test_inquiry_card_lists_land_fields_and_wo(self):
text = copy.inquiry_card(
work_order_no="WO202609170006",
facts={
"运输类型": "国内运输拼车",
"线路类别": "国内长途/零担",
"运输分类": "急件",
"起运港": "广州",
"目的港": "深圳",
"品名": "衣服",
"体积": "100CBM",
"毛重": "50kg",
"报价日期": "2026-09-17",
},
transport_mode="陆运",
)
self.assertIn("工单号:WO202609170006", text)
self.assertIn("运输方式:陆运", text)
self.assertIn("运输类型:国内运输拼车", text)
self.assertIn("始发站:广州", text)
self.assertIn("货物品名:衣服", text)
self.assertIn("工单已创建,正在查询TMS报价。", text)
self.assertNotIn("件数", text)
def test_scheme_card_uses_land_fields_not_sea(self):
facts = {
"运输类型": "国内运输拼车",
"线路类别": "国内城配/拖车/打包",
"运输分类": "普件(东南亚、中港常用线路/常规车型)",
"起运港": "泉州市",
"目的港": "南京市",
"品名": "通信机柜及线缆配件",
"体积": "10CBM",
"毛重": "10KG",
"报价日期": "2026-09-17",
}
quote = {"total": "CNY 1200", "eta": "3天", "valid_until": "2026-09-20"}
text = copy.scheme_card(
work_order_no="WO202609170011",
status="已报价",
facts=facts,
quote=quote,
transport_mode="陆运",
)
self.assertIn("运输方式:陆运", text)
self.assertIn("运输类型:国内运输拼车", text)
self.assertIn("始发站:泉州市", text)
self.assertIn("货物品名:通信机柜及线缆配件", text)
self.assertIn("体积(CBM):10CBM", text)
self.assertNotIn("整柜或拼柜", text)
self.assertNotIn("箱型箱量", text)
self.assertNotIn("件数:", text)
self.assertNotIn("包装类型:", text)
rows = {
x["keyname"]: x["value"]
for x in copy.scheme_horizontal_rows(
work_order_no="WO202609170011",
facts=facts,
quote=quote,
transport_mode="陆运",
)
}
self.assertIn("陆运 泉州市→南京市", rows["线路"])
self.assertIn("国内运输拼车", rows["类型"])
self.assertIn("国内城配/拖车/打包", rows["类型"])
self.assertIn("通信机柜及线缆配件", rows["货物"])
self.assertIn("10CBM", rows["货物"])
self.assertNotIn("航线", rows)
self.assertNotIn("箱型", rows)
self.assertNotIn("包装", rows)
self.assertNotIn("空运", "".join(rows.values()))
self.assertNotIn("海运", "".join(rows.values()))
def test_scheme_card_ftl_shows_vehicle_combo(self):
facts = {
"运输类型": "国内运输整车",
"线路类别": "国内长途/零担",
"运输分类": "急件",
"起运港": "广州",
"目的港": "深圳",
"品名": "衣服",
"车型/数量": "9米6/1",
}
rows = {
x["keyname"]: x["value"]
for x in copy.scheme_horizontal_rows(
work_order_no="WO202609170012",
facts=facts,
quote={},
transport_mode="陆运",
)
}
self.assertIn("9米6/1", rows["货物"])
self.assertNotIn("CBM", rows["货物"])
def test_land_brief_only_ltl_collab(self):
text = copy.sea_group_brief(
work_order_no="WO1",
facts={
"运输类型": "国内运输拼车",
"线路类别": "国内长途/零担",
"运输分类": "急件",
"起运港": "广州",
"目的港": "深圳",
"品名": "衣服",
"体积": "1",
"毛重": "1",
"报价日期": "2026-09-18",
},
quote=None,
collab_facts={"包装方式": "纸箱"},
sales_name="销",
product_names=["产"],
has_price=False,
transport_mode="陆运",
)
self.assertIn("包装方式:纸箱", text)
self.assertIn("客户名称:-", text)
self.assertIn("货值:-", text)
self.assertIn("是否为危险品:-", text)
self.assertNotIn("贸易条款", text)
self.assertNotIn("商品海关编码", text)
self.assertNotIn("海关编码", text)
def test_land_brief_ftl_longhaul_order(self):
text = copy.sea_group_brief(
work_order_no="WO2",
facts={
"运输类型": "国内运输整车",
"线路类别": "国内长途/零担",
"运输分类": "急件",
"起运港": "广州",
"目的港": "深圳",
"品名": "衣服",
"车型/数量": "9米/1",
"报价日期": "2026-09-18",
},
quote=None,
collab_facts={},
sales_name="销",
product_names=["产"],
has_price=False,
transport_mode="陆运",
)
collab = text.split("协同补充字段")[1]
self.assertLess(collab.find("客户名称"), collab.find("货值"))
self.assertLess(collab.find("货值"), collab.find("包装方式"))
self.assertNotIn("贸易条款", text)
def test_land_unrecognized_lists_keys(self):
keys = ("客户名称", "包装方式", "货值", "是否为危险品")
text = copy.group_fields_not_recognized(keys=keys, business_line="LAND")
self.assertIn("客户名称", text)
self.assertNotIn("货好时间", text)
def test_image_copy(self):
self.assertEqual(copy.IMAGE_RECOGNIZING, "正在识别图片")
self.assertIn("没看清", copy.IMAGE_UNREADABLE)
self.assertIn("暂时没认出来", copy.IMAGE_TECH_FAIL)
merged = copy.image_fail_then_clarify(copy.IMAGE_UNREADABLE, copy.ASK_TRANSPORT)
self.assertTrue(merged.startswith(copy.IMAGE_UNREADABLE))
self.assertIn(copy.ASK_TRANSPORT, merged)
def test_attachment_copy_and_card(self):
self.assertEqual(copy.ATTACH_RECOGNIZING, "正在识别附件")
self.assertIn("没看清", copy.ATTACH_UNREADABLE)
self.assertIn("暂时没认出来", copy.ATTACH_TECH_FAIL)
payload = copy.attachment_upload_card("https://ai.ytd-scm.com/inquiry-form/upload/tok")
card = payload["template_card"]
self.assertEqual(payload["msgtype"], "template_card")
# 现网上传卡是 text_notice。news_notice 必须带 card_image,企微会 42044 后退成纯文本。
self.assertEqual(card["card_type"], "text_notice")
self.assertNotIn("card_image", card)
self.assertEqual(card["source"]["desc"], "附件询价")
self.assertEqual(card["main_title"]["title"], "上传询价附件")
self.assertIn("Excel", card["main_title"]["desc"])
self.assertIn("图片请直接在企微聊天窗口发送", card["main_title"]["desc"])
self.assertIn("图片请直接在当前企微会话发送", card["sub_title_text"])
self.assertEqual(card["jump_list"][0]["title"], "上传询价附件")
self.assertIn("/upload/tok", card["card_action"]["url"])
self.assertEqual(card["card_action"]["type"], 1)
self.assertNotIn("userid", card["card_action"]["url"])
if __name__ == "__main__":
unittest.main()