Files
baiyue-logistics-chat/tests/test_rules.py
T
ouyangxq 805675f8db 重构物流客服模块并完善会话接待工作台
- 拆分应用工厂、业务服务与路由,保留原有 HTTP/SSE 和存储入口
- 分离页面资源,重排客服工作台并完善响应式导航、草稿和附件交互
- 整理维护脚本、请求示例和贡献指南,移除启动脚本中的密钥配置
- 上传文件改为仅本地保留,补充隔离的后端与前端回归验证

验证:46 项 Python 测试通过,含 14 个已有子测试;12 个 Node 前端场景通过。
2026-10-29 10:59:29 +08:00

82 lines
4.1 KiB
Python

"""Business boundaries for extracted pure rules; no model service is contacted."""
from datetime import datetime
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest
from unittest.mock import patch
from logistics_chat import knowledge, pricing, tracking
class RuleTests(unittest.TestCase):
def test_specific_knowledge_wins_and_unknown_questions_have_no_match(self):
self.assertIn('22KG+', knowledge.search_knowledge('英国空运价格'))
self.assertIsNone(knowledge.search_knowledge('没有相关关键词的测试'))
def test_sea_tier_boundary_and_minimum(self):
self.assertEqual(pricing.calc_freight(100, 'sea')['price'], 12.3)
self.assertEqual(pricing.calc_freight(101, 'sea')['price'], 10.3)
self.assertEqual(pricing.calc_freight(1, 'sea')['total'], 258.3)
self.assertEqual(pricing.calc_freight(1, 'air_uk')['charge'], 22)
def test_large_air_shipments_use_the_highest_applicable_tier(self):
self.assertEqual(pricing.calc_freight(2000, 'air')['total'], 72000)
self.assertEqual(pricing.calc_freight(2000, 'air_uk')['total'], 84000)
def test_volume_weight_and_unit_conversion(self):
for dims, unit in (([100, 100, 100], 'cm'), ([1, 1, 1], 'm'), ([1000]*3, 'mm')):
with self.subTest(unit=unit):
result = pricing.calc_freight(20, 'sea', dims, unit)
self.assertEqual(result['vol'], 166.67)
self.assertEqual(result['charge'], 166.67)
def test_shipping_intent_keeps_dimensions_separate_from_weight(self):
intent = pricing.parse_shipping_intent('100x80x60 200kg 海运')
self.assertEqual(intent['dims'], [100, 80, 60])
self.assertEqual(intent['weight'], 200)
self.assertEqual(intent['channel'], 'sea')
self.assertEqual(pricing.parse_shipping_intent('1吨铁路')['weight'], 1000)
self.assertEqual(pricing.parse_shipping_intent('100 lbs air')['weight'], 45.36)
def test_warehouse_country_and_surcharge(self):
result = pricing.calc_warehouse_card(2, '海运', country='DE')
self.assertIn('-DE', result['warehouse'])
self.assertEqual(result['total'], 3472)
product, fee = pricing.detect_surcharge('寄手机到德国')
self.assertIn('手机', product)
self.assertEqual(fee, '5/KG')
self.assertIn('500', pricing.surcharge_reply(product, fee, 100))
self.assertEqual(pricing.check_island('07000')[1], 'IT')
self.assertIsNone(pricing.check_island('not a postcode'))
def test_tracking_recognition_and_card_context(self):
self.assertEqual(tracking.extract_tracking_no('查询15252125'), '15252125')
self.assertFalse(tracking.is_tracking_no('2026-10-28'))
self.assertFalse(tracking.is_tracking_no('i want to go 1t how money'))
with patch.object(tracking, 'datetime') as clock:
clock.now.return_value = datetime(2026, 10, 28, 12)
card = tracking.build_track('15252125')
self.assertEqual(card, tracking.build_track('15252125'))
self.assertEqual(card['status'], '派送中')
self.assertEqual(len(card['nodes']), 6)
self.assertIn('15252125', tracking.card_to_text('__CARD__{"no":"15252125","status":"派送中"}'))
def test_pure_modules_import_without_site_packages_or_runtime_files(self):
root = str(Path(__file__).resolve().parents[1])
code = ('import sys; sys.dont_write_bytecode=True; sys.path.insert(0, sys.argv[1]); '
'import logistics_chat.knowledge, logistics_chat.pricing, logistics_chat.tracking; '
'import logistics_chat.config, logistics_chat.db, logistics_chat.file_service; '
'assert "flask" not in sys.modules; assert "requests" not in sys.modules')
with tempfile.TemporaryDirectory() as directory:
result = subprocess.run([sys.executable, '-S', '-c', code, root], cwd=directory,
capture_output=True, text=True, timeout=15)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(list(Path(directory).iterdir()), [])
if __name__ == '__main__':
unittest.main()