manager: option to apply exceptions to all desks (#55826)

This commit is contained in:
Lauréline Guérin 2021-08-10 14:58:31 +02:00
parent 85c10920a7
commit f355ed0492
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
3 changed files with 85 additions and 1 deletions

View File

@ -762,11 +762,19 @@ class ExceptionsImportForm(forms.ModelForm):
required=False,
help_text=_('URL to remote calendar which will be synchronised hourly.'),
)
all_desks = forms.BooleanField(label=_('Apply exceptions on all desks of the agenda'), required=False)
class Meta:
model = Desk
fields = []
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance.agenda.desk_set.count() == 1:
del self.fields['all_desks']
elif self.instance.agenda.desk_simple_management:
del self.fields['all_desks']
def clean(self, *args, **kwargs):
cleaned_data = super().clean(*args, **kwargs)
if not cleaned_data.get('ics_file') and not cleaned_data.get('ics_url'):

View File

@ -2634,9 +2634,10 @@ class DeskImportTimePeriodExceptionsView(ManagedAgendaSubobjectMixin, UpdateView
def form_valid(self, form):
desk = self.get_object()
sources = []
all_desks = form.cleaned_data.get('all_desks')
try:
with transaction.atomic():
if desk.agenda.desk_simple_management:
if all_desks or desk.agenda.desk_simple_management:
for _desk in desk.agenda.desk_set.all():
sources.append(self.import_file(_desk, form))
else:

View File

@ -781,6 +781,79 @@ def test_agenda_import_time_period_exception_from_remote_ics_with_ssl_error(mock
assert 'Failed to retrieve remote calendar (https://example.com/foo.ics, SSL error).' in resp.text
@mock.patch('chrono.agendas.models.requests.get')
def test_agenda_import_time_period_exception_url_desk_all_desks(mocked_get, app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(agenda=agenda, label='Desk A')
# only one desk: no option to apply to all desks
app = login(app)
resp = app.get('/manage/agendas/desk/%s/import-exceptions-from-ics/' % desk.pk)
assert 'all_desks' not in resp.form.fields
# more than one desk
Desk.objects.create(agenda=agenda, label='Desk B')
agenda2 = Agenda.objects.create(label='Foo bar', kind='meetings')
Desk.objects.create(agenda=agenda2, label='Other Desk') # check exceptions are not created for this one
resp = app.get('/manage/agendas/desk/%s/import-exceptions-from-ics/' % desk.pk)
resp.form['all_desks'] = True
resp.form['ics_url'] = 'http://example.com/foo.ics'
mocked_response = mock.Mock()
mocked_response.text = """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//foo.bar//EN
BEGIN:VEVENT
DTSTART:20180101
DTEND:20180101
SUMMARY:New Year's Eve
END:VEVENT
END:VCALENDAR"""
mocked_get.return_value = mocked_response
resp = resp.form.submit(status=302)
assert TimePeriodException.objects.count() == 2
assert TimePeriodException.objects.filter(desk__slug='desk-a').exists()
assert TimePeriodException.objects.filter(desk__slug='desk-b').exists()
agenda = Agenda.objects.create(label='New Example', kind='meetings', desk_simple_management=True)
desk = Desk.objects.create(agenda=agenda, label='New Desk')
desk.duplicate()
assert agenda.is_available_for_simple_management() is True
def test_agenda_import_time_period_exception_file_desk_all_desks(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(agenda=agenda, label='Desk A')
# only one desk: no option to apply to all desks
app = login(app)
resp = app.get('/manage/agendas/desk/%s/import-exceptions-from-ics/' % desk.pk)
assert 'all_desks' not in resp.form.fields
# more than one desk
Desk.objects.create(agenda=agenda, label='Desk B')
agenda2 = Agenda.objects.create(label='Foo bar', kind='meetings')
Desk.objects.create(agenda=agenda2, label='Other Desk') # check exceptions are not created for this one
resp = app.get('/manage/agendas/desk/%s/import-exceptions-from-ics/' % desk.pk)
resp.form['all_desks'] = True
ics_exceptions = b"""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//foo.bar//EN
BEGIN:VEVENT
DTSTART:20180101
DTEND:20180101
SUMMARY:New Year's Eve
END:VEVENT
END:VCALENDAR"""
resp.form['ics_file'] = Upload('exceptions.ics', ics_exceptions, 'text/calendar')
resp = resp.form.submit(status=302)
assert TimePeriodException.objects.count() == 2
assert TimePeriodException.objects.filter(desk__slug='desk-a').exists()
assert TimePeriodException.objects.filter(desk__slug='desk-b').exists()
agenda = Agenda.objects.create(label='New Example', kind='meetings', desk_simple_management=True)
desk = Desk.objects.create(agenda=agenda, label='New Desk')
desk.duplicate()
assert agenda.is_available_for_simple_management() is True
@mock.patch('chrono.agendas.models.requests.get')
def test_agenda_import_time_period_exception_url_desk_simple_management(mocked_get, app, admin_user):
agenda = Agenda.objects.create(label='New Example', kind='meetings', desk_simple_management=True)
@ -790,6 +863,7 @@ def test_agenda_import_time_period_exception_url_desk_simple_management(mocked_g
login(app)
resp = app.get('/manage/agendas/desk/%s/import-exceptions-from-ics/' % desk.pk)
assert 'all_desks' not in resp.form.fields
resp.form['ics_url'] = 'http://example.com/foo.ics'
mocked_response = mock.Mock()
mocked_response.text = """BEGIN:VCALENDAR
@ -815,6 +889,7 @@ def test_agenda_import_time_period_exception_file_desk_simple_management(app, ad
login(app)
resp = app.get('/manage/agendas/desk/%s/import-exceptions-from-ics/' % desk.pk)
assert 'all_desks' not in resp.form.fields
ics_exceptions = b"""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//foo.bar//EN