c62826daea
- providers table seeded with 3 NPIs (Montrose, Delta, Salida) - payers + payer_configs (per-tx config) join table - clearhouse singleton (dzinesco identity, SFTP block, filename block) - config/payers.yaml loader with Pydantic schema validation - cyclone/edi/filenames.py: HCPF X12 File Naming Standards helpers - cyclone/clearhouse/sftp.py: stub that copies to ./var/sftp/staging/... - cyclone/secrets.py: macOS Keychain wrapper via keyring - 11 new validation rules R200-R210 (CO MAP + HCPF naming) - 6 new API endpoints (/api/clearhouse/*, /api/config/*, /api/admin/reload-config) - migration 0007 - 72 new tests (646 total passing, was 574) See spec: docs/superpowers/specs/2026-06-20-cyclone-multi-payer-npi-sftp-design.md
114 lines
3.7 KiB
Python
114 lines
3.7 KiB
Python
"""SP9 — payer config YAML loader tests."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
import yaml
|
|
|
|
from cyclone import payers
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _reset_registry():
|
|
payers.reset()
|
|
yield
|
|
payers.reset()
|
|
|
|
|
|
def test_load_default_config_has_co_txix_837p():
|
|
configs = payers.load_payer_configs()
|
|
assert ("CO_TXIX", "837P") in configs
|
|
block = configs[("CO_TXIX", "837P")]
|
|
assert block["payer_id"] == "CO_TXIX"
|
|
assert "CH" in block["bht06_allowed"]
|
|
assert "RP" in block["bht06_allowed"]
|
|
assert block["bht06_default"] == "CH"
|
|
assert block["sbr09_default"] == "MC"
|
|
|
|
|
|
def test_load_default_config_has_co_txix_835():
|
|
configs = payers.load_payer_configs()
|
|
assert ("CO_TXIX", "835") in configs
|
|
block = configs[("CO_TXIX", "835")]
|
|
assert "1811725341" in block["expected_payer_tax_ids"]
|
|
assert block["expected_payer_health_plan_id"] == "7912900843"
|
|
|
|
|
|
def test_get_config_returns_block():
|
|
payers.load_payer_configs()
|
|
block = payers.get_config("CO_TXIX", "837P")
|
|
assert block is not None
|
|
assert block["submitter_name"] == "Dzinesco"
|
|
|
|
|
|
def test_get_config_returns_none_for_missing():
|
|
payers.load_payer_configs()
|
|
assert payers.get_config("UNKNOWN_PAYER", "837P") is None
|
|
|
|
|
|
def test_load_invalid_yaml_raises(tmp_path):
|
|
bad = tmp_path / "bad.yaml"
|
|
bad.write_text(yaml.safe_dump({"payers": [
|
|
{"payer_id": "X", "configs": {"837P": {"submitter_name": "ok"}}} # missing required keys
|
|
]}))
|
|
with pytest.raises(ValueError, match="invalid config"):
|
|
payers.load_payer_configs(bad)
|
|
|
|
|
|
def test_load_missing_payers_key_raises(tmp_path):
|
|
bad = tmp_path / "bad.yaml"
|
|
bad.write_text("not_a_payers_key: 1")
|
|
with pytest.raises(ValueError, match="missing top-level 'payers:'"):
|
|
payers.load_payer_configs(bad)
|
|
|
|
|
|
def test_load_missing_file_warns_and_clears(tmp_path, caplog):
|
|
fake = tmp_path / "does-not-exist.yaml"
|
|
with caplog.at_level("WARNING"):
|
|
result = payers.load_payer_configs(fake)
|
|
assert result == {}
|
|
|
|
|
|
def test_all_configs_returns_snapshot():
|
|
payers.load_payer_configs()
|
|
snap = payers.all_configs()
|
|
assert isinstance(snap, dict)
|
|
assert len(snap) >= 2
|
|
# Mutating snapshot must not affect registry
|
|
snap.clear()
|
|
assert len(payers.all_configs()) >= 2
|
|
|
|
|
|
def test_reload_picks_up_changes(tmp_path):
|
|
a = tmp_path / "a.yaml"
|
|
a.write_text(yaml.safe_dump({"payers": [
|
|
{"payer_id": "AAA", "configs": {"837P": {
|
|
"submitter_name": "A", "submitter_contact_name": "A",
|
|
"submitter_contact_email": "a@a",
|
|
"receiver_name": "R", "receiver_id": "R",
|
|
"bht06_allowed": ["CH"], "bht06_default": "CH",
|
|
"sbr09_default": "MC", "sbr09_allowed": ["MC"],
|
|
"payer_id_qualifier": "PI", "payer_id": "AAA",
|
|
"pwk_supported": False, "cas_2320_group_allowed": False,
|
|
}}}
|
|
]}))
|
|
b = tmp_path / "b.yaml"
|
|
b.write_text(yaml.safe_dump({"payers": [
|
|
{"payer_id": "BBB", "configs": {"837P": {
|
|
"submitter_name": "B", "submitter_contact_name": "B",
|
|
"submitter_contact_email": "b@b",
|
|
"receiver_name": "R", "receiver_id": "R",
|
|
"bht06_allowed": ["CH"], "bht06_default": "CH",
|
|
"sbr09_default": "MC", "sbr09_allowed": ["MC"],
|
|
"payer_id_qualifier": "PI", "payer_id": "BBB",
|
|
"pwk_supported": False, "cas_2320_group_allowed": False,
|
|
}}}
|
|
]}))
|
|
payers.load_payer_configs(a)
|
|
assert payers.get_config("AAA", "837P") is not None
|
|
payers.load_payer_configs(b)
|
|
assert payers.get_config("BBB", "837P") is not None
|
|
assert payers.get_config("AAA", "837P") is None
|