From deabab63a2dc77cb7a71c5b01edb6e5884af67a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Mon, 1 Jun 2020 10:11:42 +0200
Subject: [PATCH] agendas: manager can add exception even if not timeperiod
 defined (#42629)

---
 .../manager_meetings_agenda_settings.html     |  20 ++-
 tests/test_manager.py                         | 117 ++++--------------
 2 files changed, 32 insertions(+), 105 deletions(-)

diff --git a/chrono/manager/templates/chrono/manager_meetings_agenda_settings.html b/chrono/manager/templates/chrono/manager_meetings_agenda_settings.html
index 84cbf81..4c5a034 100644
--- a/chrono/manager/templates/chrono/manager_meetings_agenda_settings.html
+++ b/chrono/manager/templates/chrono/manager_meetings_agenda_settings.html
@@ -69,19 +69,17 @@
                 </li>
                 {% endfor %}
                 <li><a class="add" rel="popup" href="{{add_time_period_url}}">{% trans 'Add a time period' %}</a></li>
-                {% if desk.timeperiod_set.count %}
                 {% url 'chrono-manager-agenda-add-time-period-exception' agenda_pk=object.pk pk=desk.pk as add_time_period_exception_url %}
-                    <li><a><strong>{% trans 'Exceptions' %}</strong></a><a class="link-action-icon upload" rel="popup" href="{% url 'chrono-manager-desk-add-import-time-period-exceptions' pk=desk.pk %}" title="{% trans 'Import exceptions from .ics' %}">{% trans 'upload' %}</a></li>
-                    {% for exception in desk.get_exceptions_within_two_weeks %}
-                         <li><a rel="popup" href="{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}">
-                        {{ exception }}
-                        <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>
-                    {% endfor %}
-                    {% if not desk.are_all_exceptions_displayed %}
-                    <li><a class="timeperiod-exception-all desk-{{ desk.pk }}" rel="popup" data-selector="div.timeperiod" href="{% url 'chrono-manager-time-period-exception-extract-list' pk=desk.id %}">({% trans 'see all exceptions' %})</a></li>
-                    {% endif %}
-                    <li><a class="add" rel="popup" href="{{add_time_period_exception_url}}">{% trans 'Add a time period exception' %}</a></li>
+                <li><a><strong>{% trans 'Exceptions' %}</strong></a><a class="link-action-icon upload" rel="popup" href="{% url 'chrono-manager-desk-add-import-time-period-exceptions' pk=desk.pk %}" title="{% trans 'Import exceptions from .ics' %}">{% trans 'upload' %}</a></li>
+                {% for exception in desk.get_exceptions_within_two_weeks %}
+                     <li><a rel="popup" href="{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}">
+                    {{ exception }}
+                    <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>
+                {% endfor %}
+                {% if not desk.are_all_exceptions_displayed %}
+                <li><a class="timeperiod-exception-all desk-{{ desk.pk }}" rel="popup" data-selector="div.timeperiod" href="{% url 'chrono-manager-time-period-exception-extract-list' pk=desk.id %}">({% trans 'see all exceptions' %})</a></li>
                 {% endif %}
+                <li><a class="add" rel="popup" href="{{add_time_period_exception_url}}">{% trans 'Add a time period exception' %}</a></li>
             </ul>
         </div>
         {% endfor %}
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 1fb5faf..0b92501 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -848,14 +848,12 @@ def test_meetings_agenda_delete_meeting_type(app, admin_user):
 
 
 def test_meetings_agenda_add_time_period(app, admin_user):
-    agenda = Agenda(label=u'Foo bar', kind='meetings')
-    agenda.save()
+    agenda = Agenda.objects.create(label=u'Foo bar', kind='meetings')
     desk = Desk.objects.create(agenda=agenda, label='Desk A')
-    MeetingType(agenda=agenda, label='Blah').save()
+    MeetingType.objects.create(agenda=agenda, label='Blah')
     app = login(app)
-    resp = app.get('/manage/agendas/%s/' % agenda.id, status=302).follow()
-    resp = resp.click('Settings')
-    resp = resp.click('Add a time period')
+    resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
+    resp = resp.click('Add a time period$')
     resp.form['weekdays-2'].checked = True
     resp.form['start_time'] = '10:00'
     resp.form['end_time'] = '17:00'
@@ -1054,23 +1052,11 @@ def test_meetings_agenda_delete_desk(app, admin_user):
 
 
 def test_meetings_agenda_add_time_period_exception(app, admin_user):
+    agenda = Agenda.objects.create(label=u'Foo bar', kind='meetings')
+    desk = Desk.objects.create(agenda=agenda, label='Desk A')
+    MeetingType.objects.create(agenda=agenda, label='Blah')
     app = login(app)
-    resp = app.get('/manage/', status=200)
-    resp = resp.click('New')
-    resp.form['label'] = 'Foo bar'
-    resp.form['kind'] = 'meetings'
-    resp = resp.form.submit().follow()
-    agenda = Agenda.objects.first()
-    resp = resp.click('New Meeting Type')
-    resp.form['label'] = 'Blah'
-    resp.form['duration'] = '60'
-    resp = resp.form.submit().follow()
-    # adding a new time period
-    resp = resp.click('Add a time period')
-    resp.form['weekdays-2'].checked = True
-    resp.form['start_time'] = '10:00'
-    resp.form['end_time'] = '17:00'
-    resp = resp.form.submit().follow()
+    resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
     resp = resp.click('Add a time period exception')
     today = datetime.datetime.today().replace(hour=0, minute=0, second=0, microsecond=0)
     tomorrow = make_aware(today + datetime.timedelta(days=1))
@@ -1101,9 +1087,7 @@ def test_meetings_agenda_add_time_period_exception(app, admin_user):
     assert TimePeriodException.objects.count() == 2
     assert 'Exception 1' in resp.text
     assert 'Exception 2' not in resp.text
-    resp = resp.click(
-        href="/manage/time-period-exceptions/%d/exception-extract-list" % agenda.desk_set.first().pk
-    )
+    resp = resp.click(href="/manage/time-period-exceptions/%d/exception-extract-list" % desk.pk)
     assert 'Exception 1' in resp.text
     assert 'Exception 2' in resp.text
 
@@ -1292,25 +1276,15 @@ def test_exception_list(app, admin_user):
 def test_agenda_import_time_period_exception_from_ics(app, admin_user):
     agenda = Agenda.objects.create(label='Example', kind='meetings')
     desk = Desk.objects.create(agenda=agenda, label='Test Desk')
-    MeetingType(agenda=agenda, label='Foo').save()
+    MeetingType.objects.create(agenda=agenda, label='Foo')
     login(app)
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
-    assert 'Import exceptions from .ics' not in resp.text
-
-    TimePeriod.objects.create(
-        weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
-    )
-
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
+    resp = app.get('/manage/agendas/%d/settings' % agenda.pk)
     assert 'Import exceptions from .ics' in resp.text
     resp = resp.click('upload')
     assert "To add new exceptions, you can upload a file or specify an address to a remote calendar." in resp
     resp = resp.form.submit(status=200)
     assert 'Please provide an ICS File or an URL.' in resp.text
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
+    resp = app.get('/manage/agendas/%d/settings' % agenda.pk)
     resp = resp.click('upload')
     resp.form['ics_file'] = Upload('exceptions.ics', b'invalid content', 'text/calendar')
     resp = resp.form.submit(status=200)
@@ -1343,8 +1317,7 @@ DTEND:20180101
 SUMMARY:New Year's Eve
 END:VEVENT
 END:VCALENDAR"""
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
+    resp = app.get('/manage/agendas/%d/settings' % agenda.pk)
     resp = resp.click('upload')
     resp.form['ics_file'] = Upload('exceptions.ics', ics_with_exceptions, 'text/calendar')
     resp = resp.form.submit(status=302)
@@ -1391,18 +1364,9 @@ END:VCALENDAR"""
 def test_agenda_import_time_period_exception_with_remote_ics(mocked_get, app, admin_user):
     agenda = Agenda.objects.create(label='New Example', kind='meetings')
     desk = Desk.objects.create(agenda=agenda, label='New Desk')
-    MeetingType(agenda=agenda, label='Bar').save()
+    MeetingType.objects.create(agenda=agenda, label='Bar')
     login(app)
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
-    assert 'Import exceptions from .ics' not in resp.text
-
-    TimePeriod.objects.create(
-        weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
-    )
-
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
+    resp = app.get('/manage/agendas/%d/settings' % agenda.pk)
     resp = resp.click('upload')
 
     assert 'ics_file' in resp.form.fields
@@ -1435,18 +1399,9 @@ END:VCALENDAR"""
 def test_agenda_import_time_period_exception_with_remote_ics_no_events(mocked_get, app, admin_user):
     agenda = Agenda.objects.create(label='New Example', kind='meetings')
     desk = Desk.objects.create(agenda=agenda, label='New Desk')
-    MeetingType(agenda=agenda, label='Bar').save()
+    MeetingType.objects.create(agenda=agenda, label='Bar')
     login(app)
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
-    assert 'Import exceptions from .ics' not in resp.text
-
-    TimePeriod.objects.create(
-        weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
-    )
-
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
+    resp = app.get('/manage/agendas/%d/settings' % agenda.pk)
     resp = resp.click('upload')
     resp.form['ics_url'] = 'http://example.com/foo.ics'
     mocked_response = mock.Mock()
@@ -1470,18 +1425,9 @@ def test_agenda_import_time_period_exception_from_remote_ics_with_connection_err
 ):
     agenda = Agenda.objects.create(label='New Example', kind='meetings')
     desk = Desk.objects.create(agenda=agenda, label='New Desk')
-    MeetingType(agenda=agenda, label='Bar').save()
+    MeetingType.objects.create(agenda=agenda, label='Bar')
     login(app)
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
-    assert 'Import exceptions from .ics' not in resp.text
-
-    TimePeriod.objects.create(
-        weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
-    )
-
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
+    resp = app.get('/manage/agendas/%d/settings' % agenda.pk)
     resp = resp.click('upload')
 
     assert 'ics_file' in resp.form.fields
@@ -1502,18 +1448,9 @@ def test_agenda_import_time_period_exception_from_remote_ics_with_connection_err
 def test_agenda_import_time_period_exception_from_forbidden_remote_ics(mocked_get, app, admin_user):
     agenda = Agenda.objects.create(label='New Example', kind='meetings')
     desk = Desk.objects.create(agenda=agenda, label='New Desk')
-    MeetingType(agenda=agenda, label='Bar').save()
+    MeetingType.objects.create(agenda=agenda, label='Bar')
     login(app)
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
-    assert 'Import exceptions from .ics' not in resp.text
-
-    TimePeriod.objects.create(
-        weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
-    )
-
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
+    resp = app.get('/manage/agendas/%d/settings' % agenda.pk)
     resp = resp.click('upload')
     resp.form['ics_url'] = 'http://example.com/foo.ics'
     mocked_response = mock.Mock()
@@ -1532,17 +1469,9 @@ def test_agenda_import_time_period_exception_from_forbidden_remote_ics(mocked_ge
 def test_agenda_import_time_period_exception_from_remote_ics_with_ssl_error(mocked_get, app, admin_user):
     agenda = Agenda.objects.create(label='New Example', kind='meetings')
     desk = Desk.objects.create(agenda=agenda, label='New Desk')
-    MeetingType(agenda=agenda, label='Bar').save()
+    MeetingType.objects.create(agenda=agenda, label='Bar')
     login(app)
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
-    assert 'Import exceptions from .ics' not in resp.text
-    TimePeriod.objects.create(
-        weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
-    )
-
-    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
-    resp = resp.click('Settings')
+    resp = app.get('/manage/agendas/%d/settings' % agenda.pk)
     resp = resp.click('upload')
     resp.form['ics_url'] = 'https://example.com/foo.ics'
     mocked_response = mock.Mock()
-- 
2.20.1

