"""Testy mostu obliczenia → sygnifikatory → wyszukiwanie (bez efemeryd/HTTP).""" from app.engine.models import DEFAULT_OBJECTS, ObjectPosition from app.significators import PLANET_ABBR, build_report class FakeData: def __init__(self, rows_by_value: dict) -> None: self.rows_by_value = rows_by_value def search(self, key, value, exact, limit, fields=None) -> dict: rows = self.rows_by_value.get(value, []) return {"provider": "fake", "total": len(rows), "rows": rows} def test_build_report_filters_to_sign_and_drops_noise(): positions = [ObjectPosition("Sun", 40.0, 0.0, 0.95, False)] # Taurus 10° -> [Su + [Tau data = FakeData({"[Su": [ {"significator": "[Su in [Tau", "actioneffect": "efekt A"}, # trafienie {"significator": "[Su in [Vir", "actioneffect": "inny znak"}, # zły znak {"significator": "[Su in [Tau", "actioneffect": "nan"}, # szum (pusty efekt) {"significator": "SIGNIFICATOR nagłówek", "actioneffect": "x"}, # szum (nagłówek) ]}) item = build_report(positions, data, per_object_limit=100)["objects"][0] assert item["object"] == "Sun" and item["sign"] == "Taurus" assert item["planet_token"] == "[Su" and item["sign_token"] == "[Tau" assert item["planet_total"] == 4 assert item["in_sign_count"] == 1 assert item["samples"][0]["effect"] == "efekt A" def test_effect_falls_back_to_topic_or_bodypart(): positions = [ObjectPosition("Mars", 220.0, 0.0, -0.2, True)] # Scorpio -> [Ma + [Sco data = FakeData({"[Ma": [ {"significator": "[Ma in [Sco", "actioneffect": "", "topicresult": "temat X"}, {"significator": "[Ma in [Sco", "bodypart": "część ciała"}, ]}) samples = build_report(positions, data)["objects"][0]["samples"] assert samples[0]["effect"] == "temat X" assert samples[1]["effect"] == "część ciała" def test_planet_abbr_covers_all_default_objects(): for o in DEFAULT_OBJECTS: assert o in PLANET_ABBR