Add scripts/obsidian-wiki-ops.py as the repo-local command surface for common wiki, Kingdee, timer, daily update, and MCP operations. Route the existing business and MCP shell wrappers through the unified entrypoint for compatibility, and update docs to recommend the single command path. Validation: python3 -m unittest discover -v; python3 -m compileall obsidian_wiki tests scripts; git diff --check.
93 lines
3.8 KiB
Python
93 lines
3.8 KiB
Python
import os
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import call, patch
|
|
|
|
|
|
SCRIPTS_DIR = Path(__file__).resolve().parent.parent / "scripts"
|
|
if str(SCRIPTS_DIR) not in sys.path:
|
|
sys.path.insert(0, str(SCRIPTS_DIR))
|
|
|
|
import manage_business_sync
|
|
|
|
|
|
class BusinessSyncServiceTests(unittest.TestCase):
|
|
def test_shell_entrypoint_delegates_to_unified_user_ops_entrypoint(self):
|
|
entrypoint = SCRIPTS_DIR / "business_sync_service.sh"
|
|
|
|
self.assertTrue(entrypoint.is_file())
|
|
self.assertTrue(os.access(entrypoint, os.X_OK))
|
|
content = entrypoint.read_text(encoding="utf-8")
|
|
self.assertIn('exec python3 "$SCRIPT_DIR/obsidian-wiki-ops.py" timer "$@"', content)
|
|
|
|
def test_render_service_and_timer_units_for_incremental_sync(self):
|
|
service = manage_business_sync.render_service_unit(
|
|
project_root=Path("/opt/obsidian-wiki"),
|
|
vault_path=Path("/data/bjd-vault"),
|
|
config_path=Path("/opt/obsidian-wiki/.runtime/kingdee.env"),
|
|
python_path=Path("/usr/bin/python3"),
|
|
lookback_hours=48,
|
|
initial_days=7,
|
|
)
|
|
timer = manage_business_sync.render_timer_unit(
|
|
on_calendar="*-*-* 07:10:00",
|
|
randomized_delay_sec="15m",
|
|
)
|
|
|
|
self.assertIn("WorkingDirectory=/opt/obsidian-wiki", service)
|
|
self.assertIn("EnvironmentFile=/opt/obsidian-wiki/.runtime/kingdee.env", service)
|
|
self.assertIn("/usr/bin/python3 -m obsidian_wiki business sync kingdee", service)
|
|
self.assertIn("--vault /data/bjd-vault", service)
|
|
self.assertIn("--config /opt/obsidian-wiki/.runtime/kingdee.env", service)
|
|
self.assertIn("--incremental", service)
|
|
self.assertIn("--lookback-hours 48", service)
|
|
self.assertIn("--initial-days 7", service)
|
|
self.assertNotIn("KINGDEE_CLIENT_SECRET=", service)
|
|
self.assertNotIn("KINGDEE_ACCESS_TOKEN=", service)
|
|
self.assertIn("OnCalendar=*-*-* 07:10:00", timer)
|
|
self.assertIn("Persistent=true", timer)
|
|
self.assertIn("RandomizedDelaySec=15m", timer)
|
|
|
|
def test_start_timer_writes_units_and_enables_timer(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
project_root = Path(tmp) / "project"
|
|
vault = Path(tmp) / "vault"
|
|
config_home = Path(tmp) / "config"
|
|
project_root.mkdir()
|
|
vault.mkdir()
|
|
(project_root / ".runtime").mkdir()
|
|
(project_root / ".runtime" / "kingdee.env").write_text("KINGDEE_ACGW_IDENTITY=test\n", encoding="utf-8")
|
|
|
|
with (
|
|
patch.dict("os.environ", {"XDG_CONFIG_HOME": str(config_home)}),
|
|
patch.object(manage_business_sync, "run_systemctl") as run_systemctl,
|
|
):
|
|
output = manage_business_sync.start_timer(
|
|
project_root=project_root,
|
|
vault_path=vault,
|
|
python_path=Path("/usr/bin/python3"),
|
|
)
|
|
|
|
paths = manage_business_sync.resolve_service_paths(project_root, config_home=config_home)
|
|
self.assertTrue(paths.service_unit_path.is_file())
|
|
self.assertTrue(paths.timer_unit_path.is_file())
|
|
self.assertIn("Business sync timer is enabled.", output)
|
|
run_systemctl.assert_has_calls(
|
|
[
|
|
call(["daemon-reload"]),
|
|
call(["enable", "--now", manage_business_sync.TIMER_NAME]),
|
|
]
|
|
)
|
|
|
|
def test_run_now_starts_service_unit(self):
|
|
with patch.object(manage_business_sync, "run_systemctl") as run_systemctl:
|
|
manage_business_sync.run_now()
|
|
|
|
run_systemctl.assert_called_once_with(["start", manage_business_sync.SERVICE_NAME])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|