# sn_basis/test/test_pruefmanager.py import unittest from unittest.mock import patch from sn_basis.modules.Pruefmanager import Pruefmanager from sn_basis.modules.pruef_ergebnis import pruef_ergebnis class TestPruefmanager(unittest.TestCase): def setUp(self): self.manager = Pruefmanager() # ----------------------------------------------------- # 1. OK-Ergebnis → keine Interaktion # ----------------------------------------------------- def test_ok(self): """Prüft, dass ein bereits erfolgreiches Prüfergebnis ohne Nutzerinteraktion als 'ok' durchgereicht wird.""" ergebnis = pruef_ergebnis(True, "Alles gut", "ok", None) entscheidung = self.manager.verarbeite(ergebnis) self.assertTrue(entscheidung.ok) self.assertEqual(entscheidung.aktion, "ok") # ----------------------------------------------------- # 2. Leere Eingabe erlaubt → Nutzer sagt JA # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.ask_yes_no", return_value=True) def test_leereingabe_erlaubt_ja(self, mock_ask): """Prüft, dass bei erlaubter leerer Eingabe eine Ja-Antwort des Nutzers die Entscheidung 'ok' liefert.""" ergebnis = pruef_ergebnis(False, "Leer?", "leereingabe_erlaubt", None) entscheidung = self.manager.verarbeite(ergebnis) self.assertTrue(entscheidung.ok) self.assertEqual(entscheidung.aktion, "ok") # ----------------------------------------------------- # 3. Leere Eingabe erlaubt → Nutzer sagt NEIN # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.ask_yes_no", return_value=False) def test_leereingabe_erlaubt_nein(self, mock_ask): """Prüft, dass bei erlaubter leerer Eingabe eine Nein-Antwort die Aktion 'leereingabe_erlaubt' als abgelehnt bestehen lässt.""" ergebnis = pruef_ergebnis(False, "Leer?", "leereingabe_erlaubt", None) entscheidung = self.manager.verarbeite(ergebnis) self.assertFalse(entscheidung.ok) self.assertEqual(entscheidung.aktion, "leereingabe_erlaubt") # ----------------------------------------------------- # 4. Standarddatei vorschlagen → Nutzer sagt JA # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.ask_yes_no", return_value=True) def test_standarddatei_vorschlagen_ja(self, mock_ask): """Prüft, dass eine Ja-Antwort auf den Vorschlag der Standarddatei die Entscheidung 'ok' mit dem Standardpfad als Kontext liefert.""" ergebnis = pruef_ergebnis( False, "Standarddatei verwenden?", "standarddatei_vorschlagen", "/tmp/std.txt", ) entscheidung = self.manager.verarbeite(ergebnis) self.assertTrue(entscheidung.ok) self.assertEqual(entscheidung.aktion, "ok") self.assertEqual(entscheidung.kontext, "/tmp/std.txt") # ----------------------------------------------------- # 5. Standarddatei vorschlagen → Nutzer sagt NEIN # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.ask_yes_no", return_value=False) def test_standarddatei_vorschlagen_nein(self, mock_ask): """Prüft, dass eine Nein-Antwort auf den Vorschlag der Standarddatei die Aktion 'standarddatei_vorschlagen' als abgelehnt bestehen lässt.""" ergebnis = pruef_ergebnis( False, "Standarddatei verwenden?", "standarddatei_vorschlagen", "/tmp/std.txt", ) entscheidung = self.manager.verarbeite(ergebnis) self.assertFalse(entscheidung.ok) self.assertEqual(entscheidung.aktion, "standarddatei_vorschlagen") # ----------------------------------------------------- # 6. Temporäre Datei erzeugen → Nutzer sagt JA # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.ask_yes_no", return_value=True) def test_temporaer_erlaubt_ja(self, mock_ask): """Prüft, dass eine Ja-Antwort auf die Rückfrage nach einer temporären Datei die Aktion 'temporaer_erzeugen' auslöst.""" ergebnis = pruef_ergebnis(False, "Temporär?", "temporaer_erlaubt", None) entscheidung = self.manager.verarbeite(ergebnis) self.assertTrue(entscheidung.ok) self.assertEqual(entscheidung.aktion, "temporaer_erzeugen") # ----------------------------------------------------- # 7. Temporäre Datei erzeugen → Nutzer sagt NEIN # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.ask_yes_no", return_value=False) def test_temporaer_erlaubt_nein(self, mock_ask): """Prüft, dass eine Nein-Antwort auf die Rückfrage nach einer temporären Datei die Aktion 'temporaer_erlaubt' als abgelehnt bestehen lässt.""" ergebnis = pruef_ergebnis(False, "Temporär?", "temporaer_erlaubt", None) entscheidung = self.manager.verarbeite(ergebnis) self.assertFalse(entscheidung.ok) self.assertEqual(entscheidung.aktion, "temporaer_erlaubt") # ----------------------------------------------------- # 8. Layer unsichtbar → Nutzer sagt JA # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.ask_yes_no", return_value=True) @patch("sn_basis.modules.Pruefmanager.set_layer_visible") def test_layer_unsichtbar_ja(self, mock_set, mock_ask): """Prüft, dass eine Ja-Antwort bei unsichtbarem Layer den Layer sichtbar schaltet und die Entscheidung 'ok' liefert.""" fake_layer = object() ergebnis = pruef_ergebnis(False, "Layer unsichtbar", "layer_unsichtbar", fake_layer) entscheidung = self.manager.verarbeite(ergebnis) mock_set.assert_called_once_with(fake_layer, True) self.assertTrue(entscheidung.ok) self.assertEqual(entscheidung.aktion, "ok") # ----------------------------------------------------- # 9. Layer unsichtbar → Nutzer sagt NEIN # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.ask_yes_no", return_value=False) def test_layer_unsichtbar_nein(self, mock_ask): """Prüft, dass eine Nein-Antwort bei unsichtbarem Layer die Aktion 'layer_unsichtbar' als abgelehnt bestehen lässt.""" fake_layer = object() ergebnis = pruef_ergebnis(False, "Layer unsichtbar", "layer_unsichtbar", fake_layer) entscheidung = self.manager.verarbeite(ergebnis) self.assertFalse(entscheidung.ok) self.assertEqual(entscheidung.aktion, "layer_unsichtbar") # ----------------------------------------------------- # 10. Fehlerhafte Aktion → Fallback # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.warning") def test_unbekannte_aktion(self, mock_warn): """Prüft, dass eine unbekannte Aktion eine Warnung auslöst und unverarbeitet als Fehlschlag zurückgegeben wird.""" ergebnis = pruef_ergebnis(False, "???", "unbekannt", None) entscheidung = self.manager.verarbeite(ergebnis) mock_warn.assert_called_once() self.assertFalse(entscheidung.ok) self.assertEqual(entscheidung.aktion, "unbekannt") @patch("sn_basis.modules.Pruefmanager.ask_overwrite_append_cancel_custom", return_value="overwrite") def test_datei_existiert_overwrite(self, _mock_choice): """Prüft, dass die Nutzerwahl 'überschreiben' bei bestehender Datei zur Aktion 'datei_existiert_ueberschreiben' führt.""" ergebnis = pruef_ergebnis(False, "Datei existiert", "datei_existiert", "C:/tmp/v.gpkg") entscheidung = self.manager.verarbeite(ergebnis) self.assertTrue(entscheidung.ok) self.assertEqual(entscheidung.aktion, "datei_existiert_ueberschreiben") self.assertEqual(entscheidung.kontext, "C:/tmp/v.gpkg") @patch("sn_basis.modules.Pruefmanager.ask_overwrite_append_cancel_custom", return_value="append") def test_datei_existiert_append(self, _mock_choice): """Prüft, dass die Nutzerwahl 'anhängen' bei bestehender Datei zur Aktion 'datei_existiert_anhaengen' führt.""" ergebnis = pruef_ergebnis(False, "Datei existiert", "datei_existiert", "C:/tmp/v.gpkg") entscheidung = self.manager.verarbeite(ergebnis) self.assertTrue(entscheidung.ok) self.assertEqual(entscheidung.aktion, "datei_existiert_anhaengen") @patch("sn_basis.modules.Pruefmanager.ask_overwrite_append_cancel_custom", return_value="cancel") def test_datei_existiert_cancel(self, _mock_choice): """Prüft, dass die Nutzerwahl 'abbrechen' bei bestehender Datei zur Aktion 'datei_existiert_ueberspringen' führt.""" ergebnis = pruef_ergebnis(False, "Datei existiert", "datei_existiert", "C:/tmp/v.gpkg") entscheidung = self.manager.verarbeite(ergebnis) self.assertTrue(entscheidung.ok) self.assertEqual(entscheidung.aktion, "datei_existiert_ueberspringen") def test_datei_existiert_in_non_qgis_mode_returns_input(self): """Prüft, dass außerhalb des QGIS-Modus bei bestehender Datei keine Rückfrage erfolgt, sondern die ursprüngliche Aktion unentschieden zurückgegeben wird.""" manager = Pruefmanager(ui_modus="test") ergebnis = pruef_ergebnis(False, "Datei existiert", "datei_existiert", "C:/tmp/v.gpkg") entscheidung = manager.verarbeite(ergebnis) self.assertFalse(entscheidung.ok) self.assertEqual(entscheidung.aktion, "datei_existiert") # ----------------------------------------------------- # 11. Verfahrensgebiet-Layer existiert bereits # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.ask_ergaenzen_entfernen_ersetzen_abbrechen", return_value="ergaenzen") def test_verfahrensgebiet_layer_existiert_ergaenzen(self, _mock_choice): """Prüft, dass die Nutzerwahl 'ergänzen' bei bestehendem Verfahrensgebiet zur Aktion 'verfahrensgebiet_ergaenzen' führt.""" ergebnis = pruef_ergebnis(False, "VG existiert", "verfahrensgebiet_layer_existiert", None) entscheidung = self.manager.verarbeite(ergebnis) self.assertTrue(entscheidung.ok) self.assertEqual(entscheidung.aktion, "verfahrensgebiet_ergaenzen") @patch("sn_basis.modules.Pruefmanager.ask_ergaenzen_entfernen_ersetzen_abbrechen", return_value="abbrechen") def test_verfahrensgebiet_layer_existiert_abbrechen(self, _mock_choice): """Prüft, dass die Nutzerwahl 'abbrechen' bei bestehendem Verfahrensgebiet ok=False mit Aktion 'verfahrensgebiet_abbrechen' liefert.""" ergebnis = pruef_ergebnis(False, "VG existiert", "verfahrensgebiet_layer_existiert", None) entscheidung = self.manager.verarbeite(ergebnis) self.assertFalse(entscheidung.ok) self.assertEqual(entscheidung.aktion, "verfahrensgebiet_abbrechen") def test_verfahrensgebiet_layer_existiert_in_non_qgis_mode_returns_input(self): """Prüft, dass außerhalb des QGIS-Modus bei bestehendem Verfahrensgebiet keine Rückfrage erfolgt.""" manager = Pruefmanager(ui_modus="test") ergebnis = pruef_ergebnis(False, "VG existiert", "verfahrensgebiet_layer_existiert", None) entscheidung = manager.verarbeite(ergebnis) self.assertFalse(entscheidung.ok) self.assertEqual(entscheidung.aktion, "verfahrensgebiet_layer_existiert") # ----------------------------------------------------- # 12. report_error: Einstufung nach Aktionscode # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.error") @patch("sn_basis.modules.Pruefmanager.warning") def test_report_error_kritische_aktion_ruft_error_auf(self, mock_warning, mock_error): """Prüft, dass eine kritische Aktion (z. B. 'netzwerkfehler') über error() gemeldet wird, nicht über warning().""" self.manager.report_error("Thema", "Meldung", aktion="netzwerkfehler") mock_error.assert_called_once_with("Thema", "Meldung") mock_warning.assert_not_called() @patch("sn_basis.modules.Pruefmanager.error") @patch("sn_basis.modules.Pruefmanager.warning") def test_report_error_warn_aktion_ruft_warning_auf(self, mock_warning, mock_error): """Prüft, dass eine Warn-Aktion (z. B. 'datei_nicht_gefunden') über warning() gemeldet wird, nicht über error().""" self.manager.report_error("Thema", "Meldung", aktion="datei_nicht_gefunden") mock_warning.assert_called_once_with("Thema", "Meldung") mock_error.assert_not_called() @patch("sn_basis.modules.Pruefmanager.error") @patch("sn_basis.modules.Pruefmanager.warning") def test_report_error_unbekannte_aktion_faellt_auf_warning_zurueck(self, mock_warning, mock_error): """Prüft, dass eine nicht eingestufte Aktion als Fallback über warning() gemeldet wird.""" self.manager.report_error("Thema", "Meldung", aktion="voellig_unbekannt") mock_warning.assert_called_once_with("Thema", "Meldung") mock_error.assert_not_called() # ----------------------------------------------------- # 13. frage_ja_nein # ----------------------------------------------------- @patch("sn_basis.modules.Pruefmanager.ask_yes_no", return_value=True) def test_frage_ja_nein_im_qgis_modus_fragt_nutzer(self, mock_ask): """Prüft, dass frage_ja_nein im QGIS-Modus den Nutzer fragt und dessen Antwort liefert.""" ergebnis = self.manager.frage_ja_nein("Titel", "Meldung", default=False) self.assertTrue(ergebnis) mock_ask.assert_called_once() @patch("sn_basis.modules.Pruefmanager.ask_yes_no") def test_frage_ja_nein_ausserhalb_qgis_liefert_default_ohne_rueckfrage(self, mock_ask): """Prüft, dass frage_ja_nein außerhalb des QGIS-Modus den Default-Wert liefert, ohne den Nutzer zu fragen.""" manager = Pruefmanager(ui_modus="test") ergebnis = manager.frage_ja_nein("Titel", "Meldung", default=True) self.assertTrue(ergebnis) mock_ask.assert_not_called() # ----------------------------------------------------- # 14. frage_text # ----------------------------------------------------- @patch("sn_basis.functions.dialog_wrapper.ask_text", return_value=("Neuer Text", True)) def test_frage_text_im_qgis_modus_fragt_nutzer(self, mock_ask): """Prüft, dass frage_text im QGIS-Modus den Nutzer fragt und Text plus OK-Status liefert.""" text, ok = self.manager.frage_text("Titel", "Meldung", default_text="Alt") self.assertEqual(text, "Neuer Text") self.assertTrue(ok) mock_ask.assert_called_once() @patch("sn_basis.functions.dialog_wrapper.ask_text") def test_frage_text_ausserhalb_qgis_liefert_default_ohne_rueckfrage(self, mock_ask): """Prüft, dass frage_text außerhalb des QGIS-Modus den Standardtext mit OK=True liefert, ohne den Nutzer zu fragen.""" manager = Pruefmanager(ui_modus="test") text, ok = manager.frage_text("Titel", "Meldung", default_text="Standard") self.assertEqual(text, "Standard") self.assertTrue(ok) mock_ask.assert_not_called() if __name__ == "__main__": unittest.main()