"""Tests for collector.py — _extract_district unit tests + collect_all integration tests.""" from datetime import date, timedelta # ── _extract_district unit tests ───────────────────────────────────────────── def test_extract_district_seoul_full_address(): from app.collector import _extract_district parsed = {"address": "서울특별시 강남구 도곡동 123-45", "region_name": None} assert _extract_district(parsed) == "강남구" def test_extract_district_seoul_short(): from app.collector import _extract_district parsed = {"address": None, "region_name": "서울 송파구"} assert _extract_district(parsed) == "송파구" def test_extract_district_busan_returns_none(): from app.collector import _extract_district parsed = {"address": "부산광역시 해운대구 우동", "region_name": None} assert _extract_district(parsed) is None def test_extract_district_empty_returns_none(): from app.collector import _extract_district parsed = {"address": "", "region_name": ""} assert _extract_district(parsed) is None def test_extract_district_seoul_county(): from app.collector import _extract_district parsed = {"address": "서울 강서구", "region_name": None} assert _extract_district(parsed) == "강서구" def test_extract_district_prefers_address_over_region(): from app.collector import _extract_district parsed = {"address": "서울특별시 마포구 합정동", "region_name": "서울 강남구"} assert _extract_district(parsed) == "마포구" # ── collect_all integration tests ──────────────────────────────────────────── def test_collect_skips_completed_status(monkeypatch): """winner_date가 과거인 응답은 status='완료'로 판정되어 upsert되지 않는다.""" from app import collector from app.db import _conn monkeypatch.setenv("DATA_GO_KR_API_KEY", "TEST") monkeypatch.setattr(collector, "API_KEY", "TEST") past_winner = (date.today() - timedelta(days=10)).strftime("%Y-%m-%d") fake_detail_rows = [{ "HOUSE_MANAGE_NO": "DONE-1", "PBLANC_NO": "01", "HOUSE_NM": "완료된단지", "HSSPLY_ADRES": "서울특별시 강남구", "RCEPT_BGNDE": "2026-01-01", "RCEPT_ENDDE": "2026-01-05", "PRZWNER_PRESNATN_DE": past_winner, }] def fake_call(endpoint, params=None): if "Detail" in endpoint: return fake_detail_rows return [] monkeypatch.setattr(collector, "_api_call", fake_call) collector.collect_all() with _conn() as conn: rows = conn.execute("SELECT * FROM announcements WHERE house_manage_no='DONE-1'").fetchall() assert len(rows) == 0 def test_collect_stores_district_for_seoul_announcement(monkeypatch): from app import collector from app.db import _conn monkeypatch.setenv("DATA_GO_KR_API_KEY", "TEST") monkeypatch.setattr(collector, "API_KEY", "TEST") future_start = (date.today() + timedelta(days=10)).strftime("%Y-%m-%d") future_end = (date.today() + timedelta(days=15)).strftime("%Y-%m-%d") future_winner = (date.today() + timedelta(days=30)).strftime("%Y-%m-%d") fake_detail = [{ "HOUSE_MANAGE_NO": "SEOUL-1", "PBLANC_NO": "01", "HOUSE_NM": "강남단지", "HSSPLY_ADRES": "서울특별시 강남구 도곡동 1", "RCEPT_BGNDE": future_start, "RCEPT_ENDDE": future_end, "PRZWNER_PRESNATN_DE": future_winner, }] def fake_call(endpoint, params=None): if "Detail" in endpoint: return fake_detail return [] monkeypatch.setattr(collector, "_api_call", fake_call) collector.collect_all() with _conn() as conn: row = conn.execute("SELECT district, status FROM announcements WHERE house_manage_no='SEOUL-1'").fetchone() assert row["district"] == "강남구" assert row["status"] in ("청약예정", "청약중") def test_extract_district_no_separator(): """주소에 공백이 없어도 자치구를 추출해야 한다.""" from app.collector import _extract_district parsed = {"address": "서울특별시강남구도곡동", "region_name": None} assert _extract_district(parsed) == "강남구" def test_collect_passes_date_window_param(monkeypatch): from app import collector monkeypatch.setenv("DATA_GO_KR_API_KEY", "TEST") monkeypatch.setattr(collector, "API_KEY", "TEST") captured_params = [] def fake_call(endpoint, params=None): captured_params.append(params or {}) return [] monkeypatch.setattr(collector, "_api_call", fake_call) collector.collect_all() expected_from = (date.today() - timedelta(days=30)).strftime("%Y%m%d") detail_calls = [p for p in captured_params if "RCRIT_PBLANC_DE_FROM" in p] assert detail_calls, "detail 엔드포인트 호출에 윈도우 파라미터가 없음" assert detail_calls[0]["RCRIT_PBLANC_DE_FROM"] == expected_from