test_s3_hermes_call.py 2.92 KB
#!/usr/bin/env python3
"""Test S3: call_hermes() function in app.py."""
import sys, os, unittest
from unittest.mock import patch, MagicMock

# Add wechat-viewer to path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.expanduser("~/wechat-viewer"))

class TestCallHermes(unittest.TestCase):
    """Test the call_hermes() function."""

    def test_call_hermes_exists(self):
        """call_hermes() should exist as a callable function in app module."""
        import app
        self.assertTrue(hasattr(app, 'call_hermes'), "app module must have call_hermes function")
        self.assertTrue(callable(app.call_hermes), "call_hermes must be callable")

    @patch('app.subprocess.run')
    def test_call_hermes_returns_stdout(self, mock_run):
        """call_hermes should return stdout from hermes chat."""
        mock_run.return_value = MagicMock(stdout="AI reply text\n", stderr="", returncode=0)
        import app
        result = app.call_hermes("Hello")
        self.assertIn("AI reply text", result)
        mock_run.assert_called_once()

    @patch('app.subprocess.run')
    def test_call_hermes_passes_user_input(self, mock_run):
        """call_hermes should pass user input to hermes chat -m."""
        mock_run.return_value = MagicMock(stdout="OK", stderr="", returncode=0)
        import app
        app.call_hermes("What is Python?")
        args = mock_run.call_args[0][0]
        self.assertIn("-m", args)
        self.assertIn("What is Python?", args)

    @patch('app.subprocess.run')
    def test_call_hermes_timeout_error(self, mock_run):
        """call_hermes should return error string on timeout."""
        import subprocess as sp
        import app
        # Force module reload to get fresh patches
        mock_run.side_effect = sp.TimeoutExpired(cmd=["hermes"], timeout=1)
        result = app.call_hermes("test")
        self.assertIn("超时", result, f"Expected timeout message, got: {result}")

    @patch('app.subprocess.run')
    def test_call_hermes_file_not_found(self, mock_run):
        """call_hermes should return error string when hermes not found."""
        import app
        mock_run.side_effect = FileNotFoundError("hermes not found")
        result = app.call_hermes("test")
        self.assertIn("未找到", result, f"Expected not found message, got: {result}")


if __name__ == '__main__':
    # Don't actually import app (it does db init etc) — just check if function exists
    try:
        app_path = os.path.expanduser("~/wechat-viewer/app.py")
        code = open(app_path).read()
        if 'def call_hermes' in code:
            print("FOUND: call_hermes function defined in app.py")
            # Run the actual tests
            unittest.main(verbosity=2)
        else:
            print("RED: call_hermes function NOT FOUND in app.py — test fails as expected")
            sys.exit(1)
    except Exception as e:
        print(f"RED: Error checking app.py: {e}")
        sys.exit(1)