from datetime import date from decimal import Decimal import pytest from app.parsers.base import (ParsedStatement, ParsedTransaction, ParserError, parse_german_amount, parse_german_date) from app.parsers.detect import detect_bank from app.parsers.validate import balance_difference, dedup_hash def test_parse_german_amount(): assert parse_german_amount("1.234,56") == Decimal("1234.56") assert parse_german_amount("1.234,56-") == Decimal("-1234.56") assert parse_german_amount("12,00 S") == Decimal("-12.00") assert parse_german_amount("12,00 H") == Decimal("12.00") assert parse_german_amount("1\xa0234,56") == Decimal("1234.56") def test_parse_german_date(): assert parse_german_date("03.06.2026") == date(2026, 6, 3) assert parse_german_date("03.06.", default_year=2026) == date(2026, 6, 3) def test_parse_german_date_invalid(): with pytest.raises(ParserError): parse_german_date("31.02.2026") def test_detect_bank(): assert detect_bank("... Volksbank Musterstadt eG ...") == "vr" assert detect_bank("... Raiffeisenbank ...") == "vr" assert detect_bank("... HypoVereinsbank ...") == "hvb" assert detect_bank("... UniCredit Bank ...") == "hvb" assert detect_bank("... Deutsche Kreditbank AG ...") == "dkb" assert detect_bank("... DKB ...") == "dkb" assert detect_bank("irgendwas") is None def _stmt(txs, opening, closing): return ParsedStatement(bank="vr", iban=None, period_start=None, period_end=None, opening_balance=opening, closing_balance=closing, transactions=txs) def test_balance_difference(): txs = [ParsedTransaction(date(2026, 6, 1), None, Decimal("-50"), "Miete", "V"), ParsedTransaction(date(2026, 6, 2), None, Decimal("20"), "Gutschrift", "K")] assert balance_difference(_stmt(txs, Decimal("100"), Decimal("70"))) == Decimal("0") assert balance_difference(_stmt(txs, Decimal("100"), Decimal("75"))) == Decimal("5") def test_dedup_hash_normalizes_whitespace(): a = dedup_hash(1, date(2026, 6, 1), Decimal("-50.00"), "Miete Juni") b = dedup_hash(1, date(2026, 6, 1), Decimal("-50.00"), "Miete Juni") assert a == b and len(a) == 64