import json from pathlib import Path from typer.testing import CliRunner from tht.cli import app runner = CliRunner() def _config(path: Path, *, absolute_sessions: Path | None = None) -> Path: sessions = absolute_sessions or Path("sessions") path.write_text( "dwh:\n" " type: postgres_direct\n" " connection:\n" " database: patient_db\n" " schema: private_schema\n" " user: pii_user\n" " password: super-secret\n" "roots:\n" " artifacts: artifacts\n" " indexes: indexes\n" f" sessions: {sessions}\n" ) return path def test_doctor_json_reports_portable_path_statuses_without_secrets(monkeypatch, tmp_path): cfg = _config(tmp_path / "demo.yaml") monkeypatch.setenv("THT_DATA_ROOT", str(tmp_path / "data")) result = runner.invoke(app, ["doctor", "--json", "--config", str(cfg)]) assert result.exit_code == 0 payload = json.loads(result.stdout) assert payload == { "ok": True, "components": { "config": {"status": "ok"}, "data_root": {"status": "ok"}, "workspace_paths": {"status": "ok", "legacy_absolute": []}, }, } assert "super-secret" not in result.stdout assert "patient_db" not in result.stdout assert "pii_user" not in result.stdout assert result.stderr == "" def test_doctor_json_flags_absolute_legacy_paths(monkeypatch, tmp_path): cfg = _config(tmp_path / "demo.yaml", absolute_sessions=tmp_path / "old-sessions") monkeypatch.setenv("THT_DATA_ROOT", str(tmp_path / "data")) result = runner.invoke(app, ["doctor", "--json", "--config", str(cfg)]) assert result.exit_code == 0 payload = json.loads(result.stdout) assert payload["components"]["workspace_paths"] == { "status": "warning", "legacy_absolute": ["sessions"], } assert str(tmp_path) not in result.stdout def test_doctor_json_returns_structured_config_error(monkeypatch, tmp_path): cfg = _config(tmp_path / "demo.yaml") monkeypatch.setenv("THT_DATA_ROOT", str(tmp_path / "data")) cfg.write_text(cfg.read_text().replace("sessions: sessions", "sessions: ../../private")) result = runner.invoke(app, ["doctor", "--json", "--config", str(cfg)]) assert result.exit_code == 1 payload = json.loads(result.stdout) assert payload["ok"] is False assert payload["components"]["workspace_paths"]["status"] == "error" assert "outside workspace root" in payload["components"]["workspace_paths"]["message"] assert result.stderr == "" def test_doctor_json_does_not_echo_invalid_config_values(monkeypatch, tmp_path): cfg = _config(tmp_path / "demo.yaml") monkeypatch.setenv("THT_DATA_ROOT", str(tmp_path / "data")) cfg.write_text(cfg.read_text().replace("database: patient_db", "")) result = runner.invoke(app, ["doctor", "--json", "--config", str(cfg)]) assert result.exit_code == 1 payload = json.loads(result.stdout) assert payload["components"]["config"] == { "status": "error", "message": "configuration is invalid", } assert "super-secret" not in result.stdout assert "pii_user" not in result.stdout