From c2939459e7bc3fba055937616ddff976f110da72 Mon Sep 17 00:00:00 2001 From: gahusb Date: Tue, 28 Apr 2026 08:50:29 +0900 Subject: [PATCH] fix(realestate-notifier): preserve threshold=0 and test sent_ids retry path - Replace `or 70` fallback with explicit None-check so that min_match_score=0 ("notify all matches") is no longer silently coerced to 70 - Add test: 200 OK + sent_ids=[] must not mark matches notified - Add test: threshold=0 correctly pushes low-score matches Co-Authored-By: Claude Sonnet 4.6 --- realestate-lab/app/notifier.py | 3 ++- realestate-lab/tests/test_notifier.py | 39 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/realestate-lab/app/notifier.py b/realestate-lab/app/notifier.py index 94ab940..301ee34 100644 --- a/realestate-lab/app/notifier.py +++ b/realestate-lab/app/notifier.py @@ -24,7 +24,8 @@ def notify_new_matches() -> dict: if not profile.get("notify_enabled"): return {"sent": 0, "skipped": "notify_disabled"} - threshold = profile.get("min_match_score") or 70 + raw_threshold = profile.get("min_match_score") + threshold = 70 if raw_threshold is None else raw_threshold matches = get_unnotified_matches(threshold) if not matches: return {"sent": 0} diff --git a/realestate-lab/tests/test_notifier.py b/realestate-lab/tests/test_notifier.py index 2c29127..edea56a 100644 --- a/realestate-lab/tests/test_notifier.py +++ b/realestate-lab/tests/test_notifier.py @@ -83,3 +83,42 @@ def test_notify_does_not_mark_on_failure(): assert row["notified_at"] is None assert result["sent"] == 0 assert "error" in result + + +def test_notify_does_not_mark_when_sent_ids_empty(): + """agent-office가 200 OK + sent_ids=[]을 반환하면 마킹하지 않고 다음 사이클 재시도 가능.""" + from app import notifier + from app.db import _conn + + match_id = _seed_profile_and_match(score=80, threshold=70) + + fake_resp = MagicMock() + fake_resp.json.return_value = {"sent": 0, "sent_ids": []} + fake_resp.raise_for_status.return_value = None + + with patch.object(notifier.requests, "post", return_value=fake_resp): + result = notifier.notify_new_matches() + + with _conn() as conn: + row = conn.execute("SELECT notified_at FROM match_results WHERE id=?", (match_id,)).fetchone() + + assert row["notified_at"] is None + assert result["sent"] == 0 + + +def test_notify_threshold_zero_pushes_all_matches(): + """min_match_score=0이면 모든 양수 점수 매치를 알림.""" + from app import notifier + from app.db import _conn + + match_id = _seed_profile_and_match(score=10, threshold=0) + + fake_resp = MagicMock() + fake_resp.json.return_value = {"sent": 1, "sent_ids": [match_id]} + fake_resp.raise_for_status.return_value = None + + with patch.object(notifier.requests, "post", return_value=fake_resp) as post: + result = notifier.notify_new_matches() + + assert post.call_count == 1 + assert result["sent"] == 1