chrono/tests/manager/test_import_export.py

305 lines
12 KiB
Python

import copy
import json
import freezegun
import pytest
from django.utils.encoding import force_text
from django.utils.timezone import now
from webtest import Upload
from chrono.agendas.models import (
Agenda,
Booking,
Desk,
Event,
MeetingType,
SharedCustodySettings,
UnavailabilityCalendar,
)
from tests.utils import login
pytestmark = pytest.mark.django_db
def test_export_site(app, admin_user):
login(app)
resp = app.get('/manage/')
resp = resp.click('Export')
with freezegun.freeze_time('2020-06-15'):
resp = resp.form.submit()
assert resp.headers['content-type'] == 'application/json'
assert resp.headers['content-disposition'] == 'attachment; filename="export_agendas_20200615.json"'
site_json = json.loads(resp.text)
assert site_json == {
'unavailability_calendars': [],
'agendas': [],
'events_types': [],
'resources': [],
'categories': [],
}
agenda = Agenda.objects.create(label='Foo Bar', kind='events')
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
UnavailabilityCalendar.objects.create(label='Calendar 1')
resp = app.get('/manage/agendas/export/')
resp = resp.form.submit()
site_json = json.loads(resp.text)
assert len(site_json['agendas']) == 1
assert len(site_json['unavailability_calendars']) == 1
assert len(site_json['events_types']) == 0
assert len(site_json['resources']) == 0
assert len(site_json['categories']) == 0
resp = app.get('/manage/agendas/export/')
resp.form['agendas'] = False
resp.form['events_types'] = False
resp.form['resources'] = False
resp.form['categories'] = False
resp = resp.form.submit()
site_json = json.loads(resp.text)
assert 'agendas' not in site_json
assert 'unavailability_calendars' in site_json
assert 'events_types' not in site_json
assert 'resources' not in site_json
assert 'categories' not in site_json
def test_import_agenda_as_manager(app, manager_user):
# open /manage/ access to manager_user, and check agenda import is not
# allowed.
agenda = Agenda(label='Foo bar')
agenda.view_role = manager_user.groups.all()[0]
agenda.save()
app = login(app, username='manager', password='manager')
app.get('/manage/', status=200)
app.get('/manage/agendas/import/', status=403)
def test_import_agenda(app, admin_user):
agenda = Agenda(label='Foo bar')
agenda.save()
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
app = login(app)
with freezegun.freeze_time('2020-06-15'):
resp = app.get('/manage/agendas/%s/export' % agenda.id)
assert resp.headers['content-type'] == 'application/json'
assert resp.headers['content-disposition'] == 'attachment; filename="export_agenda_foo-bar_20200615.json"'
agenda_export = resp.text
# invalid json
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', b'garbage', 'application/json')
resp = resp.form.submit()
assert 'File is not in the expected JSON format.' in resp.text
# empty json
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', b'{}', 'application/json')
resp = resp.form.submit().follow()
assert 'No data found.' in resp.text
# existing agenda
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', agenda_export.encode('utf-8'), 'application/json')
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
resp = resp.follow()
assert 'No agenda created. An agenda has been updated.' not in resp.text
assert Agenda.objects.count() == 1
# new agenda
Agenda.objects.all().delete()
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', agenda_export.encode('utf-8'), 'application/json')
resp = resp.form.submit()
agenda = Agenda.objects.latest('pk')
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
resp = resp.follow()
assert 'An agenda has been created. No agenda updated.' not in resp.text
assert Agenda.objects.count() == 1
# multiple agendas
agendas = json.loads(agenda_export)
agendas['agendas'].append(copy.copy(agendas['agendas'][0]))
agendas['agendas'].append(copy.copy(agendas['agendas'][0]))
agendas['agendas'][1]['label'] = 'Foo bar 2'
agendas['agendas'][1]['slug'] = 'foo-bar-2'
agendas['agendas'][2]['label'] = 'Foo bar 3'
agendas['agendas'][2]['slug'] = 'foo-bar-3'
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', json.dumps(agendas).encode('utf-8'), 'application/json')
resp = resp.form.submit()
assert resp.location.endswith('/manage/')
resp = resp.follow()
assert '2 agendas have been created. An agenda has been updated.' in resp.text
assert Agenda.objects.count() == 3
Agenda.objects.all().delete()
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', json.dumps(agendas).encode('utf-8'), 'application/json')
resp = resp.form.submit().follow()
assert '3 agendas have been created. No agenda updated.' in resp.text
assert Agenda.objects.count() == 3
# reference to unknown group
agenda_export_dict = json.loads(force_text(agenda_export))
agenda_export_dict['agendas'][0]['permissions']['view'] = 'gé1'
agenda_export = json.dumps(agenda_export_dict).encode('utf-8')
Agenda.objects.all().delete()
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', agenda_export, 'application/json')
resp = resp.form.submit()
assert 'Missing roles: "gé1"' in resp.text
del agenda_export_dict['agendas'][0]['permissions']['view']
# missing field
del agenda_export_dict['agendas'][0]['kind']
agenda_export = json.dumps(agenda_export_dict).encode('utf-8')
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', agenda_export, 'application/json')
resp = resp.form.submit()
assert resp.context['form'].errors['agendas_json'] == ['Key "kind" is missing.']
def test_import_does_not_delete_bookings(app, admin_user):
agenda = Agenda.objects.create(label='Foo', kind='meetings')
meeting_type = MeetingType.objects.create(agenda=agenda, label='Meeting Type', duration=30)
desk = Desk.objects.create(agenda=agenda, label='Desk', slug='desk')
event = Event(start_datetime=now(), places=10, meeting_type=meeting_type, desk=desk, agenda=agenda)
event.save()
booking = Booking(event=event)
booking.save()
assert Booking.objects.count() == 1
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.id)
resp = resp.click('Export')
assert resp.headers['content-type'] == 'application/json'
agenda_export = resp.text
# existing agenda
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', agenda_export.encode('utf-8'), 'application/json')
resp = resp.form.submit().follow()
assert Agenda.objects.count() == 1
assert Booking.objects.count() == 1
def test_import_unavailability_calendar(app, admin_user):
calendar = UnavailabilityCalendar.objects.create(label='Foo bar')
app = login(app)
with freezegun.freeze_time('2020-06-15'):
resp = app.get('/manage/unavailability-calendar/%s/export' % calendar.id)
assert resp.headers['content-type'] == 'application/json'
assert (
resp.headers['content-disposition']
== 'attachment; filename="export_unavailability-calendar_foo-bar_20200615.json"'
)
calendar_export = resp.text
# empty json
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', b'{}', 'application/json')
resp = resp.form.submit().follow()
assert 'No data found.' in resp.text
# existing unavailability calendar
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', calendar_export.encode('utf-8'), 'application/json')
resp = resp.form.submit()
assert resp.location.endswith('/manage/unavailability-calendar/%s/settings' % calendar.pk)
resp = resp.follow()
assert 'No unavailability calendar created. An unavailability calendar has been updated.' not in resp.text
assert UnavailabilityCalendar.objects.count() == 1
# new unavailability calendar
UnavailabilityCalendar.objects.all().delete()
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', calendar_export.encode('utf-8'), 'application/json')
resp = resp.form.submit()
calendar = UnavailabilityCalendar.objects.latest('pk')
assert resp.location.endswith('/manage/unavailability-calendar/%s/settings' % calendar.pk)
resp = resp.follow()
assert 'An unavailability calendar has been created. No unavailability calendar updated.' not in resp.text
assert UnavailabilityCalendar.objects.count() == 1
# multiple unavailability calendars
calendars = json.loads(calendar_export)
calendars['unavailability_calendars'].append(copy.copy(calendars['unavailability_calendars'][0]))
calendars['unavailability_calendars'].append(copy.copy(calendars['unavailability_calendars'][0]))
calendars['unavailability_calendars'][1]['label'] = 'Foo bar 2'
calendars['unavailability_calendars'][1]['slug'] = 'foo-bar-2'
calendars['unavailability_calendars'][2]['label'] = 'Foo bar 3'
calendars['unavailability_calendars'][2]['slug'] = 'foo-bar-3'
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload(
'export.json', json.dumps(calendars).encode('utf-8'), 'application/json'
)
resp = resp.form.submit()
assert resp.location.endswith('/manage/')
resp = resp.follow()
assert (
'2 unavailability calendars have been created. An unavailability calendar has been updated.'
in resp.text
)
assert UnavailabilityCalendar.objects.count() == 3
UnavailabilityCalendar.objects.all().delete()
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload(
'export.json', json.dumps(calendars).encode('utf-8'), 'application/json'
)
resp = resp.form.submit().follow()
assert '3 unavailability calendars have been created. No unavailability calendar updated.' in resp.text
assert UnavailabilityCalendar.objects.count() == 3
# reference to unknown group
calendar_export_dict = json.loads(force_text(calendar_export))
calendar_export_dict['unavailability_calendars'][0]['permissions']['view'] = 'gé1'
calendar_export = json.dumps(calendar_export_dict).encode('utf-8')
UnavailabilityCalendar.objects.all().delete()
resp = app.get('/manage/', status=200)
resp = resp.click('Import')
resp.form['agendas_json'] = Upload('export.json', calendar_export, 'application/json')
resp = resp.form.submit()
assert 'Missing roles: "gé1"' in resp.text
del calendar_export_dict['unavailability_calendars'][0]['permissions']['view']
def test_export_site_shared_custody_settings(app, admin_user):
login(app)
resp = app.get('/manage/agendas/export/')
assert resp.form['shared_custody'].value == 'False'
assert resp.form['shared_custody'].attrs == {'type': 'hidden'}
SharedCustodySettings.objects.create()
resp = app.get('/manage/agendas/export/')
assert 'shared_custody' in resp.form.fields
resp = resp.form.submit()
site_json = json.loads(resp.text)
assert 'management_role' in site_json['shared_custody_settings']