Files
Jyotisha/tests/test_declared_window_chart.py
T
Jesse_Chen 9958e00abc fix(web): keep unrectified birth data usable without inventing a minute
Rectification stays optional. Reported minutes can consult and generate reports; date-plus-period uses a declared window instead of a midpoint or 00:00. Updates BUG-341.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 15:29:58 +08:00

93 lines
2.9 KiB
Python

from __future__ import annotations
import sys
from pathlib import Path
import pytest
SCRIPTS = Path(__file__).resolve().parents[1] / "scripts"
if str(SCRIPTS) not in sys.path:
sys.path.insert(0, str(SCRIPTS))
import domain_calculation_service as calculation_service # noqa: E402
BIRTH_PLACE = {
"year": 1997,
"month": 8,
"day": 8,
"lat": 36.420487,
"lon": 114.209936,
"tz": 8,
"ayanamsa": "lahiri",
}
def test_evening_probes_are_not_the_range_midpoint() -> None:
clocks = calculation_service.declared_window_probe_clocks("18:00", "22:59")
assert clocks[0] == "18:00"
assert clocks[-1] == "22:59"
assert len(clocks) == 4
assert "20:29" not in clocks
assert "20:30" not in clocks
assert "12:00" not in clocks
def test_unknown_day_probes_keep_explicit_clocks_including_midnight() -> None:
clocks = calculation_service.declared_window_probe_clocks("00:00", "23:59")
assert clocks[0] == "00:00"
assert clocks[-1] == "23:59"
assert len(clocks) == 4
def test_window_packet_rejects_a_single_birth_minute() -> None:
with pytest.raises(calculation_service.CalculationError, match="single birth minute"):
calculation_service.compute_declared_window_chart({
**BIRTH_PLACE,
"range_start": "18:00",
"range_end": "22:59",
"hour": 20,
"minute": 30,
})
def test_window_packet_probes_always_pass_hour_and_minute(monkeypatch: pytest.MonkeyPatch) -> None:
seen: list[tuple[int, int]] = []
real = calculation_service.compute_chart
def wrapped(payload: dict) -> dict:
assert "hour" in payload
assert "minute" in payload
seen.append((int(payload["hour"]), int(payload["minute"])))
return real(payload)
monkeypatch.setattr(calculation_service, "compute_chart", wrapped)
packet = calculation_service.compute_declared_window_chart({
**BIRTH_PLACE,
"range_start": "18:00",
"range_end": "22:59",
})
assert packet["probe_count"] == 4
assert seen == [(18, 0), (19, 40), (21, 19), (22, 59)]
assert packet["answer_policy"]["can_answer_precise_timing"] is False
assert packet["answer_policy"]["birth_time_confidence"] == "declared_window"
assert "hour" not in packet
assert "minute" not in packet
assert "birth_time" not in packet
assert packet["stable_layers"]["planet_signs"]["Sun"]
assert len(packet["varying_layers"].get("ascendant_signs", [])) >= 2
def test_api_handler_rejects_hour_on_declared_window() -> None:
from jyotish_api_server import BadRequest, JyotishAPIHandler
handler = JyotishAPIHandler.__new__(JyotishAPIHandler)
with pytest.raises(BadRequest, match="single birth minute"):
handler._compute_declared_window_chart({
**BIRTH_PLACE,
"range_start": "18:00",
"range_end": "22:59",
"hour": 12,
"minute": 0,
})