"""Produkt składa się z modułów — i węższe złożenie naprawdę działa. Ekrany mieszkają w `app/ekrany/*.py`, moduły opcjonalne w `app/moduly/*`, a `main.py` jest samym złożeniem. Sens tego podziału jest jeden: z tego samego kodu ma dać się zbudować WĘŻSZY produkt, w którym pozostałych ekranów nie ma — nie są wyłączone, tylko ich nie ma. Test buduje takie złożenie naprawdę: kopiuje drzewo, usuwa moduły, uruchamia aplikację w osobnym procesie i sprawdza, co się stało. Robi to w podprocesie, bo importy Pythona są zapamiętywane w procesie — sprawdzanie „aplikacji bez modułu" w tym samym procesie, w którym moduł już się zaimportował, dawałoby wynik fałszywie pozytywny. Czego ten test NIE sprawdza: czy w drzewie nie ma wzmianek o nieobecnych ekranach. To ma sens dopiero wobec KONKRETNEGO produktu (wiadomo wtedy, których ekranów nie ma) i tam jest sprawdzane — patrz zapory słownikowe. """ import json import pathlib import shutil import subprocess import sys import pytest APP = pathlib.Path(__file__).resolve().parents[1] / "app" # Złożenie węższe: same funkcje astrologiczne, bez raportu zbiorczego, # bez administracji, bez generowania i bez wynoszenia treści na zewnątrz. EKRANY_WASKIE = ["horoskop", "interpretacje", "kalendarz", "logowanie", "lokalizacja", "sygnifikatory", "synastria"] USUWANE = ["ekrany/skompiluj.py", "ekrany/ustawienia.py", "ekrany/konta.py", "ekrany/pliki.py", "moduly/dodatki", "moduly/eksport"] SONDA = ''' import json, os, tempfile os.environ.update(ACCOUNTS_FILE=tempfile.mkdtemp()+"/a.json", APP_USER="szef", APP_PASSWORD="t", RATE_LIMIT_PER_MIN="0", SESSION_SECRET="t"*64, COOKIES_INSECURE="1") from starlette.testclient import TestClient from app.main import app from app import security, session, features c = TestClient(app, follow_redirects=False) H = {"Cookie": f"{session.COOKIE}={security.issue_session('szef')}"} wynik = { "ekrany": [f.label for f in features.SCREENS], "rozszerzenia": [f.label for f in features.EXTRAS], "dziala": {a: c.get(a, headers=H).status_code for a in ("/", "/interpret", "/timeline", "/synastry", "/significators")}, "nie_ma": {a: c.get(a, headers=H).status_code for a in ("/compile", "/settings", "/accounts", "/files")}, # Liczymy odsyłacze WEWNĄTRZ paska nawigacji. Zliczanie wszystkich na stronie # łapało też przypis OSM z wyszukiwarki miejsca — czyli test mierzyłby # co innego, niż nazwa mu każe. "nawigacja": (lambda h: h.split("")[0].count('