Coverage for apps/communications/status.py: 85%
9 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 14:06 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 14:06 +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."""
4from __future__ import annotations
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}
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}
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