"""Tests for AdminNotifier helper methods.""" import pytest from src.notifications.notifier import AdminNotifier from src.models.registration import RegistrationData, Booking, BookingDay @pytest.fixture def notifier(): return AdminNotifier( smtp_host="smtp.example.com", smtp_port=587, username="agent@example.com", password="secret", use_tls=True, from_email="agent@example.com", admin_emails=["to@example.com", "cc1@example.com", "cc2@example.com"], ) # --------------------------------------------------------------------------- # _format_types # --------------------------------------------------------------------------- class TestFormatTypes: def test_indoor_label(self, notifier): assert "Innen" in notifier._format_types(["indoor"]) or "indoor" in notifier._format_types(["indoor"]).lower() def test_outdoor_label(self, notifier): assert "Wald" in notifier._format_types(["outdoor"]) or "outdoor" in notifier._format_types(["outdoor"]).lower() def test_both_labels(self, notifier): result = notifier._format_types(["indoor", "outdoor"]) assert len(result) > 0 # --------------------------------------------------------------------------- # _calculate_age # --------------------------------------------------------------------------- class TestCalculateAge: def test_returns_age_string(self, notifier): result = notifier._calculate_age("2022-01-01") assert isinstance(result, str) assert len(result) > 0 def test_invalid_dob_returns_original_string(self, notifier): result = notifier._calculate_age("not-a-date") assert result == "not-a-date" # --------------------------------------------------------------------------- # _calculate_monthly_fee # --------------------------------------------------------------------------- class TestCalculateMonthlyFee: def test_indoor_one_day(self, notifier, complete_registration): complete_registration.booking = Booking( playgroup_types=["indoor"], selected_days=[BookingDay(day="monday", type="indoor")], ) fee = notifier._calculate_monthly_fee(complete_registration) assert "130" in fee def test_indoor_two_days(self, notifier, complete_registration): complete_registration.booking = Booking( playgroup_types=["indoor"], selected_days=[ BookingDay(day="monday", type="indoor"), BookingDay(day="wednesday", type="indoor"), ], ) fee = notifier._calculate_monthly_fee(complete_registration) assert "260" in fee def test_indoor_three_days(self, notifier, complete_registration): complete_registration.booking = Booking( playgroup_types=["indoor"], selected_days=[ BookingDay(day="monday", type="indoor"), BookingDay(day="wednesday", type="indoor"), BookingDay(day="thursday", type="indoor"), ], ) fee = notifier._calculate_monthly_fee(complete_registration) assert "390" in fee def test_outdoor_one_day(self, notifier, complete_registration): complete_registration.booking = Booking( playgroup_types=["outdoor"], selected_days=[BookingDay(day="monday", type="outdoor")], ) fee = notifier._calculate_monthly_fee(complete_registration) assert "250" in fee # --------------------------------------------------------------------------- # _send — SMTP interaction # --------------------------------------------------------------------------- class TestSend: def test_send_calls_smtp(self, notifier, mocker): # _send uses smtplib.SMTP directly (not as context manager) mock_smtp_cls = mocker.patch("smtplib.SMTP") mock_server = mock_smtp_cls.return_value notifier._send( to=["admin@example.com"], cc=["cc@example.com"], subject="Test", body="Hello", ) mock_server.sendmail.assert_called_once() def test_send_includes_all_recipients(self, notifier, mocker): mock_smtp_cls = mocker.patch("smtplib.SMTP") mock_server = mock_smtp_cls.return_value notifier._send( to=["a@example.com"], cc=["b@example.com"], subject="Test", body="Hello", ) call_args = mock_server.sendmail.call_args recipients = call_args[0][1] # positional arg: to_addrs assert "a@example.com" in recipients assert "b@example.com" in recipients