224 lines
9.4 KiB
Python
224 lines
9.4 KiB
Python
"""sn_verfahrensgebiet/tests/test_flurstueck_alkis.py
|
||
|
||
Unit-Tests für das flurstueck_alkis-Modul.
|
||
|
||
Getestet werden:
|
||
- Nutzerabbruch bei ask_text → (None, LoadStatus.NONE)
|
||
- Ungültiger WFS-Layer → (None, LoadStatus.NONE)
|
||
- Erfolgreicher Ladevorgang → gültiger Layer + LoadStatus.FIRST
|
||
- Bestehender Layer: Nutzer wählt "Neu laden" → LoadStatus.RELOAD
|
||
- Bestehender Layer: Nutzer wählt "Behalten" → LoadStatus.KEEP
|
||
"""
|
||
|
||
import sys
|
||
import types
|
||
import unittest
|
||
from unittest.mock import patch, MagicMock
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Minimales QGIS-Mock-Setup
|
||
# ---------------------------------------------------------------------------
|
||
if "qgis" not in sys.modules:
|
||
qgis_mod = types.ModuleType("qgis")
|
||
qgis_core = types.ModuleType("qgis.core")
|
||
qgis_utils = types.ModuleType("qgis.utils")
|
||
qgis_utils.iface = types.SimpleNamespace()
|
||
qgis_utils.plugins = {}
|
||
qgis_mod.utils = qgis_utils
|
||
qgis_mod.core = qgis_core
|
||
sys.modules["qgis"] = qgis_mod
|
||
sys.modules["qgis.core"] = qgis_core
|
||
sys.modules["qgis.utils"] = qgis_utils
|
||
|
||
from sn_verfahrensgebiet.functions.flurstueck_alkis import flurstueck_alkis, FLST_LAYER_NAME
|
||
from sn_verfahrensgebiet.functions.verfahrensgebiet_alkis import LoadStatus
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Dummies
|
||
# ---------------------------------------------------------------------------
|
||
|
||
class _DummyLayer:
|
||
def __init__(self, valid: bool, layer_id="L1"):
|
||
self._valid = valid
|
||
self._id = layer_id
|
||
|
||
def isValid(self):
|
||
return self._valid
|
||
|
||
def id(self):
|
||
return self._id
|
||
|
||
def extent(self):
|
||
return object()
|
||
|
||
|
||
class _DummyProject:
|
||
def __init__(self, named_layers=None):
|
||
self._named_layers = named_layers or []
|
||
self.removed = []
|
||
|
||
def mapLayersByName(self, name):
|
||
return self._named_layers
|
||
|
||
def removeMapLayer(self, lid):
|
||
self.removed.append(lid)
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Tests
|
||
# ---------------------------------------------------------------------------
|
||
|
||
class TestFlurstueckAlkis(unittest.TestCase):
|
||
|
||
# ------------------------------------------------------------------ #
|
||
# 1. Nutzerabbruch (ask_text liefert ok=False / None) #
|
||
# ------------------------------------------------------------------ #
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QMessageBox")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||
def test_user_cancel_returns_none(self, mock_ask_text, mock_project, mock_msgbox):
|
||
"""ask_text → ok=False, text="" → (None, NONE)."""
|
||
mock_ask_text.return_value = ("", False)
|
||
mock_project.return_value = _DummyProject()
|
||
|
||
layer, status = flurstueck_alkis(None)
|
||
|
||
self.assertIsNone(layer)
|
||
self.assertEqual(status, LoadStatus.NONE)
|
||
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QMessageBox")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||
def test_empty_text_after_confirmation_returns_none(self, mock_ask_text, mock_project, mock_msgbox):
|
||
"""ask_text → ok=True, aber Text leer → (None, NONE)."""
|
||
mock_ask_text.return_value = (" ", True)
|
||
mock_project.return_value = _DummyProject()
|
||
|
||
layer, status = flurstueck_alkis(None)
|
||
|
||
self.assertIsNone(layer)
|
||
self.assertEqual(status, LoadStatus.NONE)
|
||
|
||
# ------------------------------------------------------------------ #
|
||
# 2. Ungültiger WFS-Layer #
|
||
# ------------------------------------------------------------------ #
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QMessageBox")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||
def test_invalid_wfs_layer_returns_none(
|
||
self, mock_ask_text, mock_project, mock_wfs_layer_cls, mock_msgbox
|
||
):
|
||
"""WFS-Layer nicht valide → (None, NONE)."""
|
||
mock_ask_text.return_value = ("1234", True)
|
||
mock_project.return_value = _DummyProject()
|
||
mock_wfs_layer_cls.return_value = _DummyLayer(valid=False)
|
||
|
||
layer, status = flurstueck_alkis(None)
|
||
|
||
self.assertIsNone(layer)
|
||
self.assertEqual(status, LoadStatus.NONE)
|
||
|
||
# ------------------------------------------------------------------ #
|
||
# 3. Erfolgreicher Erstladevorgang #
|
||
# ------------------------------------------------------------------ #
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||
def test_success_returns_layer_and_first_status(
|
||
self, mock_ask_text, mock_project, mock_wfs_layer_cls
|
||
):
|
||
"""Kein bestehender Layer, WFS valide → (layer, FIRST)."""
|
||
mock_ask_text.return_value = ("1234, 5678", True)
|
||
mock_project.return_value = _DummyProject()
|
||
valid_layer = _DummyLayer(valid=True, layer_id="wfs_ok")
|
||
mock_wfs_layer_cls.return_value = valid_layer
|
||
|
||
layer, status = flurstueck_alkis(None)
|
||
|
||
self.assertIs(layer, valid_layer)
|
||
self.assertEqual(status, LoadStatus.FIRST)
|
||
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||
def test_sql_filter_contains_all_schluessel(
|
||
self, mock_ask_text, mock_project, mock_wfs_layer_cls
|
||
):
|
||
"""Der WFS-URI enthält alle eingegebenen Gemarkungsschlüssel."""
|
||
mock_ask_text.return_value = ("1111, 2222, 3333", True)
|
||
mock_project.return_value = _DummyProject()
|
||
mock_wfs_layer_cls.return_value = _DummyLayer(valid=True)
|
||
|
||
flurstueck_alkis(None)
|
||
|
||
# Erster Positionsarg von QgsVectorLayer ist der URI-String
|
||
call_args = mock_wfs_layer_cls.call_args
|
||
uri_str = call_args[0][0] if call_args[0] else call_args[1].get("path", "")
|
||
self.assertIn("1111", uri_str)
|
||
self.assertIn("2222", uri_str)
|
||
self.assertIn("3333", uri_str)
|
||
|
||
# ------------------------------------------------------------------ #
|
||
# 4. Bestehender Layer – Nutzer wählt "Neu laden" #
|
||
# ------------------------------------------------------------------ #
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QMessageBox")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||
def test_existing_layer_reload_yes(
|
||
self, mock_ask_text, mock_project, mock_msgbox_cls, mock_wfs_layer_cls
|
||
):
|
||
"""Bestehender Layer + Nutzer: 'Ja, neu laden' → LoadStatus.RELOAD."""
|
||
existing = _DummyLayer(valid=True, layer_id="old_flst")
|
||
project = _DummyProject(named_layers=[existing])
|
||
mock_ask_text.return_value = ("1234", True)
|
||
mock_project.return_value = project
|
||
|
||
# StandardButton als int, damit | Operator funktioniert
|
||
mock_msgbox_cls.StandardButton.Yes = 0x4000
|
||
mock_msgbox_cls.StandardButton.No = 0x10000
|
||
# QMessageBox.question → Yes
|
||
mock_msgbox_cls.question.return_value = 0x4000
|
||
|
||
new_layer = _DummyLayer(valid=True, layer_id="new_flst")
|
||
mock_wfs_layer_cls.return_value = new_layer
|
||
|
||
layer, status = flurstueck_alkis(None)
|
||
|
||
self.assertIn(existing.id(), project.removed)
|
||
self.assertIs(layer, new_layer)
|
||
self.assertEqual(status, LoadStatus.RELOAD)
|
||
|
||
# ------------------------------------------------------------------ #
|
||
# 5. Bestehender Layer – Nutzer wählt "Behalten" #
|
||
# ------------------------------------------------------------------ #
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QMessageBox")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||
def test_existing_layer_keep_no(
|
||
self, mock_ask_text, mock_project, mock_msgbox_cls
|
||
):
|
||
"""Bestehender Layer + Nutzer: 'Nein, behalten' → LoadStatus.KEEP."""
|
||
existing = _DummyLayer(valid=True, layer_id="keep_flst")
|
||
project = _DummyProject(named_layers=[existing])
|
||
mock_ask_text.return_value = ("1234", True)
|
||
mock_project.return_value = project
|
||
|
||
# StandardButton als int, damit | Operator funktioniert
|
||
mock_msgbox_cls.StandardButton.Yes = 0x4000
|
||
mock_msgbox_cls.StandardButton.No = 0x10000
|
||
# QMessageBox.question → No
|
||
mock_msgbox_cls.question.return_value = 0x10000
|
||
|
||
layer, status = flurstueck_alkis(None)
|
||
|
||
self.assertIs(layer, existing)
|
||
self.assertEqual(status, LoadStatus.KEEP)
|
||
self.assertEqual(project.removed, []) # nichts gelöscht
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|