feat: AR-House initial commit
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user