571 lines
23 KiB
Python
571 lines
23 KiB
Python
import sys
|
||
import types
|
||
import unittest
|
||
from unittest.mock import patch
|
||
|
||
if "qgis" not in sys.modules:
|
||
qgis_mod = types.ModuleType("qgis")
|
||
qgis_utils = types.ModuleType("qgis.utils")
|
||
qgis_utils.iface = types.SimpleNamespace(
|
||
mapCanvas=lambda: types.SimpleNamespace(setExtent=lambda _e: None, refresh=lambda: None)
|
||
)
|
||
qgis_utils.plugins = {}
|
||
qgis_mod.utils = qgis_utils
|
||
sys.modules["qgis"] = qgis_mod
|
||
sys.modules["qgis.utils"] = qgis_utils
|
||
|
||
from sn_verfahrensgebiet.ui.tabs.working_tab import WorkingTab, LoadStatus
|
||
|
||
|
||
class _DummyLayer:
|
||
def __init__(self, valid=True, layer_id="L1", layer_name="DummyLayer"):
|
||
self._valid = valid
|
||
self._id = layer_id
|
||
self._name = layer_name
|
||
|
||
def isValid(self):
|
||
return self._valid
|
||
|
||
def id(self):
|
||
return self._id
|
||
|
||
def name(self):
|
||
return self._name
|
||
|
||
def extent(self):
|
||
return object()
|
||
|
||
|
||
class _DummyProject:
|
||
def __init__(self):
|
||
self.added = []
|
||
|
||
def addMapLayer(self, layer):
|
||
self.added.append(layer)
|
||
|
||
|
||
class _DummyCanvas:
|
||
def __init__(self):
|
||
self.extent = None
|
||
|
||
def setExtent(self, extent):
|
||
self.extent = extent
|
||
|
||
def refresh(self):
|
||
return None
|
||
|
||
|
||
class _DummyButton:
|
||
def __init__(self):
|
||
self._enabled = True
|
||
self._text = "Aus ALKIS laden"
|
||
|
||
def setEnabled(self, enabled):
|
||
self._enabled = enabled
|
||
|
||
def isEnabled(self):
|
||
return self._enabled
|
||
|
||
def setText(self, text):
|
||
self._text = text
|
||
|
||
def text(self):
|
||
return self._text
|
||
|
||
|
||
class _DummyCombo:
|
||
def __init__(self):
|
||
self.layer = None
|
||
|
||
def setLayer(self, layer):
|
||
self.layer = layer
|
||
|
||
|
||
class TestWorkingTab(unittest.TestCase):
|
||
|
||
def _make_tab(self):
|
||
tab = WorkingTab.__new__(WorkingTab)
|
||
tab.btn_verf_alkis = _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
|
||
# Pruefmanager-Mock: verarbeite() wird im Test ggf. überschrieben
|
||
tab.pruefmanager = types.SimpleNamespace(
|
||
verarbeite=lambda ergebnis: ergebnis
|
||
)
|
||
return tab
|
||
|
||
def test_set_busy_updates_button_state(self):
|
||
tab = self._make_tab()
|
||
|
||
tab._set_busy(tab.btn_verf_alkis, True)
|
||
self.assertFalse(tab.btn_verf_alkis.isEnabled())
|
||
self.assertEqual(tab.btn_verf_alkis.text(), "Lade ...")
|
||
|
||
tab._set_busy(tab.btn_verf_alkis, False)
|
||
self.assertTrue(tab.btn_verf_alkis.isEnabled())
|
||
self.assertEqual(tab.btn_verf_alkis.text(), "Aus ALKIS laden")
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
|
||
def test_on_verf_layer_changed_valid_sets_variable(self, mock_set_layer_id):
|
||
tab = self._make_tab()
|
||
layer = _DummyLayer(valid=True, layer_id="layer_123")
|
||
|
||
tab._on_verf_layer_changed(layer)
|
||
|
||
mock_set_layer_id.assert_called_once_with("layer_123")
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
|
||
def test_on_verf_layer_changed_none_clears_variable(self, mock_set_layer_id):
|
||
tab = self._make_tab()
|
||
|
||
tab._on_verf_layer_changed(None)
|
||
|
||
mock_set_layer_id.assert_called_once_with("")
|
||
|
||
@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_alkis_komplett")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
|
||
def test_handle_verf_alkis_success_path(
|
||
self,
|
||
mock_set_layer_id,
|
||
mock_iface,
|
||
mock_alkis_komplett,
|
||
mock_project_instance,
|
||
mock_apply_style,
|
||
mock_success,
|
||
):
|
||
"""verfahrensgebiet_alkis_komplett → 4-Tupel (enriched, flst, bror, FIRST)."""
|
||
tab = self._make_tab()
|
||
enriched = _DummyLayer(valid=True, layer_id="enriched_ok")
|
||
flst = _DummyLayer(valid=True, layer_id="flst_ok")
|
||
mock_alkis_komplett.return_value = (enriched, flst, None, LoadStatus.FIRST)
|
||
proj = _DummyProject()
|
||
proj.mapLayersByName = lambda _n: [] # kein bestehender Flst-Layer
|
||
mock_project_instance.return_value = proj
|
||
mock_iface.mapCanvas.return_value = _DummyCanvas()
|
||
|
||
tab.handle_verf_alkis()
|
||
|
||
mock_apply_style.assert_called()
|
||
mock_success.assert_called_once()
|
||
mock_set_layer_id.assert_called_with("enriched_ok")
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
|
||
@patch(
|
||
"sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_alkis_komplett",
|
||
return_value=(None, None, None, LoadStatus.NONE),
|
||
)
|
||
def test_handle_verf_alkis_failure_clears_layer_var(self, _mock_alkis, mock_set_layer_id):
|
||
"""Status NONE → Layer-Variable wird auf '' gesetzt."""
|
||
tab = self._make_tab()
|
||
|
||
tab.handle_verf_alkis()
|
||
|
||
mock_set_layer_id.assert_called_once_with("")
|
||
|
||
# ------------------------------------------------------------------
|
||
# handle_grenz_alkis
|
||
# ------------------------------------------------------------------
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.grenzpunkt_alkis")
|
||
def test_handle_grenz_alkis_success_sets_haken(self, mock_grenz):
|
||
"""Grenzpunkte erfolgreich geladen → haken_grenz wird gesetzt."""
|
||
tab = self._make_tab()
|
||
haken_calls = []
|
||
tab.setze_haken = lambda lbl, v: haken_calls.append((lbl, v))
|
||
|
||
pta = _DummyLayer(valid=True)
|
||
gp = _DummyLayer(valid=True)
|
||
mock_grenz.return_value = (pta, gp)
|
||
|
||
tab.handle_grenz_alkis()
|
||
|
||
self.assertEqual(len(haken_calls), 1)
|
||
self.assertIs(haken_calls[0][0], tab.haken_grenz)
|
||
self.assertTrue(haken_calls[0][1])
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.grenzpunkt_alkis")
|
||
def test_handle_grenz_alkis_none_result_sets_no_haken(self, mock_grenz):
|
||
"""grenzpunkt_alkis liefert (None, None) → kein Haken."""
|
||
tab = self._make_tab()
|
||
haken_calls = []
|
||
tab.setze_haken = lambda lbl, v: haken_calls.append((lbl, v))
|
||
|
||
mock_grenz.return_value = (None, None)
|
||
|
||
tab.handle_grenz_alkis()
|
||
|
||
self.assertEqual(len(haken_calls), 0)
|
||
# Button wieder aktiviert (finally)
|
||
self.assertTrue(tab.btn_grenz_alkis.isEnabled())
|
||
|
||
# ------------------------------------------------------------------
|
||
# handle_flurst_alkis
|
||
# ------------------------------------------------------------------
|
||
|
||
@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.iface")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.flurstueck_alkis")
|
||
def test_handle_flurst_alkis_success_sets_haken_and_style(
|
||
self, mock_alkis, mock_iface, mock_project, mock_apply_style, mock_success
|
||
):
|
||
tab = self._make_tab()
|
||
haken_calls = []
|
||
tab.setze_haken = lambda lbl, v: haken_calls.append((lbl, v))
|
||
|
||
layer = _DummyLayer(valid=True)
|
||
mock_alkis.return_value = (layer, LoadStatus.FIRST)
|
||
mock_project.return_value = _DummyProject()
|
||
mock_iface.mapCanvas.return_value = _DummyCanvas()
|
||
|
||
tab.handle_flurst_alkis()
|
||
|
||
mock_apply_style.assert_called_once_with(layer, "GIS_Flst_Beschriftung_ALKIS_NAS.qml")
|
||
mock_success.assert_called_once()
|
||
self.assertEqual(len(haken_calls), 1)
|
||
self.assertTrue(haken_calls[0][1]) # haken gesetzt
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.info")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.flurstueck_alkis")
|
||
def test_handle_flurst_alkis_existing_layer_keep_path(self, mock_alkis, mock_info):
|
||
tab = self._make_tab()
|
||
haken_calls = []
|
||
tab.setze_haken = lambda lbl, v: haken_calls.append((lbl, v))
|
||
|
||
layer = _DummyLayer(valid=True)
|
||
mock_alkis.return_value = (layer, LoadStatus.KEEP)
|
||
|
||
tab.handle_flurst_alkis()
|
||
|
||
mock_info.assert_called_once()
|
||
self.assertEqual(len(haken_calls), 1)
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.flurstueck_alkis")
|
||
def test_handle_flurst_alkis_invalid_input_returns_early(self, mock_alkis):
|
||
"""Status NONE (z. B. Nutzerabbruch) → kein Layer, kein Haken."""
|
||
tab = self._make_tab()
|
||
haken_calls = []
|
||
tab.setze_haken = lambda lbl, v: haken_calls.append((lbl, v))
|
||
mock_alkis.return_value = (None, LoadStatus.NONE)
|
||
|
||
tab.handle_flurst_alkis()
|
||
|
||
self.assertEqual(len(haken_calls), 0)
|
||
# Button muss am Ende wieder freigegeben sein (finally)
|
||
self.assertTrue(tab.btn_flurst_alkis.isEnabled())
|
||
|
||
# ------------------------------------------------------------------
|
||
# handle_verf_aus_auswahl – Vorbedingungsprüfungen
|
||
# ------------------------------------------------------------------
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.warning")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||
def test_handle_verfahrensgebiet_from_selection_requires_active_layer(
|
||
self, mock_iface, mock_warning
|
||
):
|
||
"""Kein aktiver Layer → warning, kein Layer wird erstellt."""
|
||
tab = self._make_tab()
|
||
mock_iface.activeLayer.return_value = None
|
||
|
||
tab.handle_verf_aus_auswahl()
|
||
|
||
mock_warning.assert_called_once()
|
||
self.assertIn("aktiver Layer", mock_warning.call_args[0][1])
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.warning")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.pruefe_flurstueck_layer")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||
def test_handle_verfahrensgebiet_from_selection_requires_required_fields(
|
||
self, mock_iface, mock_pruefe, mock_warning
|
||
):
|
||
"""Layer ohne Pflichtfelder → warning, kein Layer wird erstellt."""
|
||
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis as PruefErg
|
||
tab = self._make_tab()
|
||
active = _DummyLayer(valid=True)
|
||
mock_iface.activeLayer.return_value = active
|
||
mock_pruefe.return_value = PruefErg(
|
||
ok=False, aktion="felder_fehlen", meldung="Feld fehlt"
|
||
)
|
||
|
||
tab.handle_verf_aus_auswahl()
|
||
|
||
mock_warning.assert_called_once()
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.warning")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.pruefe_auswahl")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.pruefe_flurstueck_layer")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||
def test_handle_verfahrensgebiet_from_selection_requires_selection(
|
||
self, mock_iface, mock_pruefe_layer, mock_pruefe_auswahl, mock_warning
|
||
):
|
||
"""Keine Flurstück-Auswahl → warning, kein Layer erstellt."""
|
||
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis as PruefErg
|
||
tab = self._make_tab()
|
||
active = _DummyLayer(valid=True)
|
||
mock_iface.activeLayer.return_value = active
|
||
mock_pruefe_layer.return_value = PruefErg(ok=True, aktion="ok")
|
||
mock_pruefe_auswahl.return_value = PruefErg(
|
||
ok=False, aktion="layer_leer", meldung="Keine Auswahl"
|
||
)
|
||
|
||
tab.handle_verf_aus_auswahl()
|
||
|
||
mock_warning.assert_called_once()
|
||
|
||
# ------------------------------------------------------------------
|
||
# handle_verf_aus_auswahl – Erstlauf (kein bestehender Layer)
|
||
# ------------------------------------------------------------------
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QMessageBox")
|
||
@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.erstelle_verfahrensgebiet_aus_auswahl")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.pruefe_auswahl")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.pruefe_flurstueck_layer")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||
def test_handle_verfahrensgebiet_from_selection_new_layer_success(
|
||
self, mock_iface, mock_pruefe_layer, mock_pruefe_auswahl,
|
||
mock_erstelle, mock_project_inst, mock_apply_style, mock_msgbox
|
||
):
|
||
"""Erstlauf ohne bestehenden Layer → Layer wird erstellt und hinzugefügt."""
|
||
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis as PruefErg
|
||
tab = self._make_tab()
|
||
haken_calls = []
|
||
tab.setze_haken = lambda lbl, v: haken_calls.append(v)
|
||
active = _DummyLayer(valid=True)
|
||
mock_iface.activeLayer.return_value = active
|
||
mock_iface.mapCanvas.return_value = _DummyCanvas()
|
||
mock_pruefe_layer.return_value = PruefErg(ok=True, aktion="ok")
|
||
mock_pruefe_auswahl.return_value = PruefErg(ok=True, aktion="ok", meldung="3 Flurstücke")
|
||
|
||
new_layer = _DummyLayer(valid=True, layer_id="new_verf")
|
||
mock_erstelle.return_value = (new_layer, 3, 0)
|
||
|
||
project = _DummyProject()
|
||
project.mapLayersByName = lambda _name: [] # kein bestehender Layer
|
||
mock_project_inst.return_value = project
|
||
|
||
tab.handle_verf_aus_auswahl()
|
||
|
||
self.assertIn(new_layer, project.added)
|
||
mock_apply_style.assert_called_once_with(new_layer, "verfahrensgebiet.qml")
|
||
self.assertTrue(haken_calls[0])
|
||
|
||
# ------------------------------------------------------------------
|
||
# handle_verf_aus_auswahl – Ergänzen / Entfernen / Ersetzen
|
||
# ------------------------------------------------------------------
|
||
|
||
def _make_entscheidungs_ergebnis(self, aktion: str):
|
||
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis as PruefErg
|
||
return PruefErg(ok=True, aktion=aktion)
|
||
|
||
def _setup_existierenden_layer(self, tab, mock_iface, mock_pruefe_layer,
|
||
mock_pruefe_auswahl, mock_project_inst,
|
||
mock_canvas, entscheidung: str):
|
||
"""Gemeinsames Setup für Delta-Operationen mit bestehendem Layer."""
|
||
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis as PruefErg
|
||
active = _DummyLayer(valid=True)
|
||
mock_iface.activeLayer.return_value = active
|
||
mock_iface.mapCanvas.return_value = mock_canvas
|
||
mock_pruefe_layer.return_value = PruefErg(ok=True, aktion="ok")
|
||
mock_pruefe_auswahl.return_value = PruefErg(ok=True, aktion="ok", meldung="2 Flurstücke")
|
||
|
||
verf_layer = _DummyLayer(valid=True, layer_id="verf_existing")
|
||
project = _DummyProject()
|
||
project.added = []
|
||
project.mapLayersByName = lambda _: [verf_layer]
|
||
project.removeMapLayer = lambda lid: None
|
||
mock_project_inst.return_value = project
|
||
|
||
# Pruefmanager gibt Entscheidung zurück
|
||
tab.pruefmanager.verarbeite = lambda _e: self._make_entscheidungs_ergebnis(entscheidung)
|
||
|
||
return active, verf_layer, project
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QMessageBox")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.apply_style")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.ergaenze_verfahrensgebiet")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.pruefe_auswahl")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.pruefe_flurstueck_layer")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||
def test_handle_verfahrensgebiet_from_selection_existing_layer_ergaenzen_dispatch(
|
||
self, mock_iface, mock_pruefe_layer, mock_pruefe_auswahl,
|
||
mock_project_inst, mock_ergaenze, mock_apply_style, mock_msgbox
|
||
):
|
||
"""Entscheidung 'ergaenzen' → ergaenze_verfahrensgebiet wird aufgerufen."""
|
||
tab = self._make_tab()
|
||
canvas = _DummyCanvas()
|
||
active, verf_layer, _ = self._setup_existierenden_layer(
|
||
tab, mock_iface, mock_pruefe_layer, mock_pruefe_auswahl,
|
||
mock_project_inst, canvas, "verfahrensgebiet_ergaenzen"
|
||
)
|
||
mock_ergaenze.return_value = (verf_layer, 2, 0, 0)
|
||
|
||
tab.handle_verf_aus_auswahl()
|
||
|
||
mock_ergaenze.assert_called_once_with(verf_layer, active)
|
||
mock_apply_style.assert_called_once_with(verf_layer, "verfahrensgebiet.qml")
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QMessageBox")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.apply_style")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.entferne_aus_verfahrensgebiet")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.pruefe_auswahl")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.pruefe_flurstueck_layer")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||
def test_handle_verfahrensgebiet_from_selection_existing_layer_entfernen_dispatch(
|
||
self, mock_iface, mock_pruefe_layer, mock_pruefe_auswahl,
|
||
mock_project_inst, mock_entferne, mock_apply_style, mock_msgbox
|
||
):
|
||
"""Entscheidung 'entfernen' → entferne_aus_verfahrensgebiet wird aufgerufen."""
|
||
tab = self._make_tab()
|
||
canvas = _DummyCanvas()
|
||
active, verf_layer, _ = self._setup_existierenden_layer(
|
||
tab, mock_iface, mock_pruefe_layer, mock_pruefe_auswahl,
|
||
mock_project_inst, canvas, "verfahrensgebiet_entfernen"
|
||
)
|
||
mock_entferne.return_value = (verf_layer, 1, 1, 0)
|
||
|
||
tab.handle_verf_aus_auswahl()
|
||
|
||
mock_entferne.assert_called_once_with(verf_layer, active)
|
||
mock_apply_style.assert_called_once_with(verf_layer, "verfahrensgebiet.qml")
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QMessageBox")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.apply_style")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.ersetze_verfahrensgebiet")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.pruefe_auswahl")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.pruefe_flurstueck_layer")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||
def test_handle_verfahrensgebiet_from_selection_existing_layer_ersetzen_dispatch(
|
||
self, mock_iface, mock_pruefe_layer, mock_pruefe_auswahl,
|
||
mock_project_inst, mock_ersetze, mock_apply_style, mock_msgbox
|
||
):
|
||
"""Entscheidung 'ersetzen' → alter Layer entfernt, neuer hinzugefügt."""
|
||
tab = self._make_tab()
|
||
canvas = _DummyCanvas()
|
||
active, verf_layer, project = self._setup_existierenden_layer(
|
||
tab, mock_iface, mock_pruefe_layer, mock_pruefe_auswahl,
|
||
mock_project_inst, canvas, "verfahrensgebiet_ersetzen"
|
||
)
|
||
removed = []
|
||
project.removeMapLayer = lambda lid: removed.append(lid)
|
||
new_layer = _DummyLayer(valid=True, layer_id="new_verf_replaced")
|
||
mock_ersetze.return_value = (new_layer, 3, 0)
|
||
|
||
tab.handle_verf_aus_auswahl()
|
||
|
||
mock_ersetze.assert_called_once_with(active)
|
||
self.assertIn(verf_layer.id(), removed)
|
||
self.assertIn(new_layer, project.added)
|
||
mock_apply_style.assert_called_once_with(new_layer, "verfahrensgebiet.qml")
|
||
|
||
# ------------------------------------------------------------------
|
||
# handle_verf_aus_liste
|
||
# ------------------------------------------------------------------
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.show_info_dialog")
|
||
def test_aus_liste_button_shows_not_implemented_hint(self, mock_info):
|
||
tab = self._make_tab()
|
||
tab.handle_verf_aus_liste()
|
||
mock_info.assert_called_once()
|
||
|
||
# ------------------------------------------------------------------
|
||
# handle_gem_alkis
|
||
# ------------------------------------------------------------------
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.success")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.apply_style")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.lade_gemarkungen_layer")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
|
||
def test_handle_gem_alkis_service_reachable_adds_layer(
|
||
self, mock_project_inst, mock_lade, mock_apply_style, mock_success
|
||
):
|
||
"""Dienst erreichbar → Layer ins Projekt, Stil angewendet, Haken gesetzt."""
|
||
tab = self._make_tab()
|
||
haken_calls = []
|
||
tab.setze_haken = lambda lbl, v: haken_calls.append((lbl, v))
|
||
|
||
layer = _DummyLayer(valid=True, layer_name="Gemarkungen")
|
||
mock_lade.return_value = layer
|
||
|
||
project = _DummyProject()
|
||
project.mapLayersByName = lambda _n: []
|
||
mock_project_inst.return_value = project
|
||
|
||
tab.handle_gem_alkis()
|
||
|
||
self.assertIn(layer, project.added)
|
||
mock_apply_style.assert_called_once_with(layer, "gemarkungen_beschriftet.qml")
|
||
mock_success.assert_called_once()
|
||
self.assertEqual(len(haken_calls), 1)
|
||
self.assertIs(haken_calls[0][0], tab.haken_gem)
|
||
self.assertTrue(haken_calls[0][1])
|
||
self.assertTrue(tab.btn_gem_alkis.isEnabled()) # finally
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.warning")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.lade_gemarkungen_layer")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
|
||
def test_handle_gem_alkis_service_unreachable_shows_warning(
|
||
self, mock_project_inst, mock_lade, mock_warning
|
||
):
|
||
"""Dienst nicht erreichbar (None) → warning, kein addMapLayer."""
|
||
tab = self._make_tab()
|
||
haken_calls = []
|
||
tab.setze_haken = lambda lbl, v: haken_calls.append((lbl, v))
|
||
|
||
mock_lade.return_value = None
|
||
project = _DummyProject()
|
||
project.mapLayersByName = lambda _n: []
|
||
mock_project_inst.return_value = project
|
||
|
||
tab.handle_gem_alkis()
|
||
|
||
mock_warning.assert_called_once()
|
||
self.assertEqual(len(project.added), 0)
|
||
self.assertEqual(len(haken_calls), 0)
|
||
self.assertTrue(tab.btn_gem_alkis.isEnabled()) # finally
|
||
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.info")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.lade_gemarkungen_layer")
|
||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
|
||
def test_handle_gem_alkis_layer_already_exists_shows_info(
|
||
self, mock_project_inst, mock_lade, mock_info
|
||
):
|
||
"""Layer 'Gemarkungen' bereits vorhanden → info, kein erneutes Laden."""
|
||
tab = self._make_tab()
|
||
haken_calls = []
|
||
tab.setze_haken = lambda lbl, v: haken_calls.append((lbl, v))
|
||
|
||
existing_layer = _DummyLayer(valid=True, layer_name="Gemarkungen")
|
||
project = _DummyProject()
|
||
project.mapLayersByName = lambda _n: [existing_layer]
|
||
mock_project_inst.return_value = project
|
||
|
||
tab.handle_gem_alkis()
|
||
|
||
mock_info.assert_called_once()
|
||
mock_lade.assert_not_called()
|
||
self.assertEqual(len(project.added), 0)
|
||
self.assertTrue(tab.btn_gem_alkis.isEnabled()) # finally
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|