Projet

Général

Profil

0001-general-move-agenda-settings-to-a-secondary-page-111.patch

Frédéric Péters, 26 novembre 2017 19:25

Télécharger (52 ko)

Voir les différences:

Subject: [PATCH 1/2] general: move agenda settings to a secondary page
 (#11114)

 .../templates/chrono/manager_agenda_settings.html  | 173 +++++++++++++++++++++
 .../templates/chrono/manager_agenda_view.html      | 144 +----------------
 .../templates/chrono/manager_desk_form.html        |   2 +-
 .../templates/chrono/manager_event_form.html       |   2 +-
 .../templates/chrono/manager_import_events.html    |   2 +-
 .../chrono/manager_import_exceptions.html          |   2 +-
 .../chrono/manager_meeting_type_form.html          |   2 +-
 .../chrono/manager_time_period_exception_form.html |   2 +-
 .../templates/chrono/manager_time_period_form.html |   2 +-
 chrono/manager/urls.py                             |   2 +
 chrono/manager/views.py                            |  43 +++--
 tests/test_manager.py                              | 154 +++++++++---------
 12 files changed, 293 insertions(+), 237 deletions(-)
 create mode 100644 chrono/manager/templates/chrono/manager_agenda_settings.html
chrono/manager/templates/chrono/manager_agenda_settings.html
1
{% extends "chrono/manager_agenda_view.html" %}
2
{% load i18n %}
3

  
4
{% block breadcrumb %}
5
{{ block.super }}
6
<a href=".">{% trans "Settings" %}</a>
7
{% endblock %}
8

  
9
{% block appbar %}
10
<h2>{% trans "Settings" %}
11
    <span class="identifier">[{% trans "identifier:" %} {{object.slug}}]</span></h2>
12
</h2>
13
{% if user.is_staff %}
14
  <a rel="popup" href="{% url 'chrono-manager-agenda-delete' pk=object.id %}">{% trans 'Delete' %}</a>
15
{% endif %}
16
{% if user_can_manage %}
17
  <a rel="popup" href="{% url 'chrono-manager-agenda-edit' pk=object.id %}">{% trans 'Options' %}</a>
18
  {% if object.kind == "events" %}
19
    <a rel="popup" href="{% url 'chrono-manager-agenda-import-events' pk=object.id %}">{% trans 'Import Events' %}</a>
20
    <a rel="popup" href="{% url 'chrono-manager-agenda-add-event' pk=object.id %}">{% trans 'New Event' %}</a>
21
  {% else %}
22
    <a rel="popup" href="{% url 'chrono-manager-agenda-add-meeting-type' pk=object.id %}">{% trans 'New Meeting Type' %}</a>
23
    <a rel="popup" href="{% url 'chrono-manager-agenda-add-desk' pk=object.id %}">{% trans 'New Desk' %}</a>
24
  {% endif %}
25
{% endif %}
26
{% endblock %}
27

  
28
{% block content %}
29

  
30
{% if object.kind == "events" %}
31
<h3>{% trans "Events" %}</h3>
32
{% if object.event_set.count %}
33
<div>
34
  <ul class="objects-list single-links">
35
    {% for event in object.event_set.all %}
36
    <li class="{% if event.booked_places > event.places %}overbooking{% endif %}
37
               {% if event.full %}full{% endif %}
38
               {% if not event.in_bookable_period %}not-{% endif %}bookable"
39
        {% if event.places %}
40
          data-total="{{event.places}}" data-booked="{{event.booked_places}}"
41
        {% elif event.waiting_list_places %}
42
          data-total="{{event.waiting_list_places}}" data-booked="{{event.waiting_list}}"
43
        {% endif %}
44
        ><a rel="popup" href="{% if user_can_manage %}{% url 'chrono-manager-event-edit' pk=event.id %}{% else %}#{% endif %}">
45
        {% if event.label %}{{event.label}} / {% endif %}
46
        {{ event.start_datetime }}
47
        {% if event.full %}/ <span class="full">{% trans "full" %}</span>{% endif %}
48
        (
49
        {% if event.places %}
50
        {% blocktrans with places=event.places booked_places=event.booked_places %}{{ places }} places, {{ booked_places }} booked places{% endblocktrans %}
51
        {% endif %}
52
        {% if event.places and event.waiting_list_places %} / {% endif %}
53
        {% if event.waiting_list_places %}
54
        {% blocktrans with places=event.waiting_list_places waiting_places=event.waiting_list %}
55
        {{waiting_places}} on {{ places }} in waiting list
56
        {% endblocktrans %}
57
        {% endif %}
58
        )
59
        {% if not event.in_bookable_period %}
60
        ({% trans "out of bookable period" %})
61
        {% endif %}
62
            </a>
63
        {% if user_can_manage %}<a rel="popup" class="delete" href="{% url 'chrono-manager-event-delete' pk=event.id %}">{% trans "remove" %}</a>{% endif %}
64
        <span class="occupation-bar"></span>
65
    </li>
66
    {% endfor %}
67
  </ul>
68
</div>
69
{% else %}
70
<div class="big-msg-info">
71
  {% blocktrans %}
72
  This agenda doesn't have any event yet. Click on the "New Event" button in
73
  the top right of the page to add a first one.
74
  {% endblocktrans %}
75
</div>
76
{% endif %}
77
{% endif %}
78

  
79
{% if object.kind == "meetings" %}
80

  
81
<h3>{% trans 'Meeting Types' %}</h3>
82
{% if object.meetingtype_set.count %}
83
<div>
84
  <ul class="objects-list single-links">
85
    {% for meeting_type in object.meetingtype_set.all %}
86
    <li><a rel="popup" href="{% if user_can_manage %}{% url 'chrono-manager-meeting-type-edit' pk=meeting_type.id %}{% else %}#{% endif %}">
87
        {{meeting_type.label}}
88
        <span class="identifier">[{% trans "identifier:" %} {{meeting_type.slug}}]</span>
89
        </a>
90
        {% if user_can_manage %}<a rel="popup" class="delete" href="{% url 'chrono-manager-meeting-type-delete' pk=meeting_type.id %}">{% trans "remove" %}</a>{% endif %}
91
    </li>
92
    {% endfor %}
93
  </ul>
94
</div>
95

  
96
<h3>{% trans 'Time Periods' %}</h3>
97
    {% if object.desk_set.count %}
98
    <div class="timeperiods">
99
        {% for desk in object.desk_set.all %}
100
        <div class="timeperiod">
101
            {% url 'chrono-manager-agenda-add-time-period' agenda_pk=object.pk pk=desk.pk as add_time_period_url %}
102
            <ul class="objects-list single-links">
103
                {% if forloop.counter != 1 or forloop.revcounter != 1 %}
104
                <li><a rel="popup" href="{% if user_can_manage %}{% url 'chrono-manager-desk-edit' pk=desk.id %}{% else %}#{% endif %}">
105
                    <strong>{{ desk.label }}</strong>
106
                    </a>
107
                   {% if user_can_manage %}<a rel="popup" class="delete" href="{% url 'chrono-manager-desk-delete' pk=desk.id %}">{% trans "remove" %}</a>{% endif %}
108
                </li>
109
                {% endif %}
110
                {% for time_period in desk.timeperiod_set.all %}
111
                <li><a rel="popup" href="{% if user_can_manage %}{% url 'chrono-manager-time-period-edit' pk=time_period.id %}{% else %}#{% endif %}">
112
                {{time_period.weekday_str}} / {{time_period.start_time}} → {{time_period.end_time}} </a>
113
                {% if user_can_manage %}<a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-delete' pk=time_period.id %}">{% trans "remove" %}</a>{% endif %}
114

  
115
                </li>
116
                {% endfor %}
117
                {% if user_can_manage %}
118
                <li><a class="add" rel="popup" href="{{add_time_period_url}}">{% trans 'Add a time period' %}</a></li>
119
                {% endif %}
120
                {% if desk.timeperiod_set.count %}
121
                {% url 'chrono-manager-agenda-add-time-period-exception' agenda_pk=object.pk pk=desk.pk as add_time_period_exception_url %}
122
                    <li><a href="#"><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>
123
                    {% for exception in desk.get_exceptions_within_two_weeks %}
124
                         <li><a rel="popup"  href="{% if user_can_manage %}{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}{% else %}#{% endif %}">
125
                        {{ exception }}
126
                        {% if user_can_manage %}<a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>{% endif %}
127
                    {% endfor %}
128
                    {% if not desk.are_all_exceptions_displayed %}
129
                    <li><a class="timeperiod-exception-all" rel="popup" data-selector="div.timeperiod" href="{% url 'chrono-manager-time-period-exception-list' pk=desk.id %}">({% trans 'see all exceptions' %})</a></li>
130
                    {% endif %}
131
                    <li><a class="add" rel="popup" href="{{add_time_period_exception_url}}">{% trans 'Add a time period exception' %}</a></li>
132
                {% endif %}
133
            </ul>
134
        </div>
135
        {% endfor %}
136
    </div>
137
    {% else %}
138
    <div>
139
    {% blocktrans %}
140
    This agenda doesn't have any desk yet. Click on the "New Desk" button in
141
    the top right of the page to add a first one.
142
    {% endblocktrans %}
143
    </div>
144
{% endif %}
145

  
146
{% else %}
147
<div class="big-msg-info">
148
  {% blocktrans %}
149
  This agenda doesn't have any meeting type yet. Click on the "New Meeting Type" button in
150
  the top right of the page to add a first one.
151
  {% endblocktrans %}
152
</div>
153
{% endif %}
154

  
155

  
156
{% endif %}
157

  
158

  
159
<h3>{% trans "Permissions" %}</h3>
160

  
161
<ul>
162
  <li>{% trans "Edit Role:" %} {% if agenda.edit_role %}{{ agenda.edit_role }}{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
163
  <li>{% trans "View Role:" %} {% if agenda.view_role %}{{ agenda.view_role }}{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
164
</ul>
165

  
166
<h3>{% trans "Booking Delays" %}</h3>
167

  
168
<ul>
169
  <li>{% trans "Minimal booking delay:" %} {{ agenda.minimal_booking_delay }} {% trans "days" %}</li>
170
  <li>{% trans "Maximal booking delay:" %} {{ agenda.maximal_booking_delay }} {% trans "days" %}</li>
171
</ul>
172

  
173
{% endblock %}
chrono/manager/templates/chrono/manager_agenda_view.html
2 2
{% load i18n %}
3 3

  
4 4
{% block appbar %}
5
<h2>{{ object.label }}
6
    <span class="identifier">[{% trans "identifier:" %} {{object.slug}}]</span></h2>
7
</h2>
8
{% if user.is_staff %}
9
  <a rel="popup" href="{% url 'chrono-manager-agenda-delete' pk=object.id %}">{% trans 'Delete' %}</a>
10
{% endif %}
5
<h2>{{ object.label }}</h2>
11 6
{% if user_can_manage %}
12
  <a rel="popup" href="{% url 'chrono-manager-agenda-edit' pk=object.id %}">{% trans 'Options' %}</a>
13
  {% if object.kind == "events" %}
14
    <a rel="popup" href="{% url 'chrono-manager-agenda-import-events' pk=object.id %}">{% trans 'Import Events' %}</a>
15
    <a rel="popup" href="{% url 'chrono-manager-agenda-add-event' pk=object.id %}">{% trans 'New Event' %}</a>
16
  {% else %}
17
    <a rel="popup" href="{% url 'chrono-manager-agenda-add-meeting-type' pk=object.id %}">{% trans 'New Meeting Type' %}</a>
18
    <a rel="popup" href="{% url 'chrono-manager-agenda-add-desk' pk=object.id %}">{% trans 'New Desk' %}</a>
19
  {% endif %}
7
  <a href="{% url 'chrono-manager-agenda-settings' pk=object.id %}">{% trans 'Settings' %}</a>
20 8
{% endif %}
21 9
{% endblock %}
22 10

  
......
30 18
{% endblock %}
31 19

  
32 20
{% block content %}
33

  
34
{% if object.kind == "events" %}
35
{% if object.event_set.count %}
36
<div>
37
  <ul class="objects-list single-links">
38
    {% for event in object.event_set.all %}
39
    <li class="{% if event.booked_places > event.places %}overbooking{% endif %}
40
               {% if event.full %}full{% endif %}
41
               {% if not event.in_bookable_period %}not-{% endif %}bookable"
42
        {% if event.places %}
43
          data-total="{{event.places}}" data-booked="{{event.booked_places}}"
44
        {% elif event.waiting_list_places %}
45
          data-total="{{event.waiting_list_places}}" data-booked="{{event.waiting_list}}"
46
        {% endif %}
47
        ><a rel="popup" href="{% if user_can_manage %}{% url 'chrono-manager-event-edit' pk=event.id %}{% else %}#{% endif %}">
48
        {% if event.label %}{{event.label}} / {% endif %}
49
        {{ event.start_datetime }}
50
        {% if event.full %}/ <span class="full">{% trans "full" %}</span>{% endif %}
51
        (
52
        {% if event.places %}
53
        {% blocktrans with places=event.places booked_places=event.booked_places %}{{ places }} places, {{ booked_places }} booked places{% endblocktrans %}
54
        {% endif %}
55
        {% if event.places and event.waiting_list_places %} / {% endif %}
56
        {% if event.waiting_list_places %}
57
        {% blocktrans with places=event.waiting_list_places waiting_places=event.waiting_list %}
58
        {{waiting_places}} on {{ places }} in waiting list
59
        {% endblocktrans %}
60
        {% endif %}
61
        )
62
        {% if not event.in_bookable_period %}
63
        ({% trans "out of bookable period" %})
64
        {% endif %}
65
            </a>
66
        {% if user_can_manage %}<a rel="popup" class="delete" href="{% url 'chrono-manager-event-delete' pk=event.id %}">{% trans "remove" %}</a>{% endif %}
67
        <span class="occupation-bar"></span>
68
    </li>
69
    {% endfor %}
70
  </ul>
71
</div>
72
{% else %}
73
<div class="big-msg-info">
74
  {% blocktrans %}
75
  This agenda doesn't have any event yet. Click on the "New Event" button in
76
  the top right of the page to add a first one.
77
  {% endblocktrans %}
78
</div>
79
{% endif %}
80
{% endif %}
81

  
82
{% if object.kind == "meetings" %}
83

  
84
<h3>{% trans 'Meeting Types' %}</h3>
85
{% if object.meetingtype_set.count %}
86
<div>
87
  <ul class="objects-list single-links">
88
    {% for meeting_type in object.meetingtype_set.all %}
89
    <li><a rel="popup" href="{% if user_can_manage %}{% url 'chrono-manager-meeting-type-edit' pk=meeting_type.id %}{% else %}#{% endif %}">
90
        {{meeting_type.label}}
91
        <span class="identifier">[{% trans "identifier:" %} {{meeting_type.slug}}]</span>
92
        </a>
93
        {% if user_can_manage %}<a rel="popup" class="delete" href="{% url 'chrono-manager-meeting-type-delete' pk=meeting_type.id %}">{% trans "remove" %}</a>{% endif %}
94
    </li>
95
    {% endfor %}
96
  </ul>
97
</div>
98

  
99
<h3>{% trans 'Time Periods' %}</h3>
100
    {% if object.desk_set.count %}
101
    <div class="timeperiods">
102
        {% for desk in object.desk_set.all %}
103
        <div class="timeperiod">
104
            {% url 'chrono-manager-agenda-add-time-period' agenda_pk=object.pk pk=desk.pk as add_time_period_url %}
105
            <ul class="objects-list single-links">
106
                {% if forloop.counter != 1 or forloop.revcounter != 1 %}
107
                <li><a rel="popup" href="{% if user_can_manage %}{% url 'chrono-manager-desk-edit' pk=desk.id %}{% else %}#{% endif %}">
108
                    <strong>{{ desk.label }}</strong>
109
                    </a>
110
                   {% if user_can_manage %}<a rel="popup" class="delete" href="{% url 'chrono-manager-desk-delete' pk=desk.id %}">{% trans "remove" %}</a>{% endif %}
111
                </li>
112
                {% endif %}
113
                {% for time_period in desk.timeperiod_set.all %}
114
                <li><a rel="popup" href="{% if user_can_manage %}{% url 'chrono-manager-time-period-edit' pk=time_period.id %}{% else %}#{% endif %}">
115
                {{time_period.weekday_str}} / {{time_period.start_time}} → {{time_period.end_time}} </a>
116
                {% if user_can_manage %}<a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-delete' pk=time_period.id %}">{% trans "remove" %}</a>{% endif %}
117

  
118
                </li>
119
                {% endfor %}
120
                {% if user_can_manage %}
121
                <li><a class="add" rel="popup" href="{{add_time_period_url}}">{% trans 'Add a time period' %}</a></li>
122
                {% endif %}
123
                {% if desk.timeperiod_set.count %}
124
                {% url 'chrono-manager-agenda-add-time-period-exception' agenda_pk=object.pk pk=desk.pk as add_time_period_exception_url %}
125
                    <li><a href="#"><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>
126
                    {% for exception in desk.get_exceptions_within_two_weeks %}
127
                         <li><a rel="popup"  href="{% if user_can_manage %}{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}{% else %}#{% endif %}">
128
                        {{ exception }}
129
                        {% if user_can_manage %}<a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>{% endif %}
130
                    {% endfor %}
131
                    {% if not desk.are_all_exceptions_displayed %}
132
                    <li><a class="timeperiod-exception-all" rel="popup" data-selector="div.timeperiod" href="{% url 'chrono-manager-time-period-exception-list' pk=desk.id %}">({% trans 'see all exceptions' %})</a></li>
133
                    {% endif %}
134
                    <li><a class="add" rel="popup" href="{{add_time_period_exception_url}}">{% trans 'Add a time period exception' %}</a></li>
135
                {% endif %}
136
            </ul>
137
        </div>
138
        {% endfor %}
139
    </div>
140
    {% else %}
141
    <div>
142
    {% blocktrans %}
143
    This agenda doesn't have any desk yet. Click on the "New Desk" button in
144
    the top right of the page to add a first one.
145
    {% endblocktrans %}
146
    </div>
147
{% endif %}
148

  
149
{% else %}
150
<div class="big-msg-info">
151
  {% blocktrans %}
152
  This agenda doesn't have any meeting type yet. Click on the "New Meeting Type" button in
153
  the top right of the page to add a first one.
154
  {% endblocktrans %}
155
</div>
156
{% endif %}
157

  
158

  
159
{% endif %}
160

  
161 21
{% endblock %}
chrono/manager/templates/chrono/manager_desk_form.html
31 31
  {{ form.as_p }}
32 32
  <div class="buttons">
33 33
    <button class="submit-button">{% trans "Save" %}</button>
34
    <a class="cancel" href="{% url 'chrono-manager-agenda-view' pk=agenda.id %}">{% trans 'Cancel' %}</a>
34
    <a class="cancel" href="{% url 'chrono-manager-agenda-settings' pk=agenda.id %}">{% trans 'Cancel' %}</a>
35 35
  </div>
36 36
</form>
37 37
{% endblock %}
chrono/manager/templates/chrono/manager_event_form.html
29 29
  {{ form.as_p }}
30 30
  <div class="buttons">
31 31
    <button class="submit-button">{% trans "Save" %}</button>
32
    <a class="cancel" href="{% url 'chrono-manager-agenda-view' pk=agenda.id %}">{% trans 'Cancel' %}</a>
32
    <a class="cancel" href="{% url 'chrono-manager-agenda-settings' pk=agenda.id %}">{% trans 'Cancel' %}</a>
33 33
  </div>
34 34
</form>
35 35
{% endblock %}
chrono/manager/templates/chrono/manager_import_events.html
25 25
  </p>
26 26
  <div class="buttons">
27 27
    <button>{% trans "Import" %}</button>
28
    <a class="cancel" href="{% url 'chrono-manager-agenda-view' pk=agenda.id %}">{% trans 'Cancel' %}</a>
28
    <a class="cancel" href="{% url 'chrono-manager-agenda-settings' pk=agenda.id %}">{% trans 'Cancel' %}</a>
29 29
  </div>
30 30
</form>
31 31
{% endblock %}
chrono/manager/templates/chrono/manager_import_exceptions.html
20 20
  </p>
21 21
  <div class="buttons">
22 22
    <button>{% trans "Import" %}</button>
23
    <a class="cancel" href="{% url 'chrono-manager-agenda-view' pk=agenda.id %}">{% trans 'Cancel' %}</a>
23
    <a class="cancel" href="{% url 'chrono-manager-agenda-settings' pk=agenda.id %}">{% trans 'Cancel' %}</a>
24 24
  </div>
25 25
</form>
26 26
{% endblock %}
chrono/manager/templates/chrono/manager_meeting_type_form.html
29 29
  {{ form.as_p }}
30 30
  <div class="buttons">
31 31
    <button class="submit-button">{% trans "Save" %}</button>
32
    <a class="cancel" href="{% url 'chrono-manager-agenda-view' pk=agenda.id %}">{% trans 'Cancel' %}</a>
32
    <a class="cancel" href="{% url 'chrono-manager-agenda-settings' pk=agenda.id %}">{% trans 'Cancel' %}</a>
33 33
  </div>
34 34
</form>
35 35
{% endblock %}
chrono/manager/templates/chrono/manager_time_period_exception_form.html
31 31
  {{ form.as_p }}
32 32
  <div class="buttons">
33 33
    <button class="submit-button">{% trans "Save" %}</button>
34
    <a class="cancel" href="{% url 'chrono-manager-agenda-view' pk=desk.agenda.id %}">{% trans 'Cancel' %}</a>
34
    <a class="cancel" href="{% url 'chrono-manager-agenda-settings' pk=desk.agenda.id %}">{% trans 'Cancel' %}</a>
35 35
  </div>
36 36
</form>
37 37
{% endblock %}
chrono/manager/templates/chrono/manager_time_period_form.html
31 31
  {{ form.as_p }}
32 32
  <div class="buttons">
33 33
    <button class="submit-button">{% trans "Save" %}</button>
34
    <a class="cancel" href="{% url 'chrono-manager-agenda-view' pk=desk.agenda.id %}">{% trans 'Cancel' %}</a>
34
    <a class="cancel" href="{% url 'chrono-manager-agenda-settings' pk=desk.agenda.id %}">{% trans 'Cancel' %}</a>
35 35
  </div>
36 36
</form>
37 37
{% endblock %}
chrono/manager/urls.py
24 24
            name='chrono-manager-agenda-add'),
25 25
        url(r'^agendas/(?P<pk>\w+)/$', views.agenda_view,
26 26
            name='chrono-manager-agenda-view'),
27
        url(r'^agendas/(?P<pk>\w+)/settings$', views.agenda_settings,
28
            name='chrono-manager-agenda-settings'),
27 29
        url(r'^agendas/(?P<pk>\w+)/edit$', views.agenda_edit,
28 30
            name='chrono-manager-agenda-edit'),
29 31
        url(r'^agendas/(?P<pk>\w+)/delete$', views.agenda_delete,
chrono/manager/views.py
20 20
from django.core.exceptions import PermissionDenied
21 21
from django.core.urlresolvers import reverse, reverse_lazy
22 22
from django.db.models import Q
23
from django.http import HttpResponse, Http404
23
from django.http import HttpResponse, Http404, HttpResponseRedirect
24 24
from django.utils.timezone import now
25 25
from django.utils.translation import ugettext_lazy as _
26 26
from django.utils.translation import ungettext
......
67 67
            default_desk.save()
68 68
        return model_form
69 69

  
70
    def get_success_url(self):
71
        return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.object.id})
72

  
70 73
agenda_add = AgendaAddView.as_view()
71 74

  
72 75

  
......
81 84
            raise PermissionDenied()
82 85
        return obj
83 86

  
87
    def get_success_url(self):
88
        return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.object.id})
