shape Verfahrensgebiet ergänzt

This commit is contained in:
2026-07-15 15:29:48 +02:00
parent 0c5e6df736
commit f37f33584d
6 changed files with 1856 additions and 7 deletions
+257
View File
@@ -566,5 +566,262 @@ class TestWorkingTab(unittest.TestCase):
self.assertTrue(tab.btn_gem_alkis.isEnabled()) # finally
# ---------------------------------------------------------------------------
# handle_verf_shape
# ---------------------------------------------------------------------------
class TestHandleVerfShape(unittest.TestCase):
def _make_tab(self):
tab = WorkingTab.__new__(WorkingTab)
tab.btn_verf_alkis = _DummyButton()
tab.btn_verf_shape = _DummyButton()
tab.btn_flurst_alkis = _DummyButton()
tab.btn_gem_alkis = _DummyButton()
tab.btn_grenz_alkis = _DummyButton()
tab.btn_verf_aus_auswahl = _DummyButton()
tab.btn_verf_aus_liste = _DummyButton()
tab.verf_layer_combo = _DummyCombo()
tab.haken_verf = types.SimpleNamespace(setText=lambda _t: None, setStyleSheet=lambda _s: None)
tab.haken_flurst = types.SimpleNamespace(setText=lambda _t: None, setStyleSheet=lambda _s: None)
tab.haken_gem = types.SimpleNamespace(setText=lambda _t: None, setStyleSheet=lambda _s: None)
tab.haken_grenz = types.SimpleNamespace(setText=lambda _t: None, setStyleSheet=lambda _s: None)
tab.setze_haken = lambda *_args, **_kwargs: None
tab.pruefmanager = types.SimpleNamespace(verarbeite=lambda ergebnis: ergebnis)
return tab
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
@patch(
"sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_shape_komplett",
return_value=(None, None, None, LoadStatus.NONE),
)
def test_status_none_clears_layer_variable(self, _mock_shape, mock_set_id):
"""Status NONE → Layer-Variable wird auf '' gesetzt."""
tab = self._make_tab()
with patch("sn_verfahrensgebiet.ui.tabs.working_tab.get_variable", return_value="VF-123"), \
patch("sn_verfahrensgebiet.ui.tabs.working_tab.ask_yes_no"):
tab.handle_verf_shape()
mock_set_id.assert_called_once_with("")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
@patch(
"sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_shape_komplett",
return_value=(None, None, None, LoadStatus.NONE),
)
def test_button_always_re_enabled_on_failure(self, _mock_shape, _mock_set_id):
"""Button muss nach Status NONE wieder freigegeben sein (finally)."""
tab = self._make_tab()
with patch("sn_verfahrensgebiet.ui.tabs.working_tab.get_variable", return_value="VF-123"), \
patch("sn_verfahrensgebiet.ui.tabs.working_tab.ask_yes_no"):
tab.handle_verf_shape()
self.assertTrue(tab.btn_verf_shape.isEnabled())
self.assertEqual(tab.btn_verf_shape.text(), "Aus Shape laden")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.ask_yes_no", return_value=False)
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.get_variable", return_value="")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_shape_komplett")
def test_verfahrensnummer_nicht_gesetzt_nein_bricht_ab(
self, mock_shape, mock_get_var, mock_ask
):
"""Verfahrensnummer leer + Nutzer wählt 'Nein' → Vorgang abgebrochen."""
tab = self._make_tab()
tab.handle_verf_shape()
mock_ask.assert_called_once()
mock_shape.assert_not_called()
# Button darf nicht busy geblieben sein
self.assertTrue(tab.btn_verf_shape.isEnabled())
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.ask_yes_no", return_value=True)
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.get_variable", return_value="")
@patch(
"sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_shape_komplett",
return_value=(None, None, None, LoadStatus.NONE),
)
def test_verfahrensnummer_nicht_gesetzt_ja_fuehrt_fort(
self, mock_shape, mock_get_var, mock_ask, mock_set_id
):
"""Verfahrensnummer leer + Nutzer wählt 'Ja' → Pipeline wird aufgerufen."""
tab = self._make_tab()
tab.handle_verf_shape()
mock_ask.assert_called_once()
mock_shape.assert_called_once_with(tab)
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.ask_yes_no")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.get_variable", return_value="VF-2026-001")
@patch(
"sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_shape_komplett",
return_value=(None, None, None, LoadStatus.NONE),
)
def test_verfahrensnummer_gesetzt_kein_rueckfrage_dialog(
self, mock_shape, mock_get_var, mock_ask, mock_set_id
):
"""Verfahrensnummer gesetzt → kein ask_yes_no-Dialog."""
tab = self._make_tab()
tab.handle_verf_shape()
mock_ask.assert_not_called()
mock_shape.assert_called_once_with(tab)
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.get_variable", return_value="VF-123")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.success")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.apply_style")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_shape_komplett")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
def test_success_path_applies_style_and_sets_haken(
self,
mock_set_layer_id,
mock_iface,
mock_shape_komplett,
mock_project_instance,
mock_apply_style,
mock_success,
mock_get_var,
):
"""Erfolg → verfahrensgebiet.qml angewendet, haken_verf gesetzt, success aufgerufen."""
tab = self._make_tab()
haken_calls = []
tab.setze_haken = lambda lbl, v: haken_calls.append((lbl, v))
enriched = _DummyLayer(valid=True, layer_id="shape_vg")
flst = _DummyLayer(valid=True, layer_id="flst_ok")
mock_shape_komplett.return_value = (enriched, flst, None, LoadStatus.FIRST)
proj = _DummyProject()
proj.mapLayersByName = lambda _n: []
proj.mapLayer = lambda _lid: None
mock_project_instance.return_value = proj
mock_iface.mapCanvas.return_value = _DummyCanvas()
tab.handle_verf_shape()
# Style auf enriched layer angewendet
apply_calls = [str(c) for c in mock_apply_style.call_args_list]
self.assertTrue(
any("verfahrensgebiet.qml" in c for c in apply_calls),
"verfahrensgebiet.qml muss angewendet werden",
)
# Flurstücke-Style angewendet
self.assertTrue(
any("GIS_Flst_Beschriftung_ALKIS_NAS.qml" in c for c in apply_calls),
"Flurstücke-Style muss angewendet werden",
)
# Haken gesetzt
self.assertTrue(any(v for _, v in haken_calls), "Mindestens ein Haken muss gesetzt werden")
# Layer-ID gespeichert
mock_set_layer_id.assert_called_with("shape_vg")
# Success-Meldung
mock_success.assert_called_once()
# Button wieder freigegeben
self.assertTrue(tab.btn_verf_shape.isEnabled())
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.get_variable", return_value="VF-123")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.success")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.apply_style")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_shape_komplett")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
def test_bror_layer_erhaelt_qml_stil(
self,
mock_set_layer_id,
mock_iface,
mock_shape_komplett,
mock_project_instance,
mock_apply_style,
mock_success,
mock_get_var,
):
"""Wenn bror_layer zurückgegeben → BauRaumOderBodenordnungsrecht.qml angewendet."""
tab = self._make_tab()
tab.setze_haken = lambda *a, **kw: None
enriched = _DummyLayer(valid=True, layer_id="shape_vg")
bror = _DummyLayer(valid=True, layer_id="bror_id")
mock_shape_komplett.return_value = (enriched, None, bror, LoadStatus.FIRST)
proj = _DummyProject()
proj.mapLayersByName = lambda _n: []
proj.mapLayer = lambda lid: enriched if lid == "shape_vg" else None
mock_project_instance.return_value = proj
mock_iface.mapCanvas.return_value = _DummyCanvas()
tab.handle_verf_shape()
apply_calls = [str(c) for c in mock_apply_style.call_args_list]
self.assertTrue(
any("BauRaumOderBodenordnungsrecht.qml" in c for c in apply_calls),
"BauRaumOderBodenordnungsrecht.qml muss auf bror_layer angewendet werden",
)
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.get_variable", return_value="VF-123")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.apply_style")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_shape_komplett")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
def test_enriched_layer_already_in_project_not_added_again(
self,
mock_set_layer_id,
mock_iface,
mock_shape_komplett,
mock_project_instance,
mock_apply_style,
mock_get_var,
):
"""Layer bereits im Projekt → kein erneutes addMapLayer für VG-Layer."""
tab = self._make_tab()
tab.setze_haken = lambda *a, **kw: None
enriched = _DummyLayer(valid=True, layer_id="shape_vg")
mock_shape_komplett.return_value = (enriched, None, None, LoadStatus.FIRST)
proj = _DummyProject()
proj.mapLayersByName = lambda _n: []
proj.mapLayer = lambda lid: enriched if lid == "shape_vg" else None
mock_project_instance.return_value = proj
mock_iface.mapCanvas.return_value = _DummyCanvas()
tab.handle_verf_shape()
# Enriched-Layer darf NICHT erneut via addMapLayer hinzugefügt worden sein
self.assertNotIn(enriched, proj.added)
def test_busy_state_set_during_execution(self):
"""Button wird während der Ausführung auf busy gesetzt."""
tab = self._make_tab()
busy_states = []
original_set_busy = WorkingTab._set_busy
def capture_busy(self_ref, button, busy, original_text="Aus Shape laden"):
busy_states.append(busy)
original_set_busy(self_ref, button, busy, original_text)
with patch.object(WorkingTab, "_set_busy", capture_busy), \
patch(
"sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_shape_komplett",
return_value=(None, None, None, LoadStatus.NONE),
), \
patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id"), \
patch("sn_verfahrensgebiet.ui.tabs.working_tab.get_variable", return_value="VF-123"):
tab.handle_verf_shape()
self.assertIn(True, busy_states, "Button muss mindestens einmal auf busy gesetzt werden")
self.assertIn(False, busy_states, "Button muss am Ende wieder freigegeben werden")
if __name__ == "__main__":
unittest.main()