♻️(backend) refacto email invitation

Remove email invitation from Invitation model
to be able to use it in other context.
We add it in utils.py instead, and it will be called
from the viewset.
We add the document_id to link to the document from
the mail.
This commit is contained in:
Anthony LC
2024-08-15 15:38:38 +02:00
committed by Anthony LC
parent 2391098aba
commit 2f8c5637f4
8 changed files with 143 additions and 123 deletions

View File

@@ -100,6 +100,8 @@ def test_api_document_invitations__create__privileged_members(
"role": invited,
}
assert len(mail.outbox) == 0
client = APIClient()
client.force_login(user)
response = client.post(
@@ -110,6 +112,12 @@ def test_api_document_invitations__create__privileged_members(
if is_allowed:
assert response.status_code == status.HTTP_201_CREATED
assert models.Invitation.objects.count() == 1
assert len(mail.outbox) == 1
email = mail.outbox[0]
assert email.to == ["guest@example.com"]
email_content = " ".join(email.body.split())
assert "Invitation to join Docs!" in email_content
else:
assert response.status_code == status.HTTP_403_FORBIDDEN
assert models.Invitation.objects.exists() is False

View File

@@ -1,14 +1,10 @@
"""
Unit tests for the Invitation model
"""
import smtplib
import time
from logging import Logger
from unittest import mock
from django.contrib.auth.models import AnonymousUser
from django.core import exceptions, mail
from django.core import exceptions
import pytest
from faker import Faker
@@ -168,97 +164,6 @@ def test_models_invitation__new_user__user_creation_constant_num_queries(
models.User.objects.create(email=user_email, password="!")
def test_models_document_invitations_email():
"""Check email invitation during invitation creation."""
member_access = factories.UserDocumentAccessFactory(role="reader")
document = member_access.document
# pylint: disable-next=no-member
assert len(mail.outbox) == 0
factories.UserDocumentAccessFactory(document=document)
issuer = factories.UserFactory(language="en-us")
invitation = factories.InvitationFactory(
document=document, email="john@people.com", issuer=issuer
)
# pylint: disable-next=no-member
assert len(mail.outbox) == 1
# pylint: disable-next=no-member
email = mail.outbox[0]
assert email.to == [invitation.email]
assert email.subject == "Invitation to join Docs!"
email_content = " ".join(email.body.split())
assert "Invitation to join Docs!" in email_content
assert "[//example.com]" in email_content
def test_models_document_invitations_email_language_fr():
"""Check email invitation during invitation creation."""
member_access = factories.UserDocumentAccessFactory(role="reader")
document = member_access.document
# pylint: disable-next=no-member
assert len(mail.outbox) == 0
factories.UserDocumentAccessFactory(document=document)
issuer = factories.UserFactory(language="fr-fr")
invitation = factories.InvitationFactory(
document=document, email="john@people.com", issuer=issuer
)
# pylint: disable-next=no-member
assert len(mail.outbox) == 1
# pylint: disable-next=no-member
email = mail.outbox[0]
assert email.to == [invitation.email]
email_content = " ".join(email.body.split())
assert "Invitation à rejoindre Docs !" in email_content
assert "[//example.com]" in email_content
@mock.patch(
"django.core.mail.send_mail",
side_effect=smtplib.SMTPException("Error SMTPException"),
)
@mock.patch.object(Logger, "error")
def test_models_document_invitations_email_failed(mock_logger, _mock_send_mail):
"""Check invitation behavior when an SMTP error occurs during invitation creation."""
member_access = factories.UserDocumentAccessFactory(role="reader")
document = member_access.document
# pylint: disable-next=no-member
assert len(mail.outbox) == 0
factories.UserDocumentAccessFactory(document=document)
# No error should be raised
invitation = factories.InvitationFactory(document=document, email="john@people.com")
# No email has been sent
# pylint: disable-next=no-member
assert len(mail.outbox) == 0
# Logger should be called
mock_logger.assert_called_once()
(
_,
email,
exception,
) = mock_logger.call_args.args
assert email == invitation.email
assert isinstance(exception, smtplib.SMTPException)
# get_abilities

View File

@@ -0,0 +1,86 @@
"""
Unit tests for the Invitation model
"""
import smtplib
from logging import Logger
from unittest import mock
from django.core import mail
import pytest
from core.utils import email_invitation
pytestmark = pytest.mark.django_db
def test_utils__email_invitation_success():
"""
The email invitation is sent successfully.
"""
# pylint: disable-next=no-member
assert len(mail.outbox) == 0
email_invitation("en", "guest@example.com", "123-456-789")
# pylint: disable-next=no-member
assert len(mail.outbox) == 1
# pylint: disable-next=no-member
email = mail.outbox[0]
assert email.to == ["guest@example.com"]
email_content = " ".join(email.body.split())
assert "Invitation to join Docs!" in email_content
assert "docs/123-456-789/" in email_content
def test_utils__email_invitation_success_fr():
"""
The email invitation is sent successfully in french.
"""
# pylint: disable-next=no-member
assert len(mail.outbox) == 0
email_invitation("fr-fr", "guest@example.com", "123-456-789")
# pylint: disable-next=no-member
assert len(mail.outbox) == 1
# pylint: disable-next=no-member
email = mail.outbox[0]
assert email.to == ["guest@example.com"]
email_content = " ".join(email.body.split())
assert "Invitation à rejoindre Docs !" in email_content
assert "docs/123-456-789/" in email_content
@mock.patch(
"core.utils.send_mail",
side_effect=smtplib.SMTPException("Error SMTPException"),
)
@mock.patch.object(Logger, "error")
def test_utils__email_invitation_failed(mock_logger, _mock_send_mail):
"""Check mail behavior when an SMTP error occurs when sent an email invitation."""
# pylint: disable-next=no-member
assert len(mail.outbox) == 0
email_invitation("en", "guest@example.com", "123-456-789")
# No email has been sent
# pylint: disable-next=no-member
assert len(mail.outbox) == 0
# Logger should be called
mock_logger.assert_called_once()
(
_,
email,
exception,
) = mock_logger.call_args.args
assert email == "guest@example.com"
assert isinstance(exception, smtplib.SMTPException)