70 neue Testfälle für Datenabruf.py, Datenschreiber.py, LayerLoader.py und excel_importer.py - die einzigen Module ohne jede Testdatei laut Testkatalog-Abschnitt "Ungetestete Funktionen". Schwerpunkt: Provider-URL- Bau (WFS/REST/OGR), Raumfilter, CRS-Transformation, GPKG-Schreib-/Ladepfad und Excel-Import-Fehlerzweige. qgiscore_wrapper._MockQgsProject um transformContext() und addMapLayer() ergänzt - beide fehlten im Mock und ließen die betroffenen Funktionen im Mock-Modus für jeden gültigen Layer scheitern (siehe fallstricke.md). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
117 lines
4.8 KiB
Python
117 lines
4.8 KiB
Python
"""Tests für sn_basis/modules/excel_importer.py (Excel-Import für Linklisten, Issue #63)."""
|
|
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from typing import Any, List, cast
|
|
|
|
from openpyxl import Workbook
|
|
|
|
from sn_basis.modules.excel_importer import ExcelImporter
|
|
|
|
|
|
class _AufzeichnenderPruefmanager:
|
|
def __init__(self) -> None:
|
|
self.ergebnisse: List[Any] = []
|
|
|
|
def verarbeite(self, ergebnis: Any):
|
|
self.ergebnisse.append(ergebnis)
|
|
return ergebnis
|
|
|
|
|
|
class ImportXlsxTests(unittest.TestCase):
|
|
def test_erfolgreicher_import_liefert_zeilen_als_dicts(self):
|
|
"""Prüft, dass eine gültige Excel-Datei als Liste von Dicts mit den Header-Spalten geliefert wird."""
|
|
pruefmanager = _AufzeichnenderPruefmanager()
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
pfad = Path(tmp) / "linkliste.xlsx"
|
|
wb = Workbook()
|
|
ws = wb.active
|
|
ws.append(["ident", "Link", "Provider"])
|
|
ws.append(["1", "http://server/wfs", "WFS"])
|
|
ws.append(["2", "http://server/rest", "REST"])
|
|
wb.save(pfad)
|
|
|
|
importer = ExcelImporter(filepath=str(pfad), pruefmanager=cast(Any, pruefmanager))
|
|
zeilen = importer.import_xlsx()
|
|
|
|
self.assertEqual(
|
|
zeilen,
|
|
[
|
|
{"ident": "1", "Link": "http://server/wfs", "Provider": "WFS"},
|
|
{"ident": "2", "Link": "http://server/rest", "Provider": "REST"},
|
|
],
|
|
)
|
|
|
|
def test_fehlende_datei_liefert_leere_liste(self):
|
|
"""Prüft, dass eine nicht vorhandene Datei eine leere Liste liefert, statt eine Ausnahme zu werfen."""
|
|
pruefmanager = _AufzeichnenderPruefmanager()
|
|
importer = ExcelImporter(filepath="C:/nicht/vorhanden/linkliste.xlsx", pruefmanager=cast(Any, pruefmanager))
|
|
|
|
zeilen = importer.import_xlsx()
|
|
|
|
self.assertEqual(zeilen, [])
|
|
aktionen = [getattr(e, "aktion", None) for e in pruefmanager.ergebnisse]
|
|
self.assertIn("datei_nicht_gefunden", aktionen)
|
|
|
|
def test_arbeitsblatt_ohne_header_liefert_leere_liste_und_meldet_kein_header(self):
|
|
"""Prüft, dass ein leeres Arbeitsblatt ohne Header-Zeile 'kein_header' meldet und eine leere Liste liefert."""
|
|
pruefmanager = _AufzeichnenderPruefmanager()
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
pfad = Path(tmp) / "leer.xlsx"
|
|
Workbook().save(pfad)
|
|
|
|
importer = ExcelImporter(filepath=str(pfad), pruefmanager=cast(Any, pruefmanager))
|
|
zeilen = importer.import_xlsx()
|
|
|
|
self.assertEqual(zeilen, [])
|
|
aktionen = [getattr(e, "aktion", None) for e in pruefmanager.ergebnisse]
|
|
self.assertIn("kein_header", aktionen)
|
|
|
|
def test_header_zeile_nur_leere_werte_liefert_kein_header(self):
|
|
"""Prüft, dass eine Header-Zeile aus ausschließlich leeren Zellen ebenfalls als 'kein_header' gilt."""
|
|
pruefmanager = _AufzeichnenderPruefmanager()
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
pfad = Path(tmp) / "leerer_header.xlsx"
|
|
wb = Workbook()
|
|
ws = wb.active
|
|
ws.append([None, None, None])
|
|
wb.save(pfad)
|
|
|
|
importer = ExcelImporter(filepath=str(pfad), pruefmanager=cast(Any, pruefmanager))
|
|
zeilen = importer.import_xlsx()
|
|
|
|
self.assertEqual(zeilen, [])
|
|
aktionen = [getattr(e, "aktion", None) for e in pruefmanager.ergebnisse]
|
|
self.assertIn("kein_header", aktionen)
|
|
|
|
def test_nicht_lesbare_datei_liefert_leere_liste_und_meldet_read_error(self):
|
|
"""Prüft, dass eine Datei mit ungültigem Excel-Inhalt 'read_error' meldet und eine leere Liste liefert."""
|
|
pruefmanager = _AufzeichnenderPruefmanager()
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
pfad = Path(tmp) / "kaputt.xlsx"
|
|
pfad.write_text("Das ist keine gültige Excel-Datei", encoding="utf-8")
|
|
|
|
importer = ExcelImporter(filepath=str(pfad), pruefmanager=cast(Any, pruefmanager))
|
|
zeilen = importer.import_xlsx()
|
|
|
|
self.assertEqual(zeilen, [])
|
|
aktionen = [getattr(e, "aktion", None) for e in pruefmanager.ergebnisse]
|
|
self.assertIn("read_error", aktionen)
|
|
|
|
|
|
class ExcelImporterKonstruktorTests(unittest.TestCase):
|
|
def test_ohne_dateipfad_wirft_valueerror(self):
|
|
"""Prüft, dass ExcelImporter ohne Dateipfad einen ValueError wirft."""
|
|
with self.assertRaises(ValueError):
|
|
ExcelImporter(filepath="", pruefmanager=cast(Any, _AufzeichnenderPruefmanager()))
|
|
|
|
def test_ohne_pruefmanager_wirft_valueerror(self):
|
|
"""Prüft, dass ExcelImporter ohne Pruefmanager einen ValueError wirft."""
|
|
with self.assertRaises(ValueError):
|
|
ExcelImporter(filepath="C:/tmp/x.xlsx", pruefmanager=cast(Any, None))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|