| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- from __future__ import annotations
- from pathlib import Path
- from fastapi.testclient import TestClient
- from src.ephemeris_mcp.server import (
- _parse_datetime,
- create_app,
- get_constellation_at_ecliptic,
- get_moon_phase,
- get_lunar_state,
- get_planetary_positions,
- get_sidereal_time,
- get_solar_events,
- list_available_bodies,
- )
- from src.ephemeris_mcp.storage import EphemerisCache, cache_key
- def test_parse_datetime_accepts_iso_zulu() -> None:
- jd = _parse_datetime("2026-05-10T12:00:00Z")
- assert isinstance(jd, float)
- assert 2461170 < jd < 2461172
- def test_cache_roundtrip(tmp_path: Path) -> None:
- cache = EphemerisCache(tmp_path / "cache.sqlite3")
- key = cache_key("demo", lon=8.5, lat=47.3)
- assert cache.get(key) is None
- cache.set(key, {"ok": True, "value": 42}, ttl=60)
- assert cache.get(key) == {"ok": True, "value": 42}
- def test_health_endpoint_smoke() -> None:
- client = TestClient(create_app())
- res = client.get("/health")
- assert res.status_code == 200
- data = res.json()
- assert data == {"ok": True, "server": "ephemeris-mcp", "port": 7015}
- def test_root_lists_core_tools() -> None:
- client = TestClient(create_app())
- res = client.get("/")
- assert res.status_code == 200
- data = res.json()
- assert data["server"] == "ephemeris-mcp"
- assert data["status"] == "ready"
- assert data["tools"] == [
- "get_planetary_positions",
- "get_solar_events",
- "get_lunar_state",
- "get_moon_phase",
- "get_sidereal_time",
- "get_constellation_at_ecliptic",
- "list_available_bodies",
- ]
- assert data["mcp"] == {"sse": "/mcp/sse", "messages": "/mcp/messages"}
- def test_list_available_bodies_shape() -> None:
- result = list_available_bodies()
- assert "bodies" in result
- names = {body["name"] for body in result["bodies"]}
- assert "sun" in names
- assert "moon" in names
- assert "mars" in names
- def test_tool_shapes_are_present() -> None:
- body_positions = get_planetary_positions(datetime="2026-05-10T12:00:00Z")
- solar_events = get_solar_events(date="2026-05-10", lat=47.0, lon=8.0)
- lunar_state = get_lunar_state(datetime="2026-05-10T12:00:00Z")
- sidereal_time = get_sidereal_time(datetime="2026-05-10T12:00:00Z")
- constellation = get_constellation_at_ecliptic(120.0)
- assert body_positions["input"]["datetime"] == "2026-05-10T12:00:00Z"
- assert "bodies" in body_positions
- assert solar_events["input"]["date"] == "2026-05-10"
- assert "events_jd" in solar_events
- assert "lunar_state" in lunar_state
- assert "greenwich_sidereal_time" in sidereal_time
- assert constellation["input"]["ecliptic_lon"] == 120.0
- def test_moon_phase_tool_shape() -> None:
- moon_phase = get_moon_phase(datetime="2026-05-10T12:00:00Z")
- assert moon_phase["phase_name"]
- assert 0.0 <= moon_phase["illumination_fraction"] <= 1.0
- assert moon_phase["input"]["datetime"] == "2026-05-10T12:00:00Z"
- assert moon_phase["phase_name"] == "Last Quarter"
- assert moon_phase["next_major_phase"]["phase_name"] in {"New Moon", "First Quarter", "Full Moon", "Last Quarter"}
- assert "at_utc" in moon_phase["next_major_phase"]
- assert moon_phase["next_major_phase"]["in_text"]
- 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"]
- def test_default_location_can_be_configured(monkeypatch) -> None:
- monkeypatch.setenv("EPHEMERIS_DEFAULT_LAT", "48.2")
- monkeypatch.setenv("EPHEMERIS_DEFAULT_LON", "16.37")
- from importlib import reload
- import src.ephemeris_mcp.config as config
- import src.ephemeris_mcp.server as server
- reload(config)
- server = reload(server)
- result = server.get_moon_phase(datetime="2026-05-10T12:00:00Z")
- assert result["input"]["lat"] == 48.2
- assert result["input"]["lon"] == 16.37
|