"""unit test: build_product_details thresholding, promo read, and combined_discount run from the repo root: uv run pytest tests/test_build_product_details.py pure and offline — no Mongo. Builds a Product from a raw doc dict and checks the discount threshold (with percentage codes compounding onto the sale price), the promo fields read through via .get, and the combined_discount helper. """ from datetime import datetime, timezone from monitor_utils.runner import build_product_details, combined_discount def _doc(**overrides) -> dict: """A well-formed product doc; override prices/promo per test.""" doc = { "_id": "p1_tools", "title": "Widget", "url": "http://x/p1", "currentPrice": 80.0, "originalPrice": 100.0, "imageUrl": "http://img/1", "customizationIndex": None, "memberNonMemberComparison": None, "overstockText": None, "discoveredDate": datetime(2026, 7, 26, tzinfo=timezone.utc), "startDate": None, "endDate": None, "priceBeforeDrop": None, "eduPrice": None, "pastPrices": [ {"price": 80.0, "date": datetime(2026, 7, 26, tzinfo=timezone.utc)} ], "available": True, "condition": None, "appExclusive": None, "memberPick": None, "memberDeal": None, } doc.update(overrides) return doc # ------------------------------------------------------------ combined_discount def test_combined_discount_no_promo_is_base(): assert combined_discount(24, None) == 24 assert combined_discount(24, 0) == 24 def test_combined_discount_compounds_not_adds(): # 20% off then extra 30% code -> 44% off list (customer pays $56), not 50% assert combined_discount(20, 30) == 44 def test_combined_discount_rounds_to_nearest(): # 24% sale + 22% code: 1 - .76*.78 = .4072 -> 41 (rounded, not truncated 40) assert combined_discount(24, 22) == 41 # --------------------------------------------------------- build_product_details def test_promo_fields_read_through(): doc = _doc( promoCode="BIRTHDAY26", promoPercentage=22, promoDollarOff=None, promoMinSpend=None, ) product = build_product_details(doc, min_percentage=0) assert product.metadata.promo_code == "BIRTHDAY26" assert product.metadata.promo_percentage == 22 # base percentage is the raw price delta, unchanged by the code assert product.metadata.percentage == 20 def test_missing_promo_keys_default_to_none(): """a doc from a lagging monitor lacks promo keys -> None, not KeyError""" product = build_product_details(_doc(), min_percentage=0) assert product.metadata.promo_code is None assert product.metadata.promo_percentage is None def test_percentage_code_lifts_item_over_threshold(): # 30% base fails min 40, but +22% code -> 45% combined clears it doc = _doc(currentPrice=70.0, originalPrice=100.0, promoPercentage=22) assert build_product_details(doc, min_percentage=40) is not None def test_below_threshold_without_code_is_skipped(): doc = _doc(currentPrice=70.0, originalPrice=100.0) # 30%, no code assert build_product_details(doc, min_percentage=40) is None def test_dollar_code_does_not_affect_threshold(): # a dollar code has no promoPercentage, so 30% base stays below min 40 doc = _doc( currentPrice=70.0, originalPrice=100.0, promoCode="STORE22", promoDollarOff=22, promoMinSpend=100, ) assert build_product_details(doc, min_percentage=40) is None # ----------------------------------------------------------------- pastPrices def test_past_prices_read_through(): """Price history passes through unchanged.""" history = [ {"price": 95.0, "date": datetime(2026, 7, 20, tzinfo=timezone.utc)}, {"price": 90.0, "date": datetime(2026, 7, 24, tzinfo=timezone.utc)}, ] product = build_product_details(_doc(pastPrices=history), min_percentage=0) assert product.pricing.past_prices == history