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.')