""" Tests für die Anbindung der Basemap-Legende an Druckablauf, Dialog und Druck-Tab (Basis #88): Mehrfachauswahl-Dialog, PrintLogic/PrintLayout und Basemap-Bereich im Druck-Tab. """ import json import unittest from unittest.mock import MagicMock, patch from sn_basis.functions.dialog_wrapper import ask_mehrfachauswahl from sn_basis.functions.variable_wrapper import get_variable, set_variable from sn_basis.modules import basemap_legende as bl from sn_basis.modules.print_layout import PrintLayout from sn_basis.modules.print_logic import ( KARTENNAME_38, KARTENNAME_41, KARTENNAME_BAUFREIGABE, LAYOUTS_MIT_BASEMAP_LEGENDE, PrintLogic, ) from sn_basis.ui.tabs.print_tab import PrintTab from sn_basis.ui.widgets.basemap_bereich import BasemapBereich class TestMehrfachauswahl(unittest.TestCase): def test_mock_modus_liefert_vorauswahl_in_listenreihenfolge(self): """Prüft, dass der Mehrfachauswahl-Dialog im Mock-Modus die vorausgewählten Schlüssel in Listenreihenfolge liefert.""" eintraege = [{"schluessel": s, "text": s.upper()} for s in ("a", "b", "c")] self.assertEqual(ask_mehrfachauswahl("T", "H", eintraege, {"c", "a"}), ["a", "c"]) class TestDruckanbindung(unittest.TestCase): def tearDown(self): set_variable(bl.LEGENDE_ERZEUGEN_VAR, "", scope="project") def test_basemap_legende_nur_fuer_38_und_41_und_bei_eingeschaltetem_schalter(self): """Prüft, dass nur §-38- und §-41-Vorlagen eine Basemap-Legende bekommen und nur, wenn der Schalter im Druck-Tab an ist.""" logik = PrintLogic(pruefmanager=MagicMock()) self.assertEqual(LAYOUTS_MIT_BASEMAP_LEGENDE, {KARTENNAME_38, KARTENNAME_41}) self.assertTrue(logik._basemap_legende_erzeugen(KARTENNAME_41)) self.assertFalse(logik._basemap_legende_erzeugen(KARTENNAME_BAUFREIGABE)) bl.setze_legende_erzeugen(False) self.assertFalse(logik._basemap_legende_erzeugen(KARTENNAME_38)) def test_layout_wird_markiert_und_legende_erzeugt(self): """Prüft, dass PrintLayout das Layout als Basemap-Nutzer kennzeichnet und die Basemap-Legende erzeugen lässt.""" layout = MagicMock() with patch("sn_basis.modules.basemap_legende.BasemapLegende") as klasse: klasse.return_value.aktualisiere.return_value = {"status": "ok"} PrintLayout(project=MagicMock())._erzeuge_basemap_legende(layout) layout.setCustomProperty.assert_any_call("sn_basemap_legende", 1) klasse.return_value.aktualisiere.assert_called_once_with(layout) def test_fehler_der_basemap_legende_verhindert_die_vorlage_nicht(self): """Prüft, dass ein Fehler beim Erzeugen der Basemap-Legende nur als Warnung gemeldet wird und keine Ausnahme durchreicht.""" with patch("sn_basis.modules.basemap_legende.BasemapLegende") as klasse, \ patch("sn_basis.functions.message_wrapper.warning") as warnung: klasse.return_value.aktualisiere.side_effect = RuntimeError("Netz weg") PrintLayout(project=MagicMock())._erzeuge_basemap_legende(MagicMock()) warnung.assert_called_once() self.assertIn("Netz weg", warnung.call_args[0][1]) def test_druck_tab_aktualisiert_basemap_bereich_falls_vorhanden(self): """Prüft, dass der Druck-Tab den Basemap-Bereich neu einliest und ohne Bereich nichts tut.""" tab = PrintTab.__new__(PrintTab) tab._basemap_bereich_aktualisieren() # ohne Bereich: keine Ausnahme tab._basemap_bereich = MagicMock() tab._basemap_bereich_aktualisieren() tab._basemap_bereich.aktualisieren.assert_called_once() def _bereich(stil_name="Ohne_Hausnummern", layer=None, layout_name="§41"): bereich = BasemapBereich.__new__(BasemapBereich) bereich._project = MagicMock() bereich._stilvorlagen = MagicMock() bereich._stil_combo = MagicMock() bereich._stil_combo.currentData.return_value = stil_name bereich._stil_combo.currentText.return_value = stil_name bereich._layout_combo = MagicMock() bereich._layout_combo.currentText.return_value = layout_name bereich._bereich_combo = MagicMock() bereich.basemap_layer = MagicMock(return_value=layer) bereich.aktualisieren = MagicMock() return bereich class TestBasemapBereich(unittest.TestCase): def tearDown(self): for schluessel in (bl.AUSWAHL_VAR, bl.AUSWERTEBEREICH_VAR): set_variable(schluessel, "", scope="project") def test_auswertebereich_wird_gespeichert(self): """Prüft, dass die Wahl des Auswertebereichs in der Projektvariable landet.""" bereich = _bereich() bereich._bereich_combo.currentData.return_value = bl.AUSWERTEBEREICH_DRUCKBEREICH bereich._on_bereich_geaendert(1) self.assertEqual(bl.lies_auswertebereich(), bl.AUSWERTEBEREICH_DRUCKBEREICH) @patch("sn_basis.ui.widgets.basemap_bereich.warning") def test_aktualisieren_ohne_vorlage_warnt(self, warnung): """Prüft, dass „Basemap-Legende aktualisieren“ ohne vorhandene Vorlage warnt und nichts auswertet.""" bereich = _bereich() bereich._project.layoutManager.return_value.layoutByName.return_value = None with patch("sn_basis.modules.basemap_legende.BasemapLegende") as klasse: bereich._on_legende_aktualisieren() klasse.assert_not_called() warnung.assert_called_once() @patch("sn_basis.ui.widgets.basemap_bereich.success") def test_aktualisieren_wertet_gewaehlte_vorlage_aus(self, erfolg): """Prüft, dass „Basemap-Legende aktualisieren“ die gewählte Vorlage auswertet und den Erfolg meldet.""" bereich = _bereich() layout = bereich._project.layoutManager.return_value.layoutByName.return_value with patch("sn_basis.modules.basemap_legende.BasemapLegende") as klasse: klasse.return_value.aktualisiere.return_value = {"status": "ok", "meldung": "3 Einträge"} bereich._on_legende_aktualisieren() klasse.return_value.aktualisiere.assert_called_once_with(layout) erfolg.assert_called_once() @patch("sn_basis.ui.widgets.basemap_bereich.ask_yes_no", return_value=True) @patch("sn_basis.ui.widgets.basemap_bereich.success") def test_stil_laden_uebernimmt_legendenauswahl(self, _erfolg, _frage): """Prüft, dass das Laden einer Stilvorlage den Layerstil ersetzt und ihre Legendenauswahl in das Projekt übernimmt.""" layer = MagicMock() bereich = _bereich(layer=layer) bereich._stilvorlagen.pruefe_passung.return_value = [] bereich._stilvorlagen.legendenauswahl.return_value = {"ausgeblendet": ["wald"], "eingeblendet": []} bereich._on_stil_laden() bereich._stilvorlagen.laden.assert_called_once_with(layer, "Ohne_Hausnummern") self.assertEqual(json.loads(get_variable(bl.AUSWAHL_VAR, scope="project"))["ausgeblendet"], ["wald"]) @patch("sn_basis.ui.widgets.basemap_bereich.ask_yes_no", side_effect=[True, False]) def test_stil_laden_bricht_bei_fremder_vorlage_ab(self, _frage): """Prüft, dass eine Vorlage mit unbekannten Styles nur nach Bestätigung geladen wird.""" bereich = _bereich(layer=MagicMock()) bereich._stilvorlagen.pruefe_passung.return_value = ["Fremder_Style"] bereich._on_stil_laden() bereich._stilvorlagen.laden.assert_not_called() @patch("sn_basis.ui.widgets.basemap_bereich.ask_text", return_value=("Ohne Hausnummern", True)) @patch("sn_basis.ui.widgets.basemap_bereich.ask_yes_no", return_value=False) def test_vorhandene_vorlage_wird_nur_nach_rueckfrage_ersetzt(self, _frage, _text): """Prüft, dass eine gleichnamige Stilvorlage ohne Bestätigung nicht überschrieben wird.""" bereich = _bereich(layer=MagicMock()) bereich._stilvorlagen.vorhanden.return_value = True bereich._on_stil_speichern() bereich._stilvorlagen.speichern.assert_not_called() @patch("sn_basis.ui.widgets.basemap_bereich.ask_text", return_value=("Neu", True)) @patch("sn_basis.ui.widgets.basemap_bereich.success") def test_speichern_mit_aktueller_legendenauswahl(self, _erfolg, _text): """Prüft, dass eine neue Stilvorlage zusammen mit der aktuellen Legendenauswahl gespeichert wird.""" layer = MagicMock() bereich = _bereich(layer=layer) bereich._stilvorlagen.vorhanden.return_value = False bl.merke_auswahl([bl.LegendenEintrag("wald", "Wald", "Vegetation", [])], []) bereich._on_stil_speichern() bereich._stilvorlagen.speichern.assert_called_once_with( layer, "Neu", {"ausgeblendet": ["wald"], "eingeblendet": []}) bereich.aktualisieren.assert_called_once() @patch("sn_basis.ui.widgets.basemap_bereich.warning") def test_stil_speichern_ohne_basemap_layer_warnt(self, warnung): """Prüft, dass ohne Basemap-Layer keine Stilvorlage gespeichert, sondern gewarnt wird.""" bereich = _bereich(layer=None) bereich._on_stil_speichern() bereich._stilvorlagen.speichern.assert_not_called() warnung.assert_called_once() if __name__ == "__main__": unittest.main()