730 lines
27 KiB
Python
730 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 django.utils.timezone import localtime, now
|
|
|
|
from chrono.agendas.models import (
|
|
AbsenceReason,
|
|
AbsenceReasonGroup,
|
|
Agenda,
|
|
Category,
|
|
Desk,
|
|
Event,
|
|
MeetingType,
|
|
Resource,
|
|
TimePeriodException,
|
|
VirtualMember,
|
|
)
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
|
|
def test_agendas_api(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')
|
|
group = AbsenceReasonGroup.objects.create(label='Foo')
|
|
reason = AbsenceReason.objects.create(group=group, label='Foo bar')
|
|
reason2 = AbsenceReason.objects.create(group=group, label='Foo bar baz')
|
|
event_agenda = Agenda.objects.create(
|
|
label='Foo bar', category=category_a, absence_reasons_group=group, 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)
|
|
Desk.objects.create(agenda=event_agenda2, slug='_exceptions_holder')
|
|
event_agenda3 = Agenda.objects.create(label='Foo bar 3', absence_reasons_group=group)
|
|
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
|
|
)
|
|
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)
|
|
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,
|
|
'edit_role': 'Edit',
|
|
'view_role': None,
|
|
'category': 'category-a',
|
|
'absence_reasons': [
|
|
{'id': reason.slug, 'slug': reason.slug, 'text': reason.label, 'label': reason.label},
|
|
{'id': reason2.slug, 'slug': reason2.slug, 'text': reason2.label, 'label': reason2.label},
|
|
],
|
|
'api': {
|
|
'datetimes_url': 'http://testserver/api/agenda/foo-bar/datetimes/',
|
|
'fillslots_url': 'http://testserver/api/agenda/foo-bar/fillslots/',
|
|
},
|
|
},
|
|
{
|
|
'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,
|
|
'edit_role': None,
|
|
'view_role': None,
|
|
'category': 'category-a',
|
|
'api': {
|
|
'datetimes_url': 'http://testserver/api/agenda/foo-bar-2/datetimes/',
|
|
'fillslots_url': 'http://testserver/api/agenda/foo-bar-2/fillslots/',
|
|
},
|
|
},
|
|
{
|
|
'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,
|
|
'edit_role': None,
|
|
'view_role': None,
|
|
'category': None,
|
|
'absence_reasons': [
|
|
{'id': reason.slug, 'slug': reason.slug, 'text': reason.label, 'label': reason.label},
|
|
{'id': reason2.slug, 'slug': reason2.slug, 'text': reason2.label, 'label': reason2.label},
|
|
],
|
|
'api': {
|
|
'datetimes_url': 'http://testserver/api/agenda/foo-bar-3/datetimes/',
|
|
'fillslots_url': 'http://testserver/api/agenda/foo-bar-3/fillslots/',
|
|
},
|
|
},
|
|
{
|
|
'text': 'Foo bar Meeting',
|
|
'id': 'foo-bar-meeting',
|
|
'slug': 'foo-bar-meeting',
|
|
'minimal_booking_delay': 1,
|
|
'maximal_booking_delay': 56,
|
|
'edit_role': None,
|
|
'view_role': 'View',
|
|
'category': '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/',
|
|
'fillslots_url': 'http://testserver/api/agenda/foo-bar-meeting/fillslots/',
|
|
},
|
|
},
|
|
{
|
|
'text': 'Foo bar Meeting 2',
|
|
'id': 'foo-bar-meeting-2',
|
|
'slug': 'foo-bar-meeting-2',
|
|
'minimal_booking_delay': 1,
|
|
'maximal_booking_delay': 56,
|
|
'edit_role': None,
|
|
'view_role': None,
|
|
'category': 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/',
|
|
'fillslots_url': 'http://testserver/api/agenda/foo-bar-meeting-2/fillslots/',
|
|
},
|
|
},
|
|
{
|
|
'text': 'Virtual Agenda',
|
|
'id': 'virtual-agenda',
|
|
'slug': 'virtual-agenda',
|
|
'minimal_booking_delay': 1,
|
|
'maximal_booking_delay': 56,
|
|
'edit_role': 'Edit',
|
|
'view_role': 'View',
|
|
'category': None,
|
|
'kind': 'virtual',
|
|
'api': {
|
|
'meetings_url': 'http://testserver/api/agenda/virtual-agenda/meetings/',
|
|
'desks_url': 'http://testserver/api/agenda/virtual-agenda/desks/',
|
|
'fillslots_url': 'http://testserver/api/agenda/virtual-agenda/fillslots/',
|
|
},
|
|
},
|
|
],
|
|
}
|
|
|
|
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) == 4
|
|
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()
|
|
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.objects.create(
|
|
start_datetime=now(),
|
|
places=10,
|
|
agenda=event_agenda,
|
|
recurrence_days=list(range(7)),
|
|
)
|
|
assert len(event_agenda.get_open_events()) == 2
|
|
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
|
|
assert len(resp.json['data']) == 1
|
|
|
|
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.objects.create(
|
|
start_datetime=now(), places=10, agenda=event_agenda, recurrence_days=[now().weekday()]
|
|
)
|
|
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) == 8
|
|
|
|
|
|
def test_agendas_meetingtypes_api(app, some_data, meetings_agenda):
|
|
resp = app.get('/api/agenda/%s/meetings/' % meetings_agenda.slug)
|
|
expected_resp = {
|
|
'data': [
|
|
{
|
|
'text': 'Blah',
|
|
'id': 'blah',
|
|
'duration': 30,
|
|
'api': {
|
|
'datetimes_url': 'http://testserver/api/agenda/foo-bar-meeting/meetings/blah/datetimes/',
|
|
},
|
|
}
|
|
]
|
|
}
|
|
assert resp.json == expected_resp
|
|
|
|
# deleted meeting type does not show up
|
|
MeetingType.objects.create(agenda=meetings_agenda, slug='deleted-meeting-type', duration=43, deleted=True)
|
|
resp = app.get('/api/agenda/%s/meetings/' % meetings_agenda.slug)
|
|
assert resp.json == expected_resp
|
|
|
|
# wrong kind
|
|
agenda1 = Agenda.objects.filter(label='Foo bar')[0]
|
|
resp = app.get('/api/agenda/%s/meetings/' % agenda1.slug, status=404)
|
|
|
|
# unknown
|
|
resp = app.get('/api/agenda/xxxx/meetings/', status=404)
|
|
|
|
|
|
def test_agendas_meetingtype_api(app):
|
|
agenda = Agenda.objects.create(label='Foo bar meeting', kind='meetings')
|
|
MeetingType.objects.create(agenda=agenda, label='Blah', duration=30)
|
|
resp = app.get('/api/agenda/%s/meetings/blah/' % agenda.slug)
|
|
assert resp.json == {
|
|
'data': {
|
|
'text': 'Blah',
|
|
'id': 'blah',
|
|
'duration': 30,
|
|
'api': {
|
|
'datetimes_url': 'http://testserver/api/agenda/foo-bar-meeting/meetings/blah/datetimes/',
|
|
},
|
|
}
|
|
}
|
|
|
|
# unknown
|
|
resp = app.get('/api/agenda/xxxx/meetings/', status=404)
|
|
resp = app.get('/api/agenda/%s/meetings/xxxx/' % agenda.slug, status=404)
|
|
|
|
# wrong kind
|
|
agenda.kind = 'virtual'
|
|
agenda.save()
|
|
resp = app.get('/api/agenda/%s/resources/' % agenda.slug, status=404)
|
|
agenda.kind = 'events'
|
|
agenda.save()
|
|
resp = app.get('/api/agenda/%s/resources/' % agenda.slug, status=404)
|
|
|
|
|
|
def test_agendas_desks_api(app):
|
|
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
|
|
Desk.objects.create(agenda=agenda, label='Desk 1')
|
|
resp = app.get('/api/agenda/%s/desks/' % agenda.slug)
|
|
assert resp.json == {
|
|
'data': [
|
|
{
|
|
'text': 'Desk 1',
|
|
'id': 'desk-1',
|
|
}
|
|
]
|
|
}
|
|
|
|
# unknown
|
|
resp = app.get('/api/agenda/xxxx/resources/', status=404)
|
|
|
|
# wrong kind
|
|
agenda.kind = 'virtual'
|
|
agenda.save()
|
|
resp = app.get('/api/agenda/%s/resources/' % agenda.slug, status=404)
|
|
agenda.kind = 'events'
|
|
agenda.save()
|
|
resp = app.get('/api/agenda/%s/resources/' % agenda.slug, status=404)
|
|
|
|
|
|
def test_agendas_resources_api(app):
|
|
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
|
|
resource1 = Resource.objects.create(label='Resource 1', description='Foo bar Resource 1')
|
|
resource2 = Resource.objects.create(label='Resource 2')
|
|
agenda.resources.add(resource1, resource2)
|
|
resp = app.get('/api/agenda/%s/resources/' % agenda.slug)
|
|
assert resp.json == {
|
|
'data': [
|
|
{
|
|
'text': 'Resource 1',
|
|
'id': 'resource-1',
|
|
'description': 'Foo bar Resource 1',
|
|
},
|
|
{
|
|
'text': 'Resource 2',
|
|
'id': 'resource-2',
|
|
'description': '',
|
|
},
|
|
]
|
|
}
|
|
|
|
# unknown
|
|
resp = app.get('/api/agenda/xxxx/resources/', status=404)
|
|
|
|
# wrong kind
|
|
agenda.kind = 'virtual'
|
|
agenda.save()
|
|
resp = app.get('/api/agenda/%s/resources/' % agenda.slug, status=404)
|
|
agenda.kind = 'events'
|
|
agenda.save()
|
|
resp = app.get('/api/agenda/%s/resources/' % agenda.slug, status=404)
|
|
|
|
|
|
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()
|
|
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,
|
|
'edit_role': None,
|
|
'view_role': None,
|
|
'category': 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,
|
|
'fillslots_url': 'http://testserver/api/agenda/%s/fillslots/' % virtual_meetings_agenda.slug,
|
|
},
|
|
},
|
|
}
|
|
|
|
|
|
def test_virtual_agendas_meetingtypes_api(app):
|
|
virt_agenda = Agenda.objects.create(label='Virtual agenda', kind='virtual')
|
|
|
|
# No meetings because no real agenda
|
|
resp = app.get('/api/agenda/%s/meetings/' % virt_agenda.slug)
|
|
assert resp.json == {'data': []}
|
|
|
|
# One real agenda : every meetings exposed
|
|
foo_agenda = Agenda.objects.create(label='Foo', kind='meetings')
|
|
MeetingType.objects.create(agenda=foo_agenda, label='Meeting1', duration=30)
|
|
MeetingType.objects.create(agenda=foo_agenda, label='Meeting2', duration=15)
|
|
VirtualMember.objects.create(virtual_agenda=virt_agenda, real_agenda=foo_agenda)
|
|
resp = app.get('/api/agenda/%s/meetings/' % virt_agenda.slug)
|
|
assert resp.json == {
|
|
'data': [
|
|
{
|
|
'text': 'Meeting1',
|
|
'id': 'meeting1',
|
|
'duration': 30,
|
|
'api': {
|
|
'datetimes_url': 'http://testserver/api/agenda/virtual-agenda/meetings/meeting1/datetimes/',
|
|
},
|
|
},
|
|
{
|
|
'text': 'Meeting2',
|
|
'id': 'meeting2',
|
|
'duration': 15,
|
|
'api': {
|
|
'datetimes_url': 'http://testserver/api/agenda/virtual-agenda/meetings/meeting2/datetimes/',
|
|
},
|
|
},
|
|
]
|
|
}
|
|
|
|
# Several real agendas
|
|
|
|
bar_agenda = Agenda.objects.create(label='Bar', kind='meetings')
|
|
MeetingType.objects.create(agenda=bar_agenda, label='Meeting Bar', duration=30)
|
|
VirtualMember.objects.create(virtual_agenda=virt_agenda, real_agenda=bar_agenda)
|
|
|
|
# Bar agenda has no meeting type: no meetings exposed
|
|
resp = app.get('/api/agenda/%s/meetings/' % virt_agenda.slug)
|
|
assert resp.json == {'data': []}
|
|
|
|
# Bar agenda has a meetings wih different label, slug, duration: no meetings exposed
|
|
mt = MeetingType.objects.create(agenda=bar_agenda, label='Meeting Type Bar', duration=15)
|
|
resp = app.get('/api/agenda/%s/meetings/' % virt_agenda.slug)
|
|
assert resp.json == {'data': []}
|
|
|
|
# Bar agenda has a meetings wih same label, but different slug and duration: no meetings exposed
|
|
mt.label = 'Meeting1'
|
|
mt.save()
|
|
resp = app.get('/api/agenda/%s/meetings/' % virt_agenda.slug)
|
|
assert resp.json == {'data': []}
|
|
|
|
# Bar agenda has a meetings wih same label and slug, but different duration: no meetings exposed
|
|
mt.slug = 'meeting1'
|
|
mt.save()
|
|
resp = app.get('/api/agenda/%s/meetings/' % virt_agenda.slug)
|
|
assert resp.json == {'data': []}
|
|
|
|
# Bar agenda has a meetings wih same label, slug and duration: only this meeting exposed
|
|
mt.duration = 30
|
|
mt.save()
|
|
resp = app.get('/api/agenda/%s/meetings/' % virt_agenda.slug)
|
|
assert resp.json == {
|
|
'data': [
|
|
{
|
|
'text': 'Meeting1',
|
|
'id': 'meeting1',
|
|
'duration': 30,
|
|
'api': {
|
|
'datetimes_url': 'http://testserver/api/agenda/virtual-agenda/meetings/meeting1/datetimes/',
|
|
},
|
|
},
|
|
]
|
|
}
|
|
|
|
|
|
@pytest.mark.freeze_time('2021-07-09')
|
|
def test_add_agenda(app, user, settings):
|
|
category_a = Category.objects.create(label='Category A')
|
|
api_url = '/api/agenda/'
|
|
|
|
# no authentication
|
|
resp = app.post(api_url, status=401)
|
|
assert resp.json['detail'] == 'Authentication credentials were not provided.'
|
|
|
|
# wrong password
|
|
app.authorization = ('Basic', ('john.doe', 'wrong'))
|
|
resp = app.post(api_url, status=401)
|
|
assert resp.json['detail'] == 'Invalid username/password.'
|
|
|
|
app.authorization = ('Basic', ('john.doe', 'password'))
|
|
|
|
# missing fields
|
|
resp = app.post(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',
|
|
}
|
|
resp = app.post(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'],
|
|
}
|
|
|
|
# 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(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(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']
|
|
}
|
|
|
|
# add an agenda using only required fields
|
|
params = {
|
|
'label': 'My Agenda',
|
|
'slug': 'my-agenda',
|
|
}
|
|
resp = app.post(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'
|
|
|
|
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',
|
|
}
|
|
resp = app.post(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.date() == datetime.date(2021, 7, 10)
|
|
assert agenda.edit_role == edit_group
|
|
assert agenda.view_role == view_group
|
|
assert agenda.category == category_a
|
|
|
|
# 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,
|
|
'anonymize_delay': 30,
|
|
'edit_role': 'Edit',
|
|
'view_role': 'View',
|
|
'category': 'category-a',
|
|
}
|
|
resp = app.post(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.date() == datetime.date(2021, 7, 12)
|
|
assert agenda.category == category_a
|