Fassung 0.7.0: Landkreis-Linkliste, oFB liest nur, Untergruppen, 403 meldet nicht ab
- Auswahl über GET /tgen/auswahl (Manager seit 06.10.2026): oben die eigenen Landkreise („… — Linkliste des Landkreises“), dann die Verfahren; als oFB die Verfahren des Landkreises mit „(nur lesen)“. Älterer Server ohne die Route: Rückfall auf /tgen. - Landkreis gewählt: „Liste holen“ lädt die Linkliste des ganzen Landkreises; „Layer laden“ erklärt, dass es für einen Landkreis keine Verfahrenslayer gibt. - 401 und 403 getrennt: nur 401 (AuthError) meldet ab, 403 (KeinZugriff) zeigt eine Meldung. Bis 0.6.0 verwarf jedes 403 den gespeicherten API-Key. - OGC-Sammlungen mit vln:schreibbar: false werden schreibgeschützt geladen; Meldungen für Stil und Verkehrszeichen nennen „nur lesen“ als Grund. - Linkliste: Gruppe › Untergruppe › Layer im Ebenenbaum (linkliste.zielgruppe), Untergruppe auch in der Dienstliste. - README: Abschnitt „Geodienste aus der Linkliste“; Tests ohne Netz: tools/headless_linkliste_test.py (neu), tools/headless_panel_test.py erweitert — beide grün mit QGIS 4.2 offscreen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Plugin 0.7.0 ohne Netz pruefen: Fehlerzuordnung 401/403, Auswahl mit Rueckfall, Untergruppen-Baum.
|
||||
|
||||
Aufruf (macOS, QGIS 4.2 im Bundle):
|
||||
|
||||
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_linkliste_test.py
|
||||
|
||||
Kein Schluessel, keine Anfrage ans Netz: ``_request`` wird ersetzt.
|
||||
"""
|
||||
import os, sys
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from qgis.core import QgsApplication
|
||||
|
||||
app = QgsApplication([], False)
|
||||
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.core import QgsLayerTreeGroup
|
||||
|
||||
from vln_karten import api_client as ac
|
||||
from vln_karten.linkliste import zielgruppe
|
||||
|
||||
FEHLER = []
|
||||
|
||||
|
||||
def pruefe(bed, text):
|
||||
print((" OK " if bed else " FEHL ") + text)
|
||||
if not bed:
|
||||
FEHLER.append(text)
|
||||
|
||||
|
||||
print("== 401 meldet ab, 403 nicht (0.7.0) ==")
|
||||
e401, e403, e500 = (ac.fehler_fuer_status(s, "x") for s in (401, 403, 500))
|
||||
pruefe(isinstance(e401, ac.AuthError) and e401.status == 401, "401 -> AuthError")
|
||||
pruefe(isinstance(e403, ac.KeinZugriff) and not isinstance(e403, ac.AuthError) and e403.status == 403,
|
||||
"403 -> KeinZugriff, KEIN AuthError (sonst verwirft das Plugin den API-Key)")
|
||||
pruefe(type(e500) is ac.ApiError and e500.status == 500, "500 -> ApiError mit Status")
|
||||
pruefe(isinstance(e403, ac.ApiError), "KeinZugriff bleibt ein ApiError (Meldung statt Abmelden)")
|
||||
|
||||
print("== Auswahl: /tgen/auswahl und Rueckfall auf /tgen ==")
|
||||
client = ac.KartenApiClient(api_key="pruef")
|
||||
client._request = lambda m, p, **k: {"verfahren": [{"vkz": 27027, "name": "TG A", "zugriff": "voll"},
|
||||
{"vkz": 31005, "name": "TG B", "zugriff": "lesen"},
|
||||
{"name": "ohne vkz"}],
|
||||
"aemter": [{"vkz": 27, "name": "Landkreis Meißen"}]}
|
||||
a = client.get_auswahl()
|
||||
pruefe(a["verfahren"] == [{"vkz": "27027", "name": "TG A", "zugriff": "voll"},
|
||||
{"vkz": "31005", "name": "TG B", "zugriff": "lesen"}], "Verfahren gelesen: %r" % a["verfahren"])
|
||||
pruefe(a["aemter"] == [{"vkz": "27", "name": "Landkreis Meißen"}], "Landkreise gelesen")
|
||||
|
||||
|
||||
def alter_server(m, p, **k):
|
||||
if p == "/tgen/auswahl":
|
||||
raise ac.ApiError("GET /tgen/auswahl lieferte HTTP 400", 400) # /tgen/{vkz} faengt „auswahl“
|
||||
return [{"VKZ": "22017", "kurzname": "TG Schrebitz"}]
|
||||
|
||||
|
||||
client._request = alter_server
|
||||
a = client.get_auswahl()
|
||||
pruefe(a == {"verfahren": [{"vkz": "22017", "name": "TG Schrebitz", "zugriff": "voll"}], "aemter": []},
|
||||
"aelterer Server: Rueckfall auf /tgen: %r" % a)
|
||||
|
||||
|
||||
def verboten(m, p, **k):
|
||||
raise ac.fehler_fuer_status(403, "nein")
|
||||
|
||||
|
||||
client._request = verboten
|
||||
try:
|
||||
client.get_auswahl()
|
||||
pruefe(False, "403 muss durchgereicht werden")
|
||||
except ac.KeinZugriff:
|
||||
pruefe(True, "403 kommt als KeinZugriff beim Aufrufer an (kein Rueckfall)")
|
||||
|
||||
print("== Ebenenbaum: Gruppe › Untergruppe › Layer ==")
|
||||
oben = QgsLayerTreeGroup("Geodienste 27 Landkreis Meißen")
|
||||
knoten = {}
|
||||
natur = zielgruppe(oben, knoten, "Natur und Landschaft", None)
|
||||
bio = zielgruppe(oben, knoten, "Natur und Landschaft", "Biotope")
|
||||
bio2 = zielgruppe(oben, knoten, "Natur und Landschaft", " Biotope ")
|
||||
sonst = zielgruppe(oben, knoten, None, "")
|
||||
pruefe([g.name() for g in oben.children()] == ["Natur und Landschaft", "Sonstiges"],
|
||||
"oberste Ebene: Gruppen (ohne Gruppe -> Sonstiges): %r" % [g.name() for g in oben.children()])
|
||||
pruefe([g.name() for g in natur.children()] == ["Biotope"], "Untergruppe unter der Gruppe")
|
||||
pruefe(bio2.name() == "Biotope" and len(natur.children()) == 1, "dieselbe Untergruppe nur einmal")
|
||||
zweiter = zielgruppe(oben, {}, "Natur und Landschaft", "Biotope") # neuer Ladelauf
|
||||
pruefe(zweiter.name() == "Biotope" and len(oben.children()) == 2 and len(natur.children()) == 1,
|
||||
"zweiter Ladelauf legt nichts doppelt an")
|
||||
pruefe(sonst.name() == "Sonstiges" and not sonst.children(), "ohne Untergruppe direkt in die Gruppe")
|
||||
|
||||
print("== Ergebnis: %d Fehler ==" % len(FEHLER))
|
||||
for f in FEHLER:
|
||||
print(" -", f)
|
||||
app.exitQgis()
|
||||
sys.exit(1 if FEHLER else 0)
|
||||
@@ -69,6 +69,28 @@ pruefe(rolle.horizontalScrollBarPolicy() == Qt.ScrollBarPolicy.ScrollBarAlwaysOf
|
||||
"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")
|
||||
panel.set_angemeldet(False)
|
||||
GERUFEN.clear()
|
||||
|
||||
if not os.environ.get("VLN_TOKEN"):
|
||||
print("== Online-Teil uebersprungen (VLN_TOKEN nicht gesetzt) ==")
|
||||
print("== Ergebnis: %d Fehler ==" % len(FEHLER))
|
||||
|
||||
Reference in New Issue
Block a user