r""" conditions/dental_payer_check.py — document #13: Dental codes are billed only to DentaQuest, Delta Dental or CHP+ Dental — on any insurance row, secondary included. None of them on a claim with a billed Dental code: the Claim Status is set to Patient (PAT) where the run may write, else Review "set it by hand"; no payer read: Review (operator, 2026-10-16 / 2026-10-21). python tests\test_conditions_dental_payer_check.py Uses tests/fixtures/dental_claim.html (D0120 row 0, DCONS row 1) for the run_all case. """ import io import sys import pathlib import inspect import contextlib ROOT = pathlib.Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT / "src")) FIXTURE = pathlib.Path(__file__).resolve().parent / "fixtures" / "dental_claim.html" from ecw_bot.conditions import dental_payer_check as cond # noqa: E402 from ecw_bot.conditions import CONDITIONS # noqa: E402 from ecw_bot.conditions.base import run_all # noqa: E402 from ecw_bot.core import charge_summary as cs # noqa: E402 from ecw_bot.pages import claim_form # noqa: E402 CASES = [] def case(fn): CASES.append(fn) return fn def _row(code, billed=True, fee="85.00"): return {"code": code, "billed": billed, "billed_fee": fee, "units": "1"} def _claim(payer, *rows): return {"insurance": [{"Name": payer}] if payer is not None else [], "cpt": list(rows)} # ── recognition ────────────────────────────────────────────────────────────── @case def a_dental_code_is_d_and_four_digits(): for code in ("D0120", "D1110", " d0274 ", "D9999"): assert cond.is_dental_code(code), code for code in ("DCONS", "Dscprit", "DPIMP", "D012", "D01200", "99213", "G8510", "", None): assert not cond.is_dental_code(code), code @case def the_three_payers_are_allowed_and_no_other(): for payer in ("DentaQuest", "CHP+ DENTAQUEST", "Delta Dental", "Delta Dental of Colorado", "DELTA DENTAL PPO", " delta dental of oregon "): assert cond.is_allowed_payer(payer), payer for payer in ("Aetna Dental PPO", "Dental Cigna", "MetLife Dental Claims", "Medicaid", "Anthem Blue Cross Blue Shield", "Dental Slide D", "", None): assert not cond.is_allowed_payer(payer), payer # ── needs_review (no browser) ──────────────────────────────────────────────── @case def allowed_payers_need_nothing(): for payer in ("DentaQuest", "CHP+ DENTAQUEST", "Delta Dental of Colorado"): data = _claim(payer, _row("D0120"), _row("D1110")) assert cond.detect("C1", data) is False assert cond.needs_review("C1", data) is None, payer @case def an_allowed_secondary_payer_is_enough(): """Operator 2026-10-21: secondary insurance counts.""" data = _claim("Medicaid", _row("D0120")) data["insurance"].append({"Name": "Delta Dental of Colorado"}) assert cond.detect("C1", data) is False assert cond.needs_review("C1", data) is None @case def another_payer_is_detected(): for payer in ("Aetna Dental PPO", "Medicaid", "Cigna HealthCare Of Colorado"): data = _claim(payer, _row("D0120"), _row("DCONS"), _row("D1110")) assert cond.detect("C1", data) is True, payer assert cond.needs_review("C1", data) is None, payer @case def no_payer_read_is_review_not_a_status_change(): for data in (_claim("", _row("D0120")), _claim(None, _row("D0120"))): assert cond.detect("C1", data) is False why = cond.needs_review("C1", data) assert why and "no payer read" in why and "D0120" in why, why @case def only_billed_dental_lines_count(): # Unchecked at 0.00, or checked at 0.00 (zero_fee_uncheck unchecks it): # nothing billed, nothing to do. for row in (_row("D0120", billed=False, fee="0.00"), _row("D0120", billed=True, fee="0.00")): assert cond.detect("C1", _claim("Medicaid", row)) is False, row # Dummy codes only: not dental codes. data = _claim("Medicaid", _row("DCONS"), _row("DPIMP"), _row("99213")) assert cond.detect("C1", data) is False @case def it_is_registered(): assert "dental_payer_check" in [m.NAME for m in CONDITIONS] assert cs.COMMENTS.get("dental_payer_check") # ── run_all on the Dental screen (browser) ────────────────────────────────── def _dental_read(page, payer): data = claim_form.extract(page) data["screen"] = "dental" data["insurance"] = [{"Name": payer}] data["progress_notes"] = {"opened": "tab", "text": "Routine dental visit."} return data def _outcome(page, payer): page.goto(FIXTURE.as_uri()) data = _dental_read(page, payer) report = {} with contextlib.redirect_stdout(io.StringIO()): results = run_all(page, "C1", data, report=report) data["_conditions"] = {"fired": [r.condition_name for r in results], "saved": False, "failed": report["failed"], "review": report["review"], "comments": report["comments"]} return cs.claim_outcome(True, data), report @case def a_dental_claim_to_aetna_dental_is_review_set_by_hand(page): # The Dental screen is never written (claims not saved): Review. outcome, report = _outcome(page, "Aetna Dental PPO") notes = [r["reason"] for r in report["review"] if r["name"] == "dental_payer_check"] assert len(notes) == 1 and "D0120" in notes[0], report["review"] assert "set it to Patient by hand" in notes[0], notes assert outcome["Category"] == "Review", outcome assert "Patient" in outcome["Comments"], outcome # ── the Claim Status dropdown (browser) ───────────────────────────────────── _STATUS = """ """ def _write(page, html, data, save=True): from ecw_bot import settings as _cfg page.set_content(html) orig = _cfg.SAVE_CORRECTIONS _cfg.SAVE_CORRECTIONS = save try: with contextlib.redirect_stdout(io.StringIO()): return cond.apply(page, "C1", data) finally: _cfg.SAVE_CORRECTIONS = orig def _value(page, selector): return page.locator(selector).input_value() @case def live_write_sets_the_claim_status_to_patient(page): data = _claim("Aetna Dental PPO", _row("D0120")) result = _write(page, _STATUS, data) assert result.changed is True and result.review == "", result assert _value(page, "#claimStatusSel1") == "string:PAT" assert _value(page, "#status") == "A", "the other status field untouched" c = result.changes[0] assert (c["before"], c["after"], c["label"]) == ("108ME", "PAT", "Patient") assert cond.summary_comment(result) == ( "Dental code(s) D0120 billed to Aetna Dental PPO — not DentaQuest / " "Delta Dental / CHP+ Dental - Claim Status set to Patient") assert "108ME -> PAT (Patient)" in cond.describe(result) @case def the_ub_dropdown_with_plain_values_works_too(page): html = ('') result = _write(page, html, _claim("Medicaid", _row("D1110"))) assert result.changed and _value(page, "#claimStatusSel2") == "PAT" @case def verify_changes_nothing_and_says_set_it_by_hand(page): result = _write(page, _STATUS, _claim("Medicaid", _row("D0120")), save=False) assert result.changed is False assert "set it to Patient by hand" in result.review, result.review assert _value(page, "#claimStatusSel1") == "string:108ME" @case def no_patient_option_or_no_dropdown_is_review(page): html = ('') result = _write(page, html, _claim("Medicaid", _row("D0120"))) assert result.changed is False and "set it by hand" in result.review result = _write(page, "
no form
", _claim("Medicaid", _row("D0120"))) assert result.changed is False and "no Claim Status box" in result.review @case def a_dental_claim_to_dentaquest_gets_no_payer_review(page): _, report = _outcome(page, "DentaQuest") assert not [r for r in report["review"] if r["name"] == "dental_payer_check"], report["review"] def main() -> int: from playwright.sync_api import sync_playwright failures = 0 with sync_playwright() as pw: browser = pw.chromium.launch(headless=True) page = browser.new_page() for fn in CASES: name = fn.__name__.replace("_", " ") try: if len(inspect.signature(fn).parameters) == 0: fn() else: fn(page) print(f" ok {name}") except AssertionError as exc: print(f" FAIL {name}: {exc}") failures += 1 except Exception as exc: print(f" ERROR {name}: {type(exc).__name__}: {exc}") failures += 1 browser.close() print(f"\n{len(CASES) - failures}/{len(CASES)} passed") return 1 if failures else 0 if __name__ == "__main__": sys.exit(main())