Coverage for config/email_recipients.py: 100%
18 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-10-06 13:07 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-10-06 13:07 +0000
1"""Who receives operational emails (for example, new account deletion requests).
3Active users in the ``operations-email`` group receive them. If the group is
4empty or missing, the addresses in ``settings.ADMINS`` are used instead.
5"""
7from django.conf import settings
8from django.contrib.auth import get_user_model
10OPERATIONS_EMAIL_GROUP_NAME = "operations-email"
13def resolve_operations_recipients() -> list[str]:
14 user_model = get_user_model()
15 candidates = list(
16 user_model.objects.filter(groups__name=OPERATIONS_EMAIL_GROUP_NAME, is_active=True)
17 .exclude(email__isnull=True)
18 .exclude(email="")
19 .order_by("email")
20 .values_list("email", flat=True),
21 )
22 if not candidates:
23 candidates = [email for _, email in getattr(settings, "ADMINS", [])]
24 return _dedupe(candidates)
27def _dedupe(candidates: list[str]) -> list[str]:
28 recipients: list[str] = []
29 seen: set[str] = set()
30 for email in candidates:
31 normalized = email.strip()
32 if normalized and normalized.lower() not in seen:
33 recipients.append(normalized)
34 seen.add(normalized.lower())
35 return recipients