import pytest from datetime import date, timedelta from room_cal.pricing import CalPrice, PriceData from room_cal.pricing.calc import net_to_list from room_cal.pricing.price_calendar import _build_description from room_cal.discount import DiscountType # ── _build_description ──────────────────────────────────────────────────────── def test_build_description_net_only(): assert _build_description(PriceData(base=100, net=100)) == 'Net: $100' def test_build_description_base_equals_net_omits_base(): result = _build_description(PriceData(base=100, net=100)) assert 'Base:' not in result assert result == 'Net: $100' def test_build_description_base_differs_from_net(): result = _build_description(PriceData(base=100, net=90)) assert 'Net: $90' in result assert 'Base: $100' in result def test_build_description_flat_discount(): prices = PriceData(base=100, net=90, discount=10, discount_type=DiscountType.FLAT, discount_value=10) result = _build_description(prices) assert 'Discount: $10' in result assert '%' not in result def test_build_description_percent_discount(): prices = PriceData(base=100, net=90, discount=10, discount_type=DiscountType.PERCENT, discount_value=10) result = _build_description(prices) assert 'Discount: $10 / 10%' in result def test_build_description_service_with_retail(): prices = PriceData(base=100, net=100, service_prices={'airbnb': 115}, service_retail={'airbnb': 130}) result = _build_description(prices) assert 'Airbnb: $115 / $130' in result def test_build_description_service_without_retail(): prices = PriceData(base=100, net=100, service_prices={'airbnb': 115}) result = _build_description(prices) assert 'Airbnb: $115' in result assert '/' not in result def test_build_description_multiple_services_sorted(): prices = PriceData( base=100, net=100, service_prices={'booking': 120, 'airbnb': 115}, service_retail={'booking': 140, 'airbnb': 130}, ) lines = _build_description(prices).splitlines() service_lines = [l for l in lines if l.startswith('Airbnb') or l.startswith('Booking')] assert service_lines[0].startswith('Airbnb') assert service_lines[1].startswith('Booking') @pytest.mark.asyncio async def test_room_price_calendars_set_readback(): cals = CalPrice() # Find a past date that has a price so we can restore it cleanly. # Past dates are safe: even if the test leaves stale data it won't affect live bookings. target = None original = None d = date.today() - timedelta(days=90) end = date.today() - timedelta(days=70) while d <= end: full = await cals._get_prices(d) if full is not None: target = d original = full.net break d += timedelta(days=1) if target is None: pytest.skip("No priced date found in the past 70–90 days") test_price = original + 2 try: await cals.set(target, test_price) prices = await cals._get_prices(target) assert prices is not None, "No price event found after set" assert round(prices.net) == round(test_price), \ f"Net mismatch: expected {round(test_price)}, got {prices.net}" for service in cals._services: expected = round(net_to_list(service, test_price)) assert round(prices.service_prices[service]) == expected, \ f"{service} mismatch: expected {expected}, got {prices.service_prices[service]}" finally: await cals.set(target, original)