test_min_price_rule.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import pytest
  2. from datetime import date
  3. from types import SimpleNamespace
  4. from room_cal.discount import DiscountData, DiscountType
  5. from room_cal.pricing import CalPrice
  6. from room_cal.pricing.price_calendar import PriceData
  7. from room_cal.rules.discount.min_price import RULE_NAME, run
  8. def _stub_prices(monkeypatch, bases: dict[date, int]):
  9. async def _get(self, start_date, end_date):
  10. return {str(d): PriceData(base=base, net=base) for d, base in bases.items()}
  11. monkeypatch.setattr(CalPrice, 'get', _get)
  12. def _stub_config(monkeypatch, min_net: int):
  13. cfg = SimpleNamespace(rules=SimpleNamespace(min_price=SimpleNamespace(min_net=min_net)))
  14. monkeypatch.setattr('room_cal.rules.discount.min_price.get_config', lambda: cfg)
  15. def test_rule_registered():
  16. assert RULE_NAME == 'min_price'
  17. @pytest.mark.asyncio
  18. async def test_empty_input_returns_empty():
  19. assert await run(date(2026, 1, 1), date(2026, 1, 1), {}) == {}
  20. @pytest.mark.asyncio
  21. async def test_percent_discount_clamped_to_floor(monkeypatch):
  22. d = date(2026, 1, 10)
  23. _stub_prices(monkeypatch, {d: 100})
  24. _stub_config(monkeypatch, 52)
  25. data = {d: DiscountData(type=DiscountType.PERCENT, value=60)}
  26. result = await run(d, d, data)
  27. # headroom = 100 - 52 = 48 -> max_pct = 48%
  28. assert result[d].value == 48
  29. @pytest.mark.asyncio
  30. async def test_flat_discount_clamped_to_floor(monkeypatch):
  31. d = date(2026, 1, 10)
  32. _stub_prices(monkeypatch, {d: 100})
  33. _stub_config(monkeypatch, 52)
  34. data = {d: DiscountData(type=DiscountType.FLAT, value=60)}
  35. result = await run(d, d, data)
  36. assert result[d].value == 48
  37. @pytest.mark.asyncio
  38. async def test_discount_under_floor_passes_through(monkeypatch):
  39. d = date(2026, 1, 10)
  40. _stub_prices(monkeypatch, {d: 100})
  41. _stub_config(monkeypatch, 52)
  42. data = {d: DiscountData(type=DiscountType.PERCENT, value=30)}
  43. result = await run(d, d, data)
  44. assert result[d].value == 30
  45. @pytest.mark.asyncio
  46. async def test_base_at_or_below_floor_drops_discount(monkeypatch):
  47. d = date(2026, 1, 10)
  48. _stub_prices(monkeypatch, {d: 50})
  49. _stub_config(monkeypatch, 52)
  50. data = {d: DiscountData(type=DiscountType.PERCENT, value=10)}
  51. result = await run(d, d, data)
  52. assert d not in result