103 lines
3.5 KiB
Python
103 lines
3.5 KiB
Python
import json
|
|
from datetime import date
|
|
from decimal import Decimal
|
|
|
|
import pytest
|
|
from pydantic import ValidationError as PydanticValidationError
|
|
|
|
from cyclone.parsers.models import (
|
|
Address,
|
|
BillingProvider,
|
|
ClaimHeader,
|
|
ClaimOutput,
|
|
Diagnosis,
|
|
Envelope,
|
|
Payer,
|
|
Procedure,
|
|
ServiceLine,
|
|
Subscriber,
|
|
ValidationIssue,
|
|
ValidationReport,
|
|
)
|
|
|
|
|
|
def test_address_round_trip():
|
|
a = Address(line1="1100 East Main St", line2="Suite A", city="Montrose", state="CO", zip="81401")
|
|
d = a.model_dump()
|
|
assert d["line1"] == "1100 East Main St"
|
|
assert d["line2"] == "Suite A"
|
|
assert Address.model_validate(d) == a
|
|
|
|
|
|
def test_address_line2_optional():
|
|
a = Address(line1="1 Main", city="X", state="CO", zip="80000")
|
|
assert a.line2 is None
|
|
|
|
|
|
def test_subscriber_splits_name():
|
|
s = Subscriber(first_name="John", last_name="Doe", member_id="ABC", dob=date(1980, 1, 1), gender="M", address=Address(line1="x", city="x", state="CO", zip="80000"))
|
|
assert s.first_name == "John"
|
|
assert s.gender == "M"
|
|
|
|
|
|
def test_service_line_units_are_decimal():
|
|
sl = ServiceLine(
|
|
line_number=1,
|
|
procedure=Procedure(qualifier="HC", code="99213", modifiers=[]),
|
|
charge=Decimal("100.00"),
|
|
unit_type="UN",
|
|
units=Decimal("1.0"),
|
|
)
|
|
assert sl.units == Decimal("1.0")
|
|
|
|
|
|
def test_claim_header_total_charge_decimal():
|
|
h = ClaimHeader(claim_id="C1", total_charge=Decimal("151.72"), place_of_service="12", frequency_code="1", provider_signature="Y", assignment="Y", release_of_info="Y", prior_auth="3173")
|
|
assert h.total_charge == Decimal("151.72")
|
|
|
|
|
|
def test_validation_issue_strict_severity():
|
|
issue = ValidationIssue(rule="R001", severity="error", message="bad")
|
|
assert issue.severity == "error"
|
|
with pytest.raises(PydanticValidationError):
|
|
ValidationIssue(rule="R001", severity="WTF", message="bad")
|
|
|
|
|
|
def test_validation_report_passed_true_when_no_errors():
|
|
r = ValidationReport(passed=True, errors=[], warnings=[])
|
|
assert r.passed is True
|
|
|
|
|
|
def test_envelope_serializes_to_iso_date():
|
|
e = Envelope(
|
|
sender_id="11525703",
|
|
receiver_id="COMEDASSISTPROG",
|
|
control_number="991102977",
|
|
transaction_date=date(2026, 6, 11),
|
|
transaction_time="081417",
|
|
implementation_guide="005010X222A1",
|
|
)
|
|
d = e.model_dump()
|
|
assert d["transaction_date"] == "2026-06-11"
|
|
|
|
|
|
def test_claim_output_full_round_trip():
|
|
claim = ClaimOutput(
|
|
claim_id="C1",
|
|
control_number="991102977",
|
|
transaction_date=date(2026, 6, 11),
|
|
billing_provider=BillingProvider(name="X", npi="1234567890", tax_id="123456789", address=Address(line1="1", city="x", state="CO", zip="80000")),
|
|
subscriber=Subscriber(first_name="J", last_name="D", member_id="M", dob=date(1980, 1, 1), gender="M", address=Address(line1="1", city="x", state="CO", zip="80000")),
|
|
payer=Payer(name="P", id="SKCO0"),
|
|
claim=ClaimHeader(claim_id="C1", total_charge=Decimal("100"), place_of_service="12", frequency_code="1", provider_signature="Y", assignment="Y", release_of_info="Y"),
|
|
diagnoses=[Diagnosis(code="R69", qualifier="ABK")],
|
|
service_lines=[],
|
|
validation=ValidationReport(passed=True, errors=[], warnings=[]),
|
|
raw_segments=[["CLM", "C1", "100"]],
|
|
)
|
|
blob = json.loads(claim.model_dump_json())
|
|
assert blob["claim_id"] == "C1"
|
|
assert blob["billing_provider"]["npi"] == "1234567890"
|
|
assert blob["raw_segments"] == [["CLM", "C1", "100"]]
|
|
assert ClaimOutput.model_validate(blob).claim_id == "C1"
|