Files

209 lines
10 KiB
Python
Raw Permalink Normal View History

2026-09-08 08:28:11 +02:00
# -*- coding: utf-8 -*-
"""Seitenleiste headless pruefen: Zustaende, Filter, Rueckrufe — und als PNG rendern.
Aufruf (macOS, QGIS 4.2 im Bundle; VLN_TOKEN = API-Key aus dem Login):
APP=/Applications/QGIS-final-4_2_0.app; LIB="$APP/Contents/Resources/python3.12"
QT_QPA_PLATFORM=offscreen PROJ_DATA="$APP/Contents/Resources/qgis/proj" \
PYTHONPATH="$LIB:$LIB/lib-dynload:$LIB/site-packages" \
"$APP/Contents/MacOS/python3.12" tools/headless_panel_test.py /tmp/panel.png
Holt die echte Verfahrensliste (GET /tgen) und prueft Zustaende, Filter und Rueckrufe der
Seitenleiste; das PNG zeigt das Layout ohne QGIS-Fenster.
"""
import os, sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from qgis.core import QgsApplication
app = QgsApplication([], True)
QgsApplication.setPrefixPath("/Applications/QGIS-final-4_2_0.app/Contents/MacOS", True)
QgsApplication.setPluginPath("/Applications/QGIS-final-4_2_0.app/Contents/PlugIns/qgis")
app.initQgis()
from qgis.PyQt.QtNetwork import QNetworkProxyFactory
QNetworkProxyFactory.setUseSystemConfiguration(False)
from qgis.PyQt.QtCore import QSize, Qt
from qgis.PyQt.QtWidgets import QScrollArea
2026-09-08 08:28:11 +02:00
from vln_karten.panel import VlnPanel
from vln_karten.api_client import KartenApiClient
ZIEL = sys.argv[1]
FEHLER, GERUFEN = [], []
def pruefe(bed, text):
print((" OK " if bed else " FEHL ") + text)
if not bed:
FEHLER.append(text)
rueckrufe = {name: (lambda *a, n=name: GERUFEN.append((n, a)))
for name in ("login", "logout", "verfahren_gewaehlt", "load_ogc",
"save_edits", "save_style")}
panel = VlnPanel(None, callbacks=rueckrufe)
2026-09-08 08:28:11 +02:00
print("== abgemeldet ==")
pruefe(panel.login_knopf.isVisible() or not panel.logout_knopf.isVisibleTo(panel),
"Anmelde-Knopf sichtbar, Abmelden verborgen")
pruefe(not panel.ogc_knopf.isEnabled() and not panel.combo.isEnabled()
and not panel.speichern_knopf.isEnabled(), "Knoepfe und Auswahl gesperrt")
2026-09-08 08:28:11 +02:00
print("== Issue #1: Rollbalken statt Fensterueberlauf ==")
# Ein QDockWidget reicht die Mindesthoehe seines Inhalts ans Hauptfenster weiter. Ohne
# Rollflaeche wuchs QGIS mit der Seitenleiste und schob seinen unteren Rand aus dem
# Bildschirm (Daniel Helbig, LK Meissen, 14.09.2026).
rolle = panel.widget()
pruefe(isinstance(rolle, QScrollArea), "Inhalt sitzt in einer Rollflaeche")
pruefe(rolle.widgetResizable(), "Inhalt folgt der Breite")
KLEIN = 400
panel.resize(320, KLEIN)
rolle.resize(320, KLEIN)
rolle.widget().adjustSize()
inhalt_hoehe = rolle.widget().sizeHint().height()
pruefe(0 < panel.minimumSizeHint().height() <= KLEIN,
"Dock verlangt hoechstens %d px, aber nicht null (verlangt %d, Inhalt will %d)"
% (KLEIN, panel.minimumSizeHint().height(), inhalt_hoehe))
pruefe(inhalt_hoehe > KLEIN, "Der Testfall greift: der Inhalt ist hoeher als das Dock")
pruefe(rolle.verticalScrollBar().maximum() > 0, "senkrechter Rollbalken wird gebraucht")
pruefe(rolle.horizontalScrollBarPolicy() == Qt.ScrollBarPolicy.ScrollBarAlwaysOff,
"kein waagerechter Rollbalken")
pruefe(rolle.minimumWidth() >= 260, "Mindestbreite bleibt lesbar: %d px" % rolle.minimumWidth())
print("== 0.7.0: Landkreise und „nur lesen“ in der Auswahl, Untergruppe in der Dienstliste ==")
from vln_karten.panel import ist_landkreis
panel.set_angemeldet(True, "pruef@example.org")
panel.set_verfahren([{"vkz": "27027", "name": "TG A", "zugriff": "voll"},
{"vkz": "31005", "name": "TG B", "zugriff": "lesen"}],
[{"vkz": "27", "name": "Landkreis Meißen"}])
texte = [panel.combo.itemText(i) for i in range(panel.combo.count())]
pruefe(texte[1:2] == ["Landkreis Meißen — Linkliste des Landkreises"],
"Landkreis steht oben: %r" % texte[1:2])
pruefe("31005 — TG B (nur lesen)" in texte and "27027 — TG A" in texte,
"Verfahren „nur lesen“ gekennzeichnet: %r" % texte)
pruefe(ist_landkreis("27") and ist_landkreis(100) and not ist_landkreis("27027")
and not ist_landkreis(None) and not ist_landkreis("x"), "ist_landkreis")
panel.set_dienste([{"name": "Denkmal Punkte", "gruppe_name": "Kultur", "untergruppe": "Denkmal",
"herkunft_text": "Landkreis"},
{"name": "Wald", "gruppe_name": "Natur", "herkunft_text": "landesweit"}])
pruefe(panel.dienste_liste.item(0).text().startswith("Denkmal Punkte · Kultur › Denkmal · "),
"Untergruppe in der Dienstliste: %r" % panel.dienste_liste.item(0).text())
pruefe(panel.dienste_liste.item(1).text().startswith("Wald · Natur · "), "ohne Untergruppe wie bisher")
print("== Karten: Wahl hakt vor ==")
from vln_karten.linkliste import KARTEN_VORGABE
panel.set_karten(KARTEN_VORGABE)
pruefe(list(panel.karten_haken) == ["p41", "ngg", "we"] and panel.karten_beschriftung.isVisibleTo(panel),
"je Karte ein Haekchen")
panel.set_dienste([{"name": "Biotope", "gruppe_name": "Natur", "karten": ["ngg"]},
{"name": "Wege", "gruppe_name": "Verkehr", "karten": ["p41", "ngg"]},
{"name": "Bodenwert", "gruppe_name": "Boden", "karten": ["we"]}])
an = lambda: [panel.dienste_liste.item(i).checkState() == Qt.CheckState.Checked
for i in range(panel.dienste_liste.count())]
pruefe(an() == [True, True, True], "ohne Wahl alles angehakt")
panel.karten_haken["p41"].setChecked(True)
pruefe(an() == [False, True, False], "Wege- und Gewaesserplan: nur passende: %r" % an())
panel.karten_haken["we"].setChecked(True)
pruefe(an() == [False, True, True], "zwei Karten zugleich: %r" % an())
panel.set_dienste([{"name": "Neu", "karten": ["we"]}, {"name": "Ohne"}])
pruefe(an() == [True, False], "neue Liste uebernimmt die Kartenwahl: %r" % an())
pruefe("Karten: Wertermittlung" in panel.dienste_liste.item(0).toolTip(), "Karten im Tooltip")
for haken in panel.karten_haken.values():
haken.setChecked(False)
print("== 0.7.1: die Liste gehoert zur Auswahl ==")
# Bis 0.7.0 blieb die Liste nach einem Wechsel stehen; „Ausgewaehlte laden“ lud sie dann unter
# dem Namen der neuen Auswahl (gefunden 07.10.2026 bei der Videoaufnahme).
dienste = [{"name": "LSG", "gruppe_name": "Natur", "herkunft_text": "landesweit"},
{"name": "Biotope Punkte", "gruppe_name": "Natur", "untergruppe": "Biotope",
"herkunft_text": "landesweit"}]
panel.combo.setCurrentIndex(panel.combo.findData("27"))
panel.set_dienste(dienste, "27")
pruefe(panel.dienste_liste.count() == 2, "Liste fuer den Landkreis geholt")
panel.filter_feld.setText("meiß")
pruefe(panel.aktuelles_vkz() == "27" and panel.dienste_liste.count() == 2,
"Filter, der die Auswahl behaelt: Liste bleibt")
panel.filter_feld.clear()
pruefe(panel.aktuelles_vkz() == "27" and panel.dienste_liste.count() == 2, "Filter geleert: Liste bleibt")
panel.combo.setCurrentIndex(panel.combo.findData("27027"))
pruefe(panel.dienste_liste.count() == 0, "Wechsel zum Verfahren leert die Liste")
pruefe("Liste holen" in panel.status_zeile.text(), "Hinweis in der Statuszeile: %r" % panel.status_zeile.text())
panel.set_dienste(dienste) # ohne vkz: gilt fuer die aktuelle Auswahl
panel.waehle_vkz("27027")
pruefe(panel.dienste_liste.count() == 2, "dieselbe Auswahl erneut gesetzt: Liste bleibt")
panel.waehle_vkz("31005")
pruefe(panel.dienste_liste.count() == 0, "stiller Wechsel (Projektdatei) leert ebenfalls")
panel.set_dienste(dienste)
panel.filter_feld.setText("gibtsnicht")
pruefe(panel.dienste_liste.count() == 0, "Filter ohne Treffer: keine Auswahl, keine Liste")
panel.filter_feld.clear()
panel.set_dienste(dienste)
panel.set_angemeldet(False)
pruefe(panel.dienste_liste.count() == 0 and panel._dienste_vkz is None, "Abmelden leert Liste und Zuordnung")
GERUFEN.clear()
if not os.environ.get("VLN_TOKEN"):
print("== Online-Teil uebersprungen (VLN_TOKEN nicht gesetzt) ==")
print("== Ergebnis: %d Fehler ==" % len(FEHLER))
for f in FEHLER:
print(" -", f)
app.exitQgis()
sys.exit(1 if FEHLER else 0)
2026-09-08 08:28:11 +02:00
print("== angemeldet, echte Verfahrensliste ==")
client = KartenApiClient(api_key=os.environ["VLN_TOKEN"])
verfahren = client.get_verfahren()
panel.set_angemeldet(True, "erik.sefkow@…")
panel.set_verfahren(verfahren)
pruefe(panel.ogc_knopf.isEnabled(), "Knoepfe frei")
pruefe(panel.anzahl_eintraege() == len(verfahren) + 1,
"Liste gefuellt: %d Verfahren + Platzhalter" % len(verfahren))
print("== Filter ==")
panel.filter_feld.setText("berb")
treffer = [panel.combo.itemText(i) for i in range(panel.combo.count())][1:]
pruefe(treffer and all("berb" in t.lower() for t in treffer),
"gefiltert auf %d Treffer: %s" % (len(treffer), ", ".join(treffer)[:70]))
panel.filter_feld.setText("gibtsnicht")
pruefe(panel.combo.count() == 1 and panel.combo.currentData() is None,
"kein Treffer -> Platzhalter, kein VKZ")
panel.filter_feld.clear()
pruefe(panel.anzahl_eintraege() == len(verfahren) + 1, "Filter geleert -> Liste wieder voll")
print("== Auswahl + Rueckruf ==")
panel.waehle_vkz("27027")
pruefe(panel.aktuelles_vkz() == "27027", "Wiederherstellen ohne Rueckruf: %s" % panel.aktuelles_vkz())
pruefe(not any(n == "verfahren_gewaehlt" for n, _ in GERUFEN), "waehle_vkz loest keinen Rueckruf aus")
panel.combo.setCurrentIndex(panel.combo.findData(verfahren[0]["vkz"]))
pruefe(any(n == "verfahren_gewaehlt" for n, _ in GERUFEN), "Nutzerauswahl meldet ans Plugin")
panel.waehle_vkz("27027")
print("== Knoepfe ==")
panel.ogc_knopf.click(); panel.speichern_knopf.click(); panel.stil_knopf.click()
2026-09-08 08:28:11 +02:00
namen = [n for n, _ in GERUFEN]
for erwartet in ("load_ogc", "save_edits", "save_style"):
2026-09-08 08:28:11 +02:00
pruefe(erwartet in namen, "Rueckruf %s" % erwartet)
pruefe(not hasattr(panel, "datensatz_knoepfe") and not hasattr(panel, "upload_knopf"),
"kein GeoJSON-Weg mehr in der Seitenleiste")
pruefe(panel.gewaehlte_gruppen() == {"Verfahren", "Vorerhebung", "Maßnahmenblätter"},
"alle Gruppen zunaechst angehakt: %s" % sorted(panel.gewaehlte_gruppen()))
panel.gruppen_haken["Verfahren"].setChecked(False)
pruefe(panel.gewaehlte_gruppen() == {"Vorerhebung", "Maßnahmenblätter"},
"Abwaehlen wirkt: %s" % sorted(panel.gewaehlte_gruppen()))
panel.gruppen_haken["Verfahren"].setChecked(True)
2026-09-08 08:28:11 +02:00
pruefe(not panel.als_vorlage(), "Vorlage-Haken standardmaessig aus")
panel.vorlage_haken.setChecked(True)
pruefe(panel.als_vorlage(), "Vorlage-Haken wirkt")
panel.vorlage_haken.setChecked(False)
print("== Bild ==")
panel.set_status("Stil gespeichert: kas-27027-flaeche (Vorlage)")
panel.widget().widget().resize(QSize(300, 760))
panel.widget().widget().grab().save(ZIEL)
2026-09-08 08:28:11 +02:00
print(" ", ZIEL, os.path.getsize(ZIEL), "Bytes")
app.exitQgis()
print("== Ergebnis: %d Fehler ==" % len(FEHLER))
for f in FEHLER:
print(" -", f)
sys.exit(1 if FEHLER else 0)