Extracted from /home/wizard/code monorepo into its own repo so Woodpecker CI can watch it. Identical content to /home/wizard/code commit e426028. See README.md for overview, env vars, and Paperless workflow config. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
from decimal import Decimal
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from payslip_ingest.schema import ExtractedPayslip, validate_totals
|
|
|
|
|
|
def _sample_payload() -> dict[str, object]:
|
|
return {
|
|
"pay_date": "2026-03-28",
|
|
"pay_period_start": "2026-03-01",
|
|
"pay_period_end": "2026-03-31",
|
|
"employer": "Acme Ltd",
|
|
"currency": "GBP",
|
|
"gross_pay": "5000.00",
|
|
"income_tax": "800.00",
|
|
"national_insurance": "350.00",
|
|
"pension_employee": "250.00",
|
|
"pension_employer": "150.00",
|
|
"student_loan": "100.00",
|
|
"other_deductions": {
|
|
"cycle_to_work": "50.00"
|
|
},
|
|
"net_pay": "3450.00",
|
|
}
|
|
|
|
|
|
def test_schema_accepts_realistic_payload() -> None:
|
|
model = ExtractedPayslip.model_validate(_sample_payload())
|
|
assert model.employer == "Acme Ltd"
|
|
assert model.gross_pay == Decimal("5000.00")
|
|
assert model.other_deductions == {"cycle_to_work": Decimal("50.00")}
|
|
|
|
|
|
def test_schema_rejects_extra_fields() -> None:
|
|
payload = _sample_payload()
|
|
payload["bonus_field"] = "not allowed"
|
|
with pytest.raises(ValidationError):
|
|
ExtractedPayslip.model_validate(payload)
|
|
|
|
|
|
def test_validate_totals_true_for_matched_numbers() -> None:
|
|
model = ExtractedPayslip.model_validate(_sample_payload())
|
|
assert validate_totals(model) is True
|
|
|
|
|
|
def test_validate_totals_false_for_mismatch() -> None:
|
|
payload = _sample_payload()
|
|
payload["net_pay"] = "4000.00"
|
|
model = ExtractedPayslip.model_validate(payload)
|
|
assert validate_totals(model) is False
|