"""Tests for the daily paper-filing batch (Standard no-login CMS filing path). Covers the pure logic that doesn't need a DB/MinIO: - postal working-day gating (weekends + federal/USPS holidays) - destination routing (state -> MAC; CMS-10114 -> NPI Enumerator) - cover-sheet rendering + multi-page pagination - merge of cover sheet + filing PDFs Run: python scripts/tests/test_paper_batch.py """ from __future__ import annotations import importlib.util import io import sys from datetime import date from pathlib import Path ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(ROOT / "scripts")) sys.path.insert(0, str(ROOT / "scripts" / "workers")) def _load(name: str, rel: str): spec = importlib.util.spec_from_file_location(name, ROOT / rel) m = importlib.util.module_from_spec(spec) spec.loader.exec_module(m) return m dpb = _load("dpb", "scripts/workers/daily_paper_batch.py") bcs = _load("bcs", "scripts/document_gen/templates/batch_cover_sheet.py") PASS = 0 FAIL = 0 def check(label, cond): global PASS, FAIL if cond: PASS += 1 print(f" PASS {label}") else: FAIL += 1 print(f" FAIL {label}") def test_working_days(): print("working-day gating") check("Saturday is not a working day", not dpb._is_postal_working_day(date(2026, 6, 6))) check("Sunday is not a working day", not dpb._is_postal_working_day(date(2026, 6, 7))) check("Monday is a working day", dpb._is_postal_working_day(date(2026, 6, 8))) check("Memorial Day (holiday) is not a working day", not dpb._is_postal_working_day(date(2026, 5, 25))) check("Christmas (holiday) is not a working day", not dpb._is_postal_working_day(date(2026, 12, 25))) def test_routing(): print("destination routing") ca = dpb._destination_for("CA", "cms855i") check("CA 855 -> Noridian JE", ca and ca[0] == "noridian_je") ny = dpb._destination_for("NY", "cms855i") check("NY 855 -> NGS JK", ny and ny[0] == "ngs_jk") tx = dpb._destination_for("TX", "cms855b") check("TX 855B -> Novitas JH", tx and tx[0] == "novitas_jh") enum = dpb._destination_for("TX", "cms10114") check("any-state CMS-10114 -> NPI Enumerator (Baltimore)", enum and enum[0] == "npi_enumerator") check("CMS-10114 ignores state for routing", dpb._destination_for("CA", "cms10114")[0] == "npi_enumerator") check("unknown state -> None (human review)", dpb._destination_for("ZZ", "cms855i") is None) check("blank state -> None", dpb._destination_for("", "cms855i") is None) def test_cover_sheet(): print("cover sheet + merge") items = [ {"order_number": f"CO-X{i:03d}", "provider": f"Provider {i} MD", "npi": f"1{i:09d}", "form": "855i"} for i in range(40) ] cover = bcs.build_cover_sheet( destination_name="Noridian JE", destination_address_lines=("Provider Enrollment (JE)", "P.O. Box VERIFY", "Fargo, ND"), batch_date=date(2026, 6, 8), items=items, ) from pypdf import PdfReader n_cover = len(PdfReader(io.BytesIO(cover)).pages) check("40-item cover sheet paginates to >1 page", n_cover > 1) merged = bcs.merge_batch_pdf(cover, [cover, cover]) n_merged = len(PdfReader(io.BytesIO(merged)).pages) check("merge concatenates cover + 2 filings", n_merged == n_cover * 3) # empty-items cover still renders one page empty = bcs.build_cover_sheet( destination_name="X", destination_address_lines=("a",), batch_date=date(2026, 6, 8), items=[], ) check("empty batch cover sheet renders", len(PdfReader(io.BytesIO(empty)).pages) >= 1) if __name__ == "__main__": test_working_days() test_routing() test_cover_sheet() print(f"\n{PASS} passed, {FAIL} failed") sys.exit(1 if FAIL else 0)