api: use check_types from lingo (#66015)

This commit is contained in:
Lauréline Guérin 2022-06-09 16:35:13 +02:00
parent b5d836d46d
commit 2d0cb4f1b2
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
3 changed files with 74 additions and 157 deletions

View File

@ -13,7 +13,6 @@ from chrono.agendas.models import (
Booking,
BookingColor,
Category,
CheckType,
Event,
EventsType,
Person,
@ -23,6 +22,7 @@ from chrono.agendas.models import (
Subscription,
TimePeriodExceptionGroup,
)
from chrono.utils.lingo import get_agenda_check_types
def get_objects_from_slugs(slugs, qs):
@ -240,19 +240,13 @@ class BookingSerializer(serializers.ModelSerializer):
'presence': _('unknown presence reason'),
}
if not self.instance.event.agenda.check_type_group:
raise serializers.ValidationError(error_messages[kind])
check_types_qs = self.instance.event.agenda.check_type_group.check_types.filter(
kind=kind, disabled=False
)
try:
return check_types_qs.get(slug=value)
except CheckType.DoesNotExist:
try:
return check_types_qs.get(label=value)
except (CheckType.DoesNotExist, CheckType.MultipleObjectsReturned):
raise serializers.ValidationError(error_messages[kind])
check_types = get_agenda_check_types(self.instance.event.agenda)
for check_type in check_types:
if check_type.kind != kind:
continue
if value in [check_type.slug, check_type.label]:
return check_type
raise serializers.ValidationError(error_messages[kind])
def validate_user_absence_reason(self, value):
return self._validate_check_type('absence', value)

View File

@ -9,8 +9,6 @@ from chrono.agendas.models import (
Agenda,
Booking,
Category,
CheckType,
CheckTypeGroup,
Desk,
Event,
EventsType,
@ -1207,9 +1205,6 @@ def test_datetimes_multiple_agendas_shared_custody_holiday_rules(app):
def test_datetimes_multiple_agendas_with_status(app):
group = CheckTypeGroup.objects.create(label='Foo bar')
check_type_absence = CheckType.objects.create(label='Foo reason', group=group, kind='absence')
check_type_presence = CheckType.objects.create(label='Foo reason', group=group, kind='presence')
agenda = Agenda.objects.create(label='agenda', kind='events')
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
event_booked = Event.objects.create(
@ -1249,7 +1244,7 @@ def test_datetimes_multiple_agendas_with_status(app):
event=event_absence_with_reason,
user_external_id='xxx',
user_was_present=False,
user_check_type_slug=check_type_absence.slug,
user_check_type_slug='foo-reason',
)
event_presence = Event.objects.create(
slug='event-presence',
@ -1268,7 +1263,7 @@ def test_datetimes_multiple_agendas_with_status(app):
event=event_presence_with_reason,
user_external_id='xxx',
user_was_present=True,
user_check_type_slug=check_type_presence.slug,
user_check_type_slug='foo-reason',
)
event_booked_future = Event.objects.create(
slug='event-booked-future',

View File

@ -6,17 +6,8 @@ from django.db import connection
from django.test.utils import CaptureQueriesContext
from django.utils.timezone import localtime, make_aware, now
from chrono.agendas.models import (
Agenda,
Booking,
BookingColor,
Category,
CheckType,
CheckTypeGroup,
Desk,
Event,
MeetingType,
)
from chrono.agendas.models import Agenda, Booking, BookingColor, Category, Desk, Event, MeetingType
from chrono.utils.lingo import CheckType
pytestmark = pytest.mark.django_db
@ -324,9 +315,6 @@ def test_bookings_api_filter_user_was_present(app, user):
def test_bookings_api_filter_user_absence_reason(app, user):
group = CheckTypeGroup.objects.create(label='Foo')
check_type_absence = CheckType.objects.create(group=group, label='Foo bar', kind='absence')
check_type_presence = CheckType.objects.create(group=group, label='Foo bar', kind='presence')
agenda = Agenda.objects.create(label='Foo bar')
event = Event.objects.create(
agenda=agenda, start_datetime=make_aware(datetime.datetime(2017, 5, 22, 0, 0)), places=10
@ -336,48 +324,37 @@ def test_bookings_api_filter_user_absence_reason(app, user):
event=event,
user_external_id='42',
user_was_present=False,
user_check_type_slug=check_type_absence.slug,
user_check_type_label=check_type_absence.label,
user_check_type_slug='foo-bar',
user_check_type_label='Foo bar',
)
Booking.objects.create(
event=event,
user_external_id='42',
user_was_present=True,
user_check_type_slug=check_type_presence.slug,
user_check_type_label=check_type_presence.label,
user_check_type_slug='foo-bar-2',
user_check_type_label='Foo bar 2',
)
app.authorization = ('Basic', ('john.doe', 'password'))
resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': 'foo'})
assert resp.json['err'] == 0
assert [b['id'] for b in resp.json['data']] == []
resp = app.get(
'/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': check_type_absence.slug}
)
resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': 'foo-bar'})
assert resp.json['err'] == 0
assert [b['id'] for b in resp.json['data']] == [booking2.pk]
resp = app.get(
'/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': check_type_absence.label}
)
resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': 'Foo bar'})
assert resp.json['err'] == 0
assert [b['id'] for b in resp.json['data']] == [booking2.pk]
resp = app.get(
'/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': check_type_presence.slug}
)
resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': 'foo-bar-2'})
assert resp.json['err'] == 0
assert [b['id'] for b in resp.json['data']] == []
Booking.objects.update(user_was_present=True)
resp = app.get(
'/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': check_type_absence.label}
)
resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': 'Foo bar 2'})
assert resp.json['err'] == 0
assert [b['id'] for b in resp.json['data']] == []
def test_bookings_api_filter_user_presence_reason(app, user):
group = CheckTypeGroup.objects.create(label='Foo')
check_type_absence = CheckType.objects.create(group=group, label='Foo bar', kind='absence')
check_type_presence = CheckType.objects.create(group=group, label='Foo bar', kind='presence')
agenda = Agenda.objects.create(label='Foo bar')
event = Event.objects.create(
agenda=agenda, start_datetime=make_aware(datetime.datetime(2017, 5, 22, 0, 0)), places=10
@ -387,40 +364,32 @@ def test_bookings_api_filter_user_presence_reason(app, user):
event=event,
user_external_id='42',
user_was_present=True,
user_check_type_slug=check_type_presence.slug,
user_check_type_label=check_type_presence.label,
user_check_type_slug='foo-bar',
user_check_type_label='Foo bar',
)
Booking.objects.create(
event=event,
user_external_id='42',
user_was_present=False,
user_check_type_slug=check_type_absence.slug,
user_check_type_label=check_type_absence.label,
user_check_type_slug='foo-bar-2',
user_check_type_label='Foo bar 2',
)
app.authorization = ('Basic', ('john.doe', 'password'))
resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'foo'})
assert resp.json['err'] == 0
assert [b['id'] for b in resp.json['data']] == []
resp = app.get(
'/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_presence.slug}
)
resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'foo-bar'})
assert resp.json['err'] == 0
assert [b['id'] for b in resp.json['data']] == [booking2.pk]
resp = app.get(
'/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_presence.label}
)
resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'Foo bar'})
assert resp.json['err'] == 0
assert [b['id'] for b in resp.json['data']] == [booking2.pk]
resp = app.get(
'/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_absence.slug}
)
resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'foo-bar-2'})
assert resp.json['err'] == 0
assert [b['id'] for b in resp.json['data']] == []
Booking.objects.update(user_was_present=False)
resp = app.get(
'/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_presence.label}
)
resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'Foo bar 2'})
assert resp.json['err'] == 0
assert [b['id'] for b in resp.json['data']] == []
@ -493,13 +462,9 @@ def test_bookings_api_filter_event(app, user):
@pytest.mark.parametrize('flag', [True, False, None])
def test_booking_api_present(app, user, flag):
group = CheckTypeGroup.objects.create(label='Foo')
check_type = CheckType.objects.create(
group=group, label='Foo bar', kind='presence' if flag else 'absence'
)
agenda = Agenda.objects.create(label='Foo bar', kind='events')
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
booking = Booking.objects.create(event=event, user_was_present=flag, user_check_type_slug=check_type.slug)
booking = Booking.objects.create(event=event, user_was_present=flag, user_check_type_slug='foo-bar')
app.authorization = ('Basic', ('john.doe', 'password'))
resp = app.get('/api/booking/%s/' % booking.pk)
@ -634,7 +599,9 @@ def test_booking_patch_api_present(app, user, flag):
assert resp.json['err'] == 0
def test_booking_patch_api_absence_reason(app, user):
@mock.patch('chrono.api.serializers.get_agenda_check_types')
def test_booking_patch_api_absence_reason(check_types, app, user):
check_types.return_value = []
agenda = Agenda.objects.create(kind='events')
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
booking = Booking.objects.create(event=event, user_was_present=False)
@ -648,44 +615,27 @@ def test_booking_patch_api_absence_reason(app, user):
assert resp.json['err'] == 4
assert resp.json['err_desc'] == 'invalid payload'
group = CheckTypeGroup.objects.create(label='Foo')
check_type_absence = CheckType.objects.create(group=group, label='Foo bar', kind='absence')
check_type_presence = CheckType.objects.create(group=group, label='Foo baz', kind='presence')
check_type_absence_disabled = CheckType.objects.create(
label='disabled', group=group, kind='absence', disabled=True
)
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foobar'}, status=400
)
assert resp.json['err'] == 4
assert resp.json['err_desc'] == 'invalid payload'
# wrong kind
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'Foo baz'}, status=400
)
assert resp.json['err'] == 4
assert resp.json['err_desc'] == 'invalid payload'
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_presence.slug}, status=400
)
assert resp.json['err'] == 4
assert resp.json['err_desc'] == 'invalid payload'
# set check_type
agenda.check_type_group = group
agenda.save()
check_types.return_value = [
CheckType(slug='foo-bar', label='Foo bar', kind='absence'),
CheckType(slug='foo-baz', label='Foo baz', kind='presence'),
]
# it works with label
app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'Foo bar'})
booking.refresh_from_db()
assert booking.user_check_type_slug == check_type_absence.slug
assert booking.user_check_type_label == check_type_absence.label
assert booking.user_check_type_slug == 'foo-bar'
assert booking.user_check_type_label == 'Foo bar'
# disabled
# unknown
resp = app.patch_json(
'/api/booking/%s/' % booking.pk,
params={'user_absence_reason': check_type_absence_disabled.slug},
params={'user_presence_reason': 'unknown'},
status=400,
)
assert resp.json['err'] == 4
@ -708,14 +658,14 @@ def test_booking_patch_api_absence_reason(app, user):
other_booking = Booking.objects.create(event=event)
# it works also with slug
app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug})
app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'})
booking.refresh_from_db()
assert booking.user_check_type_slug == check_type_absence.slug
assert booking.user_check_type_label == check_type_absence.label
assert booking.user_check_type_slug == 'foo-bar'
assert booking.user_check_type_label == 'Foo bar'
# all secondary bookings are updated
assert list(booking.secondary_booking_set.values_list('user_check_type_slug', flat=True)) == [
check_type_absence.slug,
check_type_absence.slug,
'foo-bar',
'foo-bar',
]
other_booking.refresh_from_db()
assert other_booking.user_check_type_slug is None # not changed
@ -724,7 +674,7 @@ def test_booking_patch_api_absence_reason(app, user):
# user_was_present is True, can not set user_absence_reason
Booking.objects.update(user_was_present=True)
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug}, status=400
'/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'}, status=400
)
assert resp.json['err'] == 6
assert resp.json['err_desc'] == 'user is marked as present, can not set absence reason'
@ -732,27 +682,25 @@ def test_booking_patch_api_absence_reason(app, user):
# but it's ok if user_was_present is set to False
resp = app.patch_json(
'/api/booking/%s/' % booking.pk,
params={'user_absence_reason': check_type_absence.slug, 'user_was_present': False},
params={'user_absence_reason': 'foo-bar', 'user_was_present': False},
)
assert resp.json['err'] == 0
booking.refresh_from_db()
assert booking.user_was_present is False
assert booking.user_check_type_slug == check_type_absence.slug
assert booking.user_check_type_label == check_type_absence.label
assert booking.user_check_type_slug == 'foo-bar'
assert booking.user_check_type_label == 'Foo bar'
# mark the event as checked
event.checked = True
event.save()
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug}
)
resp = app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'})
assert resp.json['err'] == 0
# now disable check update
agenda.disable_check_update = True
agenda.save()
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug}, status=400
'/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'}, status=400
)
assert resp.json['err'] == 5
assert resp.json['err_desc'] == 'event is marked as checked'
@ -760,7 +708,9 @@ def test_booking_patch_api_absence_reason(app, user):
assert resp.json['err'] == 0
def test_booking_patch_api_presence_reason(app, user):
@mock.patch('chrono.api.serializers.get_agenda_check_types')
def test_booking_patch_api_presence_reason(check_types, app, user):
check_types.return_value = []
agenda = Agenda.objects.create(kind='events')
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
booking = Booking.objects.create(event=event, user_was_present=True)
@ -774,44 +724,27 @@ def test_booking_patch_api_presence_reason(app, user):
assert resp.json['err'] == 4
assert resp.json['err_desc'] == 'invalid payload'
group = CheckTypeGroup.objects.create(label='Foo')
check_type_presence = CheckType.objects.create(group=group, label='Foo bar', kind='presence')
check_type_absence = CheckType.objects.create(group=group, label='Foo baz', kind='absence')
check_type_presence_disabled = CheckType.objects.create(
label='disabled', group=group, kind='presence', disabled=True
)
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foobar'}, status=400
)
assert resp.json['err'] == 4
assert resp.json['err_desc'] == 'invalid payload'
# wrong kind
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'Foo baz'}, status=400
)
assert resp.json['err'] == 4
assert resp.json['err_desc'] == 'invalid payload'
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_absence.slug}, status=400
)
assert resp.json['err'] == 4
assert resp.json['err_desc'] == 'invalid payload'
# set check_type
agenda.check_type_group = group
agenda.save()
check_types.return_value = [
CheckType(slug='foo-bar', label='Foo bar', kind='presence'),
CheckType(slug='foo-baz', label='Foo baz', kind='absence'),
]
# it works with label
app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'Foo bar'})
booking.refresh_from_db()
assert booking.user_check_type_slug == check_type_presence.slug
assert booking.user_check_type_label == check_type_presence.label
assert booking.user_check_type_slug == 'foo-bar'
assert booking.user_check_type_label == 'Foo bar'
# disabled
# unknown
resp = app.patch_json(
'/api/booking/%s/' % booking.pk,
params={'user_presence_reason': check_type_presence_disabled.slug},
params={'user_presence_reason': 'unknown'},
status=400,
)
assert resp.json['err'] == 4
@ -834,14 +767,14 @@ def test_booking_patch_api_presence_reason(app, user):
other_booking = Booking.objects.create(event=event)
# it works also with slug
app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug})
app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'})
booking.refresh_from_db()
assert booking.user_check_type_slug == check_type_presence.slug
assert booking.user_check_type_label == check_type_presence.label
assert booking.user_check_type_slug == 'foo-bar'
assert booking.user_check_type_label == 'Foo bar'
# all secondary bookings are updated
assert list(booking.secondary_booking_set.values_list('user_check_type_slug', flat=True)) == [
check_type_presence.slug,
check_type_presence.slug,
'foo-bar',
'foo-bar',
]
other_booking.refresh_from_db()
assert other_booking.user_check_type_slug is None # not changed
@ -850,7 +783,7 @@ def test_booking_patch_api_presence_reason(app, user):
# user_was_present is False, can not set user_presence_reason
Booking.objects.update(user_was_present=False)
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug}, status=400
'/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'}, status=400
)
assert resp.json['err'] == 6
assert resp.json['err_desc'] == 'user is marked as absent, can not set presence reason'
@ -858,27 +791,25 @@ def test_booking_patch_api_presence_reason(app, user):
# but it's ok if user_was_present is set to True
resp = app.patch_json(
'/api/booking/%s/' % booking.pk,
params={'user_presence_reason': check_type_presence.slug, 'user_was_present': True},
params={'user_presence_reason': 'foo-bar', 'user_was_present': True},
)
assert resp.json['err'] == 0
booking.refresh_from_db()
assert booking.user_was_present is True
assert booking.user_check_type_slug == check_type_presence.slug
assert booking.user_check_type_label == check_type_presence.label
assert booking.user_check_type_slug == 'foo-bar'
assert booking.user_check_type_label == 'Foo bar'
# mark the event as checked
event.checked = True
event.save()
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug}
)
resp = app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'})
assert resp.json['err'] == 0
# now disable check update
agenda.disable_check_update = True
agenda.save()
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug}, status=400
'/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'}, status=400
)
assert resp.json['err'] == 5
assert resp.json['err_desc'] == 'event is marked as checked'
@ -887,10 +818,7 @@ def test_booking_patch_api_presence_reason(app, user):
def test_booking_patch_api_both_reasons(app, user):
group = CheckTypeGroup.objects.create(label='Foo')
CheckType.objects.create(group=group, label='Foo bar', kind='presence')
CheckType.objects.create(group=group, label='Foo baz', kind='absence')
agenda = Agenda.objects.create(kind='events', check_type_group=group)
agenda = Agenda.objects.create(kind='events')
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
booking = Booking.objects.create(event=event)