From a5383ead7cc7917796af80ba5fa1702269e5b0c7 Mon Sep 17 00:00:00 2001 From: Wilfried BARADAT Date: Wed, 21 Aug 2024 17:39:22 +0200 Subject: [PATCH] =?UTF-8?q?fixup!=20=E2=9C=A8(emails)=20use=20mjml=20to=20?= =?UTF-8?q?generate=20html=20and=20text=20emails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.dist | 27 ++++++++++++++------------- src/app/mork/celery/tasks.py | 5 ++++- src/app/mork/exceptions.py | 4 ++++ src/app/mork/mail.py | 9 ++++++++- src/app/mork/tests/test_mail.py | 19 ++++++++++++++++++- src/app/pyproject.toml | 1 + 6 files changed, 49 insertions(+), 16 deletions(-) diff --git a/.env.dist b/.env.dist index 244dade..d5b31d9 100644 --- a/.env.dist +++ b/.env.dist @@ -29,6 +29,20 @@ MORK_CELERY_RESULT_BACKEND=redis://redis:6379/0 MORK_CELERY_BROKER_TRANSPORT_OPTIONS={} MORK_CELERY_TASK_DEFAULT_QUEUE=celery +# Emails +MORK_EMAIL_HOST=mailcatcher +MORK_EMAIL_HOST_USER= +MORK_EMAIL_HOST_PASSWORD= +MORK_EMAIL_PORT=1025 +MORK_EMAIL_USE_TLS=False +MORK_EMAIL_FROM=from@fun-mooc.fr +MORK_EMAIL_RATE_LIMIT=100/m +MORK_EMAIL_MAX_RETRIES=3 +MORK_EMAIL_SITE_NAME="France Université Numérique" +MORK_EMAIL_SITE_BASE_URL=https://fun-mooc.fr +MORK_EMAIL_SITE_LOGIN_URL=https://lms.fun-mooc.fr/login + + # Python PYTHONPATH=/app @@ -48,16 +62,3 @@ MYSQL_PASSWORD=password POSTGRES_DB=mork-db POSTGRES_USER=fun POSTGRES_PASSWORD=pass - -# Emails -EMAIL_HOST=mailcatcher -EMAIL_HOST_USER= -EMAIL_HOST_PASSWORD= -EMAIL_PORT=1025 -EMAIL_USE_TLS=False -EMAIL_FROM=from@fun-mooc.fr -EMAIL_RATE_LIMIT=100/m -EMAIL_MAX_RETRIES=3 -EMAIL_SITE_NAME="France Université Numérique" -EMAIL_SITE_BASE_URL=https://fun-mooc.fr -EMAIL_SITE_LOGIN_URL=https://lms.fun-mooc.fr/login diff --git a/src/app/mork/celery/tasks.py b/src/app/mork/celery/tasks.py index 6537cec..fdb023a 100644 --- a/src/app/mork/celery/tasks.py +++ b/src/app/mork/celery/tasks.py @@ -8,7 +8,7 @@ from mork.celery.celery_app import app from mork.conf import settings from mork.database import MorkDB -from mork.exceptions import EmailAlreadySent, EmailSendError +from mork.exceptions import EmailAlreadySent, EmailSendError, EmailTemplateError from mork.mail import send_email from mork.models import EmailStatus @@ -43,6 +43,9 @@ def send_email_task(self, email_address: str, username: str): except EmailSendError as exc: logger.exception(exc) raise self.retry(exc=exc) from exc + except EmailTemplateError as exc: + logger.exception(exc) + raise exc # Write flag that email was correctly sent to this user mark_email_status(email_address) diff --git a/src/app/mork/exceptions.py b/src/app/mork/exceptions.py index d83b3ce..7c1eac1 100644 --- a/src/app/mork/exceptions.py +++ b/src/app/mork/exceptions.py @@ -7,3 +7,7 @@ class EmailAlreadySent(Exception): class EmailSendError(Exception): """Raised when an error occurs when sending an email.""" + + +class EmailTemplateError(Exception): + """Raised when an error occurs on temlate configuration.""" diff --git a/src/app/mork/mail.py b/src/app/mork/mail.py index ea0b90d..9a85e94 100644 --- a/src/app/mork/mail.py +++ b/src/app/mork/mail.py @@ -9,7 +9,7 @@ from jinja2 import Environment, FileSystemLoader from mork.conf import settings -from mork.exceptions import EmailSendError +from mork.exceptions import EmailSendError, EmailTemplateError from mork.templatetags.extra_tags import SVGStaticTag logger = getLogger(__name__) @@ -33,6 +33,13 @@ def render_template(template: str, context) -> str: def send_email(email_address: str, username: str): """Initialize connection to SMTP and send a warning email.""" + if ( + not settings.EMAIL_SITE_NAME + or not settings.EMAIL_SITE_BASE_URL + or not settings.EMAIL_SITE_LOGIN_URL + ): + raise EmailTemplateError("Email template misconfigured.") + template_vars = { "title": "Votre compte va être supprimé dans 30 jours.", "email": email_address, diff --git a/src/app/mork/tests/test_mail.py b/src/app/mork/tests/test_mail.py index e872b25..2342ea1 100644 --- a/src/app/mork/tests/test_mail.py +++ b/src/app/mork/tests/test_mail.py @@ -5,7 +5,7 @@ import pytest -from mork.exceptions import EmailSendError +from mork.exceptions import EmailSendError, EmailTemplateError from mork.mail import render_template, send_email @@ -28,6 +28,8 @@ def test_render_template(): assert template_vars["site"]["name"] in render_html assert template_vars["site"]["url"] in render_html assert template_vars["site"]["login_url"] in render_html + with open("test.html", "w") as f: + f.write(render_html) assert 'src="data:' in render_html render_text = render_template("warning_email.txt", template_vars) @@ -68,3 +70,18 @@ def test_send_email_with_smtp_exception(monkeypatch): with pytest.raises(EmailSendError, match="Failed sending an email"): send_email(email_address=test_address, username=test_username) + + +def test_send_email_with_template_misconfiguration(monkeypatch): + """Test the `send_email` function with an SMTP exception.""" + + mock_SMTP = MagicMock() + monkeypatch.setattr("mork.mail.smtplib.SMTP", mock_SMTP) + + monkeypatch.setattr("mork.mail.settings.EMAIL_SITE_LOGIN_URL", "") + + test_address = "john.doe@example.com" + test_username = "JohnDoe" + + with pytest.raises(EmailTemplateError, match="Email template misconfigured."): + send_email(email_address=test_address, username=test_username) diff --git a/src/app/pyproject.toml b/src/app/pyproject.toml index 18021da..33530b1 100644 --- a/src/app/pyproject.toml +++ b/src/app/pyproject.toml @@ -52,6 +52,7 @@ dev = [ "black==24.8.0", "build==1.2.1", "factory_boy==3.3.0", + "flower==2.0.1", "pytest==8.3.2", "pytest-cov==5.0.0", "pytest-httpx==0.30.0",