from unittest.mock import patch, MagicMock def _seed_profile_and_match(score, notify_enabled=True, threshold=70): from app.db import _conn, upsert_profile upsert_profile({ "name": "u", "notify_enabled": notify_enabled, "min_match_score": threshold, }) with _conn() as conn: conn.execute(""" INSERT INTO announcements (house_manage_no, pblanc_no, house_nm, status, source) VALUES ('NF1', '01', '단지', '청약중', 'manual') """) ann_id = conn.execute("SELECT id FROM announcements WHERE house_manage_no='NF1'").fetchone()["id"] conn.execute(""" INSERT INTO match_results (announcement_id, model_id, match_score, match_reasons, eligible_types, is_new) VALUES (?, NULL, ?, '[]', '[]', 1) """, (ann_id, score)) match_id = conn.execute("SELECT id FROM match_results WHERE announcement_id=?", (ann_id,)).fetchone()["id"] return match_id def test_notify_skips_when_disabled(): from app import notifier _seed_profile_and_match(score=80, notify_enabled=False) with patch.object(notifier, "requests") as r: result = notifier.notify_new_matches() assert r.post.call_count == 0 assert result["sent"] == 0 assert result.get("skipped") == "notify_disabled" def test_notify_filters_below_threshold(): from app import notifier _seed_profile_and_match(score=60, threshold=70) with patch.object(notifier, "requests") as r: result = notifier.notify_new_matches() assert r.post.call_count == 0 assert result["sent"] == 0 def test_notify_pushes_and_marks_notified(): 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": 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 args, kwargs = post.call_args assert "/api/agent-office/realestate/notify" in args[0] assert kwargs["json"]["matches"][0]["id"] == match_id with _conn() as conn: row = conn.execute("SELECT notified_at FROM match_results WHERE id=?", (match_id,)).fetchone() assert row["notified_at"] is not None assert result["sent"] == 1 def test_notify_does_not_mark_on_failure(): from app import notifier from app.db import _conn import requests as real_requests match_id = _seed_profile_and_match(score=80, threshold=70) def boom(*a, **k): raise real_requests.RequestException("agent-office down") with patch.object(notifier.requests, "post", side_effect=boom): 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 assert "error" in result