"""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()