89

  
84 90
agenda_edit = AgendaEditView.as_view()
85 91

  
86 92

  
......
113 119

  
114 120

  
115 121
class AgendaView(DetailView):
116
    template_name = 'chrono/manager_agenda_view.html'
117 122
    model = Agenda
118 123

  
119
    def get_context_data(self, **kwargs):
120
        context = super(AgendaView, self).get_context_data(**kwargs)
121
        if not self.get_object().can_be_viewed(self.request.user):
124
    def get(self, request, *args, **kwargs):
125
        try:
126
            agenda = Agenda.objects.get(id=kwargs.get('pk'))
127
        except Agenda.DoesNotExist:
128
            raise Http404()
129
        if not agenda.can_be_viewed(self.request.user):
122 130
            raise PermissionDenied()
123
        context['user_can_manage'] = self.get_object().can_be_managed(self.request.user)
124
        return context
131

  
132
        return HttpResponseRedirect(
133
                reverse('chrono-manager-agenda-settings', kwargs={'pk': agenda.id}))
125 134

  
126 135
agenda_view = AgendaView.as_view()
127 136

  
......
149 158
        return initial
150 159

  
151 160
    def get_success_url(self):
152
        return self.agenda.get_absolute_url()
161
        return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
153 162

  
154 163

  
155 164
class ManagedAgendaSubobjectMixin(object):
......
167 176
        return context
