erster versuch der KI mit Plan

This commit is contained in:
Rob committed 2026-03-27 13:18:07 +01:00
1 parent c697c64f3a
commit 2faa1689dd
20 files changed
+1749

No files matched your search

+155
View File
@@ -0,0 +1,155 @@
"""Tests for src/validators.py — pre-generation validation logic."""
import json
import re
from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
from src.validators import validate
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def _write_config(tmp_path: Path, overrides: dict = None) -> Path:
"""Write a valid config.json into tmp_path, optionally applying overrides."""
cfg = {
"antragsnummer": "12345",
"ort": "Teststadt",
"template_pdf": "template/sab.pdf",
"output_dir": "output",
"excel_year_pattern": "(19\\d{2}|20\\d{2})",
"excel_name_header": "Name, Vorname",
"excel_name_column": 1,
"excel_seq_column": 0,
"excel_day_start_col": 9,
"excel_day_end_col": 39,
"month_mapping": {"Feb": "02", "Jan": "01"},
"valid_status_codes": ["K", "KK", "E", "F", "P", "U"],
"plan_hours_value": "6",
"pauschale_value": "8,60",
}
if overrides:
cfg.update(overrides)
cfg_path = tmp_path / "config.json"
cfg_path.write_text(json.dumps(cfg), encoding="utf-8")
return cfg_path
def _write_dummy_xlsx(tmp_path: Path, name: str = "Anwesenheit_2026.xlsx") -> Path:
"""Create a minimal valid xlsx file using openpyxl."""
import openpyxl
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "Feb"
# Header row
ws.cell(row=1, column=2, value="Name, Vorname")
# Day headers (columns J–AN = col 10–40 in 1-based)
for col in range(10, 41):
ws.cell(row=1, column=col, value=col - 9) # day number as header
# Person row
ws.cell(row=2, column=1, value=1)
ws.cell(row=2, column=2, value="Mustermann, Max")
ws.cell(row=2, column=10, value=6.0) # day 1 → present 6h
xlsx_path = tmp_path / name
wb.save(str(xlsx_path))
return xlsx_path
def _write_dummy_pdf(tmp_path: Path) -> Path:
"""Create a 1-byte placeholder file that passes existence checks."""
pdf_path = tmp_path / "template" / "sab.pdf"
pdf_path.parent.mkdir(parents=True, exist_ok=True)
pdf_path.write_bytes(b"%PDF-1.4 placeholder")
return pdf_path
# ---------------------------------------------------------------------------
# Tests
# ---------------------------------------------------------------------------
class TestValidate:
def test_all_checks_pass(self, tmp_path):
cfg_path = _write_config(tmp_path)
xlsx_path = _write_dummy_xlsx(tmp_path)
_write_dummy_pdf(tmp_path)
# Reset config cache so the test config is used
from src.config_loader import reset_config_cache
reset_config_cache()
errors = validate(xlsx_path, "Feb", cfg_path)
assert errors == []
def test_excel_file_missing(self, tmp_path):
cfg_path = _write_config(tmp_path)
_write_dummy_pdf(tmp_path)
from src.config_loader import reset_config_cache
reset_config_cache()
errors = validate(tmp_path / "nonexistent.xlsx", "Feb", cfg_path)
assert any("nicht gefunden" in e for e in errors)
def test_year_not_in_filename(self, tmp_path):
cfg_path = _write_config(tmp_path)
xlsx_path = _write_dummy_xlsx(tmp_path, name="Anwesenheit_kein_jahr.xlsx")
_write_dummy_pdf(tmp_path)
from src.config_loader import reset_config_cache
reset_config_cache()
errors = validate(xlsx_path, "Feb", cfg_path)
assert any("Jahr" in e for e in errors)
def test_unknown_sheet_name(self, tmp_path):
cfg_path = _write_config(tmp_path)
xlsx_path = _write_dummy_xlsx(tmp_path)
_write_dummy_pdf(tmp_path)
from src.config_loader import reset_config_cache
reset_config_cache()
errors = validate(xlsx_path, "Xyz", cfg_path)
assert any("month_mapping" in e or "Sheet" in e for e in errors)
def test_pdf_template_missing(self, tmp_path):
# No _write_dummy_pdf call → template missing
cfg_path = _write_config(tmp_path)
xlsx_path = _write_dummy_xlsx(tmp_path)
from src.config_loader import reset_config_cache
reset_config_cache()
errors = validate(xlsx_path, "Feb", cfg_path)
assert any("Template" in e or "template" in e.lower() for e in errors)
def test_config_missing_key(self, tmp_path):
cfg = {
"antragsnummer": "123",
# omit 'ort' and other required keys
}
cfg_path = tmp_path / "config.json"
cfg_path.write_text(json.dumps(cfg), encoding="utf-8")
from src.config_loader import reset_config_cache
reset_config_cache()
errors = validate(tmp_path / "file.xlsx", "Feb", cfg_path)
assert any("Konfigurationsfehler" in e or "fehlen" in e.lower() for e in errors)
def test_non_xlsx_extension_flagged(self, tmp_path):
cfg_path = _write_config(tmp_path)
_write_dummy_pdf(tmp_path)
csv_path = tmp_path / "Anwesenheit_2026.csv"
csv_path.write_text("dummy")
from src.config_loader import reset_config_cache
reset_config_cache()
errors = validate(csv_path, "Feb", cfg_path)
assert any(".xlsx" in e or "Excel" in e for e in errors)