from unittest.mock import patch, MagicMock def _seed_passed_match(): from app import db row, _ = db.upsert_listing({"article_no": "N1", "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}) return db.get_unnotified_listing_matches()[0]["id"] def test_notify_listings_pushes_and_marks(): from app import notifier, db mid = _seed_passed_match() fake = MagicMock(); fake.json.return_value = {"sent": 1, "sent_ids": [mid]}; fake.raise_for_status.return_value = None with patch.object(notifier.requests, "post", return_value=fake) as post: res = notifier.notify_new_listings() assert post.call_count == 1 assert db.get_unnotified_listing_matches() == [] # 마킹됨 def test_notify_listings_no_mark_on_failure(): from app import notifier, db import requests as rq mid = _seed_passed_match() with patch.object(notifier.requests, "post", side_effect=rq.RequestException("down")): notifier.notify_new_listings() assert len(db.get_unnotified_listing_matches()) == 1 # 미마킹→재시도