Compare commits
2 commits
0083bc1354
...
f43957882f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f43957882f | ||
|
|
5c1f239307 |
2 changed files with 136 additions and 0 deletions
|
|
@ -235,6 +235,29 @@ screening; customers are converted to the $79/mo monitoring subscription after
|
|||
that first cycle (the standalone $948/yr of monitoring is no longer given away
|
||||
inside the bundle).
|
||||
|
||||
**Validation status (2026-06-18):**
|
||||
- ✅ *Checkout half — proven against LIVE Stripe.* A dry-run created a real
|
||||
`mode:subscription` Checkout Session with the exact production params
|
||||
(recurring `price_data`, `unit_amount=7900`, `recurring.interval=month`,
|
||||
`card`+`us_bank_account`, metadata) — Stripe returned `amount_total=7900`,
|
||||
`type=recurring`, then the session was immediately **expired** (creating a
|
||||
session never charges anyone; only a completed hosted page does). Net effect
|
||||
on prod: zero.
|
||||
- ✅ *Webhook subscription-id extraction* — `invoiceSubscriptionId()` unit tests
|
||||
(31 in `api/tests/recurring-subscription.test.ts`) cover acacia (top-level)
|
||||
AND dahlia (nested) invoice shapes, renewal-cycle gating, surcharge
|
||||
suppression, recurring line-item build.
|
||||
- ✅ *Worker renewal fulfillment* — `scripts/workers/services/test_npi_recurring.py`
|
||||
(13 assertions) runs the real handler and asserts the `[Monthly cycle]` /
|
||||
re-screen behaviour; passes locally + in the deployed workers container.
|
||||
- ⏳ *Full end-to-end with a Stripe test clock* — NOT yet run. Requires
|
||||
`STRIPE_TEST_SECRET_KEY` / `STRIPE_TEST_WEBHOOK_SECRET` in the server `.env`
|
||||
(currently unset; prod is `NODE_ENV=production`). Once those exist: place a
|
||||
test-card subscription, advance a billing cycle via a test clock, and confirm
|
||||
the live `invoice.paid` (subscription_cycle) re-dispatches the screening
|
||||
worker and a fresh certificate is issued. This is the last gap before a real
|
||||
recurring charge should be marketed.
|
||||
|
||||
### Formation Maintenance Bundles
|
||||
|
||||
| Bundle | Price | Includes | Savings |
|
||||
|
|
|
|||
113
scripts/workers/services/test_npi_recurring.py
Normal file
113
scripts/workers/services/test_npi_recurring.py
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
"""
|
||||
Logic tests for the OIG/SAM recurring-monitoring fulfillment path in
|
||||
npi_provider.py. Runs the REAL _BaseNPIHandler.handle() with _create_todo
|
||||
monkeypatched to capture the todo (so no DB / ERPNext / email side effects),
|
||||
asserting the recurring-cycle branch produces the right title prefix + notes.
|
||||
|
||||
Run: python3 -m pytest scripts/workers/services/test_npi_recurring.py -q
|
||||
or: python3 scripts/workers/services/test_npi_recurring.py
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Make 'scripts' importable when run directly from repo root.
|
||||
_REPO = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
|
||||
if _REPO not in sys.path:
|
||||
sys.path.insert(0, _REPO)
|
||||
|
||||
from scripts.workers.services import npi_provider as M # noqa: E402
|
||||
|
||||
_FAILS = []
|
||||
|
||||
|
||||
def check(label, cond):
|
||||
print((" PASS " if cond else " FAIL ") + label)
|
||||
if not cond:
|
||||
_FAILS.append(label)
|
||||
|
||||
|
||||
def run_handler(handler_cls, order_data, order_number="HC-TEST-1"):
|
||||
"""Run handler.handle() capturing the todo via a monkeypatched _create_todo."""
|
||||
captured = {}
|
||||
|
||||
def fake_create_todo(self, order_number, intake, title, description, priority="normal"):
|
||||
captured["order_number"] = order_number
|
||||
captured["title"] = title
|
||||
captured["description"] = description
|
||||
captured["priority"] = priority
|
||||
|
||||
orig = M._BaseNPIHandler._create_todo
|
||||
M._BaseNPIHandler._create_todo = fake_create_todo
|
||||
try:
|
||||
h = handler_cls()
|
||||
asyncio.run(h.handle(order_data, order_number))
|
||||
finally:
|
||||
M._BaseNPIHandler._create_todo = orig
|
||||
return captured
|
||||
|
||||
|
||||
BASE_INTAKE = {
|
||||
"npi": "1234567890",
|
||||
"provider_name": "Dr. Jane Smith",
|
||||
"specialty": "Internal Medicine",
|
||||
"practice_state": "TX",
|
||||
"email": "jane@example.com",
|
||||
}
|
||||
|
||||
|
||||
# ── 1. OIG/SAM first fulfillment (NOT recurring) ────────────────────────────
|
||||
first = run_handler(
|
||||
M.OIGSAMScreeningHandler,
|
||||
{"intake_data": dict(BASE_INTAKE), "customer_name": "Jane Smith"},
|
||||
)
|
||||
check("first screening has no [Monthly cycle] prefix", "[Monthly cycle]" not in first["title"])
|
||||
check("first screening has no RECURRING note", "RECURRING MONTHLY CYCLE" not in first["description"])
|
||||
check("first screening title names the provider", "Dr. Jane Smith" in first["title"])
|
||||
check("first screening title has the NPI", "1234567890" in first["title"])
|
||||
|
||||
|
||||
# ── 2. OIG/SAM recurring monthly cycle ──────────────────────────────────────
|
||||
renew = run_handler(
|
||||
M.OIGSAMScreeningHandler,
|
||||
{
|
||||
"intake_data": dict(BASE_INTAKE),
|
||||
"customer_name": "Jane Smith",
|
||||
"recurring_cycle": True,
|
||||
"recurring_invoice_id": "in_LIVE123",
|
||||
},
|
||||
)
|
||||
check("recurring title HAS [Monthly cycle] prefix", renew["title"].startswith("[Monthly cycle] "))
|
||||
check("recurring desc has RECURRING MONTHLY CYCLE banner", "RECURRING MONTHLY CYCLE" in renew["description"])
|
||||
check("recurring desc references the invoice id", "in_LIVE123" in renew["description"])
|
||||
check("recurring desc says re-run against CURRENT data", "CURRENT OIG LEIE" in renew["description"])
|
||||
check("recurring desc says issue NEW dated certificate", "NEW dated certificate" in renew["description"])
|
||||
|
||||
|
||||
# ── 3. recurring_cycle without invoice id still works ───────────────────────
|
||||
renew_noinv = run_handler(
|
||||
M.OIGSAMScreeningHandler,
|
||||
{"intake_data": dict(BASE_INTAKE), "recurring_cycle": True},
|
||||
)
|
||||
check("recurring (no invoice) still has prefix", renew_noinv["title"].startswith("[Monthly cycle] "))
|
||||
check("recurring (no invoice) has banner", "RECURRING MONTHLY CYCLE" in renew_noinv["description"])
|
||||
|
||||
|
||||
# ── 4. Bundle handler: first screening, no recurring prefix on first run ─────
|
||||
bundle = run_handler(
|
||||
M.ProviderComplianceBundleHandler,
|
||||
{"intake_data": dict(BASE_INTAKE), "customer_name": "Jane Smith"},
|
||||
)
|
||||
check("bundle first run has no [Monthly cycle] prefix", "[Monthly cycle]" not in bundle["title"])
|
||||
|
||||
|
||||
# ── 5. recurring flag default is falsey ─────────────────────────────────────
|
||||
check("recurring branch is off by default", "[Monthly cycle]" not in first["title"])
|
||||
|
||||
|
||||
print()
|
||||
if _FAILS:
|
||||
print(f"{len(_FAILS)} FAILED: " + ", ".join(_FAILS))
|
||||
sys.exit(1)
|
||||
print("ALL NPI RECURRING TESTS PASSED")
|
||||
Loading…
Add table
Add a link
Reference in a new issue