From 15e2204eace187b95b5a066bcad4e1b888b28a2a Mon Sep 17 00:00:00 2001 From: Jetski Date: Sat, 27 Jun 2026 14:52:43 +0000 Subject: [PATCH] Fix: prevent sending empty notifications to webhook --- camply/notifications/webhook.py | 3 ++ camply/search/base_search.py | 16 +++++------ tests/test_notifications.py | 49 +++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/camply/notifications/webhook.py b/camply/notifications/webhook.py index fe45059f..38ea4363 100755 --- a/camply/notifications/webhook.py +++ b/camply/notifications/webhook.py @@ -53,6 +53,9 @@ def send_campsites(self, campsites: List[AvailableCampsite], **kwargs) -> None: ---------- campsites: List[AvailableCampsite] """ + if not campsites: + logger.debug("No campsites to send to webhook.") + return webhook_body = WebhookBody(campsites=campsites).json().encode("utf-8") response = self.session.post(url=self.webhook_url, data=webhook_body) try: diff --git a/camply/search/base_search.py b/camply/search/base_search.py index 6b556c62..956d3b34 100644 --- a/camply/search/base_search.py +++ b/camply/search/base_search.py @@ -366,14 +366,14 @@ def _continuous_search_retry( ) logger.info(f"{len(new_campsites)} New Campsites Found.") self.campsites_found.update(new_campsites) - logged_campsites = list(new_campsites) - self._handle_notifications( - retryer=retryer, - notifier=self.notifier, - logged_campsites=logged_campsites, - continuous_search_attempts=continuous_search_attempts, - notify_first_try=notify_first_try, - ) + if new_campsites: + self._handle_notifications( + retryer=retryer, + notifier=self.notifier, + logged_campsites=list(new_campsites), + continuous_search_attempts=continuous_search_attempts, + notify_first_try=notify_first_try, + ) return list(self.campsites_found) @classmethod diff --git a/tests/test_notifications.py b/tests/test_notifications.py index 4719a3f5..e83aa420 100644 --- a/tests/test_notifications.py +++ b/tests/test_notifications.py @@ -2,8 +2,15 @@ Notification Testing """ +from unittest.mock import MagicMock + +from pytest import MonkeyPatch + from camply import AvailableCampsite +from camply.config.notification_config import WebhookConfig from camply.notifications import PushoverNotifications +from camply.notifications.webhook import WebhookNotifications +from camply.search.base_search import BaseCampingSearch from tests.conftest import vcr_cassette @@ -23,3 +30,45 @@ def test_pushover_campsite(available_campsite: AvailableCampsite): """ pusher = PushoverNotifications() pusher.send_campsites(campsites=[available_campsite]) + + +def test_no_notifications_when_no_new_campsites(): + """ + Verify that notifications are not sent when no new campsites are found + """ + self_mock = MagicMock(spec=BaseCampingSearch) + self_mock._get_polling_minutes.return_value = 10 + self_mock._search_matching_campsites_available.return_value = ["campsite1"] + self_mock.campsites_found = {"campsite1"} + + BaseCampingSearch._continuous_search_retry( + self=self_mock, + log=False, + verbose=False, + polling_interval=10, + continuous_search_attempts=1, + notification_provider="silent", + notify_first_try=False, + search_once=True, + ) + + self_mock.assemble_availabilities.assert_called_once_with( + matching_data=[], log=False, verbose=False + ) + self_mock._handle_notifications.assert_not_called() + + +def test_webhook_notifier_empty_campsites(monkeypatch: MonkeyPatch): + """ + Verify WebhookNotifications does not send empty campsite lists + """ + monkeypatch.setattr(WebhookConfig, "WEBHOOK_URL", "http://example.com/webhook") + + mock_session = MagicMock() + + notifier = WebhookNotifications() + notifier.session = mock_session + + notifier.send_campsites([]) + + mock_session.post.assert_not_called()