Skip to content

Commit

Permalink
🐛(backend) fix flaky test after add fr translations
Browse files Browse the repository at this point in the history
Define user language to test invitation email content.
  • Loading branch information
sdemagny committed Feb 4, 2025
1 parent d48a3ff commit e63de14
Show file tree
Hide file tree
Showing 9 changed files with 480 additions and 123 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to

### Added

- ✨(dimail) handle 'action required' status for MailDomain
- ✨(domains) add action required status on MailDomain
- ✨(dimail) send pending mailboxes upon domain activation

Expand Down
7 changes: 4 additions & 3 deletions src/backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
from django.db import models, transaction
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.translation import gettext, override
from django.utils.translation import gettext_lazy as _
from django.utils.translation import override

import jsonschema
from timezone_field import TimeZoneField
Expand Down Expand Up @@ -961,14 +961,15 @@ def email_invitation(self):
"""Email invitation to the user."""
try:
with override(self.issuer.language):
subject = gettext("Invitation to join La Régie!")
template_vars = {
"title": _("Invitation to join La Régie!"),
"title": subject,
"site": Site.objects.get_current(),
}
msg_html = render_to_string("mail/html/invitation.html", template_vars)
msg_plain = render_to_string("mail/text/invitation.txt", template_vars)
mail.send_mail(
_("Invitation to join La Régie!"),
subject,
msg_plain,
settings.EMAIL_FROM,
[self.email],
Expand Down
8 changes: 5 additions & 3 deletions src/backend/core/tests/test_models_invitations.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,9 @@ def test_models_team_invitations_email():
assert len(mail.outbox) == 0

factories.TeamAccessFactory(team=team)
invitation = factories.InvitationFactory(team=team, email="[email protected]")
invitation = factories.InvitationFactory(
team=team, email="[email protected]", issuer__language="fr-fr"
)

# pylint: disable-next=no-member
assert len(mail.outbox) == 1
Expand All @@ -257,10 +259,10 @@ def test_models_team_invitations_email():
email = mail.outbox[0]

assert email.to == [invitation.email]
assert email.subject == "Invitation to join La Régie!"
assert email.subject == "Invitation à rejoindre La Régie!"

email_content = " ".join(email.body.split())
assert "Invitation to join La Régie!" in email_content
assert "Invitation à rejoindre La Régie!" in email_content
assert "[//example.com]" in email_content


Expand Down
Binary file modified src/backend/locale/fr_FR/LC_MESSAGES/django.mo
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@

import pytest
import responses
from rest_framework import status

from mailbox_manager import enums, factories
from mailbox_manager.tests.fixtures.dimail import CHECK_DOMAIN_BROKEN, CHECK_DOMAIN_OK
from mailbox_manager.tests.fixtures.dimail import (
CHECK_DOMAIN_BROKEN,
CHECK_DOMAIN_OK,
)

pytestmark = pytest.mark.django_db

Expand Down Expand Up @@ -48,7 +52,7 @@ def test_fetch_domain_status():
responses.GET,
re.compile(rf".*/domains/{domain.name}/check/"),
body=json.dumps(body_content),
status=200,
status=status.HTTP_200_OK,
content_type="application/json",
)
output = StringIO()
Expand All @@ -59,8 +63,8 @@ def test_fetch_domain_status():
domain_failed.refresh_from_db()
# nothing change for the first domain enable
assert domain_enabled1.status == enums.MailDomainStatusChoices.ENABLED
# status of the second activated domain has changed to failure
assert domain_enabled2.status == enums.MailDomainStatusChoices.FAILED
# status of the second activated domain has changed to action required
assert domain_enabled2.status == enums.MailDomainStatusChoices.ACTION_REQUIRED
# status of the failed domain has changed to enabled
assert domain_failed.status == enums.MailDomainStatusChoices.ENABLED
# disabled domain was excluded
Expand Down
153 changes: 150 additions & 3 deletions src/backend/mailbox_manager/tests/fixtures/dimail.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
"smtp_domain": None,
"context_name": "example.fr",
"transport": None,
"domain_exist": {"ok": True, "internal": False, "errors": []},
"domain_exist": {
"ok": True,
"internal": False,
"errors": [],
},
"mx": {
"ok": False,
"internal": False,
Expand Down Expand Up @@ -74,8 +78,82 @@
{"code": "no_dkim", "detail": "Il faut un DKIM record, avec la bonne clef"}
],
},
"postfix": {"ok": True, "internal": True, "errors": []},
"ox": {"ok": True, "internal": True, "errors": []},
"postfix": {
"ok": True,
"internal": True,
"errors": [],
},
"ox": {
"ok": True,
"internal": True,
"errors": [],
},
"cert": {
"ok": False,
"internal": True,
"errors": [
{"code": "no_cert", "detail": "Pas de certificat pour ce domaine (ls)"}
],
},
}


