Allow zero-euro line item amounts

This commit is contained in:
m3ta-chiron
2026-06-03 07:52:52 +02:00
parent d497a4cb5b
commit e2e1d8c046
5 changed files with 71 additions and 36 deletions
+12 -12
View File
@@ -4,8 +4,10 @@ Tests are written following TDD: FAILING TESTS FIRST (RED phase),
then implementation makes them pass (GREEN phase).
"""
import pytest
import base64
import binascii
import pytest
from pypdf import PdfReader, PdfWriter
@@ -49,7 +51,7 @@ class TestFileSizeValidation:
def test_file_size_limit_exactly_10mb(self):
"""Test PDF exactly at 10MB limit passes size check but fails PDF parsing."""
from src.extractor import extract_zugferd, ExtractionError
from src.extractor import ExtractionError, extract_zugferd
# 10MB = 10 * 1024 * 1024 bytes
large_pdf = b"X" * (10 * 1024 * 1024)
@@ -63,7 +65,7 @@ class TestFileSizeValidation:
def test_file_size_limit_10mb_plus_one_byte(self):
"""Test PDF one byte over 10MB limit is rejected."""
from src.extractor import extract_zugferd, ExtractionError
from src.extractor import ExtractionError, extract_zugferd
# 10MB + 1 byte
too_large = b"X" * (10 * 1024 * 1024 + 1)
@@ -75,7 +77,7 @@ class TestFileSizeValidation:
def test_file_size_under_10mb_accepted(self):
"""Test PDF under 10MB is accepted for processing."""
from src.extractor import extract_zugferd, ExtractionError
from src.extractor import ExtractionError, extract_zugferd
# Small PDF (9MB)
small_pdf = b"X" * (9 * 1024 * 1024)
@@ -166,8 +168,8 @@ class TestEN16931Extraction:
assert first_item.description is not None and len(first_item.description) > 0
assert first_item.quantity > 0
assert first_item.unit is not None and len(first_item.unit) > 0
assert first_item.unit_price > 0
assert first_item.line_total > 0
assert first_item.unit_price is not None and first_item.unit_price > 0
assert first_item.line_total is not None and first_item.line_total > 0
# Totals
assert xml_data.totals.line_total_sum > 0
@@ -181,7 +183,7 @@ class TestErrorHandling:
def test_corrupt_pdf_raises_error(self):
"""Test corrupt PDF raises ExtractionError with correct code."""
from src.extractor import extract_zugferd, ExtractionError
from src.extractor import ExtractionError, extract_zugferd
# Invalid PDF data
corrupt_pdf = b"NOT A PDF FILE AT ALL"
@@ -194,14 +196,14 @@ class TestErrorHandling:
def test_empty_pdf_raises_error(self):
"""Test empty PDF raises ExtractionError."""
from src.extractor import extract_zugferd, ExtractionError
from src.extractor import ExtractionError, extract_zugferd
with pytest.raises(ExtractionError):
extract_zugferd(b"")
def test_invalid_base64(self):
"""Test invalid base64 raises ExtractionError."""
from src.extractor import extract_zugferd, ExtractionError
from src.extractor import ExtractionError, extract_zugferd
# This would be called by API layer, but we can test the concept
# Invalid PDF that's not valid base64-encoded
@@ -210,7 +212,7 @@ class TestErrorHandling:
# If API layer decodes invalid base64, it gets error
decoded = base64.b64decode(invalid_base64, validate=True)
extract_zugferd(decoded)
except (base64.binascii.Error, ValueError):
except (binascii.Error, ValueError):
# base64 error is expected
pass
except ExtractionError as e:
@@ -232,8 +234,6 @@ class TestPDFTextExtraction:
assert result.pdf_text is not None
assert len(result.pdf_text) > 0
# Should contain some common German invoice terms
text_lower = result.pdf_text.lower()
# PDF text may contain invoice-related terms in German or English