"""Poprawki zgłoszone przez partnerów: offset względem GMT i lokalizacja po kliknięciu „Tu i teraz" (PRE-19, PRE-20). JS-a tu nie uruchomimy, więc pilnujemy tego strukturalnie — tak samo jak niezmienników klienta HTTP. Obie regresje są ciche (nic się nie wywala, tylko formularz pokazuje nieprawdę), więc test na źródle jest tu wart więcej niż zwykle. """ import pathlib import pytest APP = pathlib.Path(__file__).resolve().parents[1] / "app" TEMPLATES = APP / "templates" GEO_JS = APP / "static" / "geo.js" WITH_OFFSET = ("chart.html", "interpret.html", "timeline.html") # ───────────────────────────── PRE-19: offset względem GMT ─────────────── @pytest.mark.parametrize("name", WITH_OFFSET) def test_offset_label_says_relative_to_gmt(name): """Etykieta musi mówić, WZGLĘDEM CZEGO liczymy przesunięcie.""" html = (TEMPLATES / name).read_text(encoding="utf-8") assert "Offset względem GMT" in html, f"{name}: etykieta nie mówi o GMT" @pytest.mark.parametrize("name", WITH_OFFSET) def test_offset_step_is_quarter_hour(name): """Krok 15 minut = 0,25 h. Strefy pół- i ćwierćgodzinne (Indie +5:30, Nepal +5:45) są realne — przy kroku 1 h nie dało się ich ustawić.""" html = (TEMPLATES / name).read_text(encoding="utf-8") assert 'name="tz_offset" step="0.25"' in html, f"{name}: krok inny niż 15 minut" @pytest.mark.parametrize("name", WITH_OFFSET) def test_offset_range_covers_real_zones(name): html = (TEMPLATES / name).read_text(encoding="utf-8") assert 'min="-12"' in html and 'max="14"' in html, f"{name}: brak sensownego zakresu stref" # ──────────────────── PRE-20: „Tu i teraz" odświeża nazwę miejsca ──────── def _geo_source() -> str: return GEO_JS.read_text(encoding="utf-8") def _handler_body() -> str: """Ciało handlera zdarzenia astrololo:coords (wysyłanego przez „Tu i teraz"). Szukamy KONKRETNIE `addEventListener`, nie samej nazwy zdarzenia — ta pada także w komentarzu nagłówkowym pliku i wtedy wycięlibyśmy komentarz zamiast kodu (test przechodziłby albo padał z niewłaściwego powodu). """ src = _geo_source() start = src.index("addEventListener('astrololo:coords'") end = src.index("});", start) return src[start:end] def test_now_button_handler_refreshes_place_name(): """REGRESJA: po „Tu i teraz" pineska i współrzędne skakały na nowe miejsce, a w polu tekstowym zostawała stara nazwa — formularz pokazywał jedno miejsce, a liczył dla innego.""" assert "reverseName(" in _handler_body(), ( "handler astrololo:coords nie odświeża nazwy miejsca (reverseName)" ) def test_reverse_name_clears_field_before_lookup(): """Nazwa jest czyszczona ZANIM przyjdzie odpowiedź. Gdyby /reverse nie odpowiedziało (brak sieci), zostałaby stara nazwa — czyli pole kłamałoby o lokalizacji. Lepiej puste pole niż nieprawdziwe.""" src = _geo_source() start = src.index("function reverseName") body = src[start:src.index("\n }", start)] clear_at = body.find("searchEl.value = ''") fetch_at = body.find("fetch(") assert clear_at != -1, "reverseName nie czyści pola nazwy" assert clear_at < fetch_at, "pole czyszczone dopiero po zapytaniu — stara nazwa zdąży zostać" def test_now_button_still_syncs_map(): """Odświeżenie nazwy nie może zastąpić przesunięcia pineski i widoku mapy.""" body = _handler_body() assert "marker.setLatLng" in body and "map.setView" in body