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() qgis_utils.plugins = {} qgis_mod.utils = qgis_utils sys.modules["qgis"] = qgis_mod sys.modules["qgis.utils"] = qgis_utils from sn_verfahrensgebiet.functions import verfahrensgebiet_alkis as vg class _DummyMessageBox: class StandardButton: Yes = 1 No = 2 last_critical = None next_reply = StandardButton.No @staticmethod def question(_parent, _title, _message, _buttons, _default): return _DummyMessageBox.next_reply @staticmethod def critical(parent, title, message): _DummyMessageBox.last_critical = (parent, title, message) class _DummyProject: def __init__(self, layers=None): self._layers = layers or [] self.removed = [] def mapLayersByName(self, _name): return self._layers def removeMapLayer(self, layer_id): self.removed.append(layer_id) class _DummyExistingLayer: def __init__(self, layer_id="existing"): self._id = layer_id def id(self): return self._id class _DummyGeom: def __init__(self, empty=False): self._empty = empty def isEmpty(self): return self._empty class _DummyFeature: def __init__(self, geom=None): self._geom = geom or _DummyGeom() def geometry(self): return self._geom class _DummyTempLayer: def __init__(self, valid=True, features=None): self._valid = valid self._features = features or [] def isValid(self): return self._valid def getFeatures(self): return self._features def crs(self): class _Crs: @staticmethod def authid(): return "EPSG:25833" return _Crs() class _DummyProvider: def addAttributes(self, _attrs): return True def addFeatures(self, _features): return True class _DummyMemoryLayer: def __init__(self): self._provider = _DummyProvider() def dataProvider(self): return self._provider def updateFields(self): return None def updateExtents(self): return None class TestVerfahrensgebietAlkis(unittest.TestCase): @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QgsProject.instance") @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QMessageBox", new=_DummyMessageBox) def test_check_existing_layer_first_load(self, mock_project_instance): mock_project_instance.return_value = _DummyProject(layers=[]) layer, status = vg._check_existing_layer(tab_widget=None) self.assertIsNone(layer) self.assertEqual(status, vg.LoadStatus.FIRST) @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QgsProject.instance") @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QMessageBox", new=_DummyMessageBox) def test_check_existing_layer_keep_existing(self, mock_project_instance): existing = _DummyExistingLayer("L1") mock_project_instance.return_value = _DummyProject(layers=[existing]) _DummyMessageBox.next_reply = _DummyMessageBox.StandardButton.No layer, status = vg._check_existing_layer(tab_widget=None) self.assertIs(layer, existing) self.assertEqual(status, vg.LoadStatus.KEEP) @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QMessageBox", new=_DummyMessageBox) @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.get_variable", return_value="") def test_verfahrensgebiet_alkis_fails_when_verfahrensnummer_missing(self, _mock_get_var): _DummyMessageBox.last_critical = None layer, status = vg.verfahrensgebiet_alkis(tab_widget=None) self.assertIsNone(layer) self.assertEqual(status, vg.LoadStatus.NONE) self.assertIsNotNone(_DummyMessageBox.last_critical) @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis._check_existing_layer", return_value=(None, vg.LoadStatus.FIRST)) @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QMessageBox", new=_DummyMessageBox) @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.get_variable", return_value="VKZ123") @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QgsVectorLayer") def test_verfahrensgebiet_alkis_fails_on_invalid_wfs_layer(self, mock_qgsvectorlayer, _mock_get_var, _mock_check): _DummyMessageBox.last_critical = None mock_qgsvectorlayer.return_value = _DummyTempLayer(valid=False) layer, status = vg.verfahrensgebiet_alkis(tab_widget=None) self.assertIsNone(layer) self.assertEqual(status, vg.LoadStatus.NONE) self.assertIsNotNone(_DummyMessageBox.last_critical) @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QgsFeature") @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QgsGeometry.unaryUnion", return_value=_DummyGeom(empty=False)) @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis._check_existing_layer", return_value=(None, vg.LoadStatus.FIRST)) @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.get_variable", return_value="VKZ123") @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QgsVectorLayer") @patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QMessageBox", new=_DummyMessageBox) def test_verfahrensgebiet_alkis_success_returns_memory_layer(self, mock_qgsvectorlayer, _mock_get_var, _mock_check, _mock_union, mock_feature_cls): temp_layer = _DummyTempLayer(valid=True, features=[_DummyFeature()]) memory_layer = _DummyMemoryLayer() mock_qgsvectorlayer.side_effect = [temp_layer, memory_layer] mock_feature = mock_feature_cls.return_value mock_feature.setGeometry.return_value = None mock_feature.setAttributes.return_value = None layer, status = vg.verfahrensgebiet_alkis(tab_widget=None) self.assertIs(layer, memory_layer) self.assertEqual(status, vg.LoadStatus.FIRST) if __name__ == "__main__": unittest.main()