"""Unit tests for the price-verdict logic (pure, no network).""" from __future__ import annotations from config.settings import PricingRules from pricing_agent.analyze import Rating, classify_trend, price_verdict, suggested_price from pricing_agent.tools.margin_engine import stack_from_quote from pricing_agent.schemas import FeeQuote RULES = PricingRules(margin_floor=0.25, margin_target=0.30) def test_suggested_price_clears_target_margin(): # Real pillow fee model: landed 8.59, fba 8.97, referral 15%, returns 2%, other 0.11. quote = FeeQuote(selling_price=24.99, landed_cost=8.59, fba_fee=8.97, referral_amt=3.75, returns_reserve=0.50, other_fees=0.11, net_takehome=3.07, source="cosmos") stack = stack_from_quote(quote, RULES) sug = suggested_price(stack, RULES.margin_target) assert sug is not None # ~$33.34 rounded up to a .99 ending. assert 33.0 <= sug <= 34.5 assert round(sug - int(sug), 2) == 0.99 # Re-price at the suggestion and confirm it clears the 30% target. requote = FeeQuote(selling_price=sug, landed_cost=8.59, fba_fee=8.97, referral_amt=0.15 * sug, returns_reserve=0.02 * sug, other_fees=0.11, source="cosmos") restack = stack_from_quote(requote, RULES) assert restack.contribution_margin_pct >= RULES.margin_target def _verdict(**kw): base = dict(trend="stable", selling=True, cover_days=60, monthly_take_home=10000.0, rules=RULES) base.update(kw) return price_verdict(**base)[0] def test_trend_classification(): assert classify_trend(1714, 1655) == "stable" # ~+3.6% assert classify_trend(2000, 1655) == "rising" # +21% assert classify_trend(1300, 1655) == "declining" # -21% assert classify_trend(None, 1655) == "unknown" def test_good_price_healthy_margin_and_demand(): assert _verdict(margin_pct=0.31) == Rating.GOOD def test_thin_margin_but_strong_demand_is_caution_raise_price(): assert _verdict(margin_pct=0.12, trend="stable", selling=True) == Rating.CAUTION def test_thin_margin_and_weak_demand_is_poor(): assert _verdict(margin_pct=0.12, trend="declining", selling=False) == Rating.POOR def test_negative_margin_is_poor_even_with_strong_demand(): assert _verdict(margin_pct=-0.059, trend="stable", selling=True) == Rating.POOR def test_overstock_storage_drain_is_caution(): assert _verdict(margin_pct=0.31, cover_days=200) == Rating.CAUTION def test_negative_monthly_takehome_is_poor(): assert _verdict(margin_pct=0.31, monthly_take_home=-2813.0) == Rating.POOR def test_declining_demand_with_good_margin_is_caution(): assert _verdict(margin_pct=0.31, trend="declining") == Rating.CAUTION