AtAnyRate/tests/airbnb/test_calendar.py
ilia c8a82e264c Add tests, geo search, noise filtering, sports scoring, and dedup improvements.
Tests cover providers, dedup, Telegram, scoring, main runner, and Airbnb stubs.
Ticketmaster and SeatGeek use configurable lat/lon/radius (Thornhill default).
Pipeline filters noise listings, merges same-day sports duplicates, optional
MIN_ALERT_SCORE, and Telegram severity summary.

Made-with: Cursor
2026-04-04 15:25:35 -04:00

100 lines
3.0 KiB
Python

"""Tests for the Airbnb calendar price automation module."""
from datetime import date
from unittest.mock import MagicMock, call, patch
import pytest
from src.airbnb.calendar import (
update_price,
_navigate_to_month,
CALENDAR_URL,
SELECTORS,
_MAX_UPDATE_ATTEMPTS,
)
class TestUpdatePrice:
def _make_page(self, *, fail_on_click: bool = False) -> MagicMock:
page = MagicMock()
if fail_on_click:
from playwright.sync_api import TimeoutError as PlaywrightTimeout
page.click.side_effect = PlaywrightTimeout("timed out")
return page
def test_successful_price_update(self):
page = self._make_page()
result = update_price(page, date(2026, 5, 10), 180)
assert result is True
page.goto.assert_called_once()
assert "2026-05-10" in str(page.click.call_args_list[0])
page.fill.assert_called_once()
def test_navigates_to_calendar_url(self):
page = self._make_page()
update_price(page, date(2026, 5, 10), 180)
page.goto.assert_called_once_with(
CALENDAR_URL, wait_until="networkidle", timeout=30_000
)
def test_fills_correct_price(self):
page = self._make_page()
update_price(page, date(2026, 5, 10), 200)
page.fill.assert_called_once_with(
SELECTORS["price_input"], "200", timeout=5_000
)
def test_retries_on_timeout(self):
from playwright.sync_api import TimeoutError as PlaywrightTimeout
page = MagicMock()
page.goto.side_effect = PlaywrightTimeout("timed out")
with patch("src.airbnb.calendar.time.sleep"):
result = update_price(page, date(2026, 5, 10), 180)
assert result is False
assert page.goto.call_count == _MAX_UPDATE_ATTEMPTS
def test_retries_on_generic_exception(self):
page = MagicMock()
page.goto.side_effect = RuntimeError("unexpected")
with patch("src.airbnb.calendar.time.sleep"):
result = update_price(page, date(2026, 5, 10), 180)
assert result is False
assert page.goto.call_count == _MAX_UPDATE_ATTEMPTS
def test_succeeds_on_second_attempt(self):
from playwright.sync_api import TimeoutError as PlaywrightTimeout
page = MagicMock()
page.goto.side_effect = [PlaywrightTimeout("first fail"), None]
with patch("src.airbnb.calendar.time.sleep"):
result = update_price(page, date(2026, 5, 10), 180)
assert result is True
assert page.goto.call_count == 2
class TestNavigateToMonth:
def test_stub_does_not_crash(self):
page = MagicMock()
_navigate_to_month(page, date(2026, 5, 10))
class TestSelectors:
def test_date_cell_selector_uses_date_format(self):
sel = SELECTORS["date_cell"].format(date_str="2026-05-10")
assert "2026-05-10" in sel
def test_all_selectors_defined(self):
assert "date_cell" in SELECTORS
assert "price_input" in SELECTORS
assert "save_button" in SELECTORS