98 lines
5.2 KiB
Plaintext
98 lines
5.2 KiB
Plaintext
def test_pending_review_is_not_bypassed_by_new_safe_message(self):
|
|
self.bot.send_mode = 'auto'
|
|
self.assistant.has_pending.return_value = True
|
|
self.bot._reply_needs_review = mock.Mock(return_value=(False, ''))
|
|
blanket, required, reason = self.bot._reply_review_decision({}, 'new question', 'safe answer')
|
|
self.assertFalse(blanket)
|
|
self.assertTrue(required)
|
|
self.assertIn('待审核', reason)
|
|
self.bot._reply_needs_review.assert_called_once()
|
|
|
|
def test_late_mobile_sync_does_not_hide_new_customer_message(self):
|
|
human = dict(self.context['last_message'])
|
|
human.update(send_time=3, rowid=5)
|
|
newer = {'is_self': False, 'dedup_key': 'next-question', 'content': 'new question',
|
|
'send_time': 4, 'rowid': 4, 'account': 'account-one', 'conv_id': 'S:1_2'}
|
|
self.context['messages'] = [newer, human]
|
|
self.context['last_message'] = human
|
|
self.assistant.reconcile.return_value.update(send_time=3, rowid=5)
|
|
self.poll()
|
|
self.assertEqual(self.bot.enqueue_detected.call_args.kwargs['database_event']['message_id'], 'next-question')
|
|
|
|
def test_send_attempt_failure_prevents_dispatch_and_local_completion_keeps_approval(self):
|
|
self.assistant.record_automated_attempt.side_effect = OSError('synthetic disk failure')
|
|
self.assertFalse(self.bot._record_assistant_automated_attempt(self.state, 'new draft'))
|
|
self.state['review_approved'] = True
|
|
self.bot._record_assistant_automated_send(self.state)
|
|
self.assistant.complete_local_review.assert_called_once_with(self.state)
|
|
self.assistant.record_automated_send.assert_not_called() # No real server receipt.
|
|
|
|
|
|
class SharedVisualAssistantTests(VisualAssistantTests):
|
|
"""Use the real durable coordinator, keeping all transports mocked."""
|
|
def use_real_coordinator(self):
|
|
from review_assistant import ReviewAssistantCoordinator
|
|
self.bot._review_assistant_identity = ('123', 42)
|
|
self.state['account'] = '123'
|
|
self.context['account'] = '123'
|
|
incoming = {'account': '123', 'conv_id': 'S:1_2', 'is_self': False, 'sender_id': '2',
|
|
'dedup_key': 'incoming-one', 'server_id': '10', 'rowid': 1,
|
|
'send_time': time.time()-1, 'content': 'original question'}
|
|
self.context['messages'] = [incoming]
|
|
self.context['last_message'] = incoming
|
|
coordinator = ReviewAssistantCoordinator(root=self.root, account='123', pid=42,
|
|
settings_loader=lambda: {'review_assistant_accounts': {'123': {
|
|
'enabled': True, 'recipient_conv_id': 'M:9'}}})
|
|
coordinator.enqueue_notifications = mock.Mock()
|
|
self.addCleanup(coordinator.close)
|
|
self.bot._get_review_assistant.return_value = coordinator
|
|
self.bot._register_assistant_review(self.fp)
|
|
self.assertTrue(self.state.get('assistant_review_id'))
|
|
return coordinator
|
|
|
|
def add_human(self, *, content='human phone reply'):
|
|
outgoing = {'account': '123', 'conv_id': 'S:1_2', 'is_self': True, 'sender_id': '123',
|
|
'dedup_key': 'human-two', 'server_id': '11', 'rowid': 2,
|
|
'send_time': time.time()+.1, 'content': content}
|
|
self.context['messages'].append(outgoing)
|
|
self.context['last_message'] = outgoing
|
|
|
|
def test_real_shared_human_completion_then_new_risk(self):
|
|
coordinator = self.use_real_coordinator()
|
|
self.add_human()
|
|
self.poll()
|
|
self.assertNotIn(self.key, self.bot._pending_reply_sessions)
|
|
self.assertTrue(coordinator.resumed('S:1_2'))
|
|
self.bot.send_mode = 'review'
|
|
self.bot._reply_needs_review = mock.Mock(return_value=(True, 'new risk'))
|
|
self.assertEqual(self.bot._reply_review_decision({'account':'123', 'conv_id':'S:1_2'}, 'q', 'a'),
|
|
(False, True, 'new risk'))
|
|
|
|
def test_real_shared_automated_attempt_is_not_human_reply(self):
|
|
coordinator = self.use_real_coordinator()
|
|
coordinator.record_automated_attempt(self.state)
|
|
self.add_human(content='old AI draft')
|
|
self.poll()
|
|
self.assertIn(self.key, self.bot._pending_reply_sessions)
|
|
self.assertFalse(coordinator.resumed('S:1_2'))
|
|
|
|
def test_real_shared_local_approval_closes_reminder_without_resuming(self):
|
|
coordinator = self.use_real_coordinator()
|
|
self.state['review_approved'] = True
|
|
self.bot._record_assistant_automated_send(self.state)
|
|
self.assertFalse(coordinator.has_pending('S:1_2'))
|
|
self.assertFalse(coordinator.resumed('S:1_2'))
|
|
|
|
def test_real_shared_completion_retries_original_episode_after_disk_failure(self):
|
|
coordinator = self.use_real_coordinator()
|
|
review_id = self.state['assistant_review_id']
|
|
self.add_human()
|
|
with mock.patch.object(self.bot, '_persist_pending_replies', side_effect=[True, False]):
|
|
self.poll()
|
|
self.assertIn(self.key, self.bot._pending_reply_sessions)
|
|
self.assertTrue(coordinator.resumed('S:1_2'))
|
|
self.poll()
|
|
self.assertNotIn(self.key, self.bot._pending_reply_sessions)
|
|
self.assertEqual(self.state['assistant_review_id'], review_id)
|
|
|