Files
astrololo/services/presentation/tests/test_aspect_settings.py
gitea 7b435d4263
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m32s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 11s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 9s
build / build (push) Successful in 25s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m18s
Testy / Kontrola składni wszystkich warstw (push) Successful in 31s
Testy / Build obrazu silnika B (swisseph) (push) Failing after 13m6s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Failing after 13m25s
feat: synastria — aspekty między dwoma horoskopami (PRE-04)
Pierwsza technika relacyjna z pełnym UI (Returns były już w kalendarzu od LOG-12).
Dwie osoby → aspekty MIĘDZY ich horoskopami (planeta osoby A do planety osoby B).

Silnik: `find_cross_aspects(a, b, orb, luminary_bonus, minor)` — każdy obiekt A ×
każdy obiekt B. `obj1` = osoba A, `obj2` = osoba B. Statyczne (dwa natale, brak
wspólnego czasu) → bez applying/separating. Par sztywnych (NN/SN) NIE wycinamy —
między dwiema osobami to realny aspekt, nie artefakt definicji. Wspólny matcher
`_first_aspect` (z find_aspects), więc orb/bonus/aspekty poboczne działają tak samo.

Endpoint `POST /chart/synastry` (dwie osoby + zodiak + ustawienia aspektów) →
pozycje obu + siatka aspektów z glifami. Prezentacja: zakładka „Synastria",
formularz dwóch osób (pętla po a_/b_), tabela aspektów A · aspekt · B · orb.

Weryfikacja na żywym API: 13+13 obiektów, 63 aspekty synastryczne z poprawnymi
glifami i bonusem świateł (A.Sun ☌ B.Venus przy orbie 8.67 = 8+2). Testy: logika
+4 (cross-aspekty, kolejność A/B, brak filtra par sztywnych, brak applying),
prezentacja +7 (trasa, formularz dwóch osób, klient, tabela). Logika 277,
prezentacja 228.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 20:55:49 +02:00

54 lines
2.2 KiB
Python

"""Konfigurowalne aspekty i orby w UI (PRE-06).
Ustawienia muszą: (1) być na obu formularzach (Horoskop i Skompiluj), (2) wędrować
między zakładkami (formsync), (3) trafiać do logiki na ekran i do PDF-a — inaczej
podsumowanie liczyłoby aspekty innym orbem niż horoskop (ta sama klasa błędu co
regresja podsumowania).
"""
import pathlib
APP = pathlib.Path(__file__).resolve().parents[1] / "app"
CHART = (APP / "templates" / "chart.html").read_text(encoding="utf-8")
COMPILE = (APP / "templates" / "compile.html").read_text(encoding="utf-8")
OPTS = (APP / "templates" / "_form_options.html").read_text(encoding="utf-8") # wspólne opcje obu formularzy
MAIN = (APP / "main.py").read_text(encoding="utf-8")
CLIENT = (APP / "clients" / "logic_client.py").read_text(encoding="utf-8")
SYNC = (APP / "static" / "formsync.js").read_text(encoding="utf-8")
COMPILE_JS = (APP / "static" / "compile.js").read_text(encoding="utf-8")
FIELDS = ("aspect_orb", "aspect_luminary_bonus", "aspect_minor")
def test_both_forms_have_aspect_settings():
"""Pola są we WSPÓLNYM pliku opcji, który oba formularze dołączają."""
for f in FIELDS:
assert f'name="{f}"' in OPTS, f"brak {f} we wspólnym pliku opcji"
assert '{% include "_form_options.html" %}' in CHART
assert '{% include "_form_options.html" %}' in COMPILE
def test_handlers_accept_and_pass_aspect_settings():
# co najmniej Horoskop i Skompiluj przekazują orb do logiki (synastria też — 3)
assert MAIN.count("aspect_orb=aspect_orb") >= 2
assert "aspect_minor: bool = Form(False)" in MAIN
def test_client_forwards_aspect_settings():
for f in FIELDS:
assert f'"{f}": {f}' in CLIENT, f"klient nie przekazuje {f}"
def test_settings_are_synced_between_tabs():
for f in FIELDS:
assert f"'{f}'" in SYNC, f"formsync nie synchronizuje {f}"
def test_pdf_payload_includes_aspect_settings():
assert "aspect_orb: v('aspect_orb')" in COMPILE_JS
assert "aspect_minor: checked('aspect_minor')" in COMPILE_JS
def test_pdf_handler_reads_aspect_settings():
assert 'aspect_orb=float(data.get("aspect_orb")' in MAIN
assert 'aspect_minor=bool(data.get("aspect_minor"))' in MAIN