168 177

  
169 178
    def get_success_url(self):
170
        return self.agenda.get_absolute_url()
179
        return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
171 180

  
172 181

  
173 182
class ManagedDeskMixin(object):
......
194 203
        return initial
195 204

  
196 205
    def get_success_url(self):
197
        return self.desk.agenda.get_absolute_url()
206
        return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda.id})
198 207

  
199 208

  
200 209
class ManagedDeskSubobjectMixin(object):
......
213 222
        return context
214 223

  
215 224
    def get_success_url(self):
216
        return self.desk.agenda.get_absolute_url()
225
        return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda.id})
226

  
227

  
228
class AgendaSettings(ManagedAgendaMixin, DetailView):
229
    template_name = 'chrono/manager_agenda_settings.html'
230
    model = Agenda
231

  
232
    def get_context_data(self, **kwargs):
233
        context = super(AgendaSettings, self).get_context_data(**kwargs)
234
        context['user_can_manage'] = self.get_object().can_be_managed(self.request.user)
235
        return context
236

  
237
agenda_settings = AgendaSettings.as_view()
217 238

  
218 239

  
219 240
class AgendaAddEventView(ManagedAgendaMixin, CreateView):
tests/test_manager.py
127 127
    resp = resp.form.submit()
128 128

  
129 129
    agenda = Agenda.objects.get(label='Foo bar')
