Einklappbarer Bereich „Basemap“: Auswertebereich (Verfahrensgebiet/Druckbereich), Basemap-Legende beim Erstellen an/aus, „Basemap-Legende aktualisieren“ für bestehende Vorlagen und Stilvorlagen des Basemap-Layers. Stilvorlagen liegen lokal im QGIS-Profil (QML plus Begleitdatei mit Legendenauswahl), mehrere Varianten, eine als Standard markierbar; geladen wird nur auf Knopfdruck nach Rückfrage, fremde Varianten (andere Style-Namen) erst nach zweiter Bestätigung. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
175 lines
9.0 KiB
Python
175 lines
9.0 KiB
Python
"""
|
|
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()
|