smriti/cli/tests/test_doctor_cli.py
2026-05-17 00:26:03 +05:30

207 lines
6.4 KiB
Python

from __future__ import annotations
import argparse
from unittest.mock import MagicMock
import pytest
from smriti_cli import main as cli_main
from smriti_cli.client import SmritiClient, SmritiError
def _client(health: dict | None = None) -> MagicMock:
client = MagicMock(spec=SmritiClient)
client.base_url = "http://localhost:8000"
if health is not None:
client.get_health.return_value = health
return client
def _patch_git(monkeypatch: pytest.MonkeyPatch, *, sha: str = "c470947abcdef", branch: str = "main") -> None:
short = sha[:7]
values = {
("rev-parse", "HEAD"): sha,
("rev-parse", "--short", "HEAD"): short,
("branch", "--show-current"): branch,
("rev-parse", "--abbrev-ref", "HEAD"): branch,
}
monkeypatch.setattr(cli_main, "_git_output", lambda *args: values.get(args))
def _patch_cli(
monkeypatch: pytest.MonkeyPatch,
*,
executable: str = "/repo/backend/.venv/bin/smriti",
path_entry: str = "/repo/backend/.venv/bin/smriti",
version: str = "0.1.0",
) -> None:
monkeypatch.setattr(
cli_main,
"_build_cli_info",
lambda: {
"executable": executable,
"path_entry": path_entry,
"path_matches_executable": executable == path_entry,
"package_version": version,
},
)
def _health(**overrides) -> dict:
base = {
"status": "ok",
"git_sha": "c470947",
"capabilities": sorted(cli_main.EXPECTED_HEALTH_CAPABILITIES),
"database": {
"mode": "local",
"url_scheme": "sqlite",
"local_db_path": "/Users/test/.smriti/smriti.db",
},
"providers": {
"background_intelligence": {
"provider": "openai",
"model": "gpt-4o-mini",
"configured": True,
}
},
}
base.update(overrides)
return base
def test_doctor_parser_wiring():
parser = cli_main._build_parser()
args = parser.parse_args(["doctor"])
assert args.command == "doctor"
assert args.func is cli_main.cmd_doctor
def test_doctor_report_ok(monkeypatch: pytest.MonkeyPatch):
_patch_git(monkeypatch)
_patch_cli(monkeypatch)
client = _client(_health())
report = cli_main._build_doctor_report(client)
assert report["backend"]["reachable"] is True
assert report["backend"]["git_sha"] == "c470947"
assert report["backend"]["database"]["mode"] == "local"
assert report["backend"]["providers"]["background_intelligence"]["configured"] is True
assert report["local"]["git_sha_short"] == "c470947"
assert report["cli"]["path_matches_executable"] is True
assert report["checks"]["runtime_match"] == "ok"
assert report["checks"]["missing_capabilities"] == []
assert report["checks"]["cli_path"] == "ok"
assert report["checks"]["background_provider"] == "ready"
assert report["hints"] == []
def test_doctor_report_flags_mismatch_and_missing_capability(
monkeypatch: pytest.MonkeyPatch,
):
_patch_git(monkeypatch, sha="c470947abcdef")
_patch_cli(monkeypatch)
capabilities = sorted(cli_main.EXPECTED_HEALTH_CAPABILITIES - {"worktree_binding"})
client = _client(_health(git_sha="deadbee", capabilities=capabilities))
report = cli_main._build_doctor_report(client)
assert report["checks"]["runtime_match"] == "mismatch"
assert report["checks"]["missing_capabilities"] == ["worktree_binding"]
assert any("differs from local HEAD" in hint for hint in report["hints"])
assert any("missing capabilities" in hint for hint in report["hints"])
def test_doctor_report_flags_cli_path_mismatch(monkeypatch: pytest.MonkeyPatch):
_patch_git(monkeypatch)
_patch_cli(
monkeypatch,
executable="/repo/backend/.venv/bin/smriti",
path_entry="/Users/test/.local/bin/smriti",
)
client = _client(_health())
report = cli_main._build_doctor_report(client)
assert report["checks"]["cli_path"] == "mismatch"
assert any("PATH differs" in hint for hint in report["hints"])
def test_doctor_report_flags_background_mock_risk(monkeypatch: pytest.MonkeyPatch):
_patch_git(monkeypatch)
_patch_cli(monkeypatch)
client = _client(
_health(
providers={
"background_intelligence": {
"provider": "openai",
"model": "gpt-4o-mini",
"configured": False,
}
}
)
)
report = cli_main._build_doctor_report(client)
assert report["checks"]["background_provider"] == "mock_or_disabled"
assert any("not configured" in hint for hint in report["hints"])
def test_cmd_doctor_handles_unreachable_backend(
monkeypatch: pytest.MonkeyPatch,
capsys: pytest.CaptureFixture[str],
):
_patch_git(monkeypatch)
_patch_cli(monkeypatch)
client = _client()
client.get_health.side_effect = SmritiError("Could not reach Smriti")
args = argparse.Namespace(json=False)
cli_main.cmd_doctor(client, args)
out = capsys.readouterr().out
assert "# Smriti Doctor" in out
assert "Backend: unreachable" in out
assert "missing capabilities: unknown" in out
assert "make dev-local" in out
assert "Backend is not reachable" in out
def test_cmd_doctor_json_outputs_report(monkeypatch: pytest.MonkeyPatch):
_patch_git(monkeypatch)
_patch_cli(monkeypatch)
client = _client(_health())
args = argparse.Namespace(json=True)
captured: list[dict] = []
original = cli_main._print_json
cli_main._print_json = captured.append
try:
cli_main.cmd_doctor(client, args)
finally:
cli_main._print_json = original
assert captured[0]["backend"]["reachable"] is True
assert captured[0]["checks"]["runtime_match"] == "ok"
def test_cmd_doctor_prints_activation_details(
monkeypatch: pytest.MonkeyPatch,
capsys: pytest.CaptureFixture[str],
):
_patch_git(monkeypatch)
_patch_cli(monkeypatch)
client = _client(_health())
args = argparse.Namespace(json=False)
cli_main.cmd_doctor(client, args)
out = capsys.readouterr().out
assert "## Runtime" in out
assert "Database mode: `local`" in out
assert "Local DB path: `/Users/test/.smriti/smriti.db`" in out
assert "Background intelligence: ready (`openai` / `gpt-4o-mini`)" in out
assert "## CLI" in out
assert "PATH matches executable: yes" in out