Files
benevoles/backend/tests/test_api_test_email.py
T
AdamThomasandClaude Opus 5.5 461742eb78
ci-cd / build-backend (push) Successful in 1m25s
ci-cd / build-frontend (push) Successful in 21s
ci-cd / deploy (push) Successful in 13s
Email de test et ajout manuel sans champ obligatoire
Étape 67 : adresse + bouton dans l'onglet « Messages » pour envoyer tout
de suite un email de test, résultat réel affiché (envoyé, désactivé,
connexion ou message refusé, réponse du serveur SMTP) —
POST .../notifications/test.

Étape 66 : prénom et nom facultatifs à l'ajout manuel d'un bénévole ;
un bénévole sans nom s'affiche « Sans nom » / « ? » partout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 19:34:24 +01:00

84 lines
2.7 KiB
Python

"""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