"""Email de test depuis l'écran « Messages » (`POST .../notifications/test`) : envoi synchrone, résultat réel du serveur SMTP renvoyé à la coordination.""" import smtplib import pytest from app.config import get_settings from app.models import Role def _url(edition): return f"/editions/{edition.id}/notifications/test" class _FakeSmtp: def __init__(self, error=None): self.sent = [] self.error = error def __enter__(self): return self def __exit__(self, *exc): return False def send_message(self, message): if self.error: raise self.error self.sent.append(message) @pytest.fixture def smtp_enabled(monkeypatch): monkeypatch.setenv("EMAIL_ENABLED", "true") get_settings.cache_clear() def test_disabled_email_is_reported(client, edition): resp = client.post(_url(edition), json={"email": "moi@exemple.fr"}) assert resp.status_code == 200 assert resp.json()["status"] == "disabled" def test_sends_the_test_email(client, edition, smtp_enabled, monkeypatch): fake = _FakeSmtp() monkeypatch.setattr("app.email.sender.open_smtp", lambda settings: fake) resp = client.post(_url(edition), json={"email": " moi@exemple.fr "}) assert resp.json()["status"] == "sent" (message,) = fake.sent assert message["To"] == "moi@exemple.fr" def test_connection_failure_is_reported_with_the_server_message( client, edition, smtp_enabled, monkeypatch ): def refuse(settings): raise smtplib.SMTPAuthenticationError(535, b"authentication failed") monkeypatch.setattr("app.email.sender.open_smtp", refuse) body = client.post(_url(edition), json={"email": "moi@exemple.fr"}).json() assert body["status"] == "connection_failed" assert "535" in body["detail"] def test_rejected_message_never_echoes_the_address(client, edition, smtp_enabled, monkeypatch): refused = smtplib.SMTPRecipientsRefused({"moi@exemple.fr": (550, b"no such user")}) monkeypatch.setattr("app.email.sender.open_smtp", lambda settings: _FakeSmtp(refused)) body = client.post(_url(edition), json={"email": "moi@exemple.fr"}).json() assert body["status"] == "rejected" assert "550" in body["detail"] assert "moi@exemple.fr" not in body["detail"] @pytest.mark.parametrize("email", ["", "pas-un-email", "@exemple.fr", "moi@", "a b@c.fr"]) def test_invalid_address_is_rejected(client, edition, email): resp = client.post(_url(edition), json={"email": email}) assert resp.status_code == 422 def test_is_coordinator_only(edition, make_account, as_account): lead = as_account(make_account(Role.LEAD)) assert lead.post(_url(edition), json={"email": "moi@exemple.fr"}).status_code == 403