| from __future__ import annotations |
|
|
| import pytest |
|
|
| from app.schemas import parse_extract_json, to_cents |
|
|
|
|
| GOOD = """ |
| { |
| "doc_kind": "receipt", |
| "category": "groceries", |
| "vendor": "HEB", |
| "date": "2026-08-21", |
| "tax": 1.23, |
| "total": 14.56, |
| "currency": "USD", |
| "line_items": [ |
| {"description": "milk", "qty": 1, "unit_price": 4.29, "amount": 4.29, "sku": null} |
| ] |
| } |
| """ |
|
|
| FENCED = "```json\n" + GOOD + "\n```" |
|
|
|
|
| def test_parse_good() -> None: |
| extract = parse_extract_json(GOOD) |
| assert extract.vendor == "HEB" |
| assert extract.category == "groceries" |
| assert extract.line_items[0].description == "milk" |
| assert to_cents(extract.total) == 1456 |
|
|
|
|
| def test_parse_fenced() -> None: |
| extract = parse_extract_json(FENCED) |
| assert extract.date.isoformat() == "2026-08-21" |
|
|
|
|
| def test_unknown_category_falls_back() -> None: |
| raw = GOOD.replace("groceries", "snacks-aisle") |
| extract = parse_extract_json(raw) |
| assert extract.category == "other" |
|
|
|
|
| def test_bad_types() -> None: |
| with pytest.raises(Exception): |
| parse_extract_json('{"doc_kind":"receipt","line_items":"nope"}') |
|
|