"""Customer-language regressions use synthetic amounts, never private tariffs.""" from decimal import Decimal from pathlib import Path import tempfile import unittest from unittest.mock import patch from logistics_chat import create_app, db from logistics_chat.quote_data import import_snapshot from logistics_chat.quote_engine import quantity, parse_intent from test_quotes import fixture_snapshot, frames class QuoteBusinessTests(unittest.TestCase): def setUp(self): folder=tempfile.TemporaryDirectory();self.addCleanup(folder.cleanup) root=Path(folder.name) self.app=create_app({'TESTING':True,'DATABASE':root/'test.db','UPLOAD_DIR':root/'uploads', 'BACKUP_DIR':root/'backups','LOG_DIR':root/'logs','DEEPSEEK_API_KEY':'','RATE_LIMIT_PER_MIN':1000}) self.client=self.app.test_client() self.client.post('/api/visitor/session',json={'key':'1'*64}) book=fixture_snapshot() documents=[ '铁铝制品另外加附加费¥5/KG', '正常货物 A.0KG<单件重量<22KG B.0CM<最长单边长度<120CM C.0CM<第二边<75CM D.最长边<260CM', '单件不能超22KG 超重收+70/件', '普通超尺寸加收90RMB/件', '大尺寸货物,任意2个条件,加收400RMB/件:22KG<单件重量<68KG;0<最长边<274CM;330CM<周长+单边长<419CM', '超大件货物,加收USD900/件', '保险费:保额的百分之0.25,min 13USD,投保金额是货值乘以1.2。', '海外进口清关,超过5个品名,续页加收USD7元RMB/个', '一般贸易出口报关费:RMB60/票', '偏远地址加收4元/kg;超偏远地址加收6元/kg', '禁止运输的货物:纯电池、液体、食品', ] book['documents']=[{'sheet':'海派','cell':f'A{i+1}','text':text} for i,text in enumerate(documents)] book['documents'].append({'sheet':'美森加班海卡','cell':'A1','text':'不可接一般贸易'}) with self.app.app_context(): c=db.connect();import_snapshot(c,book,activate=True);c.commit();c.close() def ask(self,text,cid=None): with patch('logistics_chat.ai_client.post_completion') as model: events=frames(self.client.post('/stream_chat',json={'msg':text,'conv_id':cid})) model.assert_not_called() self.assertEqual(events[-1],{'d':1},events) return events[0]['t'] def test_different_cartons_use_individual_minimums_and_dimensions(self): text=self.ask('美国美西,1箱10KG,1箱20KG,义乌普船海派') self.assertIn('32KG = 64元',text) text=self.ask('美国美西,2箱,1箱10KG,60x50x40cm,1箱20KG,40x30x20cm,义乌普船海派') self.assertIn('40KG = 80元',text) text=self.ask('美国美西,2箱,1箱10KG,60x50x40cm,1箱20KG,义乌普船海派') self.assertIn('40KG = 80元',text) self.assertIn('箱数与分箱明细不一致',self.ask('美国3箱,1箱10KG,1箱20KG海派')) def test_weight_units_chinese_followup_and_invalid_postal(self): cid=self.client.post('/api/new_chat').json['id'] self.ask('美国美西30KG,义乌海派',cid) for text in ('五十公斤呢','50000克呢','0.05吨呢'): self.assertIn('美国 50KG',self.ask(text,cid)) self.assertIn('大于 0',self.ask('美国重量为-30KG海派')) self.assertIn('邮编格式不正确',self.ask('美国30KG,邮编518000海派')) self.assertIn('美国 30KG',self.ask('美国30000克海派')) self.assertIn('未找到目的仓码',self.ask('美国30KG发ABC999海派')) def test_commodity_survives_weight_followups_and_new_commodity_replaces_it(self): cid=self.client.post('/api/new_chat').json['id'] text=self.ask('美国美西铁制品30KG,义乌普船海派',cid) self.assertIn('铁铝附加费5元/KG',text) self.assertIn('30KG = 210元',text) self.assertIn('50KG = 350元',self.ask('50KG呢',cid)) self.assertNotIn('铁铝附加费',self.ask('换成普通货50KG呢',cid)) def test_limit_fees_take_maximum_per_carton_and_do_not_guess_bad_threshold(self): text=self.ask('美国美西1箱30KG,130x50x20cm,义乌普船海派') self.assertIn('最高项90元/件',text) self.assertNotIn('160元',text) text=self.ask('美国美西1箱30KG,180x50x30cm,义乌普船海派') self.assertIn('最高项400元/件',text) text=self.ask('美国美西1箱30KG,40x30x20cm,义乌普船海派') self.assertIn('最高项70元/件',text) self.assertNotIn('400元/件',text) self.assertIn('人工确认是否接收',self.ask('美国美西1箱70KG,40x30x20cm,义乌普船海派')) def test_cbm_uses_two_decimals_half_up_without_creating_free_shipments(self): rate={'unit':'cbm','kind':'truck','service':'洛杉矶普船海卡'} intent=parse_intent('美国1KG,1.005CBM',set()) self.assertEqual(quantity(intent,rate),Decimal('1.01')) intent['cbm']='1.004';self.assertEqual(quantity(intent,rate),Decimal('1.00')) intent['weight']='0.1';intent['cbm']='0.004' self.assertIsNone(quantity(intent,rate)) def test_business_topics_use_current_documents_instead_of_generic_quotes(self): insurance=self.ask('美国保价1万美元,保险费怎么算') self.assertIn('0.25%',insurance);self.assertIn('=25USD',insurance) self.assertNotIn('元/KG',insurance) self.assertIn('大于0',self.ask('美国保价-10美元,保险费怎么算')) text=self.ask('美国30KG,7个品名清关续页收费') self.assertIn('7美元/个',text);self.assertIn('=14美元',text) text=self.ask('美国30KG还需要什么费用') self.assertIn('偏远地址加4元/KG',text);self.assertIn('超偏远地址加6元/KG',text) self.assertNotIn('250',text) self.assertIn('不可接一般贸易',self.ask('美国美森加班海卡一般贸易报关多少钱')) self.assertIn('不接收',self.ask('美国30KG纯电池可以发吗')) self.assertIn('不接收',self.ask('美国30KG食品,FDA申报费多少人民币')) def test_destination_origin_comparison_time_and_english(self): cid=self.client.post('/api/new_chat').json['id'] self.ask('美国30KG发ZZZ1,义乌海派',cid) text=self.ask('深圳交仓呢',cid) self.assertIn('美国 30KG',text);self.assertNotIn('· 义乌',text) text=self.ask('海运和空运哪个好,美国30KG') self.assertIn('没有美国空运费率',text) text=self.ask('美国美西海派多久') self.assertIn('提取不等于送达',text);self.assertNotIn('元/KG',text) text=self.ask('Please quote 30kg to US by sea') self.assertIn('CNY/kg',text) self.assertFalse(__import__('re').search(r'[\u4e00-\u9fff]',text),text) def test_human_and_photo_questions_never_use_old_regional_model_facts(self): self.assertIn('联系人工',self.ask('帮我转人工客服')) text=self.ask('我可以发张货物照片让你判断报价吗') self.assertIn('不会自动识别',text);self.assertNotIn('21KG',text)