test_basic.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. from __future__ import annotations
  2. from pathlib import Path
  3. from fastapi.testclient import TestClient
  4. from src.ephemeris_mcp.server import (
  5. _parse_datetime,
  6. create_app,
  7. get_constellation_at_ecliptic,
  8. get_moon_phase,
  9. get_lunar_state,
  10. get_planetary_positions,
  11. get_sidereal_time,
  12. get_solar_events,
  13. list_available_bodies,
  14. )
  15. from src.ephemeris_mcp.storage import EphemerisCache, cache_key
  16. def test_parse_datetime_accepts_iso_zulu() -> None:
  17. jd = _parse_datetime("2026-05-10T12:00:00Z")
  18. assert isinstance(jd, float)
  19. assert 2461170 < jd < 2461172
  20. def test_cache_roundtrip(tmp_path: Path) -> None:
  21. cache = EphemerisCache(tmp_path / "cache.sqlite3")
  22. key = cache_key("demo", lon=8.5, lat=47.3)
  23. assert cache.get(key) is None
  24. cache.set(key, {"ok": True, "value": 42}, ttl=60)
  25. assert cache.get(key) == {"ok": True, "value": 42}
  26. def test_health_endpoint_smoke() -> None:
  27. client = TestClient(create_app())
  28. res = client.get("/health")
  29. assert res.status_code == 200
  30. data = res.json()
  31. assert data == {"ok": True, "server": "ephemeris-mcp", "port": 7015}
  32. def test_root_lists_core_tools() -> None:
  33. client = TestClient(create_app())
  34. res = client.get("/")
  35. assert res.status_code == 200
  36. data = res.json()
  37. assert data["server"] == "ephemeris-mcp"
  38. assert data["status"] == "ready"
  39. assert data["tools"] == [
  40. "get_planetary_positions",
  41. "get_solar_events",
  42. "get_lunar_state",
  43. "get_moon_phase",
  44. "get_sidereal_time",
  45. "get_constellation_at_ecliptic",
  46. "list_available_bodies",
  47. ]
  48. assert data["mcp"] == {"sse": "/mcp/sse", "messages": "/mcp/messages"}
  49. def test_list_available_bodies_shape() -> None:
  50. result = list_available_bodies()
  51. assert "bodies" in result
  52. names = {body["name"] for body in result["bodies"]}
  53. assert "sun" in names
  54. assert "moon" in names
  55. assert "mars" in names
  56. def test_tool_shapes_are_present() -> None:
  57. body_positions = get_planetary_positions(datetime="2026-05-10T12:00:00Z")
  58. solar_events = get_solar_events(date="2026-05-10", lat=47.0, lon=8.0)
  59. lunar_state = get_lunar_state(datetime="2026-05-10T12:00:00Z")
  60. sidereal_time = get_sidereal_time(datetime="2026-05-10T12:00:00Z")
  61. constellation = get_constellation_at_ecliptic(120.0)
  62. assert body_positions["input"]["datetime"] == "2026-05-10T12:00:00Z"
  63. assert "bodies" in body_positions
  64. assert solar_events["input"]["date"] == "2026-05-10"
  65. assert "events_jd" in solar_events
  66. assert "lunar_state" in lunar_state
  67. assert "greenwich_sidereal_time" in sidereal_time
  68. assert constellation["input"]["ecliptic_lon"] == 120.0
  69. def test_moon_phase_tool_shape() -> None:
  70. moon_phase = get_moon_phase(datetime="2026-05-10T12:00:00Z")
  71. assert moon_phase["phase_name"]
  72. assert 0.0 <= moon_phase["illumination_fraction"] <= 1.0
  73. assert moon_phase["input"]["datetime"] == "2026-05-10T12:00:00Z"
  74. assert moon_phase["phase_name"] == "Last Quarter"
  75. assert moon_phase["next_major_phase"]["phase_name"] in {"New Moon", "First Quarter", "Full Moon", "Last Quarter"}
  76. assert "at_utc" in moon_phase["next_major_phase"]
  77. assert moon_phase["next_major_phase"]["in_text"]
  78. assert "d" in moon_phase["next_major_phase"]["in_text"] or "h" in moon_phase["next_major_phase"]["in_text"] or "m" in moon_phase["next_major_phase"]["in_text"]
  79. def test_default_location_can_be_configured(monkeypatch) -> None:
  80. monkeypatch.setenv("EPHEMERIS_DEFAULT_LAT", "48.2")
  81. monkeypatch.setenv("EPHEMERIS_DEFAULT_LON", "16.37")
  82. from importlib import reload
  83. import src.ephemeris_mcp.config as config
  84. import src.ephemeris_mcp.server as server
  85. reload(config)
  86. server = reload(server)
  87. result = server.get_moon_phase(datetime="2026-05-10T12:00:00Z")
  88. assert result["input"]["lat"] == 48.2
  89. assert result["input"]["lon"] == 16.37