V10.391 handle catalog variant listings
All checks were successful
CD Pipeline / deploy (push) Successful in 1m7s
All checks were successful
CD Pipeline / deploy (push) Successful in 1m7s
This commit is contained in:
@@ -666,6 +666,70 @@ def test_competitor_feeder_marks_weak_identity_as_true_low_confidence(monkeypatc
|
||||
assert attempts[0]["attempt_status"] == "true_low_confidence"
|
||||
|
||||
|
||||
def test_competitor_feeder_does_not_treat_spec_only_match_as_recoverable(monkeypatch):
|
||||
from services.competitor_price_feeder import CompetitorPriceFeeder
|
||||
from services.pchome_crawler import PChomeProduct
|
||||
|
||||
product = PChomeProduct(
|
||||
product_id="DDAB01-SPEC",
|
||||
name="LANCOME 蘭蔻 超極限肌因精華露150ml 專櫃公司貨",
|
||||
price=3200,
|
||||
original_price=3600,
|
||||
discount=11,
|
||||
image_url="",
|
||||
product_url="https://24h.pchome.com.tw/prod/DDAB01-SPEC",
|
||||
stock=20,
|
||||
store="24h",
|
||||
rating=4.6,
|
||||
review_count=12,
|
||||
is_on_sale=True,
|
||||
crawled_at=datetime.now(),
|
||||
)
|
||||
|
||||
class FakeCrawler:
|
||||
def __init__(self, *_args, **_kwargs):
|
||||
pass
|
||||
|
||||
def search_products(self, *_args, **_kwargs):
|
||||
return True, "ok", [product]
|
||||
|
||||
def fake_score(*_args, **_kwargs):
|
||||
return SimpleNamespace(
|
||||
score=0.748,
|
||||
brand_score=1.0,
|
||||
token_score=0.42,
|
||||
spec_score=1.0,
|
||||
sequence_score=0.49,
|
||||
type_score=0.55,
|
||||
price_penalty=0.0,
|
||||
hard_veto=False,
|
||||
reasons=("strong_exact_spec_match",),
|
||||
comparison_mode="exact_identity",
|
||||
tags=["identity_v2", "comparison_exact_identity", "brand_match"],
|
||||
)
|
||||
|
||||
monkeypatch.setattr("services.pchome_crawler.PChomeCrawler", FakeCrawler)
|
||||
monkeypatch.setattr("services.marketplace_product_matcher.score_marketplace_match", fake_score)
|
||||
feeder = CompetitorPriceFeeder(engine=object())
|
||||
attempts = []
|
||||
monkeypatch.setattr(
|
||||
feeder,
|
||||
"_record_match_attempt",
|
||||
lambda *args, **kwargs: attempts.append(kwargs),
|
||||
)
|
||||
|
||||
result = feeder._run_sku_items([{
|
||||
"sku": "LAN001",
|
||||
"name": "【LANCOME 蘭蔻】官方直營 超極光活粹晶露150ml",
|
||||
"product_id": 10,
|
||||
"momo_price": 3200,
|
||||
}])
|
||||
|
||||
assert result.matched == 0
|
||||
assert result.skipped_low_score == 1
|
||||
assert attempts[0]["attempt_status"] == "true_low_confidence"
|
||||
|
||||
|
||||
def test_competitor_feeder_downgrades_variant_selection_gap_from_recoverable(monkeypatch):
|
||||
from services.competitor_price_feeder import CompetitorPriceFeeder
|
||||
from services.pchome_crawler import PChomeProduct
|
||||
|
||||
@@ -774,6 +774,10 @@ def test_marketplace_matcher_rejects_fragrance_formula_and_finish_variant_mismat
|
||||
"【PRAMY 柏瑞美】磁吸控油定妝噴霧 100ML(柔焦霧面)",
|
||||
"【柏瑞美PRAMY】 磁吸控油定粧噴霧 水光亮面",
|
||||
),
|
||||
(
|
||||
"【Relove】8%菸鹼醯胺私密淨白清潔凝露120ml(私密清潔 私密美白 涼感潔淨 PH3.8弱酸呵護)",
|
||||
"RELOVE胺基酸私密清潔凝露120ml",
|
||||
),
|
||||
]
|
||||
|
||||
for momo_name, competitor_name in cases:
|
||||
@@ -784,6 +788,31 @@ def test_marketplace_matcher_rejects_fragrance_formula_and_finish_variant_mismat
|
||||
assert "variant_option_conflict" in diagnostics.reasons
|
||||
|
||||
|
||||
def test_marketplace_matcher_promotes_multi_variant_catalog_listings():
|
||||
from services.marketplace_product_matcher import score_marketplace_match
|
||||
|
||||
cases = [
|
||||
(
|
||||
"【日本John’s Blend】香氛擴香罐85g(車用/任選/白麝香/黑麝香/茉莉/櫻花/繡球花/魔髮奇緣/青檸羅勒)",
|
||||
"日本John’s Blend 車用香氛擴香罐85g(多款可選)",
|
||||
),
|
||||
(
|
||||
"【COCODOR】香氛蠟燭170g(多款任選/官方直營)",
|
||||
"COCODOR Premium Jar Candle 香氛精油蠟燭170g(多種香味任選)",
|
||||
),
|
||||
(
|
||||
"【COCODOR】香氛蠟燭95g(多款任選/官方直營)",
|
||||
"COCODOR Premium Jar Candle 香氛精油蠟燭95g(多種香味任選)",
|
||||
),
|
||||
]
|
||||
|
||||
for momo_name, competitor_name in cases:
|
||||
diagnostics = score_marketplace_match(momo_name, competitor_name)
|
||||
assert diagnostics.score >= 0.76
|
||||
assert diagnostics.hard_veto is False
|
||||
assert "catalog_variant_listing_alignment" in diagnostics.reasons
|
||||
|
||||
|
||||
def test_marketplace_matcher_rejects_refill_core_vs_case_only_pack():
|
||||
from services.marketplace_product_matcher import score_marketplace_match
|
||||
|
||||
|
||||
Reference in New Issue
Block a user