145 lines
8.5 KiB
Python
145 lines
8.5 KiB
Python
"""Full-list sorting, grouping and recipient identity feedback; no native I/O."""
|
|
import unittest
|
|
from unittest import mock
|
|
import review_assistant_contacts as contacts
|
|
|
|
ACCOUNT='168800000000001'
|
|
ACTIVE={'ready':True,'account_id':ACCOUNT,'account_name':'合成账号','reason':''}
|
|
|
|
|
|
def item(uid,name,stamp=0,sendable=True):
|
|
return {'id':(f'S:{ACCOUNT}_' if sendable else 'customer:')+str(uid),'name':name,
|
|
'lastTimestamp':stamp,'lastTime':'','selectable':sendable,
|
|
**contacts.recipient_display(name,str(uid))}
|
|
|
|
|
|
class ContactOrderingTest(unittest.TestCase):
|
|
def listing(self,rows,**kwargs):
|
|
with mock.patch.object(contacts,'active_context',return_value=ACTIVE), \
|
|
mock.patch.object(contacts,'_contacts',return_value=('合成账号',rows)):
|
|
return contacts.list_recipients(ACCOUNT,**kwargs)
|
|
|
|
def test_recent_sort_happens_before_page_slice(self):
|
|
rows=[item(i,'助理'+str(i),i) for i in range(120)]
|
|
first=self.listing(rows,limit=50,order='recent')
|
|
second=self.listing(rows,limit=50,offset=50,order='recent')
|
|
self.assertEqual([r['id'] for r in first['items']],[f'S:{ACCOUNT}_{i}' for i in range(119,69,-1)])
|
|
self.assertEqual(second['items'][0]['id'],f'S:{ACCOUNT}_69')
|
|
self.assertFalse({r['id'] for r in first['items']} & {r['id'] for r in second['items']})
|
|
|
|
def test_chinese_names_and_decorative_prefixes_sort_consistently(self):
|
|
rows=[item(i,name,sendable=False) for i,name in enumerate(['张助理','王助理','李助理','★陈助理'])]
|
|
result=self.listing(rows,order='name',status='directory')
|
|
self.assertEqual([r['name'] for r in result['items']],['★陈助理','李助理','王助理','张助理'])
|
|
|
|
def test_numeric_nickname_and_duplicate_name_order_is_stable(self):
|
|
rows=[item(22,'助理10'),item(9,'助理2'),item(8,'助理2')]
|
|
self.assertEqual([r['id'] for r in self.listing(rows,order='name')['items']],[f'S:{ACCOUNT}_{i}' for i in (8,9,22)])
|
|
|
|
def test_state_filter_counts_include_full_search_results_before_paging(self):
|
|
rows=[item(1,'李助理'),item(2,'李助理',sendable=False),item(3,'王助理',sendable=False)]
|
|
result=self.listing(rows,query='李',status='directory',limit=1)
|
|
self.assertEqual((result['total'],result['all_total'],result['all_selectable_total'],result['all_contact_total']),(1,2,1,1))
|
|
self.assertEqual(result['items'][0]['id'],'customer:2')
|
|
self.assertEqual(self.listing(rows,status='sendable')['total'],1)
|
|
|
|
def test_all_view_keeps_sendable_and_directory_groups_separate(self):
|
|
rows=[item(1,'张助理'),item(2,'李助理',sendable=False),item(3,'王助理')]
|
|
result=self.listing(rows,order='name',status='all')
|
|
self.assertEqual([r['id'] for r in result['items']],[f'S:{ACCOUNT}_3',f'S:{ACCOUNT}_1','customer:2'])
|
|
|
|
def test_unknown_names_explicitly_show_identity_without_inventing_a_name(self):
|
|
for name in ['', '微信联系人', '未命名微信联系人']:
|
|
value=contacts.recipient_display(name,'M:13102691405879689')
|
|
self.assertFalse(value['nameKnown'])
|
|
self.assertIn('未读取昵称',value['displayName'])
|
|
self.assertIn('879689',value['displayName'])
|
|
self.assertFalse(contacts.recipient_display('旧缓存姓名','M:123',False)['nameKnown'])
|
|
self.assertEqual(contacts.recipient_display('李助理','M:123')['displayName'],'李助理')
|
|
|
|
def test_unknown_names_are_last_for_name_sort(self):
|
|
rows=[item(1,'微信联系人'),item(2,'张助理')]
|
|
self.assertEqual(self.listing(rows,order='name')['items'][0]['id'],f'S:{ACCOUNT}_2')
|
|
|
|
def test_invalid_filters_fail_without_reading_other_data(self):
|
|
result=self.listing([],status='not-a-filter')
|
|
self.assertFalse(result['ready'])
|
|
self.assertEqual(result['items'],[])
|
|
|
|
|
|
class RecipientStateFeedbackTest(unittest.TestCase):
|
|
def setUp(self):
|
|
from test_review_assistant_ui import host_fixture
|
|
self.host=host_fixture()
|
|
self.account=self.host._review_assistant_state['account_id']
|
|
|
|
def test_old_generic_saved_name_becomes_explicit_unknown_identity(self):
|
|
self.host.runtime_settings['review_assistant_accounts'][self.account]={
|
|
'recipient_conv_id':'M:1234567','recipient_name':'微信联系人','enabled':False}
|
|
value=self.host._review_assistant_console_state()['recipient']
|
|
self.assertFalse(value['nameKnown'])
|
|
self.assertIn('234567',value['displayName'])
|
|
self.assertIn('1234567',value['label'])
|
|
|
|
def test_named_saved_recipient_keeps_name_and_full_identity(self):
|
|
self.host.runtime_settings['review_assistant_accounts'][self.account]={
|
|
'recipient_conv_id':'M:1234567','recipient_name':'李助理','recipient_name_known':True,'enabled':False}
|
|
value=self.host._review_assistant_console_state()['recipient']
|
|
self.assertTrue(value['nameKnown'])
|
|
self.assertEqual(value['displayName'],'李助理')
|
|
self.assertEqual(value['id'],'M:1234567')
|
|
|
|
def test_s_identity_displays_peer_for_both_endpoint_orders(self):
|
|
for conv in (f'S:{self.account}_1234567', f'S:1234567_{self.account}'):
|
|
with self.subTest(conversation=conv):
|
|
self.host.runtime_settings['review_assistant_accounts'][self.account] = {
|
|
'recipient_conv_id': conv, 'recipient_name': '', 'recipient_name_known': False, 'enabled': False}
|
|
value = self.host._review_assistant_console_state()['recipient']
|
|
self.assertEqual(value['id'], conv)
|
|
self.assertEqual(value['displayName'], '未读取昵称 · 尾号 234567')
|
|
self.assertIn('1234567', value['label'])
|
|
self.assertNotIn(self.account, value['label'])
|
|
|
|
def test_state_uses_current_account_mapping_and_never_rewrites_old_m(self):
|
|
other = '168800000000002'
|
|
self.host.runtime_settings['review_assistant_accounts'] = {
|
|
self.account: {'recipient_conv_id': 'M:1234567', 'recipient_name': '旧助理', 'enabled': False},
|
|
other: {'recipient_conv_id': f'S:{other}_1234567', 'recipient_name': '另一账号助理', 'enabled': True}}
|
|
original = {key: dict(value) for key, value in self.host.runtime_settings['review_assistant_accounts'].items()}
|
|
value = self.host._review_assistant_console_state()
|
|
self.assertEqual(value['accountId'], self.account)
|
|
self.assertEqual(value['recipient']['id'], 'M:1234567')
|
|
self.assertEqual(value['recipient']['displayName'], '旧助理')
|
|
self.assertFalse(value['enabled'])
|
|
self.host._review_assistant_state = {**ACTIVE, 'account_id': other}
|
|
value = self.host._review_assistant_console_state()
|
|
self.assertEqual(value['accountId'], other)
|
|
self.assertEqual(value['recipient']['id'], f'S:{other}_1234567')
|
|
self.assertEqual(value['recipient']['displayName'], '另一账号助理')
|
|
self.assertEqual(self.host.runtime_settings['review_assistant_accounts'], original)
|
|
self.host.save_runtime_settings.assert_not_called()
|
|
|
|
def test_save_keeps_verified_identity_and_clear_feedback(self):
|
|
self.host._review_assistant_serial=1
|
|
self.host._review_assistant_updated({'_serial':1,'_kind':'save','ok':True,
|
|
'expected_account':self.account,'recipient':{'id':'M:9876543','name':'微信联系人','nameKnown':False},
|
|
'requested_enabled':None,'replace_recipient':True})
|
|
saved=self.host.runtime_settings['review_assistant_accounts'][self.account]
|
|
self.assertEqual(saved['recipient_conv_id'],'M:9876543')
|
|
self.assertFalse(saved['recipient_name_known'])
|
|
self.assertIn('未读取昵称',self.host._review_assistant_state['message'])
|
|
self.assertIn('876543',self.host._review_assistant_state['message'])
|
|
|
|
|
|
def test_reselecting_same_recipient_still_names_the_saved_contact(self):
|
|
self.host.runtime_settings['review_assistant_accounts'][self.account]={
|
|
'recipient_conv_id':'M:1234567','recipient_name':'李助理','enabled':False}
|
|
self.host._review_assistant_serial=1
|
|
self.host._review_assistant_updated({'_serial':1,'_kind':'save','ok':True,
|
|
'expected_account':self.account,'recipient':{'id':'M:1234567','name':'李助理','nameKnown':True},
|
|
'requested_enabled':None,'replace_recipient':True})
|
|
self.assertIn('已选择:李助理',self.host._review_assistant_state['message'])
|
|
self.assertFalse(self.host.runtime_settings['review_assistant_accounts'][self.account]['enabled'])
|
|
|
|
|
|
if __name__=='__main__': unittest.main() |