修复目的地识别、报价短追问及删除后历史同步
This commit is contained in:
@@ -278,6 +278,35 @@ test('a failed history deletion preserves the active conversation for the next m
|
||||
assert.equal(app.calls.find(call => call.url === '/stream_chat').body.conv_id,9);
|
||||
});
|
||||
|
||||
test('successful deletion updates the local list even when its refresh is rate limited', async () => {
|
||||
const app=await customerPage({human:false,history:[{id:9,title:'待删除会话',ctime:'now'},{id:10,title:'保留会话',ctime:'now'}]});
|
||||
app.hooks['/api/get_history']=() => response({e:'请求太频繁'},429);
|
||||
await app.element('historyWrap').children[0].children[2].onclick({stopPropagation(){}});
|
||||
assert.doesNotMatch(app.element('historyWrap').textContent,/待删除会话/);
|
||||
assert.match(app.element('historyWrap').textContent,/保留会话/);
|
||||
});
|
||||
|
||||
test('successful clearing removes cached history when the followup refresh fails', async () => {
|
||||
const app=await customerPage({human:false,history:[{id:9,title:'待清空会话',ctime:'now'}]});
|
||||
app.hooks['/api/clear_all']=() => response({ok:true});
|
||||
app.hooks['/api/get_history']=() => Promise.reject(new Error('offline'));
|
||||
app.element('.clear-all-btn').click();
|
||||
await flush();
|
||||
assert.doesNotMatch(app.element('historyWrap').textContent,/待清空会话/);
|
||||
assert.ok(app.element('historyWrap').querySelector('.history-empty'));
|
||||
});
|
||||
|
||||
test('a history refresh started before a deletion cannot resurrect the deleted item', async () => {
|
||||
const app=await customerPage({human:false,history:[{id:9,title:'旧刷新中的会话',ctime:'now'}]});
|
||||
let resolve, refreshes=0;
|
||||
app.hooks['/api/get_history']=() => ++refreshes === 1 ? new Promise(done => { resolve=done; }) : response({e:'请求太频繁'},429);
|
||||
await app.click(app.element('.new-chat-btn'));
|
||||
await app.element('historyWrap').children[0].children[2].onclick({stopPropagation(){}});
|
||||
resolve(response([{id:9,title:'旧刷新中的会话',ctime:'now'}]));
|
||||
await flush();
|
||||
assert.doesNotMatch(app.element('historyWrap').textContent,/旧刷新中的会话/);
|
||||
});
|
||||
|
||||
test('history text and order cards preserve their original times and card actions', async () => {
|
||||
const app=await customerPage({human:false,history:[{id:9,title:'历史时间',ctime:'2026-10-28 07:12'}]});
|
||||
app.hooks.messages=() => response([
|
||||
|
||||
+58
-4
@@ -137,10 +137,11 @@ class ApiTests(unittest.TestCase):
|
||||
self.app.config['DEEPSEEK_API_KEY'] = 'test-model-key'
|
||||
invalid = ([1], 'hello', {'msg':7}, {'msg':['test']}, {'msg':'物流咨询', 'conv_id':{}},
|
||||
{'msg':'物流咨询', 'conv_id':-1}, {'msg':'物流咨询', 'conv_id':1.5}, {'msg':'物流咨询','conv_id':False},
|
||||
{'msg':'物流咨询','conv_id':999999999999999999999999})
|
||||
{'msg':'物流咨询','conv_id':999999999999999999999999},
|
||||
{'msg':'物流咨询','conv_id':'²'}, {'msg':'物流咨询','conv_id':'9'*5000})
|
||||
with patch('logistics_chat.ai_client.post_completion') as model:
|
||||
for payload in invalid:
|
||||
with self.subTest(payload=payload):
|
||||
for index, payload in enumerate(invalid):
|
||||
with self.subTest(case=index):
|
||||
events = frames(self.client.post('/stream_chat', json=payload))
|
||||
self.assertIn('e', events[0])
|
||||
model.assert_not_called()
|
||||
@@ -183,6 +184,59 @@ class ApiTests(unittest.TestCase):
|
||||
self.assertIn('人工',events[0]['t'])
|
||||
model.assert_not_called()
|
||||
|
||||
def test_mixed_country_codes_select_the_correct_rates(self):
|
||||
self.app.config['DEEPSEEK_API_KEY'] = 'test-model-key'
|
||||
for message, channel, amount in (('30kg发UK海运报价','英国海运','384'),
|
||||
('30kg发uk海运报价','英国海运','384'),
|
||||
('30kg发GB海运报价','英国海运','384'),
|
||||
('30kg发DE仓海运报价','欧洲海运','369')):
|
||||
with self.subTest(message=message):
|
||||
with patch('logistics_chat.ai_client.post_completion', return_value=ModelResponse()) as model, patch('logistics_chat.chat_service.gen_followups',return_value=[]):
|
||||
events=frames(self.client.post('/stream_chat',json={'msg':message}))
|
||||
self.assertEqual(events[-1],{'d':1})
|
||||
prompt=model.call_args.args[0]['messages'][0]['content']
|
||||
self.assertIn(channel,prompt)
|
||||
self.assertIn(amount,prompt)
|
||||
for message in ('30kg发US仓海运报价','30kg发us仓海运报价','30kg发USFBA仓海运报价',
|
||||
'30kg发阿根廷海运报价','30kg海运报价'):
|
||||
with self.subTest(message=message), patch('logistics_chat.ai_client.post_completion') as model:
|
||||
events=frames(self.client.post('/stream_chat',json={'msg':message}))
|
||||
self.assertIn('目的',events[0]['t'])
|
||||
model.assert_not_called()
|
||||
|
||||
def test_short_channel_followups_and_retries_keep_weight_and_region(self):
|
||||
self.app.config['DEEPSEEK_API_KEY'] = 'test-model-key'
|
||||
cid=self.conversation()
|
||||
sequence=(('30kg英国海运报价','英国海运','384'), ('海运呢','英国海运','384'),
|
||||
('空运呢','英国空运','1,440'), ('50公斤呢','英国空运','2,400'))
|
||||
for message, channel, amount in sequence:
|
||||
with self.subTest(message=message):
|
||||
with patch('logistics_chat.ai_client.post_completion',return_value=ModelResponse()) as model, patch('logistics_chat.chat_service.gen_followups',return_value=[]):
|
||||
frames(self.client.post('/stream_chat',json={'msg':message,'conv_id':cid}))
|
||||
prompt=model.call_args.args[0]['messages'][0]['content']
|
||||
self.assertIn(channel,prompt)
|
||||
self.assertIn(amount,prompt)
|
||||
with patch('logistics_chat.ai_client.post_completion',side_effect=requests.exceptions.ConnectionError):
|
||||
self.assertIn('e',frames(self.client.post('/stream_chat',json={'msg':'海运呢','conv_id':cid}))[0])
|
||||
with patch('logistics_chat.ai_client.post_completion',return_value=ModelResponse()) as model:
|
||||
frames(self.client.post('/stream_chat',json={'msg':'海运呢','conv_id':cid}))
|
||||
prompt=model.call_args.args[0]['messages'][0]['content']
|
||||
self.assertIn('英国海运',prompt)
|
||||
self.assertIn('640',prompt)
|
||||
|
||||
def test_complete_new_questions_do_not_inherit_an_old_quote(self):
|
||||
from logistics_chat.chat_service import shipping_intent_with_context
|
||||
cid=self.conversation()
|
||||
with self.app.app_context():
|
||||
db.save_message(cid,'user','30kg英国海运报价')
|
||||
db.save_message(cid,'assistant','报价结果')
|
||||
for message in ('新的一票50kg德国空运报价','空运理赔应该怎么办?','海运时效一般多久?'):
|
||||
with self.subTest(message=message):
|
||||
intent=shipping_intent_with_context(message,cid)
|
||||
self.assertNotEqual(intent['region'],'uk')
|
||||
db.save_message(cid,'user','空运理赔应该怎么办?')
|
||||
self.assertIsNone(shipping_intent_with_context('海运呢',cid)['weight'])
|
||||
|
||||
def test_uk_volume_quotes_do_not_reuse_continental_warehouse_prices(self):
|
||||
with patch('logistics_chat.ai_client.post_completion') as model:
|
||||
events = frames(self.client.post('/stream_chat',json={'msg':'2方发英国海运多少钱'}))
|
||||
@@ -308,7 +362,7 @@ class ApiTests(unittest.TestCase):
|
||||
streamed = ModelResponse('这是用于覆盖长回答压缩的说明。'*100)
|
||||
responses = [streamed, ModelResponse('基础运费2050元,时效38-45天。'), ModelResponse('["费用呢","时效呢","能带电吗"]')]
|
||||
with patch('logistics_chat.ai_client.requests.post', side_effect=responses) as post:
|
||||
events = frames(self.client.post('/stream_chat', json={'msg': '200kg 海运', 'conv_id': self.conversation()}))
|
||||
events = frames(self.client.post('/stream_chat', json={'msg': '200kg 德国海运', 'conv_id': self.conversation()}))
|
||||
self.assertTrue(any('t' in event for event in events))
|
||||
self.assertTrue(any('replace' in event for event in events))
|
||||
self.assertTrue(any('suggest' in event for event in events))
|
||||
|
||||
@@ -46,6 +46,10 @@ class RuleTests(unittest.TestCase):
|
||||
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'))
|
||||
|
||||
def test_warehouse_country_and_surcharge(self):
|
||||
result = pricing.calc_warehouse_card(2, '海运', country='DE')
|
||||
|
||||
Reference in New Issue
Block a user