Files
kefu/wechat_rpa/test_knowledge_cache_audit.py
T
2026-09-21 10:34:06 +08:00

80 lines
4.2 KiB
Python

"""Use temporary JSON to verify actual knowledge cache persistence, never credentials."""
import json
from pathlib import Path
import tempfile
from types import SimpleNamespace
import unittest
from unittest import mock
import backend_client
class KnowledgeCacheAudit(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.addCleanup(self.temp.cleanup)
self.path = Path(self.temp.name)/'backend_connection.json'
self.enterContext(mock.patch.object(backend_client, 'CONNECTION_FILE', self.path))
self.enterContext(mock.patch.object(backend_client, 'RUNTIME_FILE', Path(self.temp.name)/'no-runtime.json'))
self.enterContext(mock.patch.object(backend_client, 'discover_local_server_url', return_value=backend_client.DEFAULT_SERVER_URL))
self.enterContext(mock.patch('ai_config.apply_settings', return_value={}))
self.summary = {'enabled':True, 'published':1234, 'updated_at':'2026-09-16 10:00:00'}
def apply(self, **extra):
backend_client._apply_config_response({'config':{}, 'version':1, **extra}, backend_client.load_settings())
def test_sync_survives_actual_json_save_and_reload(self):
self.apply(knowledge=self.summary)
self.assertEqual(json.loads(self.path.read_text(encoding='utf-8'))['knowledge_summary'], self.summary)
self.assertEqual(backend_client.load_settings()['knowledge_summary'], self.summary)
def test_legacy_response_without_knowledge_keeps_cached_summary(self):
self.apply(knowledge=self.summary)
self.apply()
self.assertEqual(backend_client.load_settings()['knowledge_summary'], self.summary)
def test_old_settings_without_cache_use_empty_mapping(self):
self.path.write_text(json.dumps({'auto_sync':True}), encoding='utf-8')
self.assertEqual(backend_client.load_settings()['knowledge_summary'], {})
def test_invalid_saved_summary_shapes_are_empty(self):
for value in (None, [], 'bad', 1, False):
with self.subTest(value=value):
self.path.write_text(json.dumps({'knowledge_summary':value}), encoding='utf-8')
self.assertEqual(backend_client.load_settings()['knowledge_summary'], {})
def test_malformed_count_and_enable_flag_do_not_break_or_mislead_ui(self):
for count in ('bad', float('inf'), -5, {}, [], True):
with self.subTest(count=str(count)):
self.path.write_text(json.dumps({'knowledge_summary':{'published':count,'enabled':'false','updated_at':[]}}), encoding='utf-8')
summary = backend_client.load_settings()['knowledge_summary']
self.assertEqual(summary['published'], 0)
self.assertIs(summary['enabled'], False)
self.assertEqual(summary['updated_at'], '')
def test_disabled_knowledge_keeps_published_count_and_stays_disabled(self):
self.apply(knowledge={'published':'12', 'enabled':False, 'updated_at':'now'})
self.assertEqual(backend_client.load_settings()['knowledge_summary'], {'published':12,'enabled':False,'updated_at':'now'})
def test_logout_clears_cached_summary_before_next_account(self):
self.apply(knowledge=self.summary)
backend_client._clear_desktop_credentials()
self.assertEqual(backend_client.load_settings()['knowledge_summary'], {})
def test_ui_reads_persisted_count_without_mocking_settings_loader(self):
from wechat_gui_qt import MainWindow
self.apply(knowledge=self.summary)
value=lambda n:SimpleNamespace(value=lambda:n)
text=lambda s:SimpleNamespace(text=lambda:s,toPlainText=lambda:s)
page=SimpleNamespace(tool_switches=[], agent_name=text('测试客服'), persona_prompt=text('测试人设'),
max_tokens=value(512), rounds=value(5), mcp_rounds=value(2),
mcp_json=text('[]'), _reply_length_index=lambda _:1)
host=SimpleNamespace(persona_page=page,_console_model_plan=lambda:{},_console_review_rules=lambda:[])
state=MainWindow._console_ai_state(host)
self.assertEqual(state['knowledgeCount'], '1,234')
self.assertTrue(state['knowledgeConnected'])
if __name__ == '__main__':
unittest.main()