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

akvo / iwsims-demo / #33

15 Apr 2025 04:09AM UTC coverage: 82.73% (-2.0%) from 84.752%
#33

push

coveralls-python

web-flow
Merge pull request #14 from akvo/feature/13-eng-1178-update-main-unit-tests

Feature/13 Remove Verification and Certification

2732 of 3441 branches covered (79.4%)

Branch coverage included in aggregate %.

6226 of 7387 relevant lines covered (84.28%)

0.84 hits per line

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

67.03
backend/utils/custom_serializer_fields.py
1
from django.core.validators import EmailValidator
1✔
2
from django.utils.translation import gettext_lazy as _
1✔
3
from rest_framework.fields import (
1✔
4
    IntegerField,
5
    ChoiceField,
6
    CharField,
7
    ImageField,
8
    ListField,
9
    BooleanField,
10
    FloatField,
11
    DecimalField,
12
    URLField,
13
    DateField,
14
    MultipleChoiceField,
15
    FileField,
16
    DateTimeField,
17
    JSONField,
18
    Field,
19
)
20
from rest_framework.relations import PrimaryKeyRelatedField
1✔
21

22
key_map = {}
1✔
23

24

25
class CustomIntegerField(IntegerField):
1✔
26
    default_error_messages = {
1✔
27
        "invalid": _("A valid field_title is required."),
28
        "max_value": _(
29
            "Ensure field_title is less than or equal to {max_value}."
30
        ),
31
        "min_value": _(
32
            "Ensure field_title is greater than or equal to {min_value}."
33
        ),
34
        "max_string_length": _("field_title value too large."),
35
        "required": _("field_title is required."),
36
        "null": _("field_title may not be null."),
37
    }
38

39

40
class CustomCharField(CharField):
1✔
41
    default_error_messages = {
1✔
42
        "invalid": _("A valid field_title is required."),
43
        "blank": _("field_title may not be blank."),
44
        "max_length": _(
45
            "Ensure field_title has no more than {max_length} characters."
46
        ),
47
        "min_length": _(
48
            "Ensure field_title has at least {min_length} characters."
49
        ),
50
        "required": _("field_title is required."),
51
        "null": _("field_title may not be null."),
52
    }
53

54

55
class CustomChoiceField(ChoiceField):
1✔
56
    default_error_messages = {
1✔
57
        "invalid_choice": _('"{input}" is not a valid choice in field_title.'),
58
        "required": _("field_title is required."),
59
        "null": _("field_title may not be null."),
60
    }
61

62

63
class CustomMultipleChoiceField(MultipleChoiceField):
1✔
64
    default_error_messages = {
1✔
65
        "invalid_choice": _('"{input}" is not a valid choice in field_title.'),
66
        "not_a_list": _(
67
            'Expected a list of items but got type "{input_type}"'
68
            " in field_title."
69
        ),
70
        "empty": _("This selection may not be empty in field_title."),
71
    }
72

73

74
class CustomImageField(ImageField):
1✔
75
    default_error_messages = {
1✔
76
        "invalid_image": _(
77
            "Upload a valid image. field_title you uploaded was either not "
78
            "an image or a corrupted image."
79
        ),
80
        "required": _("field_title is required."),
81
        "null": _("field_title may not be null."),
82
    }
83

84

85
class CustomEmailField(CustomCharField):
1✔
86
    default_error_messages = {"invalid": _("Enter a valid email address.")}
1✔
87

88
    def __init__(self, **kwargs):
1✔
89
        super().__init__(**kwargs)
1✔
90
        validator = EmailValidator(message=self.error_messages["invalid"])
1✔
91
        self.validators.append(validator)
1✔
92

93

94
class CustomListField(ListField):
1✔
95
    default_error_messages = {
1✔
96
        "not_a_list": _(
97
            "Expected a list of items in field_title but got type"
98
            ' "{input_type}".'
99
        ),
100
        "empty": _("field_title may not be empty."),
101
        "min_length": _(
102
            "Ensure field_title has at least {min_length} elements."
103
        ),
104
        "max_length": _(
105
            "Ensure field_title has no more than {max_length} elements."
106
        ),
107
        "required": _("field_title is required."),
108
        "null": _("field_title may not be null."),
109
    }
