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) |
... | ... | |
265 | 268 | |
266 | 269 |
class AgendaSlugsSerializer(serializers.Serializer): |
267 | 270 |
agendas = CommaSeparatedStringField( |
268 | 271 |
required=True, child=serializers.SlugField(max_length=160, allow_blank=False) |
269 | 272 |
) |
270 | 273 | |
271 | 274 | |
272 | 275 |
class EventSerializer(serializers.ModelSerializer): |
273 |
recurrence_days = CommaSeparatedStringField(
|
|
276 |
recurrence_days = StringOrListField(
|
|
274 | 277 |
required=False, child=serializers.IntegerField(min_value=0, max_value=6) |
275 | 278 |
) |
276 | 279 | |
277 | 280 |
class Meta: |
278 | 281 |
model = Event |
279 | 282 |
fields = [ |
280 | 283 |
'start_datetime', |
281 | 284 |
'recurrence_days', |
tests/api/test_event.py | ||
---|---|---|
157 | 157 |
agenda.kind = 'meetings' |
158 | 158 |
agenda.save() |
159 | 159 |
app.post('/api/agenda/%s/check/%s/' % (agenda.slug, event.slug), status=404) |
160 | 160 |
agenda.kind = 'virtual' |
161 | 161 |
agenda.save() |
162 | 162 |
app.post('/api/agenda/%s/check/%s/' % (agenda.slug, event.slug), status=404) |
163 | 163 | |
164 | 164 | |
165 |
@pytest.mark.parametrize( |
|
166 |
'days_in, days_out', |
|
167 |
[ |
|
168 |
(1, [1]), |
|
169 |
('2', [2]), |
|
170 |
([3], [3]), |
|
171 |
(['4'], [4]), |
|
172 |
([1, 2], [1, 2]), |
|
173 |
(['2', '3'], [2, 3]), |
|
174 |
('4, 5', [4, 5]), |
|
175 |
], |
|
176 |
) |
|
177 |
def test_string_or_list_serialiser(app, user, days_in, days_out): |
|
178 |
app.authorization = ('Basic', ('john.doe', 'password')) |
|
179 |
agenda = Agenda(label='Foo bar') |
|
180 |
agenda.maximal_booking_delay = 0 |
|
181 |
agenda.save() |
|
182 |
api_url = '/api/agenda/%s/event/' % (agenda.slug) |
|
183 | ||
184 |
params = { |
|
185 |
'start_datetime': '2022-02-03 16:00', |
|
186 |
'places': '1', |
|
187 |
'recurrence_days': days_in, |
|
188 |
} |
|
189 |
resp = app.post(api_url, params=params) |
|
190 |
assert not resp.json['err'] |
|
191 |
assert Event.objects.get().recurrence_days == days_out |
|
192 | ||
193 | ||
165 | 194 |
@pytest.mark.freeze_time('2021-11-01') |
166 | 195 |
def test_add_event(app, user): |
167 | 196 |
api_url = '/api/agenda/%s/event/' % ('999') |
168 | 197 | |
169 | 198 |
# no authentication |
170 | 199 |
resp = app.post(api_url, status=401) |
171 | 200 |
assert resp.json['detail'] == 'Authentication credentials were not provided.' |
172 | 201 | |
173 |
- |