Skip to content

Commit

Permalink
✨(mailbox_manager) send notification for domain status change
Browse files Browse the repository at this point in the history
Send email notification to owners and admins of a domain
when its status changes to failed or enabled.
  • Loading branch information
sdemagny committed Jan 26, 2025
1 parent e07aa34 commit ecf65c0
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
11 changes: 11 additions & 0 deletions src/backend/mailbox_manager/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,17 @@ def get_abilities(self, user):
"manage_accesses": is_owner_or_admin,
}

def send_notification(self, subject, message):
"""
Notify owners and admins of the domain
"""
for access in self.accesses.filter(
role__in=[MailDomainRoleChoices.OWNER, MailDomainRoleChoices.ADMIN]
).all():
access.user.email_user(
subject=subject, message=message, from_email=settings.DEFAULT_FROM_EMAIL
)


class MailDomainAccess(BaseModel):
"""Allow to manage users' accesses to mail domains."""
Expand Down
10 changes: 10 additions & 0 deletions src/backend/mailbox_manager/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ def fetch_domains_status():
else:
if old_status != domain.status:
update_count += 1
# Send notification to owners and admins of the domain
# when its status changes to failed or enabled
if domain.status == MailDomainStatusChoices.FAILED:
domain.send_notification(
subject='Domain status changed', message='Domain is down',
)
elif domain.status == MailDomainStatusChoices.ENABLED:
domain.send_notification(
subject='Domain status changed', message='Domain is up',
)
else:
check_count += 1
return "Domains processed: %s updated, %s checked" % (update_count, check_count)
50 changes: 47 additions & 3 deletions src/backend/mailbox_manager/tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

import json
import re
from unittest import mock

from django.conf import settings

import pytest
import responses
Expand All @@ -16,19 +19,30 @@


@responses.activate
def test_fetch_domain_status_task_success(caplog):
def test_fetch_domain_status_task_success(caplog): # pylint: disable=too-many-locals
"""Test fetch domain status from dimail task"""
caplog.set_level("INFO")

domain_enabled1 = factories.MailDomainEnabledFactory()
domain_enabled2 = factories.MailDomainEnabledFactory()
owner_domain_enabled2 = factories.MailDomainAccessFactory(
domain=domain_enabled2, role=enums.MailDomainRoleChoices.OWNER
).user
admin_domain_enabled2 = factories.MailDomainAccessFactory(
domain=domain_enabled2, role=enums.MailDomainRoleChoices.ADMIN
).user
domain_disabled = factories.MailDomainFactory(
status=enums.MailDomainStatusChoices.DISABLED
)
domain_failed = factories.MailDomainFactory(
status=enums.MailDomainStatusChoices.FAILED
)

owner_domain_failed = factories.MailDomainAccessFactory(
domain=domain_failed, role=enums.MailDomainRoleChoices.OWNER
).user
admin_domain_failed = factories.MailDomainAccessFactory(
domain=domain_failed, role=enums.MailDomainRoleChoices.ADMIN
).user
body_content_ok1 = CHECK_DOMAIN_OK.copy()
body_content_ok1["name"] = domain_enabled1.name

Expand All @@ -53,7 +67,8 @@ def test_fetch_domain_status_task_success(caplog):
status=200,
content_type="application/json",
)
tasks.fetch_domains_status()
with mock.patch("django.core.mail.send_mail") as mock_send:
tasks.fetch_domains_status()
domain_enabled1.refresh_from_db()
domain_enabled2.refresh_from_db()
domain_disabled.refresh_from_db()
Expand All @@ -64,6 +79,35 @@ def test_fetch_domain_status_task_success(caplog):
assert domain_enabled2.status == enums.MailDomainStatusChoices.FAILED
# Status of the failed domain has changed to enabled
assert domain_failed.status == enums.MailDomainStatusChoices.ENABLED
# Check notification was sent to owners and admins
assert mock_send.call_count == 4
calls = [
mock.call(
"Domain status changed",
"Domain is down",
settings.DEFAULT_FROM_EMAIL,
[owner_domain_enabled2.email],
),
mock.call(
"Domain status changed",
"Domain is down",
settings.DEFAULT_FROM_EMAIL,
[admin_domain_enabled2.email],
),
mock.call(
"Domain status changed",
"Domain is up",
settings.DEFAULT_FROM_EMAIL,
[owner_domain_failed.email],
),
mock.call(
"Domain status changed",
"Domain is up",
settings.DEFAULT_FROM_EMAIL,
[admin_domain_failed.email],
),
]
mock_send.assert_has_calls(calls, any_order=True)
# Disabled domain was excluded
assert domain_disabled.status == enums.MailDomainStatusChoices.DISABLED
# Check that the task logged the correct messages
Expand Down

0 comments on commit ecf65c0

Please sign in to comment.