Coverage for apps/communications/status.py: 85%

9 statements  

« prev     ^ index     » next       coverage.py v7.17.0, created at 2026-11-04 17:24 +0000

1"""Message status rules shared by the staff events endpoint, the delivery module and the SendGrid 

2webhook. A status only moves forward; Failed / Bounced always win and then stick.""" 

3 

4from __future__ import annotations 

5 

6STATUS_RANK = { 

7 "Draft": 0, 

8 "Queued": 1, 

9 "Dialing": 1, 

10 "Sent": 2, 

11 "Delivered": 3, 

12 "Answered": 3, 

13 "Voicemail": 3, 

14 "NoAnswer": 3, 

15 "Opened": 4, 

16 "Completed": 4, 

17 "Clicked": 5, 

18 "Replied": 6, 

19 "Failed": 9, 

20 "Bounced": 9, 

21} 

22 

23EVENT_TO_STATUS = { 

24 "queued": "Queued", 

25 "sent": "Sent", 

26 "delivered": "Delivered", 

27 "opened": "Opened", 

28 "clicked": "Clicked", 

29 "replied": "Replied", 

30 "failed": "Failed", 

31 "bounced": "Bounced", 

32 "dialing": "Dialing", 

33 "answered": "Answered", 

34 "voicemail": "Voicemail", 

35 "no_answer": "NoAnswer", 

36 "completed": "Completed", 

37} 

38 

39 

40def advance_status(current: str, next_status: str) -> str: 

41 if next_status in ("Failed", "Bounced"): 

42 return next_status 

43 if current in ("Failed", "Bounced"): 43 ↛ 44line 43 didn't jump to line 44 because the condition on line 43 was never true

44 return current 

45 return next_status if STATUS_RANK.get(next_status, 0) >= STATUS_RANK.get(current, 0) else current