Files
web-page-backend/realestate-lab/tests/test_listing_db.py

91 lines
5.0 KiB
Python

def test_listing_criteria_seed_and_update():
from app import db
c = db.get_listing_criteria()
assert c["id"] == 1 and "신대방동" in c["dongs"] and c["max_deposit"] == 32000
db.update_listing_criteria({"max_deposit": 30000, "equity": 15000})
assert db.get_listing_criteria()["max_deposit"] == 30000
assert db.get_listing_criteria()["equity"] == 15000
def test_upsert_listing_idempotent_and_is_new():
from app import db
row = {"article_no": "A1", "source": "naver", "deal_type": "전세", "deposit": 29000,
"area_exclusive": 42.0, "complex_name": "OO", "dong": "신대방동", "dong_code": "11590"}
_, is_new = db.upsert_listing(row)
assert is_new is True
_, is_new2 = db.upsert_listing({**row, "deposit": 28000})
assert is_new2 is False
ls = db.get_listings()
assert len(ls) == 1 and ls[0]["deposit"] == 28000
def test_market_deals_dedup_and_query():
from app import db
base = {"house_type": "아파트", "dong_code": "11590", "dong": "신대방동",
"complex_name": "OO", "area": 42.0, "deal_type": "전세",
"deposit": 43000, "sale_amount": None, "deal_ym": "202605", "floor": "5", "source": "molit"}
db.upsert_market_deal(base)
db.upsert_market_deal(base) # 동일 → dedup
deals = db.get_market_deals_for("11590", "OO", 42.0, "전세", months=120)
assert len(deals) == 1
def test_unnotified_listing_match_and_mark():
from app import db
lid, _ = db.upsert_listing({"article_no": "A2", "source": "naver", "deal_type": "전세",
"deposit": 29000, "area_exclusive": 42.0, "dong": "신대방동"})
db.upsert_listing_match({"listing_id": lid[0] if isinstance(lid, tuple) else lid["id"],
"category": "임차", "passed": 1, "match_score": 90,
"safety_tier": "안전", "sample_size": 7, "reasons": ["ok"], "is_new": 1})
un = db.get_unnotified_listing_matches()
assert len(un) == 1
db.mark_listings_notified([un[0]["id"]])
assert db.get_unnotified_listing_matches() == []
# ── 최종 리뷰 fix (M1/M3/M4) ─────────────────────────────────────────────────
def test_market_deals_broad_fallback_when_complex_sample_thin():
"""complex_name 지정 시 표본이 MIN_SAMPLE(3) 미만이면 complex 제약을 풀고
같은 dong_code/deal_type/area±5/recency 조건으로 광역 재조회해야 한다."""
from app import db
base = {"house_type": "아파트", "dong_code": "11590", "dong": "신대방동",
"area": 42.0, "deal_type": "전세", "sale_amount": None, "floor": "5", "source": "molit"}
# complex "A" 단독 1건 (< MIN_SAMPLE=3)
db.upsert_market_deal({**base, "complex_name": "A", "deposit": 30000, "deal_ym": "202601"})
# complex "B" 3건 (dedup 인덱스 회피 위해 deal_ym 다르게)
db.upsert_market_deal({**base, "complex_name": "B", "deposit": 31000, "deal_ym": "202602"})
db.upsert_market_deal({**base, "complex_name": "B", "deposit": 32000, "deal_ym": "202603"})
db.upsert_market_deal({**base, "complex_name": "B", "deposit": 33000, "deal_ym": "202604"})
deals = db.get_market_deals_for("11590", "A", 42.0, "전세", months=120)
assert len(deals) == 4 # A 1건 + B 3건 광역 폴백
def test_upsert_market_deal_area_null_skipped():
"""area=None인 실거래는 median 계산에 무용 + dedup 인덱스도 못 걸려 무한중복
유발하므로 저장 자체를 skip해야 한다."""
from app import db
d = {"house_type": "아파트", "dong_code": "11590", "dong": "신대방동",
"complex_name": "OO", "area": None, "deal_type": "전세",
"deposit": 43000, "sale_amount": None, "deal_ym": "202605", "floor": "5", "source": "molit"}
db.upsert_market_deal(d)
db.upsert_market_deal(d) # 재호출해도 여전히 저장 안 됨(무한중복 방지 확인)
with db._conn() as conn:
cnt = conn.execute("SELECT COUNT(*) FROM market_deals").fetchone()[0]
assert cnt == 0
def test_get_listing_matches_json_parsed():
"""get_listing_matches()도 get_unnotified_listing_matches()와 동일하게
regulation_flags/reasons를 list로 파싱해 반환해야 한다."""
from app import db
lid, _ = db.upsert_listing({"article_no": "A3", "source": "naver", "deal_type": "전세",
"deposit": 29000, "area_exclusive": 42.0, "dong": "신대방동"})
db.upsert_listing_match({"listing_id": lid["id"], "category": "임차", "passed": 1,
"match_score": 90, "safety_tier": "안전", "sample_size": 7,
"regulation_flags": ["토지거래허가구역"], "reasons": ["ok"], "is_new": 1})
matches = db.get_listing_matches()
assert len(matches) == 1
assert isinstance(matches[0]["regulation_flags"], list)
assert matches[0]["regulation_flags"] == ["토지거래허가구역"]
assert isinstance(matches[0]["reasons"], list)
assert matches[0]["reasons"] == ["ok"]