import importlib.util import io import sys import unittest from contextlib import redirect_stdout from pathlib import Path from unittest.mock import patch SCRIPT_PATH = Path(__file__).resolve().parent.parent / "scripts" / "obsidian-wiki-ops.py" def load_user_ops(): spec = importlib.util.spec_from_file_location("obsidian_wiki_user_ops", SCRIPT_PATH) if spec is None or spec.loader is None: raise ImportError(f"cannot import {SCRIPT_PATH}") module = importlib.util.module_from_spec(spec) sys.modules[spec.name] = module spec.loader.exec_module(module) return module class UserOpsTests(unittest.TestCase): def test_kingdee_sync_forwards_to_business_cli(self): user_ops = load_user_ops() with patch.object(user_ops, "obsidian_cli_main", return_value=0) as cli_main: status = user_ops.main(["kingdee", "sync", "--vault", "/data/vault", "--incremental"]) self.assertEqual(status, 0) cli_main.assert_called_once_with( ["business", "sync", "kingdee", "--vault", "/data/vault", "--incremental"] ) def test_timer_install_alias_installs_and_starts_business_timer(self): user_ops = load_user_ops() with patch.object(user_ops.manage_business_sync, "main", return_value=0) as timer_main: status = user_ops.main(["timer", "install", "--vault", "/data/vault"]) self.assertEqual(status, 0) timer_main.assert_called_once_with(["start", "--vault", "/data/vault"]) def test_mcp_commands_forward_to_mcp_service_manager(self): user_ops = load_user_ops() with patch.object(user_ops.manage_mcp_service, "main", return_value=0) as mcp_main: status = user_ops.main(["mcp", "start", "--enable-query"]) self.assertEqual(status, 0) mcp_main.assert_called_once_with(["start", "--enable-query"]) def test_help_lists_common_user_operations(self): user_ops = load_user_ops() output = io.StringIO() with redirect_stdout(output): status = user_ops.main(["help"]) self.assertEqual(status, 0) text = output.getvalue() self.assertIn("kingdee sync", text) self.assertIn("timer install", text) self.assertIn("mcp start", text) if __name__ == "__main__": unittest.main()