0001-api-patch-booking-use_color_for-66382.patch
chrono/api/serializers.py | ||
---|---|---|
187 | 187 |
class BookingSerializer(serializers.ModelSerializer): |
188 | 188 |
user_absence_reason = serializers.CharField(required=False, allow_blank=True, allow_null=True) |
189 | 189 |
user_presence_reason = serializers.CharField(required=False, allow_blank=True, allow_null=True) |
190 |
color = serializers.SlugRelatedField( |
|
191 |
many=False, |
|
192 |
slug_field='label', |
|
193 |
queryset=BookingColor.objects.all(), |
|
194 |
) |
|
190 |
use_color_for = serializers.CharField(required=False, allow_blank=True, allow_null=True, source='color') |
|
195 | 191 | |
196 | 192 |
class Meta: |
197 | 193 |
model = Booking |
... | ... | |
205 | 201 |
'user_was_present', |
206 | 202 |
'user_absence_reason', |
207 | 203 |
'user_presence_reason', |
208 |
'color',
|
|
204 |
'use_color_for',
|
|
209 | 205 |
'extra_data', |
210 | 206 |
'creation_datetime', |
211 | 207 |
'cancellation_datetime', |
... | ... | |
218 | 214 |
'cancellation_datetime', |
219 | 215 |
] |
220 | 216 | |
217 |
def to_internal_value(self, data): |
|
218 |
if 'color' in data: |
|
219 |
# legacy |
|
220 |
data['use_color_for'] = data['color'] |
|
221 |
del data['color'] |
|
222 |
return super().to_internal_value(data) |
|
223 | ||
221 | 224 |
def to_representation(self, instance): |
222 | 225 |
ret = super().to_representation(instance) |
223 | 226 |
check_type_slug = self.instance.user_check_type.slug if self.instance.user_check_type else '' |
... | ... | |
254 | 257 |
def validate_user_presence_reason(self, value): |
255 | 258 |
return self._validate_check_type('presence', value) |
256 | 259 | |
260 |
def validate_use_color_for(self, value): |
|
261 |
return BookingColor.objects.get_or_create(label=value)[0] |
|
262 | ||
257 | 263 |
def validate(self, attrs): |
258 | 264 |
super().validate(attrs) |
259 | 265 |
if 'user_absence_reason' in attrs and 'user_presence_reason' in attrs: |
chrono/api/views.py | ||
---|---|---|
2496 | 2496 |
'user_last_name', |
2497 | 2497 |
'user_email', |
2498 | 2498 |
'user_phone_number', |
2499 |
'color', |
|
2500 | 2499 |
]: |
2501 | 2500 |
if key in request.data: |
2502 | 2501 |
secondary_bookings_update[key] = getattr(self.booking, key) |
2502 |
if 'use_color_for' in request.data: |
|
2503 |
secondary_bookings_update['color'] = self.booking.color |
|
2503 | 2504 |
if 'user_absence_reason' in request.data or 'user_presence_reason' in request.data: |
2504 | 2505 |
secondary_bookings_update['user_check_type'] = self.booking.user_check_type |
2505 | 2506 |
if extra_data: |
tests/api/test_booking.py | ||
---|---|---|
153 | 153 |
'user_was_present': None, |
154 | 154 |
'user_absence_reason': '', |
155 | 155 |
'user_presence_reason': '', |
156 |
'color': None,
|
|
156 |
'use_color_for': None,
|
|
157 | 157 |
'extra_data': None, |
158 | 158 |
'cancellation_datetime': None, |
159 | 159 |
'creation_datetime': localtime(meetings_booking1.creation_datetime).isoformat(), |
... | ... | |
168 | 168 |
'user_was_present': None, |
169 | 169 |
'user_absence_reason': '', |
170 | 170 |
'user_presence_reason': '', |
171 |
'color': None,
|
|
171 |
'use_color_for': None,
|
|
172 | 172 |
'extra_data': None, |
173 | 173 |
'event': resp.json['data'][1]['event'], |
174 | 174 |
'cancellation_datetime': None, |
... | ... | |
184 | 184 |
'user_was_present': None, |
185 | 185 |
'user_absence_reason': '', |
186 | 186 |
'user_presence_reason': '', |
187 |
'color': None,
|
|
187 |
'use_color_for': None,
|
|
188 | 188 |
'extra_data': None, |
189 | 189 |
'event': resp.json['data'][1]['event'], |
190 | 190 |
'cancellation_datetime': None, |
... | ... | |
880 | 880 |
agenda = Agenda.objects.create(kind='events') |
881 | 881 |
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10) |
882 | 882 |
BookingColor.objects.create(label='the warmest color') |
883 |
BookingColor.objects.create(label='the coolest color') |
|
883 | 884 |
color = BookingColor.objects.create(label='meh') |
884 | 885 |
booking = Booking.objects.create(event=event, color=color) |
885 | 886 |
# make secondary bookings |
... | ... | |
899 | 900 |
('user_email', ''), |
900 | 901 |
('user_phone_number', '0606'), |
901 | 902 |
('user_phone_number', ''), |
902 |
('color', 'the warmest color'), |
|
903 |
('color', 'the warmest color'), # legacy |
|
904 |
('use_color_for', 'the coolest color'), |
|
903 | 905 |
] |
904 | 906 |
for key, value in to_test: |
905 | 907 |
params = { |
... | ... | |
907 | 909 |
} |
908 | 910 |
app.patch_json('/api/booking/%s/' % booking.pk, params=params) |
909 | 911 |
booking.refresh_from_db() |
912 |
if key == 'use_color_for': |
|
913 |
key = 'color' |
|
910 | 914 |
assert str(getattr(booking, key)) == value |
911 | 915 |
# all secondary bookings are updated |
912 | 916 |
for secondary_booking in booking.secondary_booking_set.all(): |
... | ... | |
914 | 918 |
other_booking.refresh_from_db() |
915 | 919 |
assert not getattr(other_booking, key) # not changed |
916 | 920 | |
917 |
# try again with a non existing color, it should fail
|
|
921 |
# try again with a non existing color |
|
918 | 922 |
params = { |
919 | 923 |
'color': 'unicorn crimson', |
920 | 924 |
} |
921 |
response = app.patch_json('/api/booking/%s/' % booking.pk, params=params, status=400)
|
|
925 |
app.patch_json('/api/booking/%s/' % booking.pk, params=params)
|
|
922 | 926 |
booking.refresh_from_db() |
923 |
assert booking.color.label == 'the warmest color' |
|
924 |
assert response.json['err_desc'] == 'invalid payload' |
|
925 |
assert list(response.json['errors'].keys()) == ['color'] |
|
926 |
assert response.json['errors']['color'] == ['Object with label=unicorn crimson does not exist.'] |
|
927 |
assert booking.color.label == 'unicorn crimson' |
|
928 |
for secondary_booking in booking.secondary_booking_set.all(): |
|
929 |
assert secondary_booking.color.label == 'unicorn crimson' |
|
930 |
assert BookingColor.objects.count() == 4 |
|
931 |
params = { |
|
932 |
'use_color_for': 'unicorn crimson again', |
|
933 |
} |
|
934 |
app.patch_json('/api/booking/%s/' % booking.pk, params=params) |
|
935 |
booking.refresh_from_db() |
|
936 |
assert booking.color.label == 'unicorn crimson again' |
|
937 |
for secondary_booking in booking.secondary_booking_set.all(): |
|
938 |
assert secondary_booking.color.label == 'unicorn crimson again' |
|
939 |
assert BookingColor.objects.count() == 5 |
|
927 | 940 | |
928 | 941 | |
929 | 942 |
def test_booking_patch_api_extra_data(app, user): |
tests/api/test_event.py | ||
---|---|---|
990 | 990 |
'user_was_present', |
991 | 991 |
'user_absence_reason', |
992 | 992 |
'user_presence_reason', |
993 |
'color',
|
|
993 |
'use_color_for',
|
|
994 | 994 |
'extra_data', |
995 | 995 |
'creation_datetime', |
996 | 996 |
'cancellation_datetime', |
... | ... | |
1204 | 1204 |
'check_status': {'check_type': 'foo-reason', 'status': 'presence'}, |
1205 | 1205 |
'booking': { |
1206 | 1206 |
'cancellation_datetime': None, |
1207 |
'color': None,
|
|
1207 |
'use_color_for': None,
|
|
1208 | 1208 |
'creation_datetime': localtime(now()).isoformat(), |
1209 | 1209 |
'extra_data': None, |
1210 | 1210 |
'id': booking2.pk, |
... | ... | |
1242 | 1242 |
'check_status': {'check_type': 'foo-reason', 'status': 'presence'}, |
1243 | 1243 |
'booking': { |
1244 | 1244 |
'cancellation_datetime': None, |
1245 |
'color': None,
|
|
1245 |
'use_color_for': None,
|
|
1246 | 1246 |
'creation_datetime': localtime(now()).isoformat(), |
1247 | 1247 |
'extra_data': None, |
1248 | 1248 |
'id': booking1.pk, |
1249 |
- |