130
    assert resp.location.endswith('/manage/agendas/%s/' % agenda.id)
130
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
131 131
    resp = resp.follow()
132
    assert '<h2>Foo bar' in resp.body
132
    assert 'Foo bar' in resp.body
133
    assert '<h2>Settings' in resp.body
133 134

  
134 135
def test_add_agenda_as_manager(app, manager_user):
135 136
    # open /manage/ access to manager_user, and check agenda creation is not
......
146 147
    agenda.save()
147 148
    app = login(app)
148 149
    resp = app.get('/manage/', status=200)
149
    resp = resp.click('Foo bar')
150
    resp = resp.click('Foo bar').follow()
150 151
    resp = resp.click('Options')
151 152
    assert resp.form['label'].value == 'Foo bar'
152 153
    resp.form['label'] = 'Foo baz'
153 154
    resp = resp.form.submit()
154
    assert resp.location.endswith('/manage/agendas/%s/' % agenda.id)
155
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
155 156
    resp = resp.follow()
156
    assert '<h2>Foo baz' in resp.body
157
    assert 'Foo baz' in resp.body
158
    assert '<h2>Settings' in resp.body
157 159

  
158 160
def test_options_agenda_as_manager(app, manager_user):
159 161
    agenda = Agenda(label=u'Foo bar')
