fix(realestate): listings-ingest async(BackgroundTask)+매칭/알림 타이밍 로그 + notify 홍수방지(cap+baseline)

This commit is contained in:
2026-07-10 11:11:36 +09:00
parent 28418b9f5d
commit 8e28ce9ae5
5 changed files with 56 additions and 13 deletions

View File

@@ -23,6 +23,8 @@ def test_ingest_auth(monkeypatch):
def test_ingest_upserts_and_matches(monkeypatch):
c = _client(monkeypatch)
# TestClient는 BackgroundTask를 응답 반환 전 동기 실행하므로 patch된 notify는
# c.post()가 리턴하는 시점에 이미 호출되어 있다.
with patch("app.internal_router.notify_new_listings", return_value={"sent": 1, "sent_ids": [1]}) as noti:
r = c.post("/api/internal/realestate/listings-ingest",
headers={"X-Internal-Key": "SECRET"},
@@ -30,7 +32,7 @@ def test_ingest_upserts_and_matches(monkeypatch):
"batches": [{"dong": "신대방동", "articles": [_ARTICLE]}]})
assert r.status_code == 200
body = r.json()
assert body["received"] == 1 and body["new"] == 1 and body["matched"] == 1
assert body["received"] == 1 and body["new"] == 1 and body["queued"] is True
assert noti.call_count == 1
# 저장 확인
from app import db

View File

@@ -26,3 +26,26 @@ def test_notify_listings_no_mark_on_failure():
with patch.object(notifier.requests, "post", side_effect=rq.RequestException("down")):
notifier.notify_new_listings()
assert len(db.get_unnotified_listing_matches()) == 1 # 미마킹→재시도
def test_notify_caps_and_baselines(monkeypatch):
from app import notifier, db
from unittest.mock import MagicMock
for i in range(10):
row, _ = db.upsert_listing({"article_no": f"C{i}", "source": "naver", "deal_type": "전세",
"deposit": 29000, "area_exclusive": 42.0, "dong": "신대방동"})
db.upsert_listing_match({"listing_id": row["id"], "category": "임차", "passed": 1,
"match_score": 100, "safety_tier": "안전", "sample_size": 7,
"reasons": ["ok"], "is_new": 1})
monkeypatch.setattr(notifier, "LISTING_NOTIFY_MAX", 8)
captured = {}
fake = MagicMock(); fake.raise_for_status.return_value = None
def fake_post(url, json=None, timeout=None):
captured["n"] = len(json["listings"])
fake.json.return_value = {"sent": len(json["listings"]),
"sent_ids": [m["id"] for m in json["listings"]]}
return fake
monkeypatch.setattr(notifier.requests, "post", fake_post)
notifier.notify_new_listings()
assert captured["n"] == 8 # 8건만 텔레그램 전송
assert len(db.get_unnotified_listing_matches()) == 0 # 나머지 2건 baseline 마킹