Files
ewoooc/tests/test_momo_crawler_targeted_search.py
OoO 9d84cbfd43
All checks were successful
CD Pipeline / deploy (push) Successful in 1m8s
feat: deepen pchome momo backfill guardrails
2026-06-19 00:41:20 +08:00

186 lines
7.1 KiB
Python

from datetime import datetime
def test_build_targeted_momo_search_terms_keeps_identity_and_spec():
from services.momo_crawler import build_targeted_momo_search_terms
terms = build_targeted_momo_search_terms("【LA ROCHE-POSAY 理膚寶水】B5全面修復霜 40ml", max_terms=5)
assert terms[0] == "理膚寶水 全面修復霜 b5 40ml"
assert any("40ml" in term for term in terms)
assert any("b5" in term.lower() for term in terms)
def test_momo_next_search_payload_parser_extracts_goods_info_list():
from services.momo_crawler import MomoCrawler
html = (
r'{\"goodsInfoList\":[{\"goodsCode\":\"10833188\",'
r'\"goodsName\":\"【理膚寶水】B5+全面修復霜輕量版 40ml 年度限定組B\",'
r'\"goodsPrice\":\"$$468\",'
r'\"goodsPriceOri\":\"$$835\",'
r'\"imgUrl\":\"https://img3.momoshop.com.tw/goodsimg/0010/833/188/10833188_OL.jpg\"}]}'
)
products = MomoCrawler(timeout=1, delay=0)._parse_next_search_payload_results(html, limit=5)
assert len(products) == 1
assert products[0].product_id == "10833188"
assert products[0].name == "【理膚寶水】B5+全面修復霜輕量版 40ml 年度限定組B"
assert products[0].price == 468
assert products[0].original_price == 835
assert products[0].discount == 44
assert products[0].product_url.endswith("i_code=10833188")
def test_search_momo_products_for_pchome_products_uses_each_pchome_product_as_target():
from services.momo_crawler import MomoProduct, search_momo_products_for_pchome_products
calls = []
class FakeCrawler:
def search_products(self, keyword, limit=10, sort_by="sSaleQty/dc"):
calls.append((keyword, limit, sort_by))
if "b5" in keyword.lower() or "全面修復霜" in keyword:
return True, "ok", [
MomoProduct(
product_id="12345678",
name="理膚寶水 B5全面修復霜 40ml",
price=890,
original_price=990,
discount=10,
image_url="",
product_url="https://www.momoshop.com.tw/goods/GoodsDetail.jsp?i_code=12345678",
brand="理膚寶水",
crawled_at=datetime.now(),
)
]
return True, "ok", []
success, message, products = search_momo_products_for_pchome_products(
[
{
"product_id": "PCH-1",
"name": "【LA ROCHE-POSAY 理膚寶水】B5全面修復霜 40ml",
"price": 920,
}
],
crawler=FakeCrawler(),
max_products=5,
max_terms_per_product=4,
limit_per_product=3,
min_score=0.0,
)
assert success is True
assert "找到 1 筆候選" in message
assert calls
assert calls[0][1] == 3
assert products[0]["product_id"] == "12345678"
assert products[0]["target_pchome_product_id"] == "PCH-1"
assert products[0]["target_pchome_name"] == "【LA ROCHE-POSAY 理膚寶水】B5全面修復霜 40ml"
assert products[0]["target_pchome_price"] == 920
assert products[0]["target_match_score"] > 0
assert products[0]["source_strategy"] == "pchome_targeted_momo_search"
def test_targeted_momo_search_auto_routes_unit_comparable_candidates():
from services.momo_crawler import MomoProduct, search_momo_products_for_pchome_products
class FakeCrawler:
def search_products(self, keyword, limit=10, sort_by="sSaleQty/dc"):
return True, "ok", [
MomoProduct(
product_id="10833188",
name="【理膚寶水】B5+全面修復霜輕量版 40ml 年度限定組B(萬用修復)",
price=468,
original_price=835,
discount=44,
image_url="",
product_url="https://www.momoshop.com.tw/goods/GoodsDetail.jsp?i_code=10833188",
brand="理膚寶水",
crawled_at=datetime.now(),
)
]
success, message, products = search_momo_products_for_pchome_products(
[
{
"product_id": "PCH-1",
"name": "【LA ROCHE-POSAY 理膚寶水】B5全面修復霜 40ml",
"price": 920,
}
],
crawler=FakeCrawler(),
max_terms_per_product=1,
limit_per_product=3,
min_score=0.45,
)
assert success is True
assert "自動單位價比較 1 筆" in message
assert products[0]["target_comparison_mode"] == "unit_comparable"
assert products[0]["target_hard_veto"] is True
assert products[0]["can_auto_compare"] is True
assert products[0]["auto_compare_type"] == "unit_price"
assert products[0]["target_price_basis"] == "unit_price"
assert products[0]["target_review_status"] == "自動單位價比較"
assert products[0]["target_unit_price_comparison"]["comparable"] is True
assert products[0]["target_unit_price_comparison"]["unit_label"] == "ml"
assert products[0]["target_gap_pct"] < 0
def test_targeted_momo_search_keeps_identity_review_candidates_manual(monkeypatch):
from services.momo_crawler import MomoProduct, search_momo_products_for_pchome_products
class FakeDiagnostics:
score = 0.98
hard_veto = False
comparison_mode = "exact_identity"
price_basis = "manual_review"
alert_tier = "identity_review"
match_type = "exact"
reasons = ("variant_selection_review", "strong_exact_spec_match")
class FakeCrawler:
def search_products(self, keyword, limit=10, sort_by="sSaleQty/dc"):
return True, "ok", [
MomoProduct(
product_id="12876190",
name="【LAURA MERCIER 蘿拉蜜思】煥顏透明蜜粉 29g(#Rose-國際航空版)",
price=809,
original_price=999,
discount=19,
image_url="",
product_url="https://www.momoshop.com.tw/goods/GoodsDetail.jsp?i_code=12876190",
brand="蘿拉蜜思",
crawled_at=datetime.now(),
)
]
monkeypatch.setattr(
"services.marketplace_product_matcher.score_marketplace_match",
lambda *args, **kwargs: FakeDiagnostics(),
)
success, message, products = search_momo_products_for_pchome_products(
[
{
"product_id": "PCH-LAURA",
"name": "【Laura Mercier 蘿拉蜜思】煥顏透明蜜粉 29g",
"price": 899,
}
],
crawler=FakeCrawler(),
max_terms_per_product=1,
limit_per_product=3,
min_score=0.45,
)
assert success is True
assert "需人工確認 1 筆" in message
assert products[0]["auto_compare_type"] == "manual_review"
assert products[0]["can_auto_compare"] is False
assert products[0]["target_price_basis"] == "none"
assert products[0]["target_alert_tier"] == "identity_review"