From 74bee2d82cedfde69b3de6717abe48068828d4cd Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Tue, 28 Jun 2022 14:50:00 +0200 Subject: [PATCH 2/2] manager: import/export shared custody settings (#66671) --- chrono/agendas/models.py | 10 ++++++++++ chrono/manager/forms.py | 7 +++++++ chrono/manager/utils.py | 11 +++++++++++ tests/manager/test_import_export.py | 17 ++++++++++++++++ tests/test_import_export.py | 30 +++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+) diff --git a/chrono/agendas/models.py b/chrono/agendas/models.py index 73b2501a..97fb11d9 100644 --- a/chrono/agendas/models.py +++ b/chrono/agendas/models.py @@ -3500,6 +3500,16 @@ class SharedCustodySettings(models.Model): on_delete=models.SET_NULL, ) + def export_json(self): + return {'management_role': self.management_role.name if self.management_role else None} + + @classmethod + def import_json(cls, data): + if data.get('management_role'): + data['management_role'] = Group.objects.get(name=data['management_role']) + + cls.objects.update_or_create(defaults=data) + @classmethod def get_singleton(cls): try: diff --git a/chrono/manager/forms.py b/chrono/manager/forms.py index 21410f5a..7b0194f2 100644 --- a/chrono/manager/forms.py +++ b/chrono/manager/forms.py @@ -1444,6 +1444,13 @@ class AgendasExportForm(forms.Form): categories = forms.BooleanField(label=_('Categories'), required=False, initial=True) check_type_groups = forms.BooleanField(label=_('Check type groups'), required=False, initial=True) events_types = forms.BooleanField(label=_('Events types'), required=False, initial=True) + shared_custody = forms.BooleanField(label=_('Shared custody'), required=False, initial=True) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if not SharedCustodySettings.objects.exists(): + self.fields['shared_custody'].initial = False + self.fields['shared_custody'].widget = forms.HiddenInput() class SharedCustodyRuleForm(forms.ModelForm): diff --git a/chrono/manager/utils.py b/chrono/manager/utils.py index 0e2952f2..80d7d9b1 100644 --- a/chrono/manager/utils.py +++ b/chrono/manager/utils.py @@ -28,6 +28,7 @@ from chrono.agendas.models import ( CheckTypeGroup, EventsType, Resource, + SharedCustodySettings, UnavailabilityCalendar, ) @@ -39,6 +40,7 @@ def export_site( events_types=True, resources=True, categories=True, + shared_custody=True, ): '''Dump site objects to JSON-dumpable dictionnary''' data = collections.OrderedDict() @@ -56,6 +58,8 @@ def export_site( qs1 = Agenda.objects.filter(~Q(kind='virtual')) qs2 = Agenda.objects.filter(kind='virtual') data['agendas'] = [x.export_json() for x in itertools.chain(qs1, qs2)] + if shared_custody: + data['shared_custody_settings'] = SharedCustodySettings.get_singleton().export_json() return data @@ -78,6 +82,7 @@ def import_site(data, if_empty=False, clean=False, overwrite=False): EventsType.objects.all().delete() Resource.objects.all().delete() Category.objects.all().delete() + SharedCustodySettings.objects.all().delete() results = { key: collections.defaultdict(list) @@ -97,6 +102,11 @@ def import_site(data, if_empty=False, clean=False, overwrite=False): role_names = role_names.union( {name for data in objs for _, name in data.get('permissions', {}).items() if name} ) + + shared_custody_settings = data.get('shared_custody_settings') + if shared_custody_settings and shared_custody_settings['management_role']: + role_names.add(shared_custody_settings['management_role']) + existing_roles = Group.objects.filter(name__in=role_names) if existing_roles.count() != len(role_names): @@ -120,4 +130,5 @@ def import_site(data, if_empty=False, clean=False, overwrite=False): results[key]['created'].append(obj) else: results[key]['updated'].append(obj) + SharedCustodySettings.import_json(data.get('shared_custody_settings', {})) return results diff --git a/tests/manager/test_import_export.py b/tests/manager/test_import_export.py index efd161e2..31e512fa 100644 --- a/tests/manager/test_import_export.py +++ b/tests/manager/test_import_export.py @@ -15,6 +15,7 @@ from chrono.agendas.models import ( Desk, Event, MeetingType, + SharedCustodySettings, UnavailabilityCalendar, ) from tests.utils import login @@ -358,3 +359,19 @@ def test_import_check_type_group(app, admin_user): assert '3 check type groups have been created. No check type group updated.' in resp.text assert CheckTypeGroup.objects.count() == 3 assert CheckType.objects.count() == 6 + + +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'] diff --git a/tests/test_import_export.py b/tests/test_import_export.py index 30cfa29f..17cbdc08 100644 --- a/tests/test_import_export.py +++ b/tests/test_import_export.py @@ -28,6 +28,7 @@ from chrono.agendas.models import ( EventsType, MeetingType, Resource, + SharedCustodySettings, TimePeriod, TimePeriodException, TimePeriodExceptionSource, @@ -1230,3 +1231,32 @@ def test_import_export_agenda_update(app): agenda = Agenda.objects.get() assert agenda.label == 'Bar Foo' + + +def test_import_export_shared_custody_settings(app): + group = Group.objects.create(name='test') + SharedCustodySettings.objects.create(management_role=group) + + output = get_output_of_command('export_site') + import_site(data={}, clean=True) + assert SharedCustodySettings.get_singleton().management_role is None + Group.objects.all().delete() + + with pytest.raises(AgendaImportError) as excinfo: + import_site(json.loads(output)) + assert '%s' % excinfo.value == 'Missing roles: "test"' + + group = Group.objects.create(name='test') + import_site(json.loads(output)) + + settings = SharedCustodySettings.get_singleton() + assert settings.management_role == group + + 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 -- 2.30.2