CHECK_DOMAIN_BROKEN_INTERNAL = {
"name": "example.fr",
"state": "broken",
"valid": False,
"delivery": "virtual",
"features": ["webmail", "mailbox"],
"webmail_domain": None,
"imap_domain": None,
"smtp_domain": None,
"context_name": "example.fr",
"transport": None,
"domain_exist": {
"ok": True,
"internal": False,
"errors": [],
},
"mx": {
"ok": True,
"internal": False,
"errors": [],
},
"cname_imap": {
"ok": True,
"internal": False,
"errors": [],
},
"cname_smtp": {
"ok": True,
"internal": False,
"errors": [],
},
"cname_webmail": {
"ok": True,
"internal": False,
"errors": [],
},
"spf": {
"ok": True,
"internal": False,
"errors": [],
},
"dkim": {
"ok": True,
"internal": False,
"errors": [],
},
"postfix": {
"ok": True,
"internal": True,
"errors": [],
},
"ox": {
"ok": True,
"internal": True,
"errors": [],
},
"cert": {
"ok": False,
"internal": True,
Expand All @@ -85,6 +163,75 @@
},
}

CHECK_DOMAIN_BROKEN_EXTERNAL = {
"name": "example.fr",
"state": "broken",
"valid": False,
"delivery": "virtual",
"features": ["webmail", "mailbox"],
"webmail_domain": None,
"imap_domain": None,
"smtp_domain": None,
"context_name": "example.fr",
"transport": None,
"domain_exist": {
"ok": True,
"internal": False,
"errors": [],
},
"mx": {
"ok": False,
"internal": False,
"errors": [
{
"code": "wrong_mx",
"detail": "Je veux que le MX du domaine soit mx.ox.numerique.gouv.fr., or je trouve example-fr.mail.protection.outlook.com.",
}
],
},
"cname_imap": {
"ok": True,
"internal": False,
"errors": [],
},
"cname_smtp": {
"ok": True,
"internal": False,
"errors": [],
},
"cname_webmail": {
"ok": True,
"internal": False,
"errors": [],
},
"spf": {
"ok": True,
"internal": False,
"errors": [],
},
"dkim": {
"ok": True,
"internal": False,
"errors": [],
},
"postfix": {
"ok": True,
"internal": True,
"errors": [],
},
"ox": {
"ok": True,
"internal": True,
"errors": [],
},
"cert": {
"ok": True,
"internal": True,
"errors": [],
},
}


CHECK_DOMAIN_OK = {
"name": "example.fr",
"state": "ok",
Expand Down
106 changes: 53 additions & 53 deletions src/backend/mailbox_manager/tests/test_admin_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def test_sync_mailboxes__should_not_sync_if_domain_is_not_enabled(
)


@responses.activate
@pytest.mark.django_db
def test_fetch_domain_status__should_switch_to_failed_when_domain_broken(client):
"""Test admin action to check health of some domains"""
Expand All @@ -70,35 +71,34 @@ def test_fetch_domain_status__should_switch_to_failed_when_domain_broken(client)
],
}
url = reverse("admin:mailbox_manager_maildomain_changelist")

