Files

101 lines
5.7 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)
self.assertEqual(pricing.parse_shipping_intent('1.2 x 0.8 x 0.6 m 30kg海运')['dims'],[1.2,0.8,0.6])
self.assertEqual(pricing.parse_shipping_intent('长10.5宽20.5高30.5')['dims'],[10.5,20.5,30.5])
def test_shipping_regions_distinguish_country_codes_from_english_pronouns(self):
self.assertEqual(pricing.shipping_region('Give us a quote for 30kg to Germany'),'eu')
self.assertEqual(pricing.shipping_region('30kg air to US'),'unsupported')
self.assertEqual(pricing.shipping_region('30kg air to us'),'unsupported')
self.assertEqual(pricing.shipping_region('30kg to UK'),'uk')
self.assertEqual(pricing.shipping_region('30kg发UK海运'),'uk')
self.assertEqual(pricing.shipping_region('30kg发US仓海运'),'unsupported')
self.assertIsNone(pricing.shipping_region('talk about us and our work'))
self.assertIsNone(pricing.shipping_region('30kg for UKEURO warehouse'))
self.assertIsNone(pricing.shipping_region('2GB附件,30kg海运报价'))
self.assertTrue(pricing.is_shipping_destination_reply('英国的FBA仓'))
self.assertTrue(pricing.is_shipping_destination_reply('目的地是UK仓'))
self.assertFalse(pricing.is_shipping_destination_reply('英国VAT费用是什么'))
self.assertFalse(pricing.is_shipping_destination_reply('Give us a quote for 30kg to Germany'))
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'))
self.assertIsNone(pricing.calc_warehouse_card(2, '海运', country='GB'))
self.assertIsNone(pricing.calc_warehouse_card(2, '海运', warehouse_key='unknown'))
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()