infoxtractor/tests/unit/test_use_case_bank_statement_header.py
Dirk Riemann b80c7952f7
All checks were successful
tests / test (pull_request) Successful in 1m0s
tests / test (push) Successful in 58s
feat(use_cases): registry + bank_statement_header (spec §7)
First use case lands. The schema is intentionally flat — nine scalar fields,
no nested arrays — because Ollama's structured-output guidance stays most
reliable when the top level has only scalars, and every field we care about
(bank_name, IBAN, period, opening/closing balance) can be rendered as one.

Registration is explicit in `use_cases/__init__.py`, not a side effect of
importing the use-case module. That keeps load order obvious and lets tests
patch the registry without having to reload modules.

`get_use_case(name)` is the one-liner adapters use; it raises
`IX_001_001` with the offending name in `detail` when the lookup misses,
which keeps log-scrape simple.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 10:51:43 +02:00

54 lines
2.1 KiB
Python

"""Tests for the first use case, `bank_statement_header` (spec §7)."""
from __future__ import annotations
from datetime import date
from decimal import Decimal
from ix.use_cases.bank_statement_header import BankStatementHeader, Request
class TestRequest:
def test_defaults(self) -> None:
r = Request()
assert r.use_case_name == "Bank Statement Header"
assert r.default_model == "gpt-oss:20b"
# Stable substring for agent/worker tests that want to confirm the
# prompt is what they think it is.
assert "extract header metadata" in r.system_prompt
class TestBankStatementHeader:
def test_all_fields_optional_except_bank_name_and_currency(self) -> None:
# Minimal valid instance (per spec only bank_name + currency are required).
hdr = BankStatementHeader(bank_name="UBS", currency="CHF")
assert hdr.bank_name == "UBS"
assert hdr.currency == "CHF"
assert hdr.account_iban is None
assert hdr.statement_date is None
assert hdr.opening_balance is None
def test_full_populated_instance_roundtrip(self) -> None:
hdr = BankStatementHeader(
bank_name="UBS Switzerland AG",
account_iban="CH9300762011623852957",
account_type="checking",
currency="CHF",
statement_date=date(2026, 3, 31),
statement_period_start=date(2026, 3, 1),
statement_period_end=date(2026, 3, 31),
opening_balance=Decimal("1234.56"),
closing_balance=Decimal("2345.67"),
)
dumped = hdr.model_dump(mode="json")
rt = BankStatementHeader.model_validate(dumped)
assert rt.account_type == "checking"
assert rt.opening_balance == Decimal("1234.56")
assert rt.statement_period_start == date(2026, 3, 1)
def test_account_type_literal_rejects_unknown(self) -> None:
import pytest
from pydantic import ValidationError
with pytest.raises(ValidationError):
BankStatementHeader(bank_name="UBS", currency="CHF", account_type="weird") # type: ignore[arg-type]