with responses.RequestsMock() as rsps:
body_content_domain1 = CHECK_DOMAIN_BROKEN.copy()
body_content_domain1["name"] = domain1.name
body_content_domain2 = CHECK_DOMAIN_BROKEN.copy()
body_content_domain2["name"] = domain2.name
rsps.add(
rsps.GET,
re.compile(rf".*/domains/{domain1.name}/check/"),
body=json.dumps(body_content_domain1),
status=status.HTTP_200_OK,
content_type="application/json",
)
rsps.add(
rsps.GET,
re.compile(rf".*/domains/{domain2.name}/check/"),
body=json.dumps(body_content_domain2),
status=status.HTTP_200_OK,
content_type="application/json",
)
response = client.post(url, data, follow=True)
assert response.status_code == status.HTTP_200_OK
domain1.refresh_from_db()
domain2.refresh_from_db()
assert domain1.status == enums.MailDomainStatusChoices.FAILED
assert domain2.status == enums.MailDomainStatusChoices.FAILED
assert "Check domains done with success" in response.content.decode("utf-8")
body_content_domain1 = CHECK_DOMAIN_BROKEN.copy()
body_content_domain1["name"] = domain1.name
body_content_domain2 = CHECK_DOMAIN_BROKEN.copy()
body_content_domain2["name"] = domain2.name
responses.add(
responses.GET,
re.compile(rf".*/domains/{domain1.name}/check/"),
body=json.dumps(body_content_domain1),
status=status.HTTP_200_OK,
content_type="application/json",
)
responses.add(
responses.GET,
re.compile(rf".*/domains/{domain2.name}/check/"),
body=json.dumps(body_content_domain2),
status=status.HTTP_200_OK,
content_type="application/json",
)
response = client.post(url, data, follow=True)
assert response.status_code == status.HTTP_200_OK
domain1.refresh_from_db()
domain2.refresh_from_db()
assert domain1.status == enums.MailDomainStatusChoices.ACTION_REQUIRED
assert domain2.status == enums.MailDomainStatusChoices.ACTION_REQUIRED
assert "Check domains done with success" in response.content.decode("utf-8")


@responses.activate
@pytest.mark.django_db
def test_fetch_domain_status__should_switch_to_enabled_when_domain_ok(client):
"""Test admin action should switch domain state to ENABLED
Expand All @@ -115,33 +115,33 @@ def test_fetch_domain_status__should_switch_to_enabled_when_domain_ok(client):
}
url = reverse("admin:mailbox_manager_maildomain_changelist")

with responses.RequestsMock() as rsps:
body_content_domain1 = CHECK_DOMAIN_OK.copy()
body_content_domain1["name"] = domain1.name

rsps.add(
rsps.GET,
re.compile(rf".*/domains/{domain1.name}/check/"),
body=json.dumps(body_content_domain1),
status=status.HTTP_200_OK,
content_type="application/json",
)
rsps.add(
rsps.GET,
re.compile(r".*/token/"),
body=TOKEN_OK,
status=status.HTTP_200_OK,
content_type="application/json",
)
rsps.add(
rsps.POST,
re.compile(rf".*/domains/{domain1.name}/mailboxes/"),
body=response_mailbox_created(f"truc@{domain1.name}"),
status=status.HTTP_201_CREATED,
content_type="application/json",
)
body_content_domain1 = CHECK_DOMAIN_OK.copy()
body_content_domain1["name"] = domain1.name

response = client.post(url, data, follow=True)
responses.add(
responses.GET,
re.compile(rf".*/domains/{domain1.name}/check/"),
body=json.dumps(body_content_domain1),
status=status.HTTP_200_OK,
content_type="application/json",
)
# we need to get a token to create mailboxes
responses.add(
responses.GET,
re.compile(r".*/token/"),
body=TOKEN_OK,
status=status.HTTP_200_OK,
content_type="application/json",
)
responses.add(
responses.POST,
re.compile(rf".*/domains/{domain1.name}/mailboxes/"),
body=response_mailbox_created(f"truc@{domain1.name}"),
status=status.HTTP_201_CREATED,
content_type="application/json",
)

response = client.post(url, data, follow=True)
assert response.status_code == status.HTTP_200_OK
domain1.refresh_from_db()
domain2.refresh_from_db()
Expand Down
Loading

0 comments on commit e63de14

Please sign in to comment.