"""Unit tests for Apify → CompetitiveSnapshot mapping (no network).""" from __future__ import annotations import json from pathlib import Path from pricing_agent.schemas import BuyBoxStatus from pricing_agent.tools.amazon.apify import item_to_competitive FIX = Path(__file__).parent / "fixtures" / "apify_amazon_item.json" ITEMS = json.loads(FIX.read_text(encoding="utf-8")) OUR_SELLER = "A3AQP8TDYVYCGL" def test_won_when_seller_matches(): snap = item_to_competitive( ITEMS["won"], asin="B01ND3Y00M", our_price=6.98, our_seller_id=OUR_SELLER, ) assert snap.buy_box_status == BuyBoxStatus.WON assert snap.buy_box_price == 6.98 assert snap.is_suppressed is False assert "Featured Offer" in snap.reason or "hold" in snap.reason.lower() # Sole seller, no rival offers -> there is no competitive band to report. assert snap.competitive_low is None assert snap.competitive_median is None assert snap.competitive_high is None def test_our_own_offers_never_become_the_competitive_band(): """Regression: B01ND3Y00M returns three offers, all ours, one of them used. The old mapper reported low/median/high = 6.99/9.99/12.99 and told the user "Competitors: Utopia Brands" — it was quoting us back at ourselves. """ snap = item_to_competitive( ITEMS["won_self_offers_only"], asin="B01ND3Y00M", our_price=6.99, our_seller_id=OUR_SELLER, ) assert snap.buy_box_status == BuyBoxStatus.WON assert snap.buy_box_price == 6.99 # No rivals on this listing -> no band at all. assert snap.competitive_low is None assert snap.competitive_median is None assert snap.competitive_high is None assert all(o.is_ours for o in snap.offers) assert "Competitors: none" in snap.reason assert "Utopia Brands @ $9.99" not in snap.reason.split("Our own offers:")[0] def test_used_offers_excluded_from_band(): """A used rival offer must not set competitive_low; only new stock competes.""" snap = item_to_competitive( ITEMS["won_with_used_rival"], asin="B0MIXED001", our_price=19.99, our_seller_id=OUR_SELLER, ) assert snap.buy_box_status == BuyBoxStatus.WON # Only the New rival at 22.50 counts. The used $8.00 offer is ignored, and our # own $19.99 featured offer is not a competitor either. assert snap.competitive_low == 22.50 assert snap.competitive_median == 22.50 assert snap.competitive_high == 22.50 def test_rival_holds_buy_box_at_higher_price_is_not_a_price_loss(): """We are cheaper but still lost the Buy Box -> eligibility, not price.""" snap = item_to_competitive( ITEMS["lost_eligibility"], asin="B0ELIG0001", our_price=24.99, our_seller_id=OUR_SELLER, ) assert snap.buy_box_status == BuyBoxStatus.LOST_ELIGIBILITY assert snap.buy_box_price == 26.00 # Band is the rival only; our own 24.99 offer is excluded. assert snap.competitive_low == 26.00 assert snap.competitive_high == 26.00 def test_lost_price_and_offer_band(): snap = item_to_competitive( ITEMS["lost_with_offers"], asin="B0COMPETE01", our_price=24.99, our_seller_id=OUR_SELLER, ) assert snap.buy_box_status == BuyBoxStatus.LOST_PRICE assert snap.buy_box_price == 21.49 assert snap.buy_box_seller_name == "Rival Seller" assert snap.competitive_low == 21.49 assert snap.competitive_high == 24.99 assert snap.competitive_median == 22.00 assert snap.is_suppressed is False assert len(snap.offers) >= 3 names = {o.seller_name for o in snap.offers} assert "Rival Seller" in names assert "Other Mart" in names assert "Budget Goods" in names buy_box = next(o for o in snap.offers if o.is_buy_box) assert buy_box.price == 21.49 assert "Competitors:" in snap.reason def test_suppressed_when_no_featured_price(): snap = item_to_competitive( ITEMS["suppressed"], asin="B0NOSHOW", our_price=24.99, our_seller_id=OUR_SELLER, ) assert snap.buy_box_status == BuyBoxStatus.SUPPRESSED assert snap.is_suppressed is True assert snap.buy_box_price is None assert snap.competitive_low == 19.99 assert any(o.seller_name == "Third Party Co" and o.price == 19.99 for o in snap.offers) def test_undercut_without_seller_id_flags_lost_price(): snap = item_to_competitive( ITEMS["lost_with_offers"], asin="B0COMPETE01", our_price=24.99, our_seller_id=None, ) assert snap.buy_box_status == BuyBoxStatus.LOST_PRICE assert "APIFY_SELLER_ID" in snap.reason