0001-api-use-StringOrListField-for-recurrence_days-serial.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 and isinstance(data[0], str): |
|
24 |
# accept comma separated string passed as a list of only one string item |
|
25 |
data = data[0] |
|
23 | 26 |
if isinstance(data, str): |
24 | 27 |
data = [s.strip() for s in data.split(',') if s.strip()] |
25 | 28 |
return super().to_internal_value(data) |
26 | 29 | |
27 | 30 | |
28 | 31 |
class CommaSeparatedStringField(serializers.ListField): |
29 | 32 |
def get_value(self, dictionary): |
30 | 33 |
return super(serializers.ListField, self).get_value(dictionary) |
... | ... | |
254 | 257 | |
255 | 258 |
class AgendaSlugsSerializer(serializers.Serializer): |
256 | 259 |
agendas = CommaSeparatedStringField( |
257 | 260 |
required=True, child=serializers.SlugField(max_length=160, allow_blank=False) |
258 | 261 |
) |
259 | 262 | |
260 | 263 | |
261 | 264 |
class EventSerializer(serializers.ModelSerializer): |
262 |
recurrence_days = CommaSeparatedStringField(
|
|
265 |
recurrence_days = StringOrListField(
|
|
263 | 266 |
required=False, child=serializers.IntegerField(min_value=0, max_value=6) |
264 | 267 |
) |
265 | 268 | |
266 | 269 |
class Meta: |
267 | 270 |
model = Event |
268 | 271 |
fields = [ |
269 | 272 |
'start_datetime', |
270 | 273 |
'recurrence_days', |
tests/api/test_event.py | ||
---|---|---|
333 | 333 |
'2021-12-02', |
334 | 334 |
'2021-12-04', |
335 | 335 |
'2021-12-13', |
336 | 336 |
'2021-12-16', |
337 | 337 |
'2021-12-18', |
338 | 338 |
] |
339 | 339 | |
340 | 340 | |
341 |
@pytest.mark.parametrize('recurrence_days', [1, '2', [3], ['4'], [1, 2], ['2', '3'], '4, 5']) |
|
342 |
def test_add_event_serialiser(app, user, recurrence_days): |
|
343 |
app.authorization = ('Basic', ('john.doe', 'password')) |
|
344 |
agenda = Agenda(label='Foo bar') |
|
345 |
agenda.maximal_booking_delay = 0 |
|
346 |
agenda.save() |
|
347 |
api_url = '/api/agenda/%s/event/' % (agenda.slug) |
|
348 | ||
349 |
params = { |
|
350 |
'start_datetime': '2022-01-27 16:00', |
|
351 |
'places': 12, |
|
352 |
'recurrence_days': recurrence_days, |
|
353 |
} |
|
354 |
assert Event.objects.filter(agenda=agenda).count() == 0 |
|
355 |
resp = app.post(api_url, params=params) |
|
356 |
assert Event.objects.filter(agenda=agenda).count() == 1 |
|
357 |
assert not resp.json['err'] |
|
358 | ||
359 | ||
341 | 360 |
@pytest.mark.freeze_time('2021-11-01') |
342 | 361 |
def test_update_event(app, user): |
343 | 362 |
api_url = '/api/agenda/%s/event/%s/' % ('nop', 'nop') |
344 | 363 | |
345 | 364 |
# no authentication |
346 | 365 |
resp = app.patch(api_url, status=401) |
347 | 366 |
assert resp.json['detail'] == 'Authentication credentials were not provided.' |
348 | 367 | |
349 |
- |