2025-12-18 22:00:31 +01:00
# sn_basis/test/test_pruefmanager.py
2025-12-02 20:55:51 +01:00
import unittest
2025-12-18 22:00:31 +01:00
from unittest.mock import patch
2025-12-17 17:45:18 +01:00
2025-12-18 22:00:31 +01:00
from sn_basis.modules.Pruefmanager import Pruefmanager
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis
2025-12-17 17:45:18 +01:00
2025-12-18 22:00:31 +01:00
class TestPruefmanager ( unittest . TestCase ):
2025-12-02 20:55:51 +01:00
def setUp ( self ):
2025-12-18 22:00:31 +01:00
self . manager = Pruefmanager ()
2025-12-02 20:55:51 +01:00
2025-12-18 22:00:31 +01:00
# -----------------------------------------------------
# 1. OK-Ergebnis → keine Interaktion
# -----------------------------------------------------
def test_ok ( self ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass ein bereits erfolgreiches Prüfergebnis ohne Nutzerinteraktion als 'ok' durchgereicht wird."""
2025-12-18 22:00:31 +01:00
ergebnis = pruef_ergebnis ( True , "Alles gut" , "ok" , None )
entscheidung = self . manager . verarbeite ( ergebnis )
2025-12-17 17:45:18 +01:00
2025-12-18 22:00:31 +01:00
self . assertTrue ( entscheidung . ok )
self . assertEqual ( entscheidung . aktion , "ok" )
2025-12-02 20:55:51 +01:00
2025-12-18 22:00:31 +01:00
# -----------------------------------------------------
# 2. Leere Eingabe erlaubt → Nutzer sagt JA
# -----------------------------------------------------
2025-12-19 14:29:52 +01:00
@patch ( "sn_basis.modules.Pruefmanager.ask_yes_no" , return_value = True )
2025-12-18 22:00:31 +01:00
def test_leereingabe_erlaubt_ja ( self , mock_ask ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass bei erlaubter leerer Eingabe eine Ja-Antwort des Nutzers die Entscheidung 'ok' liefert."""
2025-12-18 22:00:31 +01:00
ergebnis = pruef_ergebnis ( False , "Leer?" , "leereingabe_erlaubt" , None )
entscheidung = self . manager . verarbeite ( ergebnis )
2025-12-02 20:55:51 +01:00
2025-12-18 22:00:31 +01:00
self . assertTrue ( entscheidung . ok )
self . assertEqual ( entscheidung . aktion , "ok" )
2025-12-02 20:55:51 +01:00
2025-12-18 22:00:31 +01:00
# -----------------------------------------------------
# 3. Leere Eingabe erlaubt → Nutzer sagt NEIN
# -----------------------------------------------------
2025-12-19 14:29:52 +01:00
@patch ( "sn_basis.modules.Pruefmanager.ask_yes_no" , return_value = False )
2025-12-18 22:00:31 +01:00
def test_leereingabe_erlaubt_nein ( self , mock_ask ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass bei erlaubter leerer Eingabe eine Nein-Antwort die Aktion 'leereingabe_erlaubt' als abgelehnt bestehen lässt."""
2025-12-18 22:00:31 +01:00
ergebnis = pruef_ergebnis ( False , "Leer?" , "leereingabe_erlaubt" , None )
entscheidung = self . manager . verarbeite ( ergebnis )
2025-12-17 17:45:18 +01:00
2025-12-18 22:00:31 +01:00
self . assertFalse ( entscheidung . ok )
self . assertEqual ( entscheidung . aktion , "leereingabe_erlaubt" )
2025-12-17 17:45:18 +01:00
2025-12-18 22:00:31 +01:00
# -----------------------------------------------------
# 4. Standarddatei vorschlagen → Nutzer sagt JA
# -----------------------------------------------------
2025-12-19 14:29:52 +01:00
@patch ( "sn_basis.modules.Pruefmanager.ask_yes_no" , return_value = True )
2025-12-18 22:00:31 +01:00
def test_standarddatei_vorschlagen_ja ( self , mock_ask ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass eine Ja-Antwort auf den Vorschlag der Standarddatei die Entscheidung 'ok' mit dem Standardpfad als Kontext liefert."""
2025-12-19 14:29:52 +01:00
ergebnis = pruef_ergebnis (
False ,
"Standarddatei verwenden?" ,
"standarddatei_vorschlagen" ,
"/tmp/std.txt" ,
)
2025-12-18 22:00:31 +01:00
entscheidung = self . manager . verarbeite ( ergebnis )
2025-12-17 17:45:18 +01:00
2025-12-18 22:00:31 +01:00
self . assertTrue ( entscheidung . ok )
self . assertEqual ( entscheidung . aktion , "ok" )
2025-12-19 14:29:52 +01:00
self . assertEqual ( entscheidung . kontext , "/tmp/std.txt" )
2025-12-02 20:55:51 +01:00
2025-12-18 22:00:31 +01:00
# -----------------------------------------------------
# 5. Standarddatei vorschlagen → Nutzer sagt NEIN
# -----------------------------------------------------
2025-12-19 14:29:52 +01:00
@patch ( "sn_basis.modules.Pruefmanager.ask_yes_no" , return_value = False )
2025-12-18 22:00:31 +01:00
def test_standarddatei_vorschlagen_nein ( self , mock_ask ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass eine Nein-Antwort auf den Vorschlag der Standarddatei die Aktion 'standarddatei_vorschlagen' als abgelehnt bestehen lässt."""
2025-12-19 14:29:52 +01:00
ergebnis = pruef_ergebnis (
False ,
"Standarddatei verwenden?" ,
"standarddatei_vorschlagen" ,
"/tmp/std.txt" ,
)
2025-12-18 22:00:31 +01:00
entscheidung = self . manager . verarbeite ( ergebnis )
2025-12-17 17:45:18 +01:00
2025-12-18 22:00:31 +01:00
self . assertFalse ( entscheidung . ok )
self . assertEqual ( entscheidung . aktion , "standarddatei_vorschlagen" )
2025-12-17 17:45:18 +01:00
2025-12-18 22:00:31 +01:00
# -----------------------------------------------------
# 6. Temporäre Datei erzeugen → Nutzer sagt JA
# -----------------------------------------------------
2025-12-19 14:29:52 +01:00
@patch ( "sn_basis.modules.Pruefmanager.ask_yes_no" , return_value = True )
2025-12-18 22:00:31 +01:00
def test_temporaer_erlaubt_ja ( self , mock_ask ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass eine Ja-Antwort auf die Rückfrage nach einer temporären Datei die Aktion 'temporaer_erzeugen' auslöst."""
2025-12-18 22:00:31 +01:00
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
# -----------------------------------------------------
2025-12-19 14:29:52 +01:00
@patch ( "sn_basis.modules.Pruefmanager.ask_yes_no" , return_value = False )
2025-12-18 22:00:31 +01:00
def test_temporaer_erlaubt_nein ( self , mock_ask ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass eine Nein-Antwort auf die Rückfrage nach einer temporären Datei die Aktion 'temporaer_erlaubt' als abgelehnt bestehen lässt."""
2025-12-18 22:00:31 +01:00
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
# -----------------------------------------------------
2025-12-19 14:29:52 +01:00
@patch ( "sn_basis.modules.Pruefmanager.ask_yes_no" , return_value = True )
@patch ( "sn_basis.modules.Pruefmanager.set_layer_visible" )
2025-12-18 22:00:31 +01:00
def test_layer_unsichtbar_ja ( self , mock_set , mock_ask ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass eine Ja-Antwort bei unsichtbarem Layer den Layer sichtbar schaltet und die Entscheidung 'ok' liefert."""
2025-12-18 22:00:31 +01:00
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
# -----------------------------------------------------
2025-12-19 14:29:52 +01:00
@patch ( "sn_basis.modules.Pruefmanager.ask_yes_no" , return_value = False )
2025-12-18 22:00:31 +01:00
def test_layer_unsichtbar_nein ( self , mock_ask ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass eine Nein-Antwort bei unsichtbarem Layer die Aktion 'layer_unsichtbar' als abgelehnt bestehen lässt."""
2025-12-18 22:00:31 +01:00
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
# -----------------------------------------------------
2025-12-19 14:29:52 +01:00
@patch ( "sn_basis.modules.Pruefmanager.warning" )
2025-12-18 22:00:31 +01:00
def test_unbekannte_aktion ( self , mock_warn ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass eine unbekannte Aktion eine Warnung auslöst und unverarbeitet als Fehlschlag zurückgegeben wird."""
2025-12-18 22:00:31 +01:00
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" )
2025-12-17 17:45:18 +01:00
2026-04-20 15:36:38 +02:00
@patch ( "sn_basis.modules.Pruefmanager.ask_overwrite_append_cancel_custom" , return_value = "overwrite" )
def test_datei_existiert_overwrite ( self , _mock_choice ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass die Nutzerwahl 'überschreiben' bei bestehender Datei zur Aktion 'datei_existiert_ueberschreiben' führt."""
2026-04-20 15:36:38 +02:00
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 ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass die Nutzerwahl 'anhängen' bei bestehender Datei zur Aktion 'datei_existiert_anhaengen' führt."""
2026-04-20 15:36:38 +02:00
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 ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass die Nutzerwahl 'abbrechen' bei bestehender Datei zur Aktion 'datei_existiert_ueberspringen' führt."""
2026-04-20 15:36:38 +02:00
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 ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass außerhalb des QGIS-Modus bei bestehender Datei keine Rückfrage erfolgt, sondern die ursprüngliche Aktion unentschieden zurückgegeben wird."""
2026-04-20 15:36:38 +02:00
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" )
2026-09-18 11:20:10 +02:00
# -----------------------------------------------------
# 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 ()
2025-12-17 17:45:18 +01:00
if __name__ == "__main__" :
unittest . main ()