17e0496d2f
- Adds OcrResponse Pydantic schema for OCR branch JSON output. - Validates invoice_date and due_date as strict ISO 8601 calendar dates. - Adds field descriptions to InvoiceLineItem for clearer VLM prompts. - Expands schema tests for dates, decimal coercion, negatives, and line_items_sum().
85 lines
2.3 KiB
Python
85 lines
2.3 KiB
Python
"""Tests for invoice schema validation."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from decimal import Decimal
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from odoo_ocr.schemas import ExtractedInvoice, InvoiceLineItem
|
|
|
|
|
|
def test_accepts_valid_iso_dates() -> None:
|
|
invoice = ExtractedInvoice(
|
|
vendor_name="A",
|
|
invoice_number="1",
|
|
invoice_date="2024-01-01",
|
|
due_date="2024-02-01",
|
|
)
|
|
assert invoice.invoice_date == "2024-01-01"
|
|
assert invoice.due_date == "2024-02-01"
|
|
|
|
|
|
def test_rejects_non_iso_date_format() -> None:
|
|
with pytest.raises(ValidationError, match="ISO 8601"):
|
|
ExtractedInvoice(
|
|
vendor_name="A",
|
|
invoice_number="1",
|
|
invoice_date="May 1, 2024",
|
|
)
|
|
|
|
|
|
def test_rejects_invalid_calendar_date() -> None:
|
|
with pytest.raises(ValidationError, match="not a valid calendar date"):
|
|
ExtractedInvoice(
|
|
vendor_name="A",
|
|
invoice_number="1",
|
|
invoice_date="2024-02-30",
|
|
)
|
|
|
|
|
|
def test_due_date_optional() -> None:
|
|
invoice = ExtractedInvoice(
|
|
vendor_name="A",
|
|
invoice_number="1",
|
|
invoice_date="2024-01-01",
|
|
)
|
|
assert invoice.due_date is None
|
|
|
|
|
|
def test_invoice_line_item_decimal_coercion() -> None:
|
|
line = InvoiceLineItem(
|
|
description="Widgets",
|
|
quantity="2",
|
|
unit_price="10.5",
|
|
total_price="21.0",
|
|
tax_rate="20",
|
|
)
|
|
assert line.quantity == Decimal("2")
|
|
assert line.unit_price == Decimal("10.5")
|
|
assert line.total_price == Decimal("21.0")
|
|
assert line.tax_rate == Decimal("20")
|
|
|
|
|
|
def test_invoice_line_item_rejects_negative_values() -> None:
|
|
with pytest.raises(ValidationError):
|
|
InvoiceLineItem(description="X", quantity=-1)
|
|
with pytest.raises(ValidationError):
|
|
InvoiceLineItem(description="X", unit_price=-1)
|
|
with pytest.raises(ValidationError):
|
|
InvoiceLineItem(description="X", tax_rate=-5)
|
|
|
|
|
|
def test_line_items_sum() -> None:
|
|
invoice = ExtractedInvoice(
|
|
vendor_name="A",
|
|
invoice_number="1",
|
|
invoice_date="2024-01-01",
|
|
line_items=[
|
|
InvoiceLineItem(description="X", total_price=Decimal("100")),
|
|
InvoiceLineItem(description="Y", total_price=Decimal("50.50")),
|
|
],
|
|
)
|
|
assert invoice.line_items_sum() == Decimal("150.50")
|