"""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()