110

111

112
class CustomBooleanField(BooleanField):
1✔
113
    default_error_messages = {
1✔
114
        "invalid": _("Must be a valid field_title."),
115
        "required": _("field_title is required."),
116
        "null": _("field_title may not be null."),
117
    }
118

119

120
class CustomFloatField(FloatField):
1✔
121
    default_error_messages = {
1✔
122
        "invalid": _("A valid field_title is required."),
123
        "max_value": _(
124
            "Ensure field_title is less than or equal to {max_value}."
125
        ),
126
        "min_value": _(
127
            "Ensure field_title is greater than or equal to {min_value}."
128
        ),
129
        "max_string_length": _("field_title too large."),
130
        "required": _("field_title is required."),
131
        "null": _("field_title may not be null."),
132
    }
133

134

135
class CustomDecimalField(DecimalField):
1✔
136
    default_error_messages = {
1✔
137
        "invalid": _("A field_title number is required."),
138
        "max_value": _(
139
            "Ensure field_title is less than or equal to {max_value}."
140
        ),
141
        "min_value": _(
142
            "Ensure field_title is greater than or equal to {min_value}."
143
        ),
144
        "max_digits": _(
145
            "Ensure that in field_title are no more than {max_digits} "
146
            "digits in total."
147
        ),
148
        "max_decimal_places": _(
149
            "Ensure that in field_title are no more than {max_decimal_places} "
150
            "decimal places."
151
        ),
152
        "max_whole_digits": _(
153
            "Ensure that in field_title are no more than {max_whole_digits} "
154
            "digits before the "
155
            "decimal point."
156
        ),
157
        "max_string_length": _("String value too large in field_title."),
158
        "required": _("field_title is required."),
159
        "null": _("field_title may not be null."),
160
    }
161

162

163
class CustomURLField(URLField):
1✔
164
    default_error_messages = {
1✔
165
        "invalid": _("Enter a valid URL in field_title."),
166
        "required": _("field_title is required."),
167
        "null": _("field_title may not be null."),
168
    }
169

170

171
class CustomPrimaryKeyRelatedField(PrimaryKeyRelatedField):
1✔
172
    default_error_messages = {
1✔
173
        "required": _("field_title is required."),
174
        "does_not_exist": _(
175
            'Invalid pk "{pk_value}" - object does not exist.'
176
        ),
177
        "incorrect_type": _(
178
            "Incorrect type. Expected pk value, received {data_type}."
179
        ),
180
        "null": _("field_title may not be null."),
181
    }
182

183

184
class CustomDateField(DateField):
1✔
185
    default_error_messages = {
1✔
186
        "required": _("field_title is required."),
187
        "invalid": _(
188
            "Date has wrong format. Use one of these formats instead:"
189
            " {format}."
190
        ),
191
        "datetime": _("Expected a date but got a datetime."),
192
        "null": _("field_title may not be null."),
193
    }
194

195

196
class CustomFileField(FileField):
1✔
197
    default_error_messages = {
1✔
198
        "required": _("No file was submitted in field_title."),
199
        "invalid": _(
200
            "The submitted data was not a file. Check the encoding type on the"
201
            " form in field_title."
202
        ),
203
        "no_name": _("No filename could be determined in field_title."),
204
        "empty": _("The submitted file is empty in field_title."),
205
        "max_length": _(
206
            "Ensure this filename has at most {max_length} characters"
207
            " (it has {length}) in field_title."
208
        ),
209
    }
210

211

212
class CustomDateTimeField(DateTimeField):
1✔
213
    default_error_messages = {
1✔
214
        "invalid": _(
215
            "Datetime has wrong format. Use one of these formats instead: "
216
            "{format} in field_title."
217
        ),
218
        "date": _("field_title Expected a datetime but got a date."),
219
        "make_aware": _(
220
            'Invalid datetime for the timezone "{timezone} in field_title".'
221
        ),
222
        "overflow": _("Datetime value out of range in field_title."),
223
    }
224

225

226
class CustomUrlField(URLField):
1✔
227
    default_error_messages = {"invalid": _("Enter a valid URL.")}
1✔
228

229

230
class CustomJSONField(JSONField):
1✔
231
    default_error_messages = {
1✔
232
        "invalid": _("Value must be valid JSON in field_title."),
233
        "required": _("field_title field is required"),
234
    }
235

236

237
class UnvalidatedField(Field):
1✔
238
    default_error_messages = {
1✔
239
        "null": _("field_title may not be null."),
240
    }
241

242
    def __init__(self, **kwargs):
1✔
243
        super().__init__(**kwargs)
1✔
244
        self.allow_blank = True
1✔
245
        self.allow_null = False
1✔
246

247
    def to_internal_value(self, data):
1✔
248
        return data
1✔
249

250
    def to_representation(self, value):
1✔
251
        return value
×
252

253

254
def validate_serializers_message(errors):
1✔
255
    msg = []
1✔
256
    if isinstance(errors, dict):
1!
257
        for k, v in errors.items():
1✔
258
            if isinstance(v, list):
1✔
259
                for val in v:
1✔
260
                    if isinstance(val, dict):
1✔
261
                        for ik, iv in val.items():
1✔
262
                            for viv in iv:
1✔
263
                                if isinstance(viv, dict):
1!
264
                                    for xk, xv in viv.items():
×
265
                                        for xvv in xv:
×
266
                                            msg.append(
×
267
                                                xvv.replace(
268
                                                    "field_title",
269
                                                    key_map.get(xk, xk),
270
                                                )
271
                                            )
272
                                else:
273
                                    msg.append(
1✔
274
                                        viv.replace(
275
                                            "field_title", key_map.get(ik, ik)
276
                                        )
277
                                    )
278
                    else:
279
                        msg.append(
1✔
280
                            val.replace("field_title", key_map.get(k, k))
281
                        )
282
            else:
283
                for k1, v1 in v.items():
1✔
284
                    if isinstance(v1, list):
1!
285
                        for val1 in v1:
1✔
286
                            msg.append(
1✔
287
                                val1.replace(
288
                                    "field_title",
289
                                    key_map.get(str(k1), str(k1)),
290
                                )
291
                            )
292
                    else:
293
                        for key2, val2 in v1.items():
×
294
                            for val3 in val2:
×
295
                                msg.append(
×
296
                                    val3.replace(
297
                                        "field_title",
298
                                        key_map.get(str(k1), str(k1)),
299
                                    )
300
                                )
301
    else:
302
        for v in errors:
×
303
            if isinstance(v, list):
×
304
                for val in v:
×
305
                    for ik, iv in val.items():
×
306
                        for viv in iv:
×
307
                            msg.append(
×
308
                                viv.replace("field_title", key_map.get(ik, ik))
309
                            )
310

311
            else:
312
                for k1, v1 in v.items():
×
313
                    if isinstance(v1, dict):
×
314

315
                        for k1k1, v1v1 in v1.items():
×
316
                            for v1v1v in v1v1:
×
317
                                msg.append(
×
318
                                    v1v1v.replace(
319
                                        "field_title",
320
                                        key_map.get(k1k1, str(k1k1)),
321
                                    )
322
                                )
323
                    else:
324

325
                        for val1 in v1:
×
326
                            if isinstance(val1, dict):
×
327
                                for xk1, xv1 in val1.items():
×
328
                                    for xvv1 in xv1:
×
329
                                        msg.append(
×
330
                                            xvv1.replace(
331
                                                "field_title",
332
                                                key_map.get(xk1, xk1),
333
                                            )
334
                                        )
335
                            else:
336
                                msg.append(
×
337
                                    val1.replace(
338
                                        "field_title",
339
                                        key_map.get(str(k1), str(k1)),
340
                                    )
341
                                )
342

343
    return "|".join(msg)
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

© 2026 Coveralls, Inc