From ad6c7ea3e1da7887df915bcd32c642b810ec321c Mon Sep 17 00:00:00 2001 From: daniel Date: Wed, 8 Apr 2026 14:36:30 +0200 Subject: [PATCH] verfahrensgebiet-Vaiable wird sauber gesetzt --- tests/test_tab_a_preconditions.py | 111 ++++++++++++++++++++++++++++++ ui/tab_a_logic.py | 28 ++++++++ 2 files changed, 139 insertions(+) create mode 100644 tests/test_tab_a_preconditions.py diff --git a/tests/test_tab_a_preconditions.py b/tests/test_tab_a_preconditions.py new file mode 100644 index 0000000..5196baf --- /dev/null +++ b/tests/test_tab_a_preconditions.py @@ -0,0 +1,111 @@ +import unittest +from unittest.mock import patch +from typing import Any, cast + +from sn_plan41.ui.tab_a_logic import TabALogic + + +class _DummyPruefmanager: + def __init__(self) -> None: + self.hinweise: list[tuple[str, str]] = [] + + def verarbeite(self, ergebnis): + return ergebnis + + def zeige_hinweis(self, titel: str, meldung: str) -> None: + self.hinweise.append((titel, meldung)) + + +class _DummyDateiErgebnis: + def __init__(self, ok: bool = True, kontext: str = "C:/tmp/v_db.gpkg") -> None: + self.ok = ok + self.kontext = kontext + + +class _DummyProgress: + def __init__(self) -> None: + self.closed = False + + def set_total(self, _value: int) -> None: + pass + + def set_value(self, _value: int) -> None: + pass + + def set_label(self, _value: str) -> None: + pass + + def close(self) -> None: + self.closed = True + + +class _DummyProject: + def mapLayer(self, _layer_id: str): + return None + + +class _DummyGrabber: + pass + + +class TestTabAPreconditions(unittest.TestCase): + + def _make_logic(self) -> tuple[TabALogic, _DummyPruefmanager]: + pruefmanager = _DummyPruefmanager() + logic = TabALogic( + pruefmanager=cast(Any, pruefmanager), + link_pruefer=cast(Any, object()), + stil_pruefer=cast(Any, object()), + ) + return logic, pruefmanager + + def test_get_verfahrensgebiet_layer_shows_hint_when_layer_id_missing(self): + logic, pruefmanager = self._make_logic() + + with patch.object(logic, "load_verfahrensgebiet_layer_id", return_value=None): + layer = logic._get_verfahrensgebiet_layer() + + self.assertIsNone(layer) + self.assertEqual(len(pruefmanager.hinweise), 1) + self.assertIn("Verfahrensgebiet", pruefmanager.hinweise[0][0]) + + @patch("sn_plan41.ui.tab_a_logic.QgsProject.instance", return_value=_DummyProject()) + def test_get_verfahrensgebiet_layer_shows_hint_when_layer_not_in_project(self, _mock_project_instance): + logic, pruefmanager = self._make_logic() + + with patch.object(logic, "load_verfahrensgebiet_layer_id", return_value="layer_404"): + layer = logic._get_verfahrensgebiet_layer() + + self.assertIsNone(layer) + self.assertEqual(len(pruefmanager.hinweise), 1) + self.assertIn("Verfahrensgebiet", pruefmanager.hinweise[0][0]) + + @patch("sn_plan41.ui.tab_a_logic.Dateipruefer") + def test_pipeline_aborts_and_shows_hint_when_verfahrensgebiet_missing( + self, + mock_dateipruefer, + ): + logic, pruefmanager = self._make_logic() + logic.data_grabber = cast(Any, _DummyGrabber()) + + mock_dateipruefer.return_value.pruefe.return_value = _DummyDateiErgebnis(ok=True, kontext="C:/tmp/v_db.gpkg") + + progress = _DummyProgress() + + with patch("sn_plan41.ui.tab_a_logic.create_progress_dialog", return_value=progress): + with patch.object(logic, "_resolve_linkliste", return_value="C:/tmp/linkliste.xlsx"): + with patch.object(logic, "load_verfahrensgebiet_layer_id", return_value=None): + result = logic._on_run_pipeline( + source="C:/tmp/v_db.gpkg", + linkliste=None, + raumfilter="Verfahrensgebiet", + ) + + self.assertIsNone(result) + self.assertEqual(len(pruefmanager.hinweise), 1) + self.assertIn("Verfahrensgebiet", pruefmanager.hinweise[0][0]) + self.assertTrue(progress.closed) + + +if __name__ == "__main__": + unittest.main() diff --git a/ui/tab_a_logic.py b/ui/tab_a_logic.py index fc70a89..83bbd50 100644 --- a/ui/tab_a_logic.py +++ b/ui/tab_a_logic.py @@ -66,6 +66,28 @@ class TabALogic: def _log(self, msg: str) -> None: print(f"[TabALogic] {msg}") + def _zeige_verfahrensgebiet_hinweis(self) -> None: + if not self.pruefmanager: + return + show_hint = getattr(self.pruefmanager, "zeige_hinweis", None) + if callable(show_hint): + show_hint( + "Verfahrensgebiet fehlt", + "Kein gueltiger Verfahrensgebiet-Layer vorhanden. " + "Bitte zuerst in sn_verfahrensgebiet den Layer ueber 'Aus ALKIS laden' laden " + "oder im Dropdown einen gueltigen Layer auswaehlen.", + ) + + def _close_progress_dialog(self, progress: Optional[Any]) -> None: + if progress is None: + return + close = getattr(progress, "close", None) + if callable(close): + try: + close() + except Exception: + pass + # ------------------------------- # Verfahrens-Datenbank (Pfad-Management) # ------------------------------- @@ -211,6 +233,7 @@ class TabALogic: linkliste_final = self._resolve_linkliste(linkliste) if linkliste_final is None: self._log("Linkliste kann nicht aufgelöst werden") + self._close_progress_dialog(progress) return None else: self._log(f"Linkliste final: '{linkliste_final}'") @@ -218,6 +241,7 @@ class TabALogic: raumfilter_layer = self._resolve_raumfilter(raumfilter, final_pfad) if raumfilter in ("Verfahrensgebiet", "Pufferlayer") and raumfilter_layer is None: self._log(f"Raumfilter '{raumfilter}' nicht verfügbar") + self._close_progress_dialog(progress) return None # 4) Lade-Status initialisieren (funktioniert ab Bestätigung überschreiben/anhängen) @@ -243,6 +267,7 @@ class TabALogic: if not source_dict.get("rows"): self._log("Keine validen Linkliste-Einträge für Datenabruf") print("[TabALogic] ... STOP: rows:", len(source_dict.get("rows", []))) + self._close_progress_dialog(progress) return None total_rows = len(source_dict.get("rows", [])) @@ -869,15 +894,18 @@ class TabALogic: if not layer_id: self._log("❌ Keine Layer-ID gespeichert") + self._zeige_verfahrensgebiet_hinweis() return None layer = QgsProject.instance().mapLayer(layer_id) if not layer: self._log("❌ Layer-ID existiert nicht im Projekt") + self._zeige_verfahrensgebiet_hinweis() return None if not self.is_valid_verfahrensgebiet_layer(layer): self._log("❌ Layer ist kein gültiger Vektorlayer") + self._zeige_verfahrensgebiet_hinweis() return None self._log(f"Verfahrensgebiet-Layer OK: '{layer.name()}'")