from contextlib import contextmanager class _FakeAlert: def __init__(self, driver, text="很抱歉此EDM不存在"): self._driver = driver self.text = text def accept(self): self._driver.alert_accepted = True class _FakeSwitchTo: def __init__(self, driver): self._driver = driver @property def alert(self): import scheduler if self._driver.alert_accepted: raise scheduler.NoAlertPresentException() return _FakeAlert(self._driver) class _ExpiredEdmDriver: def __init__(self): self.alert_accepted = False self.loaded_url = None self.switch_to = _FakeSwitchTo(self) def get(self, url): self.loaded_url = url @property def title(self): raise AssertionError("expired EDM alert should be handled before reading title") def _install_expired_edm_driver(monkeypatch): import scheduler driver = _ExpiredEdmDriver() @contextmanager def fake_resources(*_args, **_kwargs): yield driver, object() stats = [] monkeypatch.setattr(scheduler, "managed_scraper_resources", fake_resources) monkeypatch.setattr(scheduler.time, "sleep", lambda *_args, **_kwargs: None) monkeypatch.setattr(scheduler, "_save_stats", lambda task, data: stats.append((task, data))) return scheduler, driver, stats def test_promo_event_expired_edm_alert_skips_without_failure(monkeypatch): scheduler, driver, stats = _install_expired_edm_driver(monkeypatch) scheduler.run_promo_event_task("expired-lpn", "mothers_day", "母親節超值限時購") assert driver.alert_accepted is True assert stats == [( "mothers_day_task", { "status": "Skipped", "reason": "edm_unavailable", "alert_text": "很抱歉此EDM不存在", "url": "https://www.momoshop.com.tw/edm/cmmedm.jsp?lpn=expired-lpn&n=1", }, )] def test_festival_expired_edm_alert_skips_without_failure(monkeypatch): scheduler, driver, stats = _install_expired_edm_driver(monkeypatch) scheduler.run_festival_task(lpn_code="expired-lpn") assert driver.alert_accepted is True assert stats == [( "festival_task", { "status": "Skipped", "reason": "edm_unavailable", "alert_text": "很抱歉此EDM不存在", "url": "https://www.momoshop.com.tw/edm/cmmedm.jsp?lpn=expired-lpn&n=1", }, )]