chrono/tests/test_import_export.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1364 lines
51 KiB
Python
Raw Permalink Normal View History

import copy
import datetime
import json
import os
import shutil
import sys
import tempfile
2019-09-21 22:36:08 +02:00
from io import StringIO
from unittest import mock
import pytest
from django.contrib.auth.models import Group
from django.core.files.base import ContentFile
from django.core.management import CommandError, call_command
from django.test import override_settings
from django.utils.encoding import force_bytes
from chrono.agendas.models import (
Agenda,
AgendaImportError,
AgendaNotificationsSettings,
AgendaReminderSettings,
2020-07-24 15:59:49 +02:00
Category,
Desk,
Event,
EventsType,
MeetingType,
Resource,
SharedCustodySettings,
TimePeriod,
TimePeriodException,
TimePeriodExceptionSource,
UnavailabilityCalendar,
VirtualMember,
)
from chrono.manager.utils import import_site
from chrono.utils.timezone import make_aware, now
from .test_agendas import ICS_SAMPLE, ICS_SAMPLE_WITH_NO_EVENTS
pytestmark = pytest.mark.django_db
def get_output_of_command(command, *args, **kwargs):
old_stdout = sys.stdout
output = sys.stdout = StringIO()
call_command(command, *args, **kwargs)
sys.stdout = old_stdout
return output.getvalue()
2020-07-21 16:38:14 +02:00
def test_import_export(app):
agenda_events = Agenda.objects.create(label='Events Agenda', kind='events')
first_event = Event.objects.create(
agenda=agenda_events, start_datetime=make_aware(datetime.datetime(2020, 7, 21, 16, 42, 35)), places=10
)
agenda_meetings = Agenda.objects.create(label='Meetings Agenda', kind='meetings')
MeetingType.objects.create(agenda=agenda_meetings, label='Meeting Type', duration=30)
desk = Desk.objects.create(agenda=agenda_meetings, label='Desk')
exceptions_desk = Desk.objects.create(agenda=agenda_events, slug='_exceptions_holder')
tpx_start = make_aware(datetime.datetime(2017, 5, 22, 8, 0))
tpx_end = make_aware(datetime.datetime(2017, 5, 22, 12, 30))
TimePeriodException.objects.create(desk=desk, start_datetime=tpx_start, end_datetime=tpx_end)
TimePeriodException.objects.create(desk=exceptions_desk, start_datetime=tpx_start, end_datetime=tpx_end)
TimePeriod.objects.create(
desk=desk, weekday=2, start_time=tpx_start.time(), end_time=tpx_end.time(), weekday_indexes=[1, 3]
)
TimePeriod.objects.create(
desk=desk, date=datetime.date(2022, 10, 24), start_time=tpx_start.time(), end_time=tpx_end.time()
)
output = get_output_of_command('export_site')
2020-07-21 16:38:14 +02:00
assert len(json.loads(output)['agendas']) == 2
import_site(data={}, clean=True)
empty_output = get_output_of_command('export_site')
assert len(json.loads(empty_output)['agendas']) == 0
Agenda(label='test').save()
old_stdin = sys.stdin
sys.stdin = StringIO(json.dumps({}))
assert Agenda.objects.count() == 1
try:
call_command('import_site', '-', clean=True)
finally:
sys.stdin = old_stdin
assert Agenda.objects.count() == 0
with tempfile.NamedTemporaryFile() as f:
f.write(force_bytes(output))
f.flush()
call_command('import_site', f.name)
2020-07-21 16:38:14 +02:00
assert Agenda.objects.count() == 2
first_imported_event = Agenda.objects.get(label='Events Agenda').event_set.first()
assert first_imported_event.start_datetime == first_event.start_datetime
assert TimePeriodException.objects.get(desk__agenda__kind='meetings').start_datetime == tpx_start
assert TimePeriodException.objects.get(desk__agenda__kind='meetings').end_datetime == tpx_end
assert TimePeriodException.objects.get(desk__agenda__kind='events').start_datetime == tpx_start
assert TimePeriodException.objects.get(desk__agenda__kind='events').end_datetime == tpx_end
assert TimePeriod.objects.filter(weekday_indexes=[1, 3]).count() == 1
assert TimePeriod.objects.filter(date=datetime.date(2022, 10, 24)).count() == 1
2020-07-21 16:38:14 +02:00
agenda1 = Agenda.objects.get(label='Events Agenda')
agenda2 = Agenda.objects.get(label='Meetings Agenda')
event = Event(agenda=agenda1, start_datetime=now(), places=10)
event.save()
2017-09-01 15:01:07 +02:00
desk, _ = Desk.objects.get_or_create(agenda=agenda2, label='Desk A', slug='desk-a')
timeperiod = TimePeriod(
desk=desk, weekday=2, start_time=datetime.time(10, 0), end_time=datetime.time(11, 0)
)
timeperiod.save()
exception = TimePeriodException(
desk=desk,
start_datetime=make_aware(datetime.datetime(2017, 5, 22, 8, 0)),
end_datetime=make_aware(datetime.datetime(2017, 5, 22, 12, 30)),
)
exception.save()
import_site(json.loads(output), overwrite=True)
assert Event.objects.filter(id=event.id).count() == 0
2017-09-01 15:01:07 +02:00
assert Desk.objects.filter(slug='desk-a').count() == 0
assert TimePeriod.objects.filter(id=timeperiod.id).count() == 0
assert TimePeriodException.objects.filter(id=exception.id).count() == 0
2020-07-21 16:38:14 +02:00
event = Event(agenda=agenda1, start_datetime=now(), places=10)
event.save()
desk, _ = Desk.objects.get_or_create(agenda=agenda2, label='Desk A', slug='desk-a')
timeperiod = TimePeriod(
weekday=2, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(11, 0)
)
timeperiod.save()
exception = TimePeriodException(
desk=desk,
start_datetime=make_aware(datetime.datetime(2017, 5, 22, 8, 0)),
end_datetime=make_aware(datetime.datetime(2017, 5, 22, 12, 30)),
)
exception.save()
import_site(json.loads(output), overwrite=False)
assert Event.objects.filter(id=event.id).count() == 1
assert TimePeriod.objects.filter(id=timeperiod.id).count() == 1
assert TimePeriodException.objects.filter(id=exception.id).count() == 1
import_site(data={}, if_empty=True)
2020-07-21 16:38:14 +02:00
assert Agenda.objects.count() == 2
import_site(data={}, clean=True)
tempdir = tempfile.mkdtemp('chrono-test')
empty_output = get_output_of_command('export_site', output=os.path.join(tempdir, 't.json'))
assert os.path.exists(os.path.join(tempdir, 't.json'))
shutil.rmtree(tempdir)
def test_import_export_bad_date_format(app):
agenda_events = Agenda.objects.create(label='Events Agenda', kind='events')
Desk.objects.create(agenda=agenda_events, slug='_exceptions_holder')
Event.objects.create(
agenda=agenda_events, start_datetime=make_aware(datetime.datetime(2020, 7, 21, 16, 42, 35)), places=10
)
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['agendas']) == 1
payload['agendas'][0]['events'][0]['start_datetime'] = '20-07-21 16:42:00'
with pytest.raises(AgendaImportError) as excinfo:
import_site(payload)
assert '%s' % excinfo.value == 'Bad datetime format "20-07-21 16:42:00"'
Agenda.objects.all().delete()
agenda_meetings = Agenda.objects.create(label='Meetings Agenda', kind='meetings')
desk = Desk.objects.create(agenda=agenda_meetings, label='Desk')
tpx_start = make_aware(datetime.datetime(2017, 5, 22, 8, 0))
tpx_end = make_aware(datetime.datetime(2017, 5, 22, 12, 30))
TimePeriodException.objects.create(desk=desk, start_datetime=tpx_start, end_datetime=tpx_end)
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['agendas']) == 1
payload['agendas'][0]['desks'][0]['exceptions'][0]['start_datetime'] = '17-05-22 08:00:00'
with pytest.raises(AgendaImportError) as excinfo:
import_site(payload)
assert '%s' % excinfo.value == 'Bad datetime format "17-05-22 08:00:00"'
def test_import_export_bad_end_time_format(app):
agenda_events = Agenda.objects.create(label='Events Agenda', kind='events')
Desk.objects.create(agenda=agenda_events, slug='_exceptions_holder')
Event.objects.create(
agenda=agenda_events,
start_datetime=make_aware(datetime.datetime(2020, 7, 21, 16, 42, 35)),
places=10,
end_time=datetime.time(20, 00),
)
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['agendas']) == 1
payload['agendas'][0]['events'][0]['end_time'] = 'xxx20:00'
with pytest.raises(AgendaImportError) as excinfo:
import_site(payload)
assert '%s' % excinfo.value == 'Bad time format "xxx20:00"'
def test_import_export_events_agenda_options(app):
agenda = Agenda.objects.create(
label='Foo Bar',
kind='events',
default_view='open_events',
anonymize_delay=42,
booking_form_url='{{ eservices_url }}backoffice/submission/inscription-aux-activites/',
minimal_booking_delay_in_working_days=True,
booking_user_block_template='foo bar',
booking_check_filters='foo,bar',
event_display_template='foo bar',
mark_event_checked_auto=True,
disable_check_update=True,
enable_check_for_future_events=True,
booking_extra_user_block_template='foobar',
)
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
output = get_output_of_command('export_site')
assert len(json.loads(output)['agendas']) == 1
import_site(data={}, clean=True)
with tempfile.NamedTemporaryFile() as f:
f.write(force_bytes(output))
f.flush()
call_command('import_site', f.name)
assert Agenda.objects.count() == 1
agenda = Agenda.objects.first()
assert agenda.default_view == 'open_events'
assert agenda.anonymize_delay == 42
assert agenda.booking_form_url == '{{ eservices_url }}backoffice/submission/inscription-aux-activites/'
assert agenda.minimal_booking_delay_in_working_days is True
assert agenda.booking_user_block_template == 'foo bar'
assert agenda.booking_check_filters == 'foo,bar'
assert agenda.event_display_template == 'foo bar'
assert agenda.mark_event_checked_auto is True
assert agenda.disable_check_update is True
assert agenda.enable_check_for_future_events is True
assert agenda.booking_extra_user_block_template == 'foobar'
agenda.partial_bookings = True
agenda.invoicing_tolerance = 5
agenda.invoicing_unit = 'minute'
agenda.save()
output = get_output_of_command('export_site')
assert len(json.loads(output)['agendas']) == 1
import_site(data={}, clean=True)
with tempfile.NamedTemporaryFile() as f:
f.write(force_bytes(output))
f.flush()
call_command('import_site', f.name)
assert Agenda.objects.count() == 1
agenda = Agenda.objects.first()
assert agenda.partial_bookings is True
assert agenda.invoicing_tolerance == 5
assert agenda.invoicing_unit == 'minute'
2020-07-21 16:38:14 +02:00
def test_import_export_event_details(app):
events_type = EventsType.objects.create(
label='Foo',
custom_fields=[
{'varname': 'text', 'label': 'Text', 'field_type': 'text'},
{'varname': 'textarea', 'label': 'TextArea', 'field_type': 'textarea'},
{'varname': 'bool', 'label': 'Bool', 'field_type': 'bool'},
],
)
agenda = Agenda.objects.create(label='Foo Bar', kind='events', events_type=events_type)
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
2020-07-21 16:38:14 +02:00
Event.objects.create(
2021-05-11 14:20:14 +02:00
slug='event',
2020-07-21 16:38:14 +02:00
agenda=agenda,
description='description',
pricing='100',
url='https://example.net/',
publication_datetime=make_aware(datetime.datetime(2020, 5, 11)),
2020-07-21 16:38:14 +02:00
places=42,
start_datetime=now(),
end_time=datetime.time(20, 00),
duration=30,
custom_fields={
'text': 'foo',
'textarea': 'foo bar',
'bool': True,
},
2020-07-21 16:38:14 +02:00
)
2021-05-11 14:20:14 +02:00
# check event (agenda, slug) unicity
agenda2 = Agenda.objects.create(label='Foo Bar 2', kind='events')
Desk.objects.create(agenda=agenda2, slug='_exceptions_holder')
2021-05-11 14:20:14 +02:00
Event.objects.create(
slug='event',
agenda=agenda2,
places=42,
start_datetime=now(),
)
output = get_output_of_command('export_site')
2021-05-11 14:20:14 +02:00
assert len(json.loads(output)['agendas']) == 2
import_site(data={}, clean=True)
with tempfile.NamedTemporaryFile() as f:
f.write(force_bytes(output))
f.flush()
call_command('import_site', f.name)
2021-05-11 14:20:14 +02:00
assert Agenda.objects.count() == 2
assert Event.objects.count() == 2
2020-07-21 16:38:14 +02:00
first_imported_event = Agenda.objects.get(label='Foo Bar').event_set.first()
2021-05-11 14:20:14 +02:00
assert first_imported_event.slug == 'event'
assert first_imported_event.description == 'description'
assert first_imported_event.pricing == '100'
assert first_imported_event.url == 'https://example.net/'
assert str(first_imported_event.publication_datetime) == '2020-05-10 22:00:00+00:00'
assert str(first_imported_event.publication_datetime.tzinfo) == 'UTC'
assert first_imported_event.duration == 30
assert first_imported_event.end_time == datetime.time(20, 00)
assert first_imported_event.custom_fields == {
'text': 'foo',
'textarea': 'foo bar',
'bool': True,
}
2021-05-11 14:20:14 +02:00
assert Agenda.objects.get(label='Foo Bar 2').event_set.first().slug == 'event'
def test_import_export_recurring_event(app, freezer):
freezer.move_to('2021-01-12 12:10')
events_type = EventsType.objects.create(
label='Foo',
custom_fields=[
{'varname': 'text', 'label': 'Text', 'field_type': 'text'},
{'varname': 'textarea', 'label': 'TextArea', 'field_type': 'textarea'},
{'varname': 'bool', 'label': 'Bool', 'field_type': 'bool'},
],
)
agenda = Agenda.objects.create(label='Foo Bar', kind='events', events_type=events_type)
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
event = Event.objects.create(
agenda=agenda,
start_datetime=now(),
end_time=datetime.time(20, 00),
recurrence_days=[now().isoweekday()],
recurrence_week_interval=2,
places=10,
slug='test',
custom_fields={
'text': 'foo',
'textarea': 'foo bar',
'bool': True,
},
)
assert Event.objects.count() == 1
output = get_output_of_command('export_site')
assert len(json.loads(output)['agendas']) == 1
import_site(data={}, clean=True)
with tempfile.NamedTemporaryFile() as f:
f.write(force_bytes(output))
f.flush()
call_command('import_site', f.name)
assert Agenda.objects.count() == 1
assert Event.objects.count() == 28
event = Agenda.objects.get(label='Foo Bar').event_set.filter(primary_event__isnull=True).get()
assert event.recurrence_days == [now().isoweekday()]
assert event.recurrence_week_interval == 2
# importing event with end recurrence date removes recurrences
event.recurrence_end_date = now() + datetime.timedelta(days=7)
event.recurrence_week_interval = 1
event.save()
output = get_output_of_command('export_site')
import_site(data={}, clean=True)
with tempfile.NamedTemporaryFile() as f:
f.write(force_bytes(output))
f.flush()
call_command('import_site', f.name)
event = Event.objects.get(slug='test')
assert Event.objects.filter(primary_event=event).count() == 1
first_event = event.recurrences.first()
assert first_event.custom_fields == {
'text': 'foo',
'textarea': 'foo bar',
'bool': True,
}
first_event.custom_fields = {}
first_event.save()
# import again
with tempfile.NamedTemporaryFile() as f:
f.write(force_bytes(output))
f.flush()
call_command('import_site', f.name)
event = Event.objects.get(slug='test')
assert Event.objects.filter(primary_event=event).count() == 1
first_event2 = event.recurrences.first()
assert first_event.pk == first_event2.pk
assert first_event2.custom_fields == {
'text': 'foo',
'textarea': 'foo bar',
'bool': True,
}
# import again but change places
payload = json.loads(output)
payload['agendas'][0]['events'][0]['places'] = 42
with tempfile.NamedTemporaryFile() as f:
f.write(force_bytes(json.dumps(payload)))
f.flush()
call_command('import_site', f.name)
event = Event.objects.get(slug='test')
assert event.places == 42
assert event.end_time == datetime.time(20, 00)
assert Event.objects.filter(primary_event=event, places=42).count() == 1
def test_import_export_meetings_agenda_options(app):
agenda = Agenda.objects.create(
label='Foo Bar',
kind='meetings',
default_view='month',
)
output = get_output_of_command('export_site')
assert len(json.loads(output)['agendas']) == 1
import_site(data={}, clean=True)
with tempfile.NamedTemporaryFile() as f:
f.write(force_bytes(output))
f.flush()
call_command('import_site', f.name)
assert Agenda.objects.count() == 1
agenda = Agenda.objects.first()
assert agenda.default_view == 'month'
2020-07-21 16:38:14 +02:00
def test_import_export_permissions(app):
meetings_agenda = Agenda.objects.create(label='Foo Bar', kind='meetings')
group1 = Group.objects.create(name='gé1')
group2 = Group.objects.create(name='gé2')
meetings_agenda.view_role = group1
meetings_agenda.edit_role = group2
meetings_agenda.save()
output = get_output_of_command('export_site')
2020-07-21 16:38:14 +02:00
assert len(json.loads(output)['agendas']) == 1
import_site(data={}, clean=True)
assert Agenda.objects.count() == 0
Group.objects.all().delete()
with pytest.raises(AgendaImportError) as excinfo:
import_site(json.loads(output), overwrite=True)
assert 'gé1' in str(excinfo.value) and 'gé2' in str(excinfo.value)
group1 = Group(name='gé1')
group1.save()
with pytest.raises(AgendaImportError) as excinfo:
import_site(json.loads(output), overwrite=True)
assert '%s' % excinfo.value == 'Missing roles: "gé2"'
with tempfile.NamedTemporaryFile() as f:
f.write(force_bytes(output))
f.flush()
with pytest.raises(CommandError) as excinfo:
call_command('import_site', f.name)
assert '%s' % excinfo.value == 'Missing roles: "gé2"'
group2 = Group(name='gé2')
group2.save()
import_site(json.loads(output), overwrite=True)
agenda = Agenda.objects.get(slug=meetings_agenda.slug)
assert agenda.view_role == group1
assert agenda.edit_role == group2
def test_import_export_agenda_with_resources(app):
2020-07-21 16:38:14 +02:00
meetings_agenda = Agenda.objects.create(label='Foo Bar', kind='meetings')
resource = Resource.objects.create(label='foo')
meetings_agenda.resources.add(resource)
output = get_output_of_command('export_site')
import_site(data={}, clean=True)
assert Agenda.objects.count() == 0
assert Resource.objects.count() == 0
data = json.loads(output)
del data['resources']
with pytest.raises(AgendaImportError) as excinfo:
import_site(data, overwrite=True)
assert str(excinfo.value) == 'Missing "foo" resource'
Resource.objects.create(label='foobar')
with pytest.raises(AgendaImportError) as excinfo:
import_site(data, overwrite=True)
assert str(excinfo.value) == 'Missing "foo" resource'
resource = Resource.objects.create(label='foo')
import_site(data, overwrite=True)
agenda = Agenda.objects.get(slug=meetings_agenda.slug)
assert list(agenda.resources.all()) == [resource]
def test_import_export_agenda_with_category(app):
2020-07-24 15:59:49 +02:00
category = Category.objects.create(label='foo')
agenda = Agenda.objects.create(label='Foo Bar', category=category)
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
2020-07-24 15:59:49 +02:00
output = get_output_of_command('export_site')
import_site(data={}, clean=True)
assert Agenda.objects.count() == 0
assert Category.objects.count() == 0
data = json.loads(output)
del data['categories']
2020-07-24 15:59:49 +02:00
import_site(data.copy(), overwrite=True)
agenda = Agenda.objects.get(slug=agenda.slug)
assert agenda.category is None
2020-07-24 15:59:49 +02:00
category = Category.objects.create(label='foobar')
import_site(data.copy(), overwrite=True)
agenda = Agenda.objects.get(slug=agenda.slug)
assert agenda.category is None
2020-07-24 15:59:49 +02:00
category = Category.objects.create(label='foo')
import_site(data.copy(), overwrite=True)
2020-07-24 15:59:49 +02:00
agenda = Agenda.objects.get(slug=agenda.slug)
assert agenda.category == category
def test_import_export_agenda_with_events_type(app):
events_type = EventsType.objects.create(label='foo')
agenda = Agenda.objects.create(label='Foo Bar', kind='events', events_type=events_type)
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
output = get_output_of_command('export_site')
import_site(data={}, clean=True)
assert Agenda.objects.count() == 0
assert EventsType.objects.count() == 0
data = json.loads(output)
del data['events_types']
with pytest.raises(AgendaImportError) as excinfo:
import_site(data, overwrite=True)
assert str(excinfo.value) == 'Missing "foo" events type'
EventsType.objects.create(label='foobar')
with pytest.raises(AgendaImportError) as excinfo:
import_site(data, overwrite=True)
assert str(excinfo.value) == 'Missing "foo" events type'
events_type = EventsType.objects.create(label='foo')
import_site(data, overwrite=True)
agenda = Agenda.objects.get(slug=agenda.slug)
assert agenda.events_type == events_type
def test_import_export_virtual_agenda(app):
virtual_agenda = Agenda.objects.create(label='Virtual Agenda', kind='virtual')
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['agendas']) == 1
virtual_agenda.delete()
import_site(json.loads(output), overwrite=True)
virtual_agenda = Agenda.objects.get(label='Virtual Agenda', slug='virtual-agenda', kind='virtual')
assert virtual_agenda.minimal_booking_delay is None
assert virtual_agenda.maximal_booking_delay is None
assert virtual_agenda.real_agendas.count() == 0
assert virtual_agenda.excluded_timeperiods.count() == 0
# add booking delay
virtual_agenda.minimal_booking_delay = 2
virtual_agenda.maximal_booking_delay = 10
virtual_agenda.save()
output = get_output_of_command('export_site')
payload = json.loads(output)
virtual_agenda.delete()
import_site(json.loads(output), overwrite=True)
virtual_agenda = Agenda.objects.get(label='Virtual Agenda', slug='virtual-agenda', kind='virtual')
assert virtual_agenda.minimal_booking_delay == 2
assert virtual_agenda.maximal_booking_delay == 10
# add excluded timeperiods
tp1 = TimePeriod.objects.create(
agenda=virtual_agenda, weekday=1, start_time=datetime.time(10, 0), end_time=datetime.time(11, 0)
)
tp2 = TimePeriod.objects.create(
agenda=virtual_agenda, weekday=2, start_time=datetime.time(12, 0), end_time=datetime.time(13, 0)
)
output = get_output_of_command('export_site')
payload = json.loads(output)
virtual_agenda.delete()
tp1.delete()
tp2.delete()
import_site(json.loads(output), overwrite=True)
virtual_agenda = Agenda.objects.get(label='Virtual Agenda', slug='virtual-agenda', kind='virtual')
assert virtual_agenda.excluded_timeperiods.count() == 2
tp1 = TimePeriod.objects.get(
agenda=virtual_agenda, weekday=1, start_time=datetime.time(10, 0), end_time=datetime.time(11, 0)
)
tp2 = TimePeriod.objects.get(
agenda=virtual_agenda, weekday=2, start_time=datetime.time(12, 0), end_time=datetime.time(13, 0)
)
def test_import_export_virtual_agenda_with_included_agenda(app):
virtual_agenda = Agenda.objects.create(label='Virtual Agenda', kind='virtual')
foo_agenda = Agenda.objects.create(label='Zoo', kind='meetings')
bar_agenda = Agenda.objects.create(label='Bar', kind='meetings')
mt1 = MeetingType.objects.create(agenda=foo_agenda, label='Meeting Type', duration=30)
mt2 = MeetingType.objects.create(agenda=bar_agenda, label='Meeting Type', duration=30)
VirtualMember.objects.create(virtual_agenda=virtual_agenda, real_agenda=foo_agenda)
VirtualMember.objects.create(virtual_agenda=virtual_agenda, real_agenda=bar_agenda)
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['agendas']) == 3
virtual_agenda.delete()
foo_agenda.delete()
bar_agenda.delete()
mt1.delete()
mt2.delete()
import_site(payload, overwrite=True)
virtual_agenda = Agenda.objects.get(label='Virtual Agenda', slug='virtual-agenda', kind='virtual')
assert virtual_agenda.real_agendas.count() == 2
assert virtual_agenda.real_agendas.filter(label='Zoo').count() == 1
assert virtual_agenda.real_agendas.filter(label='Bar').count() == 1
# add incompatible meetingtype
bar_agenda = Agenda.objects.get(label='Bar', kind='meetings')
mt2 = MeetingType.objects.get(agenda=bar_agenda, label='Meeting Type')
mt2.duration = 10
mt2.save()
output = get_output_of_command('export_site')
payload = json.loads(output)
virtual_agenda.delete()
with pytest.raises(AgendaImportError) as excinfo:
import_site(json.loads(output), overwrite=False)
assert (
'This agenda does not have the same meeting types provided by the virtual agenda.'
in '%s' % excinfo.value
)
def test_import_export_virtual_agenda_with_missing_agenda(app):
virtual_agenda = Agenda.objects.create(label='Virtual Agenda', kind='virtual')
foo_agenda = Agenda.objects.create(label='Foo', kind='meetings')
VirtualMember.objects.create(virtual_agenda=virtual_agenda, real_agenda=foo_agenda)
output = get_output_of_command('export_site')
payload = json.loads(output)
del payload['agendas'][0] # remove real agenda
virtual_agenda.delete()
foo_agenda.delete()
with pytest.raises(AgendaImportError) as excinfo:
import_site(payload, overwrite=False)
assert 'The real agenda "foo" does not exist.' in '%s' % excinfo.value
2020-07-21 16:38:14 +02:00
def test_import_export_desk_missing_fields(app):
meetings_agenda = Agenda.objects.create(label='Foo Bar', kind='meetings')
MeetingType.objects.create(agenda=meetings_agenda, label='Meeting Type', duration=30)
desk = Desk.objects.create(agenda=meetings_agenda, label='Desk')
TimePeriod.objects.create(
desk=desk, weekday=2, start_time=datetime.time(10, 0), end_time=datetime.time(11, 0)
)
TimePeriodException.objects.create(
desk=desk,
start_datetime=make_aware(datetime.datetime(2017, 5, 22, 8, 0)),
end_datetime=make_aware(datetime.datetime(2017, 5, 22, 12, 30)),
)
output = get_output_of_command('export_site')
payload = json.loads(output)
del payload['agendas'][0]['desks'][0]['timeperiods']
del payload['agendas'][0]['desks'][0]['exceptions']
Agenda.objects.all().delete()
import_site(payload)
assert TimePeriod.objects.exists() is False
assert TimePeriodException.objects.exists() is False
def test_import_export_unknown_fields(app):
2020-07-21 16:38:14 +02:00
events_agenda = Agenda.objects.create(label='Events Agenda', kind='events')
Desk.objects.create(agenda=events_agenda, slug='_exceptions_holder')
2020-07-21 16:38:14 +02:00
Event.objects.create(agenda=events_agenda, start_datetime=now(), places=10)
meetings_agenda = Agenda.objects.create(label='Meetings Agenda', kind='meetings')
MeetingType.objects.create(agenda=meetings_agenda, label='Meeting Type', duration=30)
Desk.objects.create(agenda=meetings_agenda, label='Desk')
desk = meetings_agenda.desk_set.first()
2020-07-21 16:38:14 +02:00
TimePeriod.objects.create(
desk=desk, weekday=2, start_time=datetime.time(10, 0), end_time=datetime.time(11, 0)
)
TimePeriodException.objects.create(
desk=desk,
start_datetime=make_aware(datetime.datetime(2017, 5, 22, 8, 0)),
end_datetime=make_aware(datetime.datetime(2017, 5, 22, 12, 30)),
)
output = get_output_of_command('export_site')
payload = json.loads(output)
Agenda.objects.all().delete()
assert Agenda.objects.exists() is False
assert MeetingType.objects.exists() is False
assert Desk.objects.exists() is False
assert TimePeriod.objects.exists() is False
assert TimePeriodException.objects.exists() is False
# add unknown fields everywhere
2020-07-21 16:38:14 +02:00
payload['agendas'][0]['unknown_field'] = 'foobar'
payload['agendas'][0]['events'][0]['unknown_field'] = 'foobar'
payload['agendas'][0]['real_agendas'] = ['foobar'] # not available for a non virtual agenda
2020-07-21 16:38:14 +02:00
payload['agendas'][1]['unknown_field'] = 'foobar'
payload['agendas'][1]['meetingtypes'][0]['unknown_field'] = 'foobar'
payload['agendas'][1]['desks'][0]['unknown_field'] = 'foobar'
payload['agendas'][1]['desks'][0]['timeperiods'][0]['unknown_field'] = 'foobar'
payload['agendas'][1]['desks'][0]['exceptions'][0]['unknown_field'] = 'foobar'
import_site(payload)
assert Agenda.objects.exists() is True
assert MeetingType.objects.exists() is True
assert Desk.objects.exists() is True
assert TimePeriod.objects.exists() is True
assert TimePeriodException.objects.exists() is True
def test_import_export_slug_fields(app):
agenda_events = Agenda.objects.create(label='Events Agenda', kind='events')
Desk.objects.create(agenda=agenda_events, slug='_exceptions_holder')
2020-07-21 16:38:14 +02:00
Event.objects.create(agenda=agenda_events, start_datetime=now(), places=10)
agenda_meetings = Agenda.objects.create(label='Meetings Agenda', kind='meetings')
MeetingType.objects.create(agenda=agenda_meetings, label='Meeting Type', duration=30)
Desk.objects.create(agenda=agenda_meetings, label='Desk')
output = get_output_of_command('export_site')
original_payload = json.loads(output)
Agenda.objects.all().delete()
assert Agenda.objects.exists() is False
assert MeetingType.objects.exists() is False
assert Desk.objects.exists() is False
assert Event.objects.exists() is False
payload = copy.deepcopy(original_payload)
payload['agendas'][0]['slug'] = 'events-agenda&'
with pytest.raises(AgendaImportError) as excinfo:
import_site(payload)
assert str(excinfo.value) == 'Bad slug format "events-agenda&"'
payload = copy.deepcopy(original_payload)
payload['agendas'][0]['events'][0]['slug'] = 'events-agenda-event&'
with pytest.raises(AgendaImportError) as excinfo:
import_site(payload)
assert str(excinfo.value) == 'Bad slug format "events-agenda-event&"'
payload = copy.deepcopy(original_payload)
payload['agendas'][1]['desks'][0]['slug'] = 'desk&'
with pytest.raises(AgendaImportError) as excinfo:
import_site(payload)
assert str(excinfo.value) == 'Bad slug format "desk&"'
payload = copy.deepcopy(original_payload)
payload['agendas'][1]['meetingtypes'][0]['slug'] = 'meeting-type&'
with pytest.raises(AgendaImportError) as excinfo:
import_site(payload)
assert str(excinfo.value) == 'Bad slug format "meeting-type&"'
def test_import_export_notification_settings():
agenda = Agenda.objects.create(label='Foo bar', kind='events')
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
AgendaNotificationsSettings.objects.create(
agenda=agenda,
almost_full_event=AgendaNotificationsSettings.EDIT_ROLE,
full_event=AgendaNotificationsSettings.VIEW_ROLE,
cancelled_event=AgendaNotificationsSettings.EMAIL_FIELD,
cancelled_event_emails=['hop@entrouvert.com', 'top@entrouvert.com'],
)
output = get_output_of_command('export_site')
payload = json.loads(output)
agenda.delete()
assert not AgendaNotificationsSettings.objects.exists()
import_site(payload)
agenda = Agenda.objects.first()
AgendaNotificationsSettings.objects.get(
agenda=agenda,
almost_full_event=AgendaNotificationsSettings.EDIT_ROLE,
full_event=AgendaNotificationsSettings.VIEW_ROLE,
cancelled_event=AgendaNotificationsSettings.EMAIL_FIELD,
cancelled_event_emails=['hop@entrouvert.com', 'top@entrouvert.com'],
)
# again - check OneToOneField
import_site(payload)
def test_import_export_reminder_settings():
agenda = Agenda.objects.create(label='Foo bar', kind='events')
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
AgendaReminderSettings.objects.create(
agenda=agenda,
days_before_email=2,
days_before_sms=1,
email_extra_info='test',
)
output = get_output_of_command('export_site')
payload = json.loads(output)
agenda.delete()
assert not AgendaReminderSettings.objects.exists()
import_site(payload)
agenda = Agenda.objects.first()
AgendaReminderSettings.objects.get(
agenda=agenda,
days_before_email=2,
days_before_sms=1,
email_extra_info='test',
)
# again - check OneToOneField
import_site(payload)
@override_settings(
EXCEPTIONS_SOURCES={
'holidays': {'class': 'workalendar.europe.France', 'label': 'Holidays'},
}
)
def test_import_export_time_period_exception_source():
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(slug='test', agenda=agenda)
desk.import_timeperiod_exceptions_from_settings(enable=True)
output = get_output_of_command('export_site')
payload = json.loads(output)
agenda.delete()
assert not TimePeriodExceptionSource.objects.exists()
import_site(payload)
desk = Desk.objects.get(slug='test')
source = desk.timeperiodexceptionsource_set.first()
assert source.enabled
assert desk.timeperiodexception_set.exists()
source.disable()
output = get_output_of_command('export_site')
payload = json.loads(output)
Agenda.objects.all().delete()
import_site(payload)
desk = Desk.objects.get(slug='test')
source = desk.timeperiodexceptionsource_set.first()
assert not source.enabled
assert not desk.timeperiodexception_set.exists()
@override_settings(
EXCEPTIONS_SOURCES={
'holidays': {'class': 'workalendar.europe.France', 'label': 'Holidays'},
}
)
def test_import_export_time_period_exception_source_enabled():
agenda = Agenda.objects.create(label='Foo bar', kind='events')
desk = Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
desk.import_timeperiod_exceptions_from_settings()
source = desk.timeperiodexceptionsource_set.first()
assert not source.enabled
assert source.settings_slug == 'holidays'
source.enabled = True
source.save()
output = get_output_of_command('export_site')
payload = json.loads(output)
agenda.delete()
assert not TimePeriodExceptionSource.objects.exists()
import_site(payload)
agenda = Agenda.objects.get(label='Foo bar')
assert agenda.desk_set.count() == 1
desk = agenda.desk_set.first()
assert desk.timeperiodexceptionsource_set.count() == 1
source = desk.timeperiodexceptionsource_set.first()
assert source.enabled
assert source.settings_slug == 'holidays'
@mock.patch('chrono.agendas.models.requests.get')
def test_import_export_time_period_exception_source_remote_ics(mocked_get):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(label='Desk', agenda=agenda)
source = TimePeriodExceptionSource.objects.create(desk=desk, ics_url='http://example.com/sample.ics')
mocked_response = mock.Mock()
mocked_response.text = ICS_SAMPLE
mocked_get.return_value = mocked_response
source.refresh_timeperiod_exceptions_from_ics()
assert TimePeriodException.objects.count() == 2
output = get_output_of_command('export_site')
payload = json.loads(output)
Agenda.objects.all().delete()
assert not TimePeriodExceptionSource.objects.exists()
assert not TimePeriodException.objects.exists()
import_site(payload)
source = TimePeriodExceptionSource.objects.get()
assert source.timeperiodexception_set.count() == 2
assert TimePeriodException.objects.count() == 2
# import again changes nothing
import_site(payload)
assert TimePeriodExceptionSource.objects.count() == 1
assert TimePeriodException.objects.count() == 2
# empty remote ics
mocked_response.text = ICS_SAMPLE_WITH_NO_EVENTS
Agenda.objects.all().delete()
import_site(payload)
assert TimePeriodExceptionSource.objects.count() == 1
assert TimePeriodException.objects.count() == 0
@mock.patch('chrono.agendas.models.requests.get')
def test_import_export_time_period_exception_source_ics_file(mocked_get):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(label='Desk', agenda=agenda)
source = TimePeriodExceptionSource.objects.create(
desk=desk, ics_filename='sample.ics', ics_file=ContentFile(ICS_SAMPLE, name='sample.ics')
)
source.refresh_timeperiod_exceptions_from_ics()
assert TimePeriodException.objects.count() == 2
output = get_output_of_command('export_site')
payload = json.loads(output)
Agenda.objects.all().delete()
assert not TimePeriodExceptionSource.objects.exists()
assert not TimePeriodException.objects.exists()
import_site(payload)
source = TimePeriodExceptionSource.objects.get()
assert source.timeperiodexception_set.count() == 2
assert TimePeriodException.objects.count() == 2
# import again changes nothing
import_site(payload)
assert TimePeriodExceptionSource.objects.count() == 1
assert TimePeriodException.objects.count() == 2
payload['agendas'][0]['desks'][0]['exception_sources'][0]['ics_file'] = 'garbage'
with pytest.raises(AgendaImportError) as excinfo:
import_site(payload)
assert '%s' % excinfo.value == 'Bad ics file'
Agenda.objects.all().delete()
payload['agendas'][0]['desks'][0]['exception_sources'][0]['ics_file'] = None
import_site(payload)
assert TimePeriodExceptionSource.objects.count() == 0
assert TimePeriodException.objects.count() == 0
@override_settings(
EXCEPTIONS_SOURCES={
'holidays': {'class': 'workalendar.europe.France', 'label': 'Holidays'},
}
)
def test_import_export_time_period_exception_legacy_file():
agenda = Agenda.objects.create(label='Foo bar', kind='events')
desk = Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
desk.import_timeperiod_exceptions_from_settings()
output = get_output_of_command('export_site')
payload = json.loads(output)
source = payload['agendas'][0]['exceptions_desk']['exception_sources'][0]
del source['ics_file']
del source['ics_filename']
del source['ics_url']
agenda.delete()
assert not TimePeriodExceptionSource.objects.exists()
import_site(payload)
assert TimePeriodExceptionSource.objects.count() == 1
def test_import_export_do_not_duplicate_timeperiod_and_exceptions():
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(slug='test', agenda=agenda)
TimePeriod.objects.create(
desk=desk, weekday=2, start_time=datetime.time(10, 0), end_time=datetime.time(11, 0)
)
TimePeriod.objects.create(
desk=desk, weekday=3, start_time=datetime.time(10, 0), end_time=datetime.time(11, 0)
)
tpe1 = TimePeriodException.objects.create(
desk=desk,
start_datetime=make_aware(datetime.datetime(2017, 5, 22, 8, 0)),
end_datetime=make_aware(datetime.datetime(2017, 5, 22, 12, 30)),
)
TimePeriodException.objects.create(
desk=desk,
start_datetime=make_aware(datetime.datetime(2017, 6, 22, 8, 0)),
end_datetime=make_aware(datetime.datetime(2017, 6, 22, 12, 30)),
)
assert TimePeriod.objects.count() == 2
assert TimePeriodException.objects.count() == 2
output = get_output_of_command('export_site')
payload = json.loads(output)
import_site(payload)
assert TimePeriod.objects.count() == 2
assert TimePeriodException.objects.count() == 2
# duplicated exception
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['agendas'][0]['desks'][0]['exceptions']) == 2
tpe2 = TimePeriodException.objects.create(
desk=desk,
start_datetime=make_aware(datetime.datetime(2017, 5, 22, 8, 0)),
end_datetime=make_aware(datetime.datetime(2017, 5, 22, 12, 30)),
)
assert TimePeriod.objects.count() == 2
assert TimePeriodException.objects.count() == 3
assert tpe1.update_datetime < tpe2.update_datetime
import_site(payload)
assert TimePeriod.objects.count() == 2
assert TimePeriodException.objects.count() == 3
tpe1.refresh_from_db()
tpe2.refresh_from_db()
assert tpe1.update_datetime == tpe2.update_datetime
def test_import_export_unavailability_calendar(app):
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['unavailability_calendars']) == 0
group1 = Group.objects.create(name='gé1')
group2 = Group.objects.create(name='gé2')
calendar = UnavailabilityCalendar.objects.create(label='Calendar', view_role=group1, edit_role=group2)
tp1_start = make_aware(datetime.datetime(2017, 5, 22, 8, 0))
tp1_end = make_aware(datetime.datetime(2017, 5, 22, 12, 30))
tp1 = TimePeriodException.objects.create(
unavailability_calendar=calendar, start_datetime=tp1_start, end_datetime=tp1_end
)
tp2_start = make_aware(datetime.datetime(2018, 5, 22, 8, 0))
tp2_end = make_aware(datetime.datetime(2018, 5, 22, 12, 30))
tp2 = TimePeriodException.objects.create(
unavailability_calendar=calendar, start_datetime=tp2_start, end_datetime=tp2_end
)
meetings_agenda = Agenda.objects.create(label='Foo Bar', kind='meetings')
MeetingType.objects.create(agenda=meetings_agenda, label='Meeting Type', duration=30)
desk = Desk.objects.create(agenda=meetings_agenda, label='Desk')
desk.unavailability_calendars.add(calendar)
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['unavailability_calendars']) == 1
assert len(payload['agendas']) == 1
calendar.delete()
tp1.delete()
tp2.delete()
meetings_agenda.delete()
assert not UnavailabilityCalendar.objects.exists()
assert not TimePeriodException.objects.exists()
assert not Agenda.objects.exists()
assert not Desk.objects.exists()
import_site(copy.deepcopy(payload))
assert UnavailabilityCalendar.objects.count() == 1
calendar = UnavailabilityCalendar.objects.first()
assert calendar.label == 'Calendar'
assert calendar.view_role == group1
assert calendar.edit_role == group2
assert calendar.timeperiodexception_set.count() == 2
assert TimePeriodException.objects.get(
unavailability_calendar=calendar, start_datetime=tp1_start, end_datetime=tp1_end
)
assert TimePeriodException.objects.get(
unavailability_calendar=calendar, start_datetime=tp2_start, end_datetime=tp2_end
)
agenda = Agenda.objects.get(label='Foo Bar')
desk = agenda.desk_set.first()
assert desk.unavailability_calendars.count() == 1
assert desk.unavailability_calendars.first() == calendar
# update
update_payload = copy.deepcopy(payload)
update_payload['unavailability_calendars'][0]['label'] = 'Calendar Updated'
import_site(update_payload)
calendar.refresh_from_db()
assert calendar.label == 'Calendar Updated'
def test_import_export_category(app):
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['categories']) == 0
category = Category.objects.create(label='Foo bar')
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['categories']) == 1
category.delete()
assert not Category.objects.exists()
import_site(copy.deepcopy(payload))
assert Category.objects.count() == 1
category = Category.objects.first()
assert category.label == 'Foo bar'
assert category.slug == 'foo-bar'
# update
update_payload = copy.deepcopy(payload)
update_payload['categories'][0]['label'] = 'Foo bar Updated'
import_site(update_payload)
category.refresh_from_db()
assert category.label == 'Foo bar Updated'
# insert another category
category.slug = 'foo-bar-updated'
category.save()
import_site(copy.deepcopy(payload))
assert Category.objects.count() == 2
category = Category.objects.latest('pk')
assert category.label == 'Foo bar'
assert category.slug == 'foo-bar'
def test_import_export_events_type(app):
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['events_types']) == 0
events_type = EventsType.objects.create(label='Foo bar')
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['events_types']) == 1
events_type.delete()
assert not EventsType.objects.exists()
import_site(copy.deepcopy(payload))
assert EventsType.objects.count() == 1
events_type = EventsType.objects.first()
assert events_type.label == 'Foo bar'
assert events_type.slug == 'foo-bar'
# update
update_payload = copy.deepcopy(payload)
update_payload['events_types'][0]['label'] = 'Foo bar Updated'
import_site(update_payload)
events_type.refresh_from_db()
assert events_type.label == 'Foo bar Updated'
# insert another events_type
events_type.slug = 'foo-bar-updated'
events_type.save()
import_site(copy.deepcopy(payload))
assert EventsType.objects.count() == 2
events_type = EventsType.objects.latest('pk')
assert events_type.label == 'Foo bar'
assert events_type.slug == 'foo-bar'
def test_import_export_resource(app):
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['resources']) == 0
resource = Resource.objects.create(label='Foo bar')
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['resources']) == 1
resource.delete()
assert not Resource.objects.exists()
import_site(copy.deepcopy(payload))
assert Resource.objects.count() == 1
resource = Resource.objects.first()
assert resource.label == 'Foo bar'
assert resource.slug == 'foo-bar'
# update
update_payload = copy.deepcopy(payload)
update_payload['resources'][0]['label'] = 'Foo bar Updated'
import_site(update_payload)
resource.refresh_from_db()
assert resource.label == 'Foo bar Updated'
# insert another resource
resource.slug = 'foo-bar-updated'
resource.save()
import_site(copy.deepcopy(payload))
assert Resource.objects.count() == 2
resource = Resource.objects.latest('pk')
assert resource.label == 'Foo bar'
assert resource.slug == 'foo-bar'
@mock.patch('chrono.agendas.models.Agenda.is_available_for_simple_management')
def test_import_export_desk_simple_management(available_mock):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings', desk_simple_management=True)
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['agendas']) == 1
assert payload['agendas'][0]['desk_simple_management'] is True
# check on creation
for available_value in [True, False]:
agenda.delete()
available_mock.return_value = available_value
import_site(payload)
agenda = Agenda.objects.latest('pk')
assert agenda.desk_simple_management == available_value
payload['agendas'][0]['desk_simple_management'] = False
for available_value in [True, False]:
# always ok to set flag to False
agenda.delete()
available_mock.return_value = available_value
import_site(payload)
agenda = Agenda.objects.latest('pk')
assert agenda.desk_simple_management is False
# check on update
payload['agendas'][0]['desk_simple_management'] = True
for available_value in [True, False]:
agenda.desk_simple_management = False
agenda.save()
available_mock.return_value = available_value
import_site(payload)
agenda.refresh_from_db()
assert agenda.desk_simple_management == available_value
# already True, no change
agenda.desk_simple_management = True
agenda.save()
available_mock.return_value = available_value
import_site(payload)
agenda.refresh_from_db()
assert agenda.desk_simple_management is True
payload['agendas'][0]['desk_simple_management'] = False
for available_value in [True, False]:
# always ok to set flag to False
for old_value in [True, False]:
agenda.desk_simple_management = old_value
agenda.save()
available_mock.return_value = available_value
import_site(payload)
agenda.refresh_from_db()
assert agenda.desk_simple_management is False
# not in payload, no changed
del payload['agendas'][0]['desk_simple_management']
for available_value in [True, False]:
for old_value in [True, False]:
agenda.desk_simple_management = old_value
agenda.save()
available_mock.return_value = available_value
import_site(payload)
agenda.refresh_from_db()
assert agenda.desk_simple_management == old_value
def test_export_deleted_meetingtype(app):
agenda = Agenda.objects.create(label='Agenda', kind='meetings')
meeting_type = MeetingType.objects.create(agenda=agenda, label='Meeting Type', duration=30)
output = get_output_of_command('export_site')
assert len(json.loads(output)['agendas'][0]['meetingtypes']) == 1
meeting_type.deleted = True
meeting_type.save()
output = get_output_of_command('export_site')
assert len(json.loads(output)['agendas'][0]['meetingtypes']) == 0
def test_import_export_agenda_update(app):
agenda = Agenda.objects.create(label='Foo Bar', kind='meetings')
output = get_output_of_command('export_site')
data = json.loads(output)
assert len(['agendas']) == 1
import_site(data={}, clean=True)
import_site(data)
agenda = Agenda.objects.get()
assert agenda.label == 'Foo Bar'
data['agendas'][0]['label'] = 'Bar Foo'
import_site(data)
agenda = Agenda.objects.get()
assert agenda.label == 'Bar Foo'
def test_import_export_shared_custody_settings(app):
group = Group.objects.create(name='test')
calendar = UnavailabilityCalendar.objects.create(label='Calendar')
SharedCustodySettings.objects.create(management_role=group, holidays_calendar=calendar)
output = get_output_of_command('export_site')
import_site(data={}, clean=True)
assert SharedCustodySettings.get_singleton().management_role is None
Group.objects.all().delete()
payload = json.loads(output)
del payload['unavailability_calendars']
with pytest.raises(AgendaImportError) as excinfo:
import_site(payload)
assert '%s' % excinfo.value == 'Missing roles: "test"'
group = Group.objects.create(name='test')
with pytest.raises(AgendaImportError) as excinfo:
import_site(payload)
assert '%s' % excinfo.value == 'The unavailability calendar "calendar" does not exist.'
import_site(json.loads(output))
settings = SharedCustodySettings.get_singleton()
assert settings.management_role == group
assert settings.holidays_calendar.slug == calendar.slug
group2 = Group.objects.create(name='test2')
settings.management_role = group2
settings.save()
import_site(json.loads(output))
settings = SharedCustodySettings.get_singleton()
assert settings.management_role == group