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']