tests überarbeitet
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Tests für das Plugin sn_verfahrensgebiet."""
|
||||
@@ -0,0 +1,86 @@
|
||||
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.ui.dockwidget import DockWidget
|
||||
|
||||
|
||||
class _DummyTabWidget:
|
||||
def __init__(self):
|
||||
self.tabs = []
|
||||
|
||||
def addTab(self, widget, title):
|
||||
self.tabs.append((widget, title))
|
||||
|
||||
|
||||
class _TabWithServices:
|
||||
tab_title = "WithServices"
|
||||
|
||||
def __init__(self, _parent):
|
||||
self.services = None
|
||||
|
||||
def set_services(self, pruefmanager=None, data_grabber=None):
|
||||
self.services = (pruefmanager, data_grabber)
|
||||
|
||||
|
||||
class _TabWithoutServices:
|
||||
tab_title = "WithoutServices"
|
||||
|
||||
def __init__(self, _parent):
|
||||
pass
|
||||
|
||||
|
||||
class _TabRaises:
|
||||
tab_title = "Broken"
|
||||
|
||||
def __init__(self, _parent):
|
||||
raise RuntimeError("boom")
|
||||
|
||||
|
||||
class TestDockWidget(unittest.TestCase):
|
||||
|
||||
@patch("sn_verfahrensgebiet.ui.dockwidget.QTabWidget", _DummyTabWidget)
|
||||
def test_init_tabs_with_services_injects_available_services(self):
|
||||
obj = DockWidget.__new__(DockWidget)
|
||||
obj.tabs = [_TabWithServices, _TabWithoutServices]
|
||||
obj.pruefmanager = object()
|
||||
obj.data_grabber = object()
|
||||
obj._set_widget_calls = []
|
||||
obj.setWidget = lambda value: obj._set_widget_calls.append(value)
|
||||
|
||||
DockWidget._init_tabs_with_services(obj)
|
||||
|
||||
self.assertEqual(len(obj._set_widget_calls), 2)
|
||||
tab_widget = obj._set_widget_calls[-1]
|
||||
self.assertIsInstance(tab_widget, _DummyTabWidget)
|
||||
self.assertEqual(len(tab_widget.tabs), 2)
|
||||
|
||||
first_tab = tab_widget.tabs[0][0]
|
||||
self.assertEqual(first_tab.services, (obj.pruefmanager, obj.data_grabber))
|
||||
|
||||
@patch("sn_verfahrensgebiet.ui.dockwidget.error")
|
||||
@patch("sn_verfahrensgebiet.ui.dockwidget.QTabWidget", _DummyTabWidget)
|
||||
def test_init_tabs_with_services_reports_errors(self, mock_error):
|
||||
obj = DockWidget.__new__(DockWidget)
|
||||
obj.tabs = [_TabRaises]
|
||||
obj.pruefmanager = object()
|
||||
obj.data_grabber = object()
|
||||
obj.setWidget = lambda _value: None
|
||||
|
||||
DockWidget._init_tabs_with_services(obj)
|
||||
|
||||
mock_error.assert_called_once()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,121 @@
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import Mock, 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.main import Verfahrensgebiet
|
||||
|
||||
|
||||
class _DummyIface:
|
||||
def __init__(self):
|
||||
self.removed = []
|
||||
|
||||
def mainWindow(self):
|
||||
return object()
|
||||
|
||||
def removeDockWidget(self, dock):
|
||||
self.removed.append(dock)
|
||||
|
||||
|
||||
class _DummyDock:
|
||||
def __init__(self):
|
||||
self.object_name = None
|
||||
self.action = None
|
||||
self.deleted = False
|
||||
|
||||
def setObjectName(self, name):
|
||||
self.object_name = name
|
||||
|
||||
def deleteLater(self):
|
||||
self.deleted = True
|
||||
|
||||
|
||||
class TestPluginMain(unittest.TestCase):
|
||||
|
||||
@patch("sn_verfahrensgebiet.main.DataGrabber")
|
||||
@patch("sn_verfahrensgebiet.main.Pruefmanager")
|
||||
def test_init_sets_services_and_names(self, mock_pruefmanager, mock_data_grabber):
|
||||
pm = object()
|
||||
dg = object()
|
||||
mock_pruefmanager.return_value = pm
|
||||
mock_data_grabber.return_value = dg
|
||||
|
||||
plugin = Verfahrensgebiet(_DummyIface())
|
||||
|
||||
self.assertIs(plugin.pruefmanager, pm)
|
||||
self.assertIs(plugin.data_grabber, dg)
|
||||
self.assertEqual(plugin.plugin_name, "Verfahrensgebiet")
|
||||
self.assertEqual(plugin.dock_name, "sn_dock_verfahrensgebiet")
|
||||
|
||||
@patch("sn_verfahrensgebiet.main.plugins", new_callable=dict)
|
||||
def test_initGui_registers_action_when_basis_ui_exists(self, mock_plugins):
|
||||
iface = _DummyIface()
|
||||
plugin = Verfahrensgebiet(iface)
|
||||
|
||||
ui = SimpleNamespace(
|
||||
add_action=Mock(return_value="action_obj"),
|
||||
finalize_menu_and_toolbar=Mock(),
|
||||
)
|
||||
mock_plugins["sn_basis"] = SimpleNamespace(ui=ui)
|
||||
|
||||
plugin.initGui()
|
||||
|
||||
self.assertEqual(plugin.action, "action_obj")
|
||||
ui.add_action.assert_called_once()
|
||||
ui.finalize_menu_and_toolbar.assert_called_once()
|
||||
|
||||
@patch("sn_verfahrensgebiet.main.plugins", new_callable=dict)
|
||||
@patch("sn_verfahrensgebiet.main.DockManager.show")
|
||||
@patch("sn_verfahrensgebiet.main.DockWidget")
|
||||
def test_run_creates_dock_and_marks_toolbar_active(self, mock_dockwidget_cls, mock_show, mock_plugins):
|
||||
iface = _DummyIface()
|
||||
plugin = Verfahrensgebiet(iface)
|
||||
plugin.action = "action_obj"
|
||||
|
||||
dock = _DummyDock()
|
||||
mock_dockwidget_cls.return_value = dock
|
||||
|
||||
ui = SimpleNamespace(set_active_plugin=Mock())
|
||||
mock_plugins["sn_basis"] = SimpleNamespace(ui=ui)
|
||||
|
||||
plugin.run()
|
||||
|
||||
self.assertIs(plugin.dockwidget, dock)
|
||||
self.assertEqual(dock.object_name, "sn_dock_verfahrensgebiet")
|
||||
self.assertEqual(dock.action, "action_obj")
|
||||
mock_show.assert_called_once_with(dock)
|
||||
ui.set_active_plugin.assert_called_once_with("action_obj")
|
||||
|
||||
@patch("sn_verfahrensgebiet.main.plugins", new_callable=dict)
|
||||
def test_unload_removes_dock_and_action(self, mock_plugins):
|
||||
iface = _DummyIface()
|
||||
plugin = Verfahrensgebiet(iface)
|
||||
|
||||
dock = _DummyDock()
|
||||
plugin.dockwidget = dock
|
||||
plugin.action = "action_obj"
|
||||
|
||||
ui = SimpleNamespace(remove_action=Mock())
|
||||
mock_plugins["sn_basis"] = SimpleNamespace(ui=ui)
|
||||
|
||||
plugin.unload()
|
||||
|
||||
self.assertIn(dock, iface.removed)
|
||||
self.assertTrue(dock.deleted)
|
||||
self.assertIsNone(plugin.dockwidget)
|
||||
ui.remove_action.assert_called_once_with("action_obj")
|
||||
self.assertIsNone(plugin.action)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,184 @@
|
||||
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()
|
||||
@@ -0,0 +1,156 @@
|
||||
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"):
|
||||
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):
|
||||
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.verf_layer_combo = _DummyCombo()
|
||||
tab.haken_verf = object()
|
||||
tab.setze_haken = lambda *_args, **_kwargs: None
|
||||
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")
|
||||
@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,
|
||||
mock_project_instance,
|
||||
mock_apply_style,
|
||||
mock_success,
|
||||
):
|
||||
tab = self._make_tab()
|
||||
layer = _DummyLayer(valid=True, layer_id="layer_ok")
|
||||
mock_alkis.return_value = (layer, LoadStatus.FIRST)
|
||||
mock_project_instance.return_value = _DummyProject()
|
||||
mock_iface.mapCanvas.return_value = _DummyCanvas()
|
||||
|
||||
tab.handle_verf_alkis()
|
||||
|
||||
mock_apply_style.assert_called_once()
|
||||
mock_success.assert_called_once()
|
||||
mock_set_layer_id.assert_called_with("layer_ok")
|
||||
|
||||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
|
||||
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_alkis", return_value=(None, LoadStatus.NONE))
|
||||
def test_handle_verf_alkis_failure_clears_layer_var(self, _mock_alkis, mock_set_layer_id):
|
||||
tab = self._make_tab()
|
||||
|
||||
tab.handle_verf_alkis()
|
||||
|
||||
mock_set_layer_id.assert_called_once_with("")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user