first ruggedy draft

This commit is contained in:
2026-06-28 13:48:15 +02:00
parent c916f64fcb
commit 1053f6a2a3
78 changed files with 20905 additions and 2 deletions

107
tests/test_imap_importer.py Normal file
View File

@@ -0,0 +1,107 @@
from __future__ import annotations
from datetime import UTC, datetime
from email.message import EmailMessage
from email.utils import format_datetime
from mousehold_agent.imap_importer import parse_email_message
def test_klarna_email_becomes_outstanding_promised_payment() -> None:
message = EmailMessage()
message["From"] = "Klarna <noreply@klarna.de>"
message["To"] = "user@example.com"
message["Subject"] = "Deine Bestellung bei Example Shop"
message["Date"] = format_datetime(datetime(2026, 6, 20, 12, 0, tzinfo=UTC))
message["Message-ID"] = "<klarna-1@example.com>"
message.set_content(
"Bestellnummer: AB-12345\n"
"Gesamtbetrag: 84,00 €\n"
"Bitte bezahlen bis 30.06.2026.\n"
"Klarna Referenz: KR-98765"
)
parsed = parse_email_message(
message,
household_id="household-1",
owner_user_id="user-1",
source_account_id="account-1",
)
observation = parsed["observation"]
assert observation is not None
assert observation["source_type"] == "klarna_email"
assert observation["event_type"] == "promised_payment"
assert observation["status"] == "outstanding"
assert observation["amount"] == "84.00"
assert observation["due_date"] == "2026-06-30"
assert observation["provider_transaction_id"] == "KR-98765"
def test_paypal_email_becomes_announced_expense() -> None:
message = EmailMessage()
message["From"] = "service@paypal.de"
message["To"] = "user@example.com"
message["Subject"] = "You paid Example Merchant"
message["Date"] = format_datetime(datetime(2026, 6, 21, 9, 30, tzinfo=UTC))
message["Message-ID"] = "<paypal-1@example.com>"
message.set_content("Payment to: Example Merchant\nTotal EUR 18.99\nTransaction ID: 7AB123456789")
parsed = parse_email_message(
message,
household_id="household-1",
owner_user_id="user-1",
source_account_id="account-1",
)
observation = parsed["observation"]
assert observation is not None
assert observation["source_type"] == "paypal_email"
assert observation["event_type"] == "expense"
assert observation["status"] == "announced"
assert observation["amount"] == "18.99"
assert observation["provider_transaction_id"] == "7AB123456789"
def test_html_order_email_uses_html_body_and_announced_status() -> None:
message = EmailMessage()
message["From"] = "Shop <orders@example.test>"
message["Subject"] = "Your order from Example Store"
message["Date"] = format_datetime(datetime(2026, 6, 22, 18, 15, tzinfo=UTC))
message["Message-ID"] = "<order-1@example.com>"
message.set_content(
"<html><body><p>Order number: ORD-2026-1</p><p>Total: € 1.234,56</p></body></html>",
subtype="html",
)
parsed = parse_email_message(
message,
household_id="household-1",
owner_user_id=None,
source_account_id=None,
)
observation = parsed["observation"]
assert observation is not None
assert observation["source_type"] == "order_confirmation_email"
assert observation["status"] == "announced"
assert observation["amount"] == "1234.56"
assert observation["provider_transaction_id"] == "ORD-2026-1"
def test_email_without_amount_is_not_importable() -> None:
message = EmailMessage()
message["From"] = "Klarna <noreply@klarna.de>"
message["Subject"] = "Newsletter"
message.set_content("No transaction amount in this message.")
parsed = parse_email_message(
message,
household_id="household-1",
owner_user_id=None,
source_account_id=None,
)
assert parsed["observation"] is None
assert parsed["message"]["importable"] is False
assert parsed["message"]["skip_reason"] == "No EUR amount found"