Files

159 lines
5.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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", "A", "V"],
"plan_hours_value": "6",
"pdf_field_ort": "unterschrift.ort",
"pdf_field_erstellungsdatum": "unterschrift.datum",
"pdf_pauschale_prefix": "pauschale_5",
"pauschale_present_value": "1",
}
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)