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

1"""Who receives operational emails (for example, new account deletion requests). 

2 

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""" 

6 

7from django.conf import settings 

8from django.contrib.auth import get_user_model 

9 

10OPERATIONS_EMAIL_GROUP_NAME = "operations-email" 

11 

12 

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) 

25 

26 

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