Files
cyclone/backend/tests/test_scoring.py
2026-06-20 18:30:05 -06:00

126 lines
3.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""TDD: 4-field weighted scoring for Inbox candidate pairs.
Plan: docs/superpowers/plans/2026-06-20-cyclone-workflow-automation.md
Task 5 (T5).
"""
from __future__ import annotations
from dataclasses import dataclass
from datetime import date
from decimal import Decimal
import pytest
from cyclone.scoring import score_pair
@dataclass
class FakeClaim:
patient_control_number: str = "PCN-001"
service_date_from: date | None = date(2026, 6, 10)
charge_amount: Decimal = Decimal("100.00")
provider_npi: str | None = "1234567890"
@dataclass
class FakeRemit:
patient_control_number: str = "PCN-001"
service_date: date | None = date(2026, 6, 10)
charge_amount: Decimal = Decimal("100.00")
rendering_provider_npi: str | None = "1234567890"
def test_perfect_match_scores_100():
s = score_pair(FakeClaim(), FakeRemit())
assert s.total == 100
assert s.patient == 1.0
assert s.date == 1.0
assert s.amount == 1.0
assert s.provider == 1.0
def test_date_within_3_days_scores_partial():
s = score_pair(
FakeClaim(service_date_from=date(2026, 6, 10)),
FakeRemit(service_date=date(2026, 6, 12)),
)
assert s.date == pytest.approx(1 - 2/3) # 0.333
def test_date_beyond_3_days_scores_zero():
s = score_pair(
FakeClaim(service_date_from=date(2026, 6, 10)),
FakeRemit(service_date=date(2026, 6, 14)),
)
assert s.date == 0.0
def test_amount_within_10pct_scores_partial():
s = score_pair(
FakeClaim(charge_amount=Decimal("100.00")),
FakeRemit(charge_amount=Decimal("108.00")),
)
assert s.amount == pytest.approx(1 - 8/10)
def test_amount_beyond_10pct_scores_zero():
s = score_pair(
FakeClaim(charge_amount=Decimal("100.00")),
FakeRemit(charge_amount=Decimal("120.00")),
)
assert s.amount == 0.0
def test_patient_normalized_exact_match():
s = score_pair(
FakeClaim(patient_control_number="PCN-001"),
FakeRemit(patient_control_number=" pcn-001 "),
)
assert s.patient == 1.0
def test_patient_mismatch_scores_zero():
s = score_pair(
FakeClaim(patient_control_number="PCN-001"),
FakeRemit(patient_control_number="PCN-002"),
)
assert s.patient == 0.0
def test_missing_provider_npi_scores_zero():
s = score_pair(
FakeClaim(provider_npi=None),
FakeRemit(rendering_provider_npi="1234567890"),
)
assert s.provider == 0.0
def test_missing_service_date_scores_zero():
s = score_pair(
FakeClaim(service_date_from=None),
FakeRemit(service_date=date(2026, 6, 10)),
)
assert s.date == 0.0
def test_threshold_boundaries():
"""Tier boundaries: ≥75 strong, 5074 weak, <50 hidden."""
# All fields 0 except amount = 0.75 (exact) → 15 pts → total 15 → hidden
s = score_pair(
FakeClaim(
patient_control_number="X", # 0
service_date_from=date(2026, 6, 10),
charge_amount=Decimal("100.00"),
provider_npi="1234567890",
),
FakeRemit(
patient_control_number="Y", # 0
service_date=date(2026, 6, 10),
charge_amount=Decimal("100.00"),
rendering_provider_npi="1234567890",
),
)
# patient=0, date=1, amount=1, provider=1 → 0+25+20+15 = 60 → weak tier
assert 50 <= s.total < 75 # weak tier
assert s.tier == "weak"