Files
AR-House/scripts/smoke_test_all_pa.py
T
2026-07-03 12:24:58 -04:00

133 lines
4.7 KiB
Python

"""Smoke test integral — validate all 4 county PA adapters work end-to-end.
Pulls one real deal from DB per county, runs PA fetch via unified router,
verifies key fields populated. Output: pass/fail summary for user confidence.
"""
from __future__ import annotations
import sys
import time
import sqlite3
sys.path.insert(0, ".")
def test_county(county: str, expect_real_data: bool = True) -> dict:
"""Pick a deal from DB for this county, run PA fetch, validate."""
out = {"county": county, "status": "?", "errors": [], "details": {}}
# Find a testable deal
conn = sqlite3.connect("data/deals.db")
conn.row_factory = sqlite3.Row
cur = conn.cursor()
cur.execute(
"SELECT id, parcel_id, address FROM deals "
"WHERE county=? AND parcel_id IS NOT NULL AND parcel_id != '' LIMIT 1",
(county,)
)
row = cur.fetchone()
conn.close()
if not row:
out["status"] = "SKIP"
out["errors"].append(f"No deals in DB for {county}")
return out
deal_id = row["id"]
parcel = row["parcel_id"]
address = row["address"]
out["details"] = {
"deal_id": deal_id, "parcel_id": parcel, "address": address[:60] if address else "?",
}
# Run PA fetch via unified router
try:
from data_fetchers.property_appraiser import fetch_pa_record, is_pa_supported
if not is_pa_supported(county, "FL"):
out["status"] = "NOT_IMPLEMENTED"
return out
t0 = time.perf_counter()
rec = fetch_pa_record(county_name=county, state="FL",
address=address, parcel_id=parcel)
elapsed = round(time.perf_counter() - t0, 1)
out["details"]["elapsed_sec"] = elapsed
if not rec:
out["status"] = "FAIL"
out["errors"].append("PA router returned None")
return out
if rec.get("errors"):
out["status"] = "FAIL"
out["errors"].extend(rec["errors"][:2])
# Validate key fields
required = ["owner_name", "year_built", "just_value_current"]
missing = [f for f in required if not rec.get(f)]
if missing and expect_real_data:
out["status"] = "PARTIAL"
out["errors"].append(f"Missing fields: {missing}")
elif not missing:
out["status"] = "OK"
# Capture the good stuff
out["details"].update({
"owner": rec.get("owner_name"),
"year_built": rec.get("year_built"),
"just_value": rec.get("just_value_current"),
"assessed_value": rec.get("assessed_value_current"),
"homestead": rec.get("homestead_active"),
"sales_count": len(rec.get("sales_history") or []),
"renovation_signal": (rec.get("renovation_signal") or {}).get("is_flip_in_progress", False),
})
except Exception as e:
import traceback
out["status"] = "ERROR"
out["errors"].append(f"{type(e).__name__}: {e}")
out["details"]["trace"] = traceback.format_exc()[:300]
return out
def main():
counties = ["Duval", "Broward", "Miami-Dade", "Palm Beach"]
results = []
print("=" * 75)
print("PA Adapters Smoke Test — 4 counties")
print("=" * 75)
for c in counties:
print(f"\nTesting {c}...")
result = test_county(c)
results.append(result)
status = result["status"]
icon = {"OK": "PASS", "PARTIAL": "PART", "SKIP": "SKIP",
"FAIL": "FAIL", "ERROR": "ERR ", "NOT_IMPLEMENTED": "NOIM"}.get(status, "??")
det = result["details"]
print(f" [{icon}] {c} (deal id={det.get('deal_id','?')})")
if status in ("OK", "PARTIAL"):
print(f" Address: {det.get('address')}")
print(f" Owner: {det.get('owner')!r}")
print(f" Built: {det.get('year_built')}")
print(f" Just $: {det.get('just_value')}")
print(f" Assessed: {det.get('assessed_value')}")
print(f" Homestead:{det.get('homestead')}")
print(f" Sales: {det.get('sales_count')} records")
print(f" Elapsed: {det.get('elapsed_sec')}s")
if result["errors"]:
for e in result["errors"][:2]:
e_safe = str(e)[:120].encode("ascii", "replace").decode("ascii")
print(f" ERROR: {e_safe}")
# Summary
print()
print("=" * 75)
pass_count = sum(1 for r in results if r["status"] == "OK")
print(f"SUMMARY: {pass_count}/{len(results)} counties PASS")
print("=" * 75)
for r in results:
icon = "PASS" if r["status"] == "OK" else r["status"]
print(f" {icon:6s} {r['county']}")
if __name__ == "__main__":
main()