130 lines
10 KiB
Python
130 lines
10 KiB
Python
from pathlib import Path
|
|
root=Path('C:/kefu/wechat_rpa')
|
|
def read(name):return (root/name).read_text(encoding='utf-8')
|
|
def write(name,data):compile(data,name,'exec');(root/name).write_text(data,encoding='utf-8',newline='')
|
|
|
|
name='test_review_assistant_ui.py';s=read(name)
|
|
s=s.replace("RECIPIENT = {'id': 'M:10001', 'name': '合成医疗助理', 'kind': '微信客户', 'identityLabel': '编号10001'}", "RECIPIENT_ID = f'S:{ACCOUNT}_10001'\nRECIPIENT = {'id': RECIPIENT_ID, 'peer_id': '10001', 'name': '合成医疗助理', 'kind': '企业微信客户',\n 'recipient_kind': 'wecom_customer', 'identityLabel': '企业微信客户 · 客户编号 10001'}")
|
|
s=s.replace("'M:10001'", 'RECIPIENT_ID')
|
|
s=s.replace("db.executemany('INSERT INTO user_table VALUES(?,?)', [(ACCOUNT, '合成账号'), ('10001','同名助理'), ('10002','同名助理')])", """db.executemany('INSERT INTO user_table VALUES(?,?)', [(ACCOUNT, '合成账号'), ('10001','同名助理'), ('10002','同名助理')])
|
|
db.execute('CREATE TABLE external_user_relation_v3(user_id TEXT,status INTEGER,add_customer_time INTEGER,stranger_type INTEGER,remarks TEXT,real_remarks TEXT)')
|
|
db.executemany('INSERT INTO external_user_relation_v3 VALUES(?,?,?,?,?,?)', [
|
|
('10001',2049,1700000000,0,'',''), ('10002',2049,1700000000,0,'','')])
|
|
db.execute('CREATE TABLE wechat_contactV1(wxid TEXT,name TEXT)')
|
|
db.execute("INSERT INTO wechat_contactV1 VALUES('wxid_unrelated','不属于我的客户')")""")
|
|
s=s.replace('test_lists_exact_private_wechat_contacts_without_message_content','test_lists_relation_customers_with_s_and_m_chats_without_message_content')
|
|
s=s.replace("status='sendable', order='recent'", "status='all', order='recent'")
|
|
s=s.replace("reason = '尚无可发送的私人微信会话。请建立单聊并刷新消息库。'", "reason = '此客户尚无可核验的单聊会话,请刷新我的客户和本机缓存。'")
|
|
s=s.replace("'contact:wxid_synthetic'", "'customer:123456789012345'").replace("'微信通讯录'", "'企业微信客户'")
|
|
s=s.replace("'微信通讯录 · wxid_synthetic'", "'企业微信客户 · 客户编号 123456789012345'")
|
|
s=s.replace("'wxid_synthetic'", "'123456789012345'")
|
|
# Keep screenshots from synthetic web testing in this release audit directory.
|
|
s=s.replace('C:/kefu/deploy/review-assistant-20260917/assistant-settings-', 'C:/kefu/deploy/customer-picker-20260918/assistant-settings-')
|
|
marker=' def test_replacing_an_enabled_contact_requires_explicit_reenable(self):\n'
|
|
extra=''' def test_s_recipient_round_trip_preserves_raw_id_and_customer_kind(self):
|
|
raw = f'S:10001_{ACCOUNT}'
|
|
verified = {**RECIPIENT, 'id': raw, 'peer_id': '10001'}
|
|
self.validate.return_value = {'ok': True, 'account_id': ACCOUNT, 'recipient': verified}
|
|
self.host._save_review_assistant(ACCOUNT, recipient=verified)
|
|
self.validate.assert_called_once_with(ACCOUNT, raw)
|
|
saved = self.host.runtime_settings['review_assistant_accounts'][ACCOUNT]
|
|
self.assertEqual(saved['recipient_conv_id'], raw)
|
|
self.assertEqual(saved['recipient_kind'], '企业微信客户')
|
|
state = self.host._review_assistant_console_state()
|
|
self.assertEqual(state['accountId'], ACCOUNT)
|
|
self.assertEqual(state['recipient']['id'], raw)
|
|
self.assertIn('10001', state['recipient']['label'])
|
|
self.assertNotIn(ACCOUNT, state['recipient']['label'])
|
|
|
|
def test_rejected_legacy_m_recipient_is_not_silently_replaced_by_s_chat(self):
|
|
original = {'enabled': False, 'recipient_conv_id': 'M:10001', 'recipient_name': '旧助理'}
|
|
self.host.runtime_settings['review_assistant_accounts'][ACCOUNT] = dict(original)
|
|
self.validate.return_value = {'ok': False, 'reason': '旧会话不属于当前我的客户', 'recipient': None}
|
|
self.host._save_review_assistant(ACCOUNT, enabled=True)
|
|
self.validate.assert_called_once_with(ACCOUNT, 'M:10001')
|
|
self.host.save_runtime_settings.assert_not_called()
|
|
self.assertEqual(self.host.runtime_settings['review_assistant_accounts'][ACCOUNT], original)
|
|
|
|
'''
|
|
assert marker in s;s=s.replace(marker,extra+marker)
|
|
write(name,s)
|
|
|
|
name='test_review_assistant_contact_order.py';s=read(name)
|
|
s=s.replace("('M:' if sendable else 'contact:')+str(uid)", "(f'S:{ACCOUNT}_' if sendable else 'customer:')+str(uid)")
|
|
s=s.replace("[f'M:{i}' for i in range(119,69,-1)]", "[f'S:{ACCOUNT}_{i}' for i in range(119,69,-1)]")
|
|
s=s.replace("'M:69'", "f'S:{ACCOUNT}_69'")
|
|
s=s.replace("['M:8','M:9','M:22']", "[f'S:{ACCOUNT}_{i}' for i in (8,9,22)]")
|
|
s=s.replace("'contact:2'", "'customer:2'")
|
|
s=s.replace("['M:3','M:1','customer:2']", "[f'S:{ACCOUNT}_3',f'S:{ACCOUNT}_1','customer:2']")
|
|
s=s.replace("['M:3','M:1','contact:2']", "[f'S:{ACCOUNT}_3',f'S:{ACCOUNT}_1','customer:2']")
|
|
s=s.replace("['items'][0]['id'],'M:2'", "['items'][0]['id'],f'S:{ACCOUNT}_2'")
|
|
marker=" def test_save_keeps_verified_identity_and_clear_feedback(self):\n"
|
|
extra=''' 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()
|
|
|
|
'''
|
|
assert marker in s;s=s.replace(marker,extra+marker)
|
|
write(name,s)
|
|
|
|
name='test_review_assistant_picker_layout.py';s=read(name)
|
|
s=s.replace("NAMED = {'id': 'M:10001'", "NAMED = {'id': f'S:{ACCOUNT}_10001', 'peer_id': '10001', 'kind': '企业微信客户'")
|
|
s=s.replace("'identityLabel': '微信联系人 · 联系编号 10001'", "'identityLabel': '企业微信客户 · 客户编号 10001'")
|
|
s=s.replace("ANONYMOUS = {'id': 'M:13102691405879689', 'name': '微信联系人'", "ANONYMOUS = {'id': f'S:13102691405879689_{ACCOUNT}', 'peer_id': '13102691405879689', 'kind': '企业微信客户', 'name': '微信联系人'")
|
|
s=s.replace("'identityLabel': '微信联系人 · 联系编号 13102691405879689'", "'identityLabel': '企业微信客户 · 客户编号 13102691405879689'")
|
|
s=s.replace("'contact:wxid_synthetic_full_12345'", "'customer:987654321012345'")
|
|
s=s.replace("'identityLabel': '微信通讯录 · wxid_synthetic_full_12345'", "'identityLabel': '企业微信客户 · 客户编号 987654321012345'")
|
|
s=s.replace("'wxid_synthetic_full_12345'", "'987654321012345'")
|
|
s=s.replace("'尚无可发送的私人微信会话。请在当前托管企微与此联系人建立单聊并产生一条消息,再刷新消息库。'", "'客户状态或单聊会话尚未核验,请刷新我的客户和本机缓存。'")
|
|
s=s.replace('test_defaults_to_sendable_and_queries_backend_sort_before_pagination','test_defaults_to_all_customers_and_queries_backend_sort_before_pagination')
|
|
s=s.replace("status='sendable', order='recent'", "status='all', order='recent'")
|
|
s=s.replace("status='sendable', order='name'", "status='all', order='name'")
|
|
s=s.replace("self.assertTrue(self.dialog.filter_buttons['sendable'].isChecked())", "self.assertTrue(self.dialog.filter_buttons['all'].isChecked())")
|
|
s=s.replace("self.assertEqual(self.dialog.contacts.count(), 2)", "self.assertEqual(self.dialog.contacts.count(), 3)",1)
|
|
s=s.replace("self.assertIn('(3)', self.dialog.filter_buttons['all'].text())", "self.assertIn('我的客户', self.dialog.filter_buttons['all'].text())\n self.assertIn('待核验', self.dialog.filter_buttons['directory'].text())\n self.assertIn('(3)', self.dialog.filter_buttons['all'].text())",1)
|
|
s=s.replace(" self.dialog._load()\n self.assertIn('通讯录未关联', self.dialog.status.text())", " self.dialog._set_filter('sendable')\n self.assertIn('待核验', self.dialog.status.text())")
|
|
s=s.replace("{**NAMED, 'id': 'M:123456789'}", "{**NAMED, 'id': f'S:{ACCOUNT}_123456789', 'peer_id': '123456789'}")
|
|
s=s.replace("{**NAMED, 'id': 'M:123987654'}", "{**NAMED, 'id': f'S:123987654_{ACCOUNT}', 'peer_id': '123987654'}")
|
|
marker=' def test_unknown_name_is_explicit_and_gets_same_visible_selection(self):\n'
|
|
extra=''' def test_s_details_show_customer_peer_and_confirmation_preserves_raw_id(self):
|
|
self.click_row(0)
|
|
self.assertIn('企业微信客户', self.dialog.details_identity.text())
|
|
self.assertIn('10001', self.dialog.details_identity.text())
|
|
with mock.patch.object(contacts, 'validate_recipient', return_value={
|
|
'ok': True, 'account_id': ACCOUNT, 'recipient': NAMED}) as validate:
|
|
self.dialog.choose.click()
|
|
validate.assert_called_once_with(ACCOUNT, f'S:{ACCOUNT}_10001')
|
|
self.assertEqual(self.dialog.recipient['id'], f'S:{ACCOUNT}_10001')
|
|
self.assertEqual(self.dialog.result(), QDialog.DialogCode.Accepted)
|
|
|
|
'''
|
|
assert marker in s;s=s.replace(marker,extra+marker)
|
|
write(name,s)
|
|
print('Updated 3 UI test modules; added 5 customer-S and account-contract regressions.')
|