......
162 164
    app = login(app, username='manager', password='manager')
163 165
    resp = app.get('/manage/', status=200)
164 166
    resp = resp.click('Foo bar')
165
    assert not 'Options' in resp.body
167
    assert not 'Settings' in resp.body
168
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=403)
166 169
    resp = app.get('/manage/agendas/%s/edit' % agenda.id, status=403)
167 170

  
168 171
    agenda.edit_role = manager_user.groups.all()[0]
169 172
    agenda.save()
170 173

  
171 174
    resp = app.get('/manage/', status=200)
172
    resp = resp.click('Foo bar')
175
    resp = resp.click('Foo bar').follow()
173 176
    resp = resp.click('Options')
174 177
    assert resp.form['label'].value == 'Foo bar'
175 178
    resp.form['label'] = 'Foo baz'
176 179
    resp = resp.form.submit()
177
    assert resp.location.endswith('/manage/agendas/%s/' % agenda.id)
180
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
178 181
    resp = resp.follow()
179
    assert '<h2>Foo baz' in resp.body
182
    assert 'Foo baz' in resp.body
183
    assert '<h2>Settings' in resp.body
180 184

  
181 185
def test_delete_agenda(app, admin_user):
182 186
    agenda = Agenda(label=u'Foo bar')
183 187
    agenda.save()
184 188
    app = login(app)
185 189
    resp = app.get('/manage/', status=200)
186
    resp = resp.click('Foo bar')
190
    resp = resp.click('Foo bar').follow()
187 191
    resp = resp.click('Delete')
188 192
    resp = resp.form.submit()
189 193
    assert resp.location.endswith('/manage/')
......
199 203

  
200 204
    app = login(app)
201 205
    resp = app.get('/manage/', status=200)
202
    resp = resp.click('Foo bar')
206
    resp = resp.click('Foo bar').follow()
203 207
    resp = resp.click('Delete')
204 208
    assert 'Are you sure you want to delete this?' in resp.body
205 209

  
206 210
    booking = Booking(event=event)
207 211
    booking.save()
208 212
    resp = app.get('/manage/', status=200)
209
    resp = resp.click('Foo bar')
213
    resp = resp.click('Foo bar').follow()
210 214
    resp = resp.click('Delete')
211 215
    assert 'This cannot be removed' in resp.body
212 216

  
213 217
    booking.cancellation_datetime = now()
214 218
    booking.save()
215 219
    resp = app.get('/manage/', status=200)
216
    resp = resp.click('Foo bar')
220
    resp = resp.click('Foo bar').follow()
217 221
    resp = resp.click('Delete')
218 222
    assert 'Are you sure you want to delete this?' in resp.body
219 223

  
......
229 233
    agenda.save()
230 234
    app = login(app, username='manager', password='manager')
231 235
    resp = app.get('/manage/', status=200)
232
    resp = resp.click('Foo bar')
236
    resp = resp.click('Foo bar').follow()
233 237
    assert 'Options' in resp.body
234 238
    assert 'Delete' not in resp.body
235 239
    resp = app.get('/manage/agendas/%s/delete' % agenda.id, status=403)
......
239 243
    agenda.maximal_booking_delay = 0
240 244
    agenda.save()
241 245
    app = login(app)
242
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
246
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
243 247
    assert "This agenda doesn't have any event yet." in resp.body
244 248
    year = now().year + 1
245 249
    resp = resp.click('New Event')
......
266 270
    agenda.view_role = manager_user.groups.all()[0]
