from unittest.mock import MagicMock, patch from app.notifications.emailer import EmailNotifier def _notifier(**overrides) -> EmailNotifier: defaults = dict( host="smtp.example.com", port=587, username="user@example.com", password="secret", from_address="sync@example.com", use_tls=True, ) defaults.update(overrides) return EmailNotifier(**defaults) def test_unconfigured_notifier_is_not_configured() -> None: notifier = _notifier(host=None) assert notifier.configured is False def test_configured_notifier_is_configured() -> None: assert _notifier().configured is True def test_send_skips_silently_when_not_configured() -> None: notifier = _notifier(host=None) with patch("app.notifications.emailer.smtplib.SMTP") as smtp_cls: notifier.send(to_address="user@example.com", subject="s", body="b") smtp_cls.assert_not_called() def test_send_uses_starttls_and_login_when_configured() -> None: notifier = _notifier() smtp_instance = MagicMock() smtp_instance.__enter__.return_value = smtp_instance with patch("app.notifications.emailer.smtplib.SMTP", return_value=smtp_instance) as smtp_cls: notifier.send(to_address="rider@example.com", subject="Action required", body="Check the dashboard") smtp_cls.assert_called_once_with("smtp.example.com", 587, timeout=10) smtp_instance.starttls.assert_called_once() smtp_instance.login.assert_called_once_with("user@example.com", "secret") assert smtp_instance.send_message.call_count == 1 sent_message = smtp_instance.send_message.call_args[0][0] assert sent_message["To"] == "rider@example.com" assert sent_message["From"] == "sync@example.com" assert sent_message["Subject"] == "Action required" def test_send_skips_login_without_credentials() -> None: notifier = _notifier(username=None, password=None) smtp_instance = MagicMock() smtp_instance.__enter__.return_value = smtp_instance with patch("app.notifications.emailer.smtplib.SMTP", return_value=smtp_instance): notifier.send(to_address="rider@example.com", subject="s", body="b") smtp_instance.login.assert_not_called() def test_send_skips_starttls_when_disabled() -> None: notifier = _notifier(use_tls=False) smtp_instance = MagicMock() smtp_instance.__enter__.return_value = smtp_instance with patch("app.notifications.emailer.smtplib.SMTP", return_value=smtp_instance): notifier.send(to_address="rider@example.com", subject="s", body="b") smtp_instance.starttls.assert_not_called()