o2o-negosium-original/lps/tests/test_naver_transform.py
민헌 9557c1b1af feat(lps): 네이버 어댑터 + 다중 소스 병합 검색
네이버 쇼핑 오픈API 어댑터(크롤링 불필요) + 핸들러를 다중 소스로 확장.
쿠팡(브라우저)+네이버(API)를 동시 검색·병합해 교차 최저가를 뽑는다.

- search/naver/adapter: httpx + 오픈API + 키 로테이션(429/403 순환), .env 키 로드
- search/naver/transform: 순수 변환(태그/엔티티 정리, lprice). 가격비교(catalog) lprice 는
  '여러 판매자 중 최저가'라 최저가 솔루션엔 핵심 → 유지
- handler: asyncio.gather 동시 검색 + 소스별 실패 격리(일부 죽어도 결과) + 전체 실패 시 잡 실패
- worker_main: adapters={coupang, naver}
- tests: 네이버 변환 + 병합/실패격리/전체실패 4건 → 전체 31/31
- 라이브: 쿠팡30+네이버30 병합 top-N 최저가(소스 라벨 포함)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 08:38:15 +09:00

20 lines
1.0 KiB
Python

"""네이버 응답 변환 테스트 (순수, 네트워크 불필요)."""
from services.search.naver.transform import transform_items
def test_transform_strips_tags_and_keeps_catalog():
items = [
{"title": "로지텍 <b>무선</b> 마우스 &amp; 키보드", "link": "https://search.shopping.naver.com/catalog/1",
"image": "img1", "lprice": "13500", "mallName": "네이버", "maker": "로지텍", "productId": "1"},
{"title": "0원상품", "link": "https://x", "lprice": "0"}, # 가격 0 → 제외
{"title": "가격없음", "link": "https://y", "lprice": "abc"}, # 파싱 실패 → 제외
]
out = transform_items(items)
assert len(out) == 1
p = out[0]
assert p.name == "로지텍 무선 마우스 & 키보드" # <b> 제거 + 엔티티 복원
assert p.price == 13500 and p.source == "naver"
assert p.mall_name == "네이버" and p.manufacturer == "로지텍" and p.external_id == "1"
assert "catalog/1" in p.detail_url # 가격비교(catalog) 최저가 유지