"""LPS 몰별 확인 상태 미러링 — '없었다'와 '못 봤다'를 화면까지 나르는 계약. by_mall 은 **가격이 있는 몰만** 담는다. 그래서 빠진 몰이 '거기엔 없더라'인지 '거기를 못 봤다'인지는 sources/partial 에만 있다. 이 값이 중간에서 빠지면 화면은 두 경우를 구분할 방법이 없다 (실제로 그래서 차단당한 몰이 '없음'으로 보였다 — lps/docs/result-states.md). """ from crud.lps_sync_crud import _price_history from router.v1.item.protocol import LowestPriceEntry def test_read_contract_includes_source_state(): """lps_db 읽기 계약에서 이 컬럼이 빠지면 화면까지 갈 값이 사라진다.""" cols = {c.name for c in _price_history.columns} assert {"sources", "partial"} <= cols, cols assert "by_mall" in cols # 함께 읽어야 '가격 있는 몰'과 '확인한 몰'을 대조할 수 있다 def test_api_entry_exposes_state_with_safe_defaults(): """이 컬럼 추가 이전 이력(값 없음)도 화면이 깨지지 않아야 한다.""" e = LowestPriceEntry() assert e.sources is None assert e.partial is False, "기본이 True 면 정상 결과가 '일부 확인 못함'으로 보인다" def test_api_entry_carries_source_state(): e = LowestPriceEntry( lp_price=9000, success_yn=True, partial=True, sources={"naver": {"state": "matched", "count": 40}, "coupang": {"state": "blocked", "error": "차단"}}, ) assert e.partial is True assert e.sources["coupang"]["state"] == "blocked"