267 271
    agenda.save()
268 272
    app = login(app, username='manager', password='manager')
269
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
270
    assert "This agenda doesn't have any event yet." in resp.body
271
    assert '>New Event<' not in resp.body
273
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=302)
274
    app.get('/manage/agendas/%s/settings' % agenda.id, status=403)
272 275
    app.get('/manage/agendas/%s/add-event' % agenda.id, status=403)
273 276

  
274 277
    agenda.edit_role = manager_user.groups.all()[0]
275 278
    agenda.save()
276 279

  
277
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
280
    resp = app.get('/manage/agendas/%s/' % agenda.id).follow()
281
    assert '<h2>Settings' in resp.body
278 282
    resp = resp.click('New Event')
279 283
    resp.form['start_datetime'] = '2016-02-15 17:00'
280 284
    resp.form['places'] = 10
......
293 297
                  places=20, agenda=agenda)
294 298
    event.save()
295 299
    app = login(app)
296
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
300
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
297 301
    resp = resp.click('Feb. 15, 2016, 5 p.m.')
298 302
    assert resp.form['start_datetime'].value == '15/02/2016 17:00'
299 303
    resp.form['start_datetime'] = '2016-02-16 17:00'
......
316 320
                  places=20, agenda=agenda)
317 321
    event.save()
318 322
    app = login(app, username='manager', password='manager')
319
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
320
    assert '/events/%s/' % event.id not in resp.body
321 323
    resp = app.get('/manage/events/%s/' % event.id, status=403)
322 324

  
323 325
    agenda.edit_role = manager_user.groups.all()[0]
324 326
    agenda.save()
325
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
327
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
326 328
    resp = resp.click('Feb. 15, 2016, 5 p.m.')
327 329
    assert resp.form['start_datetime'].value == '15/02/2016 17:00'
328 330
    resp.form['start_datetime'] = '2016-02-16 17:00'
......
342 344
    Booking(event=event).save()
343 345
    Booking(event=event).save()
344 346
    app = login(app)
345
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
347
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
346 348
    assert '10 places' in resp.body
347 349
    assert '2 booked places' in resp.body
348 350

  
......
356 358
        Booking(event=event).save()
357 359
    app = login(app)
358 360

  
359
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
361
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
360 362
    assert not 'full' in resp.body
361 363
    assert not 'overbooking' in resp.body
362 364

  
363 365
    for i in range(8):
364 366
        Booking(event=event).save()
365 367

  
366
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
368
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
367 369
    assert 'full' in resp.body
368 370
    assert not 'overbooking' in resp.body
369 371

  
370 372
    Booking(event=event).save()
371
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
373
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
372 374
    assert 'full' in resp.body
373 375
    assert 'overbooking' in resp.body
374 376

  
......
380 382
    event.save()
381 383

  
382 384
    app = login(app)
383
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
385
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
384 386
    resp = resp.click(href=r'/manage/events/%s/$' % event.id)
385 387
    resp = resp.click('Delete')
386 388
    resp = resp.form.submit()
387
    assert resp.location.endswith('/manage/agendas/%s/' % agenda.id)
389
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
388 390
    assert Event.objects.count() == 0
389 391

  
390 392
def test_delete_busy_event(app, admin_user):
......
395 397
    event.save()
396 398

  
397 399
    app = login(app)
398
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
400
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
399 401
    resp = resp.click(href=r'/manage/events/%s/$' % event.id)
400 402
    resp = resp.click('Delete')
401 403
    assert 'Are you sure you want to delete this?' in resp.body
402 404

  
403 405
    booking = Booking(event=event)
404 406
    booking.save()
405
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
407
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
406 408
    resp = resp.click(href=r'/manage/events/%s/$' % event.id)
407 409
    resp = resp.click('Delete')
408 410
    assert 'This cannot be removed' in resp.body
409 411

  
410 412
    booking.cancellation_datetime = now()
411 413
    booking.save()
412
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
414
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
413 415
    resp = resp.click(href=r'/manage/events/%s/$' % event.id)
414 416
    resp = resp.click('Delete')
415 417
    assert 'Are you sure you want to delete this?' in resp.body
......
429 431
    event.save()
430 432

  
431 433
    app = login(app, username='manager', password='manager')
432
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
434
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
433 435
    resp = resp.click(href=r'/manage/events/%s/$' % event.id)
434 436
    resp = resp.click('Delete')
435 437
    resp = resp.form.submit()
436
    assert resp.location.endswith('/manage/agendas/%s/' % agenda.id)
438
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
437 439
    assert Event.objects.count() == 0
438 440

  
439 441
def test_import_events(app, admin_user):
......
441 443
    agenda.save()
442 444

  
443 445
    app = login(app)
444
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
446
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
445 447
    resp = resp.click('Import Events')
446 448
    sample_csv_resp = resp.click('Download sample file')
447 449
    assert sample_csv_resp.content_type == 'text/csv'
......
521 523
    resp.form['kind'] = 'meetings'
522 524
    resp = resp.form.submit()
523 525
    agenda = Agenda.objects.get(label='Foo bar')
524
    assert resp.location.endswith('/manage/agendas/%s/' % agenda.id)
526
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
525 527
    resp = resp.follow()
526
    assert '<h2>Foo bar' in resp.body
528
    assert 'Foo bar' in resp.body
529
    assert '<h2>Settings' in resp.body
527 530
    assert 'Meeting Types' in resp.body
528 531
    agenda = Agenda.objects.get(label='Foo bar')
529 532
    assert agenda.kind == 'meetings'
......
532 535
    agenda = Agenda(label=u'Foo bar', kind='meetings')
533 536
    agenda.save()
534 537
    app = login(app)
535
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
538
    resp = app.get('/manage/agendas/%s/' % agenda.id).follow()
536 539
    assert "This agenda doesn't have any meeting type yet." in resp.body
537 540
    resp = resp.click('New Meeting Type')
538 541
    resp.form['label'] = 'Blah'
......
557 560
    meeting_type.save()
558 561

  
559 562
    app = login(app)
560
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
563
    resp = app.get('/manage/agendas/%s/' % agenda.id).follow()
561 564
    resp = resp.click('Blah')
562 565
    resp = resp.click('Delete')
563 566
    resp = resp.form.submit()
564
    assert resp.location.endswith('/manage/agendas/%s/' % agenda.id)
567
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
565 568
    assert MeetingType.objects.count() == 0
566 569

  
567 570
def test_meetings_agenda_add_time_period(app, admin_user):
......
569 572
    agenda.save()
570 573
    desk = Desk.objects.create(agenda=agenda, label='Desk A')
571 574
    app = login(app)
572
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
575
    resp = app.get('/manage/agendas/%s/' % agenda.id).follow()
573 576
    assert not 'Add a time period' in resp.body
574 577
    MeetingType(agenda=agenda, label='Blah').save()
575
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
578
    resp = app.get('/manage/agendas/%s/' % agenda.id).follow()
576 579
    resp = resp.click('Add a time period')
577 580
    resp.form['weekday'].select(text='Wednesday')
578 581
    resp.form['start_time'] = '10:00'
......
617 620
    time_period.save()
618 621

  
619 622
    app = login(app)
620
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
623
    resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
621 624
    resp = resp.click('Wednesday')
622 625
    resp = resp.click('Delete')
623 626
    resp = resp.form.submit()
624
    assert resp.location.endswith('/manage/agendas/%s/' % agenda.id)
627
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
625 628
    assert TimePeriod.objects.count() == 0
626 629

  
627 630

  
......
640 643
    desk = Desk.objects.create(agenda=agenda, label='Desk A')
641 644
    app = login(app, username='manager', password='manager')
642 645
    resp = app.get('/manage/agendas/%d/' % agenda.id)
643
    assert 'New Meeting Type' in resp.content
644
    assert 'Add a time period' not in resp.content
646
    assert not 'Settings' in resp.body
647
    resp = app.get('/manage/agendas/%d/settings' % agenda.id, status=403)
645 648
    MeetingType(agenda=agenda, label='Blah').save()
646
    resp = app.get('/manage/agendas/%d/' % agenda.id)
647
    assert 'Add a time period' not in resp.content
648 649
    app.get('/manage/agendas/%d/desk/%d/add-time-period' % (agenda.id, desk.id), status=403)
649 650
    time_period = TimePeriod(desk=desk, weekday=0, start_time=datetime.time(9, 0),
650 651
                             end_time=datetime.time(12, 0))
651 652
    time_period.save()
652 653
    resp = app.get('/manage/agendas/%d/' % agenda.id)
653
    assert '/manage/timeperiods/%s/edit' % time_period.id not in resp.body
654
    assert '/manage/timeperiods/%s/delete' % time_period.id not in resp.body
655 654
    app.get('/manage/timeperiods/%d/edit' % time_period.id, status=403)
655
    app.get('/manage/timeperiods/%d/delete' % time_period.id, status=403)
656 656
    # grant edit right to manager
657 657
    agenda.edit_role = manager_user.groups.all()[0]
658 658
    agenda.save()
659 659

  
660
    resp = app.get('/manage/agendas/%d/' % agenda.id)
660
    resp = app.get('/manage/agendas/%d/' % agenda.id).follow()
661 661
    assert 'Add a time period' in resp.content
662 662
    assert '/manage/timeperiods/%s/edit' % time_period.id in resp.body
663 663
    assert '/manage/timeperiods/%s/delete' % time_period.id in resp.body
......
678 678
    agenda = Agenda.objects.get(slug='foo-bar')
679 679
    MeetingType(agenda=agenda, label='Blah').save()
680 680

  
681
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
681
    resp = app.get('/manage/agendas/%s/' % agenda.id).follow()
682 682
    resp = resp.click('New Desk')
683 683
    resp.form['label'] = 'Desk A'
684 684
    resp = resp.form.submit().follow()
......
708 708
    agenda = Agenda.objects.get(slug='foo-bar')
709 709
    MeetingType(agenda=agenda, label='Blah').save()
710 710

  
711
    resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
711
    resp = app.get('/manage/agendas/%s/' % agenda.id).follow()
712 712
    resp = resp.click('New Desk')
713 713
    resp.form['label'] = 'Desk A'
714 714
    resp = resp.form.submit().follow()
......
716 716
    resp = resp.click('Desk A', index=0)
717 717
    resp = resp.click('Delete')
718 718
    resp = resp.form.submit()
719
    assert resp.location == 'http://testserver/manage/agendas/%s/' % agenda.id
719
    assert resp.location == 'http://testserver/manage/agendas/%s/settings' % agenda.id
720 720
    assert Desk.objects.count() == 1
721 721

  
722 722

  
......
775 775
                                 start_datetime=datetime.datetime(2017, 5, 22, 10, 30))
776 776
    Booking.objects.create(event=event)
777 777
    login(app)
778
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
778
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
779 779
    resp = resp.click('Add a time period exception')
780 780
    resp.form['start_datetime'] = '2017-05-22 08:00'
781 781
    resp.form['end_datetime'] = '2017-05-26 17:30'
......
794 794
    Booking.objects.create(event=event,
795 795
            cancellation_datetime=datetime.datetime(2017, 5, 20, 10, 30))
796 796
    login(app)
797
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
797
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
798 798
    resp = resp.click('Add a time period exception')
799 799
    resp.form['start_datetime'] = '2017-05-22 08:00'
800 800
    resp.form['end_datetime'] = '2017-05-26 17:30'
......
809 809
    TimePeriod.objects.create(weekday=1, desk=desk,
810 810
                              start_time=datetime.time(10, 0), end_time=datetime.time(12, 0))
811 811
    login(app)
812
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
812
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
813 813
    resp = resp.click('Add a time period exception')
814 814
    resp.form['start_datetime'] = '2017-05-26 17:30'
815 815
    resp.form['end_datetime'] = '2017-05-22 08:00'
......
824 824
    TimePeriod.objects.create(weekday=1, desk=desk,
825 825
                              start_time=datetime.time(10, 0), end_time=datetime.time(12, 0))
826 826
    login(app)
827
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
827
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
828 828
    resp = resp.click('Add a time period exception')
829 829
    today = datetime.datetime.today().replace(hour=0, minute=0, second=0, microsecond=0)
830 830
    tomorrow = make_aware(today + datetime.timedelta(days=15))
......
847 847
    desk = Desk.objects.create(agenda=agenda, label='Test Desk')
848 848
    MeetingType(agenda=agenda, label='Foo').save()
849 849
    login(app)
850
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
850
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
851 851
    assert 'Import exceptions from .ics' not in resp.content
852 852

  
853 853
    TimePeriod.objects.create(weekday=1, desk=desk,
854 854
                start_time=datetime.time(10, 0), end_time=datetime.time(12, 0))
855 855

  
856
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
856
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
857 857
    assert 'Import exceptions from .ics' in resp.content
858 858
    resp = resp.click('upload')
859 859
    assert "You can upload a file or specify an address to a remote calendar." in resp
860 860
    resp = resp.form.submit(status=302)
861
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
861
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
862 862
    resp = resp.click('upload')
863 863
    resp.form['ics_file'] = Upload('exceptions.ics', 'invalid content', 'text/calendar')
864 864
    resp = resp.form.submit(status=200)
......
904 904
SUMMARY:New Year's Eve
905 905
END:VEVENT
906 906
END:VCALENDAR"""
907
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
907
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
908 908
    resp = resp.click('upload')
909 909
    resp.form['ics_file'] = Upload('exceptions.ics', ics_with_exceptions, 'text/calendar')
910 910
    resp = resp.form.submit(status=302)
......
918 918
    desk = Desk.objects.create(agenda=agenda, label='New Desk')
919 919
    MeetingType(agenda=agenda, label='Bar').save()
920 920
    login(app)
921
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
921
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
922 922
    assert 'Import exceptions from .ics' not in resp.content
923 923

  
924 924
    TimePeriod.objects.create(weekday=1, desk=desk,
925 925
                start_time=datetime.time(10, 0), end_time=datetime.time(12, 0))
926 926

  
927
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
927
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
928 928
    resp = resp.click('upload')
929 929

  
930 930
    assert 'ics_file' in resp.form.fields
......
946 946
    assert TimePeriodException.objects.filter(desk=desk).count() == 1
947 947
    exception = TimePeriodException.objects.get(desk=desk)
948 948
    assert exception.external_id == 'random-event-id'
949
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
949
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
950 950
    resp = resp.click('upload')
951 951
    resp.form['ics_url'] = ''
952 952
    resp = resp.form.submit(status=302)
......
959 959
    desk = Desk.objects.create(agenda=agenda, label='New Desk')
960 960
    MeetingType(agenda=agenda, label='Bar').save()
961 961
    login(app)
962
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
962
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
963 963
    assert 'Import exceptions from .ics' not in resp.content
964 964

  
965 965
    TimePeriod.objects.create(weekday=1, desk=desk,
966 966
                start_time=datetime.time(10, 0), end_time=datetime.time(12, 0))
967 967

  
968
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
968
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
969 969
    resp = resp.click('upload')
970 970
    resp.form['ics_url'] = 'http://example.com/foo.ics'
971 971
    mocked_response = mock.Mock()
......
988 988
VERSION:2.0
989 989
PRODID:-//foo.bar//EN
990 990
END:VCALENDAR"""
991
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
991
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
992 992
    resp = resp.click('upload')
993 993
    resp = resp.form.submit(status=302)
994 994
    assert not TimePeriodException.objects.filter(desk=desk,
......
1001 1001
    desk = Desk.objects.create(agenda=agenda, label='New Desk')
1002 1002
    MeetingType(agenda=agenda, label='Bar').save()
1003 1003
    login(app)
1004
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1004
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
1005 1005
    assert 'Import exceptions from .ics' not in resp.content
1006 1006

  
1007 1007
    TimePeriod.objects.create(weekday=1, desk=desk,
1008 1008
                start_time=datetime.time(10, 0), end_time=datetime.time(12, 0))
1009 1009

  
1010
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1010
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
1011 1011
    resp = resp.click('upload')
1012 1012
    resp.form['ics_url'] = 'http://example.com/foo.ics'
1013 1013
    mocked_response = mock.Mock()
......
1030 1030
    mocked_get.return_value = mocked_response
1031 1031
    resp = resp.form.submit(status=302)
1032 1032
    assert TimePeriodException.objects.filter(desk=desk).count() == 2
1033
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1033
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
1034 1034
    resp = resp.click('upload')
1035 1035
    resp.form['ics_url'] = 'http://example.com/foo.ics'
1036 1036
    mocked_response.text = """BEGIN:VCALENDAR
......
1053 1053
    desk = Desk.objects.create(agenda=agenda, label='New Desk')
1054 1054
    MeetingType(agenda=agenda, label='Bar').save()
1055 1055
    login(app)
1056
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1056
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
1057 1057
    assert 'Import exceptions from .ics' not in resp.content
1058 1058

  
1059 1059
    TimePeriod.objects.create(weekday=1, desk=desk,
1060 1060
                start_time=datetime.time(10, 0), end_time=datetime.time(12, 0))
1061 1061

  
1062
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1062
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
1063 1063
    resp = resp.click('upload')
1064 1064

  
1065 1065
    assert 'ics_file' in resp.form.fields
......
1079 1079
    desk = Desk.objects.create(agenda=agenda, label='New Desk')
1080 1080
    MeetingType(agenda=agenda, label='Bar').save()
1081 1081
    login(app)
1082
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1082
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
1083 1083
    assert 'Import exceptions from .ics' not in resp.content
1084 1084

  
1085 1085
    TimePeriod.objects.create(weekday=1, desk=desk,
1086 1086
                start_time=datetime.time(10, 0), end_time=datetime.time(12, 0))
1087 1087

  
1088
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1088
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
1089 1089
    resp = resp.click('upload')
1090 1090
    resp.form['ics_url'] = 'http://example.com/foo.ics'
1091 1091
    mocked_response = mock.Mock()
......
1103 1103
    desk = Desk.objects.create(agenda=agenda, label='New Desk')
1104 1104
    MeetingType(agenda=agenda, label='Bar').save()
1105 1105
    login(app)
1106
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1106
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
1107 1107
    assert 'Import exceptions from .ics' not in resp.content
1108 1108
    TimePeriod.objects.create(weekday=1, desk=desk,
1109 1109
                start_time=datetime.time(10, 0), end_time=datetime.time(12, 0))
1110 1110

  
1111
    resp = app.get('/manage/agendas/%d/' % agenda.pk)
1111
    resp = app.get('/manage/agendas/%d/' % agenda.pk).follow()
1112 1112
    resp = resp.click('upload')
1113 1113
    resp.form['ics_url'] = 'https://example.com/foo.ics'
1114 1114
    mocked_response = mock.Mock()
1115
-