• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mozilla / fx-private-relay / 3f809551-6712-425b-b278-bf1cf7d34ed4

19 Sep 2025 06:01PM UTC coverage: 88.138% (-0.7%) from 88.863%
3f809551-6712-425b-b278-bf1cf7d34ed4

Pull #5885

circleci

joeherm
fix(twilio): Add error handling for flaky Twilio calls
Pull Request #5885: fix(twilio): Add error handling for erroring Twilio calls

2925 of 3955 branches covered (73.96%)

Branch coverage included in aggregate %.

42 of 42 new or added lines in 2 files covered. (100.0%)

116 existing lines in 7 files now uncovered.

18199 of 20012 relevant lines covered (90.94%)

11.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.14
/api/serializers/phones.py
1
from typing import Any
1✔
2

3
from rest_framework import serializers
1✔
4

5
from phones.models import InboundContact, RealPhone, RelayNumber
1✔
6

7

8
class RealPhoneSerializer(serializers.ModelSerializer):
1✔
9
    class Meta:
1✔
10
        model = RealPhone
1✔
11
        fields = [
1✔
12
            "id",
13
            "number",
14
            "verification_code",
15
            "verification_sent_date",
16
            "verified",
17
            "verified_date",
18
            "country_code",
19
        ]
20
        read_only_fields = [
1✔
21
            "id",
22
            "verification_sent_date",
23
            "verified",
24
            "verified_date",
25
            "country_code",
26
        ]
27
        extra_kwargs = {
1✔
28
            "verification_code": {"write_only": True},
29
        }
30

31

32
class RelayNumberSerializer(serializers.ModelSerializer):
1✔
33
    class Meta:
1✔
34
        model = RelayNumber
1✔
35
        fields = [
1✔
36
            "id",
37
            "number",
38
            "location",
39
            "country_code",
40
            "enabled",
41
            "remaining_minutes",
42
            "remaining_texts",
43
            "calls_forwarded",
44
            "calls_blocked",
45
            "texts_forwarded",
46
            "texts_blocked",
47
            "calls_and_texts_forwarded",
48
            "calls_and_texts_blocked",
49
            "created_at",
50
        ]
51
        read_only_fields = [
1✔
52
            "id",
53
            "location",
54
            "country_code",
55
            "remaining_minutes",
56
            "remaining_texts",
57
            "calls_forwarded",
58
            "calls_blocked",
59
            "texts_forwarded",
60
            "texts_blocked",
61
            "calls_and_texts_forwarded",
62
            "calls_and_texts_blocked",
63
            "created_at",
64
        ]
65

66

67
class InboundContactSerializer(serializers.ModelSerializer):
1✔
68
    class Meta:
1✔
69
        model = InboundContact
1✔
70
        fields = [
1✔
71
            "id",
72
            "relay_number",
73
            "inbound_number",
74
            "last_inbound_date",
75
            "last_inbound_type",
76
            "num_calls",
77
            "num_calls_blocked",
78
            "last_call_date",
79
            "num_texts",
80
            "num_texts_blocked",
81
            "last_text_date",
82
            "blocked",
83
        ]
84
        read_only_fields = [
1✔
85
            "id",
86
            "relay_number",
87
            "inbound_number",
88
            "last_inbound_date",
89
            "last_inbound_type",
90
            "num_calls",
91
            "num_calls_blocked",
92
            "last_call_date",
93
            "num_texts",
94
            "num_texts_blocked",
95
            "last_text_date",
96
        ]
97

98

99
class TwilioInboundCallSerializer(serializers.Serializer):
1✔
100
    Caller = serializers.CharField()
1✔
101
    Called = serializers.CharField()
1✔
102

103

104
class TwilioInboundSmsSerializer(serializers.Serializer):
1✔
105
    text = serializers.CharField()
1✔
106
    from_ = serializers.CharField()
1✔
107
    to = serializers.CharField()
1✔
108

109
    def __init__(self, *args: Any, **kwargs: Any) -> None:
1✔
110
        super().__init__(*args, **kwargs)
1✔
111
        # Change to reserved keyword "from"
112
        self.fields["from"] = self.fields.pop("from_")
1✔
113

114

115
class TwilioMessagesSerializer(serializers.Serializer):
1✔
116
    from_ = serializers.CharField()
1✔
117
    to = serializers.CharField()
1✔
118
    date_sent = serializers.CharField()
1✔
119
    body = serializers.CharField()
1✔
120

121
    def __init__(self, *args: Any, **kwargs: Any) -> None:
1✔
122
        super().__init__(*args, **kwargs)
1✔
123
        # Change to reserved keyword "from"
124
        self.fields["from"] = self.fields.pop("from_")
1✔
125

126

127
class TwilioNumberSuggestion(serializers.Serializer):
1✔
128
    friendly_name = serializers.CharField()
1✔
129
    iso_country = serializers.CharField()
1✔
130
    locality = serializers.CharField()
1✔
131
    phone_number = serializers.CharField()
1✔
132
    postal_code = serializers.CharField()
1✔
133
    region = serializers.CharField()
1✔
134

135

136
class TwilioNumberSuggestionGroups(serializers.Serializer):
1✔
137
    real_num = serializers.CharField()
1✔
138
    same_prefix_options = TwilioNumberSuggestion(many=True)
1✔
139
    other_areas_options = TwilioNumberSuggestion(many=True)
1✔
140
    same_area_options = TwilioNumberSuggestion(many=True)
1✔
141
    random_options = TwilioNumberSuggestion(many=True)
1✔
142

143

144
class TwilioSmsStatusSerializer(serializers.Serializer):
1✔
145
    SmsStatus = serializers.CharField()
1✔
146
    MessageSid = serializers.CharField()
1✔
147

148

149
class TwilioVoiceStatusSerializer(serializers.Serializer):
1✔
150
    CallSid = serializers.CharField()
1✔
151
    Called = serializers.CharField()
1✔
152
    CallStatus = serializers.CharField()
1✔
153
    CallDuration = serializers.IntegerField(required=False)
1✔
154

155

156
class IqInboundSmsSerializer(serializers.Serializer):
1✔
157
    text = serializers.CharField()
1✔
158
    from_ = serializers.CharField()
1✔
159
    to = serializers.CharField()
1✔
160

161
    def __init__(self, *args: Any, **kwargs: Any) -> None:
1✔
UNCOV
162
        super().__init__(*args, **kwargs)
×
163
        # Change to reserved keyword "from"
UNCOV
164
        self.fields["from"] = self.fields.pop("from_")
×
165

166

167
class OutboundSmsSerializer(serializers.Serializer):
1✔
168
    body = serializers.CharField()
1✔
169
    destination = serializers.CharField()
1✔
170

171

172
class OutboundCallSerializer(serializers.Serializer):
1✔
173
    to = serializers.CharField()
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc