0002-api-improve-recurrence_days-serialiser-on-create-eve.patch
chrono/api/serializers.py | ||
---|---|---|
15 | 15 |
unknown_slugs = sorted(slugs - {obj.slug for obj in objects}) |
16 | 16 |
unknown_slugs = ', '.join(unknown_slugs) |
17 | 17 |
raise ValidationError(('invalid slugs: %s') % unknown_slugs) |
18 | 18 |
return objects |
19 | 19 | |
20 | 20 | |
21 | 21 |
class StringOrListField(serializers.ListField): |
22 | 22 |
def to_internal_value(self, data): |
23 |
if isinstance(data, list) and len(data) == 1: |
|
24 |
data = data[0] |
|
23 | 25 |
if isinstance(data, str): |
24 | 26 |
data = [s.strip() for s in data.split(',') if s.strip()] |
25 | 27 |
return super().to_internal_value(data) |
26 | 28 | |
27 | 29 | |
28 | 30 |
class CommaSeparatedStringField(serializers.ListField): |
29 | 31 |
def get_value(self, dictionary): |
30 | 32 |
return super(serializers.ListField, self).get_value(dictionary) |
... | ... | |
254 | 256 | |
255 | 257 |
class AgendaSlugsSerializer(serializers.Serializer): |
256 | 258 |
agendas = CommaSeparatedStringField( |
257 | 259 |
required=True, child=serializers.SlugField(max_length=160, allow_blank=False) |
258 | 260 |
) |
259 | 261 | |
260 | 262 | |
261 | 263 |
class EventSerializer(serializers.ModelSerializer): |
262 |
recurrence_days = CommaSeparatedStringField(
|
|
264 |
recurrence_days = StringOrListField(
|
|
263 | 265 |
required=False, child=serializers.IntegerField(min_value=0, max_value=6) |
264 | 266 |
) |
265 | 267 | |
266 | 268 |
class Meta: |
267 | 269 |
model = Event |
268 | 270 |
fields = [ |
269 | 271 |
'start_datetime', |
270 | 272 |
'recurrence_days', |
tests/api/test_event.py | ||
---|---|---|
385 | 385 |
'start_datetime': '2022-01-27 16:00', |
386 | 386 |
'places': 12, |
387 | 387 |
'recurrence_days': '0, 3, 5', |
388 | 388 |
} |
389 | 389 |
resp = app.post(api_url, params=params) |
390 | 390 |
assert not resp.json['err'] |
391 | 391 |
assert Event.objects.filter(agenda=agenda).count() == 5 |
392 | 392 | |
393 |
# force integer in recurrence_days field |
|
394 |
headers = {'Content-type': 'application/json'} |
|
395 |
data = '{"start_datetime": "2022-01-20 16:00", "places": "3", "recurrence_days": 2}' |
|
396 |
resp = app.post(api_url, headers=headers, params=data, status=400) |
|
397 |
assert resp.json['err'] |
|
398 |
assert resp.json['err_desc'] == 'invalid payload' |
|
399 |
assert resp.json['errors']['recurrence_days'][0] == 'Expected a list of items but got type "int".' |
|
400 | ||
393 | 401 | |
394 | 402 |
@pytest.mark.freeze_time('2021-11-01') |
395 | 403 |
def test_update_event(app, user): |
396 | 404 |
api_url = '/api/agenda/%s/event/%s/' % ('nop', 'nop') |
397 | 405 | |
398 | 406 |
# no authentication |
399 | 407 |
resp = app.patch(api_url, status=401) |
400 | 408 |
assert resp.json['detail'] == 'Authentication credentials were not provided.' |
401 |
- |