"""Powiększanie kosmogramu na pełne okno (PRE-25). Test strukturalny, jak przy pozostałych rzeczach żyjących w JS/CSS. Osobno pilnujemy warstwy nakładki: to jedyna liczba w tym pliku, którą łatwo zmienić bez zastanowienia i zepsuć coś, czego się nie widzi na pierwszy rzut oka. """ import pathlib import re APP = pathlib.Path(__file__).resolve().parents[1] / "app" JS = (APP / "static" / "wheelzoom.js").read_text(encoding="utf-8") # Arkusz jest teraz rozbity per uprawnienie (arkusz wspólny + arkusze ekranów), # bo jeden plik ze wszystkimi selektorami był spisem funkcji programu dla # każdego, kto go pobrał. Reguły szukamy w całości — który arkusz ją niesie, # pilnuje osobny test pokrycia. CSS = "\n".join(f.read_text(encoding="utf-8") for f in sorted((APP / "static").glob("*.css"))) BASE = (APP / "templates" / "base.html").read_text(encoding="utf-8") def test_script_is_loaded_only_where_there_is_a_wheel(): """Koło jest na Horoskopie i na Skompiluj — i tylko tam ten skrypt ma prawo się pojawić. Wcześniej ładowany był z base.html, czyli na KAŻDEJ stronie. Konto, które ma wyłącznie Pliki, pobierało go przy zwykłym wejściu na swój jedyny ekran, a jego treść wymienia z nazwy zakładki, o których takie konto nie ma prawa wiedzieć — łącznie z tą, której jeszcze nie ma.""" from pathlib import Path szablony = Path(__file__).resolve().parents[1] / "app" / "templates" z_kolem, bez_kola = set(), set() for f in szablony.glob("*.html"): (z_kolem if "wheelzoom.js" in f.read_text(encoding="utf-8") else bez_kola).add(f.name) assert z_kolem == {"chart.html", "compile.html"}, f"ładowany też przez: {z_kolem}" assert "files.html" in bez_kola and "logowanie.html" in bez_kola def test_toggles_on_click(): assert "addEventListener('click'" in JS assert "classList.toggle" in JS def test_closes_with_escape(): assert "'Escape'" in JS def test_reachable_from_keyboard(): """Bez tego jedyny sposób na obejrzenie szczegółów wykresu wymagałby myszy.""" assert "tabindex" in JS assert "'Enter'" in JS def test_page_scroll_is_locked_while_zoomed(): """Inaczej przewijanie „przecieka" na treść pod spodem, której i tak nie widać.""" assert "wheel-zoom-open" in JS assert re.search(r"body\.wheel-zoom-open\s*\{[^}]*overflow:\s*hidden", CSS) def test_zoomed_layer_sits_above_map_but_below_progress(): """Warstwy: kontrolki Leafleta 1000 < kosmogram < okno postępu 1200. Gdy trwa pisanie horoskopu, log operacji ma zostać na wierzchu.""" zoom = re.search(r"\.wheel-fig\.zoomed\s*\{[^}]*z-index:\s*(\d+)", CSS) progress = re.search(r"\.progress-overlay\s*\{[^}]*z-index:\s*(\d+)", CSS) assert zoom and progress, "nie znaleziono warstw w CSS" assert 1000 < int(zoom.group(1)) < int(progress.group(1)) def test_zoomed_wheel_is_bounded_by_shorter_window_side(): """Koło jest kwadratowe — ograniczamy je krótszym bokiem okna, inaczej na szerokim ekranie wystawałoby w pionie.""" block = re.search(r"\.wheel-fig\.zoomed svg\.wheel\s*\{[^}]*\}", CSS) assert block and "vh" in block.group(0) and "vw" in block.group(0) def test_cursor_signals_the_affordance(): assert "zoom-in" in CSS and "zoom-out" in CSS def test_does_nothing_without_a_wheel(): """Na zakładkach bez kosmogramu skrypt ma po prostu wyjść.""" assert "if (!figures.length) return;" in JS