706 lines
27 KiB
Python
706 lines
27 KiB
Python
import datetime
|
|
|
|
import pytest
|
|
from django.contrib.auth.models import Group
|
|
from django.db import connection
|
|
from django.test.utils import CaptureQueriesContext
|
|
|
|
from chrono.agendas.models import (
|
|
Agenda,
|
|
Booking,
|
|
Category,
|
|
Desk,
|
|
Event,
|
|
EventsType,
|
|
Resource,
|
|
TimePeriodException,
|
|
)
|
|
from chrono.apps.snapshot.models import AgendaSnapshot
|
|
from chrono.utils.timezone import localtime, now
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
|
|
def test_agendas_api(settings, app):
|
|
edit_group = Group.objects.create(name='Edit')
|
|
view_group = Group.objects.create(name='View')
|
|
category_a = Category.objects.create(label='Category A')
|
|
category_b = Category.objects.create(label='Category B')
|
|
events_type = EventsType.objects.create(label='Type A')
|
|
events_type2 = EventsType.objects.create(label='Type B')
|
|
event_agenda = Agenda.objects.create(
|
|
label='Foo bar',
|
|
category=category_a,
|
|
events_type=events_type,
|
|
edit_role=edit_group,
|
|
)
|
|
Desk.objects.create(agenda=event_agenda, slug='_exceptions_holder')
|
|
event_agenda2 = Agenda.objects.create(label='Foo bar 2', category=category_a, events_type=events_type2)
|
|
Desk.objects.create(agenda=event_agenda2, slug='_exceptions_holder')
|
|
event_agenda3 = Agenda.objects.create(label='Foo bar 3', partial_bookings=True)
|
|
Desk.objects.create(agenda=event_agenda3, slug='_exceptions_holder')
|
|
meetings_agenda1 = Agenda.objects.create(
|
|
label='Foo bar Meeting', kind='meetings', category=category_b, view_role=view_group
|
|
)
|
|
meetings_agenda2 = Agenda.objects.create(label='Foo bar Meeting 2', kind='meetings')
|
|
resource1 = Resource.objects.create(label='Resource 1', description='Foo bar Resource 1')
|
|
resource2 = Resource.objects.create(label='Resource 2', description='Foo bar Resource 2')
|
|
Resource.objects.create(label='Resource 3')
|
|
meetings_agenda1.resources.add(resource1, resource2)
|
|
virtual_agenda = Agenda.objects.create(
|
|
label='Virtual Agenda',
|
|
kind='virtual',
|
|
minimal_booking_delay=1,
|
|
maximal_booking_delay=56,
|
|
edit_role=edit_group,
|
|
view_role=view_group,
|
|
)
|
|
resp = app.get('/api/agenda/')
|
|
assert resp.json == {
|
|
'err': 0,
|
|
'data': [
|
|
{
|
|
'text': 'Foo bar',
|
|
'id': 'foo-bar',
|
|
'slug': 'foo-bar',
|
|
'kind': 'events',
|
|
'minimal_booking_delay': 1,
|
|
'minimal_booking_delay_in_working_days': False,
|
|
'maximal_booking_delay': 56,
|
|
'minimal_booking_time': '00:00:00',
|
|
'edit_role': 'Edit',
|
|
'view_role': None,
|
|
'category': 'category-a',
|
|
'category_label': 'Category A',
|
|
'events_type': 'type-a',
|
|
'booking_form_url': None,
|
|
'api': {
|
|
'datetimes_url': 'http://testserver/api/agenda/foo-bar/datetimes/',
|
|
'backoffice_url': 'http://testserver/manage/agendas/%s/' % event_agenda.pk,
|
|
},
|
|
},
|
|
{
|
|
'text': 'Foo bar 2',
|
|
'id': 'foo-bar-2',
|
|
'kind': 'events',
|
|
'slug': 'foo-bar-2',
|
|
'minimal_booking_delay': 1,
|
|
'minimal_booking_delay_in_working_days': False,
|
|
'maximal_booking_delay': 56,
|
|
'minimal_booking_time': '00:00:00',
|
|
'edit_role': None,
|
|
'view_role': None,
|
|
'category': 'category-a',
|
|
'category_label': 'Category A',
|
|
'events_type': 'type-b',
|
|
'booking_form_url': None,
|
|
'api': {
|
|
'datetimes_url': 'http://testserver/api/agenda/foo-bar-2/datetimes/',
|
|
'backoffice_url': 'http://testserver/manage/agendas/%s/' % event_agenda2.pk,
|
|
},
|
|
},
|
|
{
|
|
'text': 'Foo bar 3',
|
|
'id': 'foo-bar-3',
|
|
'kind': 'events',
|
|
'slug': 'foo-bar-3',
|
|
'minimal_booking_delay': 1,
|
|
'minimal_booking_delay_in_working_days': False,
|
|
'maximal_booking_delay': 56,
|
|
'minimal_booking_time': '00:00:00',
|
|
'edit_role': None,
|
|
'view_role': None,
|
|
'category': None,
|
|
'category_label': None,
|
|
'events_type': None,
|
|
'booking_form_url': None,
|
|
'api': {
|
|
'datetimes_url': 'http://testserver/api/agenda/foo-bar-3/datetimes/',
|
|
'backoffice_url': 'http://testserver/manage/agendas/%s/' % event_agenda3.pk,
|
|
},
|
|
},
|
|
{
|
|
'text': 'Foo bar Meeting',
|
|
'id': 'foo-bar-meeting',
|
|
'slug': 'foo-bar-meeting',
|
|
'minimal_booking_delay': 1,
|
|
'maximal_booking_delay': 56,
|
|
'minimal_booking_time': '00:00:00',
|
|
'edit_role': None,
|
|
'view_role': 'View',
|
|
'category': 'category-b',
|
|
'category_label': 'Category B',
|
|
'kind': 'meetings',
|
|
'resources': [
|
|
{'id': 'resource-1', 'text': 'Resource 1', 'description': 'Foo bar Resource 1'},
|
|
{'id': 'resource-2', 'text': 'Resource 2', 'description': 'Foo bar Resource 2'},
|
|
],
|
|
'api': {
|
|
'meetings_url': 'http://testserver/api/agenda/foo-bar-meeting/meetings/',
|
|
'desks_url': 'http://testserver/api/agenda/foo-bar-meeting/desks/',
|
|
'resources_url': 'http://testserver/api/agenda/foo-bar-meeting/resources/',
|
|
'backoffice_url': 'http://testserver/manage/agendas/%s/' % meetings_agenda1.pk,
|
|
},
|
|
},
|
|
{
|
|
'text': 'Foo bar Meeting 2',
|
|
'id': 'foo-bar-meeting-2',
|
|
'slug': 'foo-bar-meeting-2',
|
|
'minimal_booking_delay': 1,
|
|
'maximal_booking_delay': 56,
|
|
'minimal_booking_time': '00:00:00',
|
|
'edit_role': None,
|
|
'view_role': None,
|
|
'category': None,
|
|
'category_label': None,
|
|
'kind': 'meetings',
|
|
'resources': [],
|
|
'api': {
|
|
'meetings_url': 'http://testserver/api/agenda/foo-bar-meeting-2/meetings/',
|
|
'desks_url': 'http://testserver/api/agenda/foo-bar-meeting-2/desks/',
|
|
'resources_url': 'http://testserver/api/agenda/foo-bar-meeting-2/resources/',
|
|
'backoffice_url': 'http://testserver/manage/agendas/%s/' % meetings_agenda2.pk,
|
|
},
|
|
},
|
|
{
|
|
'text': 'Virtual Agenda',
|
|
'id': 'virtual-agenda',
|
|
'slug': 'virtual-agenda',
|
|
'minimal_booking_delay': 1,
|
|
'maximal_booking_delay': 56,
|
|
'minimal_booking_time': '00:00:00',
|
|
'edit_role': 'Edit',
|
|
'view_role': 'View',
|
|
'category': None,
|
|
'category_label': None,
|
|
'kind': 'virtual',
|
|
'api': {
|
|
'meetings_url': 'http://testserver/api/agenda/virtual-agenda/meetings/',
|
|
'desks_url': 'http://testserver/api/agenda/virtual-agenda/desks/',
|
|
'backoffice_url': 'http://testserver/manage/agendas/%s/' % virtual_agenda.pk,
|
|
},
|
|
},
|
|
],
|
|
}
|
|
|
|
resp = app.get('/api/agenda/', params={'q': 'foo'})
|
|
assert len(resp.json['data']) == 5
|
|
resp = app.get('/api/agenda/', params={'q': 'MEET'})
|
|
assert len(resp.json['data']) == 2
|
|
resp = app.get('/api/agenda/', params={'q': ''})
|
|
assert len(resp.json['data']) == 0
|
|
|
|
with CaptureQueriesContext(connection) as ctx:
|
|
resp = app.get('/api/agenda/')
|
|
assert len(ctx.captured_queries) == 3
|
|
with CaptureQueriesContext(connection) as ctx:
|
|
resp = app.get('/api/agenda/', params={'q': 'MEET'})
|
|
assert len(ctx.captured_queries) == 2
|
|
|
|
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
|
assert len(resp.json['data']) == 0
|
|
|
|
resp = app.get('/api/agenda/', params={'category': ''})
|
|
assert len(resp.json['data']) == 6
|
|
resp = app.get('/api/agenda/', params={'category': '__none__'})
|
|
assert len(resp.json['data']) == 3
|
|
resp = app.get('/api/agenda/', params={'category': 'category-a'})
|
|
assert len(resp.json['data']) == 2
|
|
resp = app.get('/api/agenda/', params={'category': 'category-b'})
|
|
assert len(resp.json['data']) == 1
|
|
resp = app.get('/api/agenda/', params={'category': 'unknown'})
|
|
assert len(resp.json['data']) == 0
|
|
|
|
event1 = Event.objects.create(
|
|
start_datetime=(localtime() + datetime.timedelta(days=5)).replace(hour=10, minute=0),
|
|
places=1,
|
|
agenda=event_agenda,
|
|
)
|
|
event2 = Event.objects.create(
|
|
start_datetime=(localtime() + datetime.timedelta(days=10)).replace(hour=10, minute=0),
|
|
places=1,
|
|
agenda=event_agenda,
|
|
)
|
|
event3 = Event.objects.create(
|
|
start_datetime=(localtime() + datetime.timedelta(days=15)).replace(hour=10, minute=0),
|
|
places=1,
|
|
agenda=event_agenda,
|
|
)
|
|
|
|
# all events are free
|
|
resp = app.get('/api/agenda/', params={'with_open_events': 'true'})
|
|
assert len(resp.json['data']) == 1
|
|
|
|
# one event is full
|
|
event1.booking_set.create()
|
|
event1.refresh_from_db()
|
|
assert event1.full is True
|
|
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
|
assert len(resp.json['data']) == 1
|
|
|
|
# all events are full
|
|
event2.booking_set.create()
|
|
event2.refresh_from_db()
|
|
assert event2.full is True
|
|
event3.booking_set.create()
|
|
event3.refresh_from_db()
|
|
assert event3.full is True
|
|
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
|
assert len(resp.json['data']) == 0
|
|
|
|
# event1 is not full but too soon
|
|
event1.booking_set.all().delete()
|
|
event1.refresh_from_db()
|
|
assert event1.full is False
|
|
event_agenda.minimal_booking_delay = 10
|
|
event_agenda.save()
|
|
assert list(event_agenda.get_open_events()) == [event2, event3]
|
|
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
|
assert len(resp.json['data']) == 0
|
|
|
|
# event3 is not full but too late
|
|
event3.booking_set.all().delete()
|
|
event3.refresh_from_db()
|
|
assert event3.full is False
|
|
event_agenda.maximal_booking_delay = 12
|
|
event_agenda.save()
|
|
del event_agenda.max_booking_datetime
|
|
assert list(event_agenda.get_open_events()) == [event2]
|
|
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
|
assert len(resp.json['data']) == 0
|
|
|
|
# events are not full but not published
|
|
event2.booking_set.all().delete()
|
|
event2.refresh_from_db()
|
|
assert event2.full is False
|
|
event_agenda.event_set.update(publication_datetime=now() + datetime.timedelta(days=20))
|
|
assert list(event_agenda.get_open_events()) == []
|
|
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
|
assert len(resp.json['data']) == 0
|
|
|
|
# event recurrences are available
|
|
event = Event.objects.create(
|
|
start_datetime=now(),
|
|
places=10,
|
|
agenda=event_agenda,
|
|
recurrence_days=list(range(1, 8)),
|
|
recurrence_end_date=now() + datetime.timedelta(days=15),
|
|
)
|
|
event.create_all_recurrences()
|
|
|
|
assert len(event_agenda.get_open_events()) == 2
|
|
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
|
assert len(resp.json['data']) == 1
|
|
|
|
settings.PARTIAL_BOOKINGS_ENABLED = True
|
|
resp = app.get('/api/agenda/')
|
|
assert resp.json['data'][0]['kind'] == 'events'
|
|
assert resp.json['data'][0]['partial_bookings'] is False
|
|
assert resp.json['data'][1]['kind'] == 'events'
|
|
assert resp.json['data'][1]['partial_bookings'] is False
|
|
assert resp.json['data'][2]['kind'] == 'events'
|
|
assert resp.json['data'][2]['partial_bookings'] is True
|
|
|
|
for _ in range(10):
|
|
event_agenda = Agenda.objects.create(label='Foo bar', category=category_a)
|
|
Desk.objects.create(agenda=event_agenda, slug='_exceptions_holder')
|
|
event = Event.objects.create(
|
|
start_datetime=now(),
|
|
places=10,
|
|
agenda=event_agenda,
|
|
recurrence_days=[now().isoweekday()],
|
|
recurrence_end_date=now() + datetime.timedelta(days=15),
|
|
)
|
|
event.create_all_recurrences()
|
|
TimePeriodException.objects.create(
|
|
desk=event_agenda.desk_set.get(),
|
|
start_datetime=now(),
|
|
end_datetime=now() + datetime.timedelta(hours=1),
|
|
)
|
|
|
|
with CaptureQueriesContext(connection) as ctx:
|
|
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
|
assert len(ctx.captured_queries) == 4
|
|
|
|
|
|
def test_agenda_detail_api(app):
|
|
agenda = Agenda.objects.create(label='Foo bar', kind='events', minimal_booking_delay=0)
|
|
event1 = Event.objects.create(
|
|
start_datetime=(localtime() + datetime.timedelta(days=5)).replace(hour=10, minute=0),
|
|
places=1,
|
|
agenda=agenda,
|
|
)
|
|
event2 = Event.objects.create(
|
|
start_datetime=(localtime() + datetime.timedelta(days=10)).replace(hour=10, minute=0),
|
|
places=1,
|
|
agenda=agenda,
|
|
)
|
|
event3 = Event.objects.create(
|
|
start_datetime=(localtime() + datetime.timedelta(days=15)).replace(hour=10, minute=0),
|
|
places=1,
|
|
agenda=agenda,
|
|
)
|
|
resp = app.get('/api/agenda/%s/' % agenda.slug)
|
|
data = resp.json['data']
|
|
assert data['id'] == 'foo-bar'
|
|
assert data['slug'] == 'foo-bar'
|
|
assert data['text'] == 'Foo bar'
|
|
assert data['kind'] == 'events'
|
|
assert data['opened_events_available'] is True
|
|
assert data['api']['datetimes_url'] == 'http://testserver/api/agenda/foo-bar/datetimes/'
|
|
|
|
# one event is full
|
|
event1.booking_set.create()
|
|
event1.refresh_from_db()
|
|
assert event1.full is True
|
|
resp = app.get('/api/agenda/%s/' % agenda.slug)
|
|
assert resp.json['data']['opened_events_available'] is True
|
|
|
|
# all events are full
|
|
event2.booking_set.create()
|
|
event2.refresh_from_db()
|
|
assert event2.full is True
|
|
event3.booking_set.create()
|
|
event3.refresh_from_db()
|
|
assert event3.full is True
|
|
resp = app.get('/api/agenda/%s/' % agenda.slug)
|
|
assert resp.json['data']['opened_events_available'] is False
|
|
|
|
# event1 is not full but too soon
|
|
event1.booking_set.all().delete()
|
|
event1.refresh_from_db()
|
|
assert event1.full is False
|
|
agenda.minimal_booking_delay = 10
|
|
agenda.save()
|
|
resp = app.get('/api/agenda/%s/' % agenda.slug)
|
|
assert list(agenda.get_open_events()) == [event2, event3]
|
|
assert resp.json['data']['opened_events_available'] is False
|
|
|
|
# event3 is not full but too late
|
|
event3.booking_set.all().delete()
|
|
event3.refresh_from_db()
|
|
assert event3.full is False
|
|
agenda.maximal_booking_delay = 12
|
|
agenda.save()
|
|
del agenda.max_booking_datetime
|
|
resp = app.get('/api/agenda/%s/' % agenda.slug)
|
|
assert list(agenda.get_open_events()) == [event2]
|
|
assert resp.json['data']['opened_events_available'] is False
|
|
|
|
# events are not full but not published
|
|
event2.booking_set.all().delete()
|
|
event2.refresh_from_db()
|
|
assert event2.full is False
|
|
agenda.event_set.update(publication_datetime=now() + datetime.timedelta(days=20))
|
|
resp = app.get('/api/agenda/%s/' % agenda.slug)
|
|
assert list(agenda.get_open_events()) == []
|
|
assert resp.json['data']['opened_events_available'] is False
|
|
|
|
# unknown
|
|
app.get('/api/agenda/whatever/', status=404)
|
|
|
|
|
|
def test_agenda_detail_routing(app, meetings_agenda):
|
|
api_url = '/api/agenda/%s/' % meetings_agenda.slug
|
|
resp = app.get(api_url)
|
|
assert isinstance(resp.json['data'], dict)
|
|
|
|
# check it doesn't get confused with an agenda with "agenda" in its slug
|
|
agenda = Agenda(
|
|
label='Foo bar Agenda', kind='meetings', minimal_booking_delay=1, maximal_booking_delay=56
|
|
)
|
|
agenda.save()
|
|
api_url = '/api/agenda/%s/' % agenda.slug
|
|
resp = app.get(api_url)
|
|
assert isinstance(resp.json['data'], dict)
|
|
|
|
|
|
def test_virtual_agenda_detail(app, virtual_meetings_agenda):
|
|
resp = app.get('/api/agenda/%s/' % virtual_meetings_agenda.slug)
|
|
assert resp.json == {
|
|
'data': {
|
|
'text': 'Virtual Agenda',
|
|
'id': 'virtual-agenda',
|
|
'slug': 'virtual-agenda',
|
|
'minimal_booking_delay': None,
|
|
'maximal_booking_delay': None,
|
|
'minimal_booking_time': '00:00:00',
|
|
'edit_role': None,
|
|
'view_role': None,
|
|
'category': None,
|
|
'category_label': None,
|
|
'kind': 'virtual',
|
|
'api': {
|
|
'meetings_url': 'http://testserver/api/agenda/%s/meetings/' % virtual_meetings_agenda.slug,
|
|
'desks_url': 'http://testserver/api/agenda/%s/desks/' % virtual_meetings_agenda.slug,
|
|
'backoffice_url': 'http://testserver/manage/agendas/%s/' % virtual_meetings_agenda.pk,
|
|
},
|
|
},
|
|
}
|
|
|
|
|
|
def test_agenda_api_delete(app, user):
|
|
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
|
|
|
# unauthenticated
|
|
resp = app.delete('/api/agenda/%s/' % agenda.slug, status=401)
|
|
assert Agenda.objects.count() == 1
|
|
|
|
app.authorization = ('Basic', ('john.doe', 'password'))
|
|
resp = app.delete('/api/agenda/%s/' % agenda.slug)
|
|
assert resp.json['err'] == 0
|
|
assert not Agenda.objects.exists()
|
|
assert AgendaSnapshot.objects.count() == 1
|
|
|
|
|
|
def test_agenda_api_delete_busy(app, user):
|
|
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
|
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
|
event = Event.objects.create(start_datetime=now() + datetime.timedelta(days=10), places=10, agenda=agenda)
|
|
booking = Booking.objects.create(event=event)
|
|
|
|
app.authorization = ('Basic', ('john.doe', 'password'))
|
|
resp = app.delete('/api/agenda/%s/' % agenda.slug)
|
|
assert resp.json['err'] == 1
|
|
assert 'This cannot be removed' in resp.json['err_desc']
|
|
|
|
booking.cancellation_datetime = now()
|
|
booking.save()
|
|
resp = app.delete('/api/agenda/%s/' % agenda.slug)
|
|
assert resp.json['err'] == 0
|
|
assert not Agenda.objects.exists()
|
|
|
|
|
|
@pytest.mark.freeze_time('2021-07-09T08:00:00.0+02:00')
|
|
def test_add_agenda(app, user, settings):
|
|
settings.TEMPLATE_VARS = {'eservices_url': 'http://demarches/'}
|
|
events_type = EventsType.objects.create(label='Type A')
|
|
category_a = Category.objects.create(label='Category A')
|
|
api_url = '/api/agenda/'
|
|
|
|
# no authentication
|
|
resp = app.post_json(api_url, status=401)
|
|
assert resp.json['detail'] == 'Authentication credentials were not provided.'
|
|
|
|
# wrong password
|
|
app.authorization = ('Basic', ('john.doe', 'wrong'))
|
|
resp = app.post_json(api_url, status=401)
|
|
assert resp.json['detail'] == 'Invalid username/password.'
|
|
|
|
app.authorization = ('Basic', ('john.doe', 'password'))
|
|
|
|
# missing fields
|
|
resp = app.post_json(api_url, status=400)
|
|
assert resp.json['err']
|
|
assert resp.json['errors'] == {'label': ['This field is required.'], 'slug': ['This field is required.']}
|
|
|
|
# wrong contents
|
|
params = {
|
|
'label': 'foo',
|
|
'slug': 'foo',
|
|
'kind': 'oups',
|
|
'minimal_booking_delay': 'oups',
|
|
'minimal_booking_delay_in_working_days': 'oups',
|
|
'anonymize_delay': 'oups',
|
|
'edit_role': 'oups',
|
|
'view_role': 'plop',
|
|
'category': 'oups',
|
|
'events_type': 'oups',
|
|
}
|
|
resp = app.post_json(api_url, params=params, status=400)
|
|
assert resp.json['err']
|
|
assert resp.json['errors'] == {
|
|
'kind': ['"oups" is not a valid choice.'],
|
|
'minimal_booking_delay': ['A valid integer is required.'],
|
|
'minimal_booking_delay_in_working_days': ['Must be a valid boolean.'],
|
|
'anonymize_delay': ['A valid integer is required.'],
|
|
'edit_role': ['unknown role: oups'],
|
|
'view_role': ['unknown role: plop'],
|
|
'category': ['unknown category: oups'],
|
|
'events_type': ['unknown events type: oups'],
|
|
}
|
|
|
|
# slug already used
|
|
meeting_agenda = Agenda(label='Foo bar Meeting', kind='meetings')
|
|
meeting_agenda.save()
|
|
params = {
|
|
'label': 'foo',
|
|
'slug': meeting_agenda.slug,
|
|
}
|
|
resp = app.post_json(api_url, params=params, status=400)
|
|
assert resp.json['err']
|
|
assert resp.json['errors'] == {'slug': ['agenda with this Identifier already exists.']}
|
|
|
|
# option only available on events agenda
|
|
params = {
|
|
'label': 'foo',
|
|
'slug': 'foo',
|
|
'kind': 'meetings',
|
|
'minimal_booking_delay_in_working_days': True,
|
|
}
|
|
resp = app.post_json(api_url, params=params, status=400)
|
|
assert resp.json['err']
|
|
assert resp.json['errors'] == {
|
|
'minimal_booking_delay_in_working_days': ['Option not available on meetings agenda']
|
|
}
|
|
params = {
|
|
'label': 'foo',
|
|
'slug': 'foo',
|
|
'kind': 'meetings',
|
|
'events_type': 'type-a',
|
|
}
|
|
resp = app.post_json(api_url, params=params, status=400)
|
|
assert resp.json['err']
|
|
assert resp.json['errors'] == {'events_type': ['Option not available on meetings agenda']}
|
|
|
|
# add an agenda using only required fields
|
|
params = {
|
|
'label': 'My Agenda',
|
|
'slug': 'my-agenda',
|
|
}
|
|
resp = app.post_json(api_url, params=params)
|
|
assert not resp.json['err']
|
|
assert len(resp.json['data']) == 1
|
|
agenda = Agenda.objects.get(slug='my-agenda')
|
|
assert agenda.kind == 'events'
|
|
assert agenda.partial_bookings is False
|
|
assert AgendaSnapshot.objects.count() == 1
|
|
|
|
settings.WORKING_DAY_CALENDAR = 'workalendar.europe.France'
|
|
edit_group = Group.objects.create(name='Edit')
|
|
view_group = Group.objects.create(name='View')
|
|
|
|
# add a meetings agenda
|
|
params = {
|
|
'label': 'foo Meetings',
|
|
'slug': 'foo-meetings',
|
|
'kind': 'meetings',
|
|
'minimal_booking_delay': 1,
|
|
'maximal_booking_delay': 3,
|
|
'anonymize_delay': 30,
|
|
'edit_role': 'Edit',
|
|
'view_role': 'View',
|
|
'category': 'category-a',
|
|
'mark_event_checked_auto': True,
|
|
'disable_check_update': False,
|
|
}
|
|
resp = app.post_json(api_url, params=params)
|
|
assert not resp.json['err']
|
|
assert len(resp.json['data']) == 1
|
|
agenda = Agenda.objects.get(slug='foo-meetings')
|
|
assert agenda.min_booking_datetime == localtime(now()).replace(
|
|
day=10, hour=0, minute=0, second=0, microsecond=0
|
|
)
|
|
assert agenda.minimal_booking_time == datetime.time(0)
|
|
assert agenda.edit_role == edit_group
|
|
assert agenda.view_role == view_group
|
|
assert agenda.category == category_a
|
|
assert agenda.mark_event_checked_auto is True
|
|
assert agenda.disable_check_update is False
|
|
assert not Desk.objects.filter(agenda=agenda, slug='_exceptions_holder').exists()
|
|
|
|
# add an events agenda
|
|
params = {
|
|
'label': 'foo Events',
|
|
'slug': 'foo-events',
|
|
'kind': 'events',
|
|
'minimal_booking_delay': 1,
|
|
'minimal_booking_delay_in_working_days': True,
|
|
'maximal_booking_delay': 3,
|
|
'minimal_booking_time': None,
|
|
'anonymize_delay': 30,
|
|
'edit_role': 'Edit',
|
|
'view_role': 'View',
|
|
'category': 'category-a',
|
|
'events_type': 'type-a',
|
|
'mark_event_checked_auto': False,
|
|
'disable_check_update': True,
|
|
'booking_check_filters': 'foo,bar,baz',
|
|
'booking_form_url': '{{ eservices_url }}backoffice/submission/inscription-aux-activites/',
|
|
}
|
|
resp = app.post_json(api_url, params=params)
|
|
assert not resp.json['err']
|
|
assert len(resp.json['data']) == 1
|
|
agenda = Agenda.objects.get(slug='foo-events')
|
|
assert agenda.edit_role == edit_group
|
|
assert agenda.view_role == view_group
|
|
assert agenda.min_booking_datetime == localtime(now()).replace(
|
|
day=12, hour=0, minute=0, second=0, microsecond=0
|
|
)
|
|
assert agenda.minimal_booking_time is None
|
|
assert agenda.category == category_a
|
|
assert agenda.events_type == events_type
|
|
assert agenda.mark_event_checked_auto is False
|
|
assert agenda.disable_check_update is True
|
|
assert agenda.booking_check_filters == 'foo,bar,baz'
|
|
assert agenda.booking_form_url == '{{ eservices_url }}backoffice/submission/inscription-aux-activites/'
|
|
assert Desk.objects.filter(agenda=agenda, slug='_exceptions_holder').exists()
|
|
|
|
assert (
|
|
resp.json['data'][0]['booking_form_url']
|
|
== 'http://demarches/backoffice/submission/inscription-aux-activites/'
|
|
)
|
|
|
|
resp = app.get('/api/agendas/datetimes/?agendas=%s' % agenda.slug)
|
|
assert 'data' in resp.json
|
|
|
|
|
|
def test_add_agenda_partial_bookings(app, user, settings):
|
|
app.authorization = ('Basic', ('john.doe', 'password'))
|
|
|
|
params = {
|
|
'label': 'My Agenda',
|
|
'slug': 'my-agenda',
|
|
'partial_bookings': True,
|
|
}
|
|
resp = app.post_json('/api/agenda/', params=params)
|
|
|
|
agenda = Agenda.objects.get(slug='my-agenda')
|
|
assert agenda.kind == 'events'
|
|
assert agenda.partial_bookings is True
|
|
|
|
# partial bookings meetings agenda is forbidden
|
|
params = {
|
|
'label': 'My Agenda 2',
|
|
'slug': 'my-agenda-2',
|
|
'partial_bookings': True,
|
|
'kind': 'meetings',
|
|
}
|
|
resp = app.post_json('/api/agenda/', params=params, status=400)
|
|
|
|
assert resp.json['errors'] == {'partial_bookings': ['Option not available on meetings agenda']}
|
|
|
|
|
|
@pytest.mark.freeze_time('2021-07-09T08:00:00.0+02:00')
|
|
def test_patch_agenda(app, user):
|
|
Category.objects.create(label='Category A')
|
|
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
|
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
|
|
|
app.authorization = ('Basic', ('john.doe', 'password'))
|
|
|
|
resp = app.patch_json('/api/agenda/%s/' % agenda.slug)
|
|
assert resp.json['data']['id'] == 'foo-bar'
|
|
assert resp.json['data']['text'] == 'Foo bar'
|
|
assert resp.json['data']['kind'] == 'events'
|
|
assert resp.json['data']['category'] is None
|
|
assert AgendaSnapshot.objects.count() == 1
|
|
|
|
resp = app.patch_json('/api/agenda/%s/' % agenda.slug, params={'label': 'Test', 'kind': 'events'})
|
|
assert resp.json['data']['id'] == 'foo-bar'
|
|
assert resp.json['data']['text'] == 'Test'
|
|
assert resp.json['data']['kind'] == 'events'
|
|
|
|
resp = app.patch_json('/api/agenda/%s/' % agenda.slug, params={'category': 'category-a'})
|
|
assert resp.json['data']['id'] == 'foo-bar'
|
|
assert resp.json['data']['category'] == 'category-a'
|
|
|
|
# changing kind is forbidden
|
|
resp = app.patch_json('/api/agenda/%s/' % agenda.slug, params={'kind': 'meetings'}, status=400)
|
|
assert resp.json['err'] == 1
|
|
assert resp.json['err_desc'] == 'it is not possible to change kind value'
|
|
|
|
# unkwown category
|
|
resp = app.patch_json('/api/agenda/%s/' % agenda.slug, params={'category': 'xxx'}, status=400)
|
|
assert resp.json['err'] == 1
|