test(sp41): drive shipped SP40 local validator through spot-check pipeline

Adds test_claim_passes_shipped_sp40_local_validator which feeds a
build_claim_output() result into the shipped
cyclone.parsers.validator.validate (the SP40 local pre-flight gate
that implements 25 R-codes including R010_clm01_present,
R020_npi_format, R021_npi_checksum, R030_frequency_allowed,
R100_payer_id_matches, R202_sbr09_allowed, R205_ref_ei_matches_provider).

This pins the local validator as a second source of truth for
structural correctness alongside the existing
test_full_pipeline_passes_mocked_edifabric (which drives the shipped
cyclone.edifabric.validate_edi through httpx.MockTransport). Together
the two tests prove the spot-check pipeline produces correct 837Ps
through the shipped serializer + the shipped validator + the shipped
Edifabric client, even when the live API is unavailable.

11/11 tests in test_rebill_spot_check.py pass.
This commit is contained in:
Nora
2026-07-08 01:17:36 -06:00
parent 26c948e7fc
commit ce61b36504
+22
View File
@@ -314,6 +314,28 @@ def test_full_pipeline_propagates_validate_error():
assert "quota" in str(excinfo.value.body).lower()
def test_claim_passes_shipped_sp40_local_validator():
"""The shipped SP40 local validator (25 R-codes) passes the ClaimOutput.
The local validator at ``cyclone.parsers.validator.validate`` is the
structural pre-flight gate that mirrors what Edifabric checks at the
/v2/x12/validate level. Running the same claim through it confirms
the spot-check pipeline produces structurally-correct 837Ps even
when the live Edifabric API is unavailable.
"""
from cyclone.parsers.payer import PayerConfig
from cyclone.parsers.validator import validate as validate_claim
visit = _visit()
claim = build_claim_output(visit)
report = validate_claim(claim, PayerConfig.co_medicaid())
assert report.passed, (
f"SP40 local validator rejected the claim: "
f"errors={[(i.rule, i.message) for i in report.errors]}"
)
assert not report.errors, f"unexpected errors: {report.errors}"
# --- Helpers -----------------------------------------------------------