Skip to content

Commit

Permalink
Reworked the pages that manage all the possible schedules for a meeti…
Browse files Browse the repository at this point in the history
…ng. Removed a lot of custom javascript. Fixes #1921. Commit ready for merge.

 - Legacy-Id: 11137
  • Loading branch information
rjsparks committed Apr 27, 2016
1 parent 62d3ac8 commit f34ae9c
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 573 deletions.
49 changes: 47 additions & 2 deletions ietf/meeting/tests_views.py
Expand Up @@ -11,13 +11,13 @@
from pyquery import PyQuery

from ietf.doc.models import Document
from ietf.meeting.models import Session, TimeSlot
from ietf.meeting.models import Session, TimeSlot, Meeting
from ietf.meeting.test_data import make_meeting_test_data
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent

from ietf.person.factories import PersonFactory
from ietf.group.factories import GroupFactory
from ietf.meeting.factories import SessionFactory, SessionPresentationFactory
from ietf.meeting.factories import SessionFactory, SessionPresentationFactory, ScheduleFactory, MeetingFactory
from ietf.doc.factories import DocumentFactory

class MeetingTests(TestCase):
Expand Down Expand Up @@ -401,3 +401,48 @@ def test_add_session_drafts(self):
q = PyQuery(r.content)
self.assertEqual(1,len(q(".alert-warning:contains('may affect published proceedings')")))

class EditScheduleListTests(TestCase):
def setUp(self):
self.mtg = MeetingFactory(type_id='ietf')
ScheduleFactory(meeting=self.mtg,name='Empty-Schedule')

def test_list_agendas(self):
url = urlreverse('ietf.meeting.views.list_agendas',kwargs={'num':self.mtg.number})
login_testing_unauthorized(self,"secretary",url)
r = self.client.get(url)
self.assertTrue(r.status_code, 200)

def test_delete_schedule(self):
url = urlreverse('ietf.meeting.views.delete_schedule',
kwargs={'num':self.mtg.number,
'owner':self.mtg.agenda.owner.email_address(),
'name':self.mtg.agenda.name,
})
login_testing_unauthorized(self,"secretary",url)
r = self.client.get(url)
self.assertTrue(r.status_code, 403)
r = self.client.post(url,{'save':1})
self.assertTrue(r.status_code, 403)
self.assertEqual(self.mtg.schedule_set.count(),2)
self.mtg.agenda=None
self.mtg.save()
r = self.client.get(url)
self.assertTrue(r.status_code, 200)
r = self.client.post(url,{'save':1})
self.assertTrue(r.status_code, 302)
self.assertEqual(self.mtg.schedule_set.count(),1)

def test_make_schedule_official(self):
schedule = self.mtg.schedule_set.exclude(id=self.mtg.agenda.id).first()
url = urlreverse('ietf.meeting.views.make_schedule_official',
kwargs={'num':self.mtg.number,
'owner':schedule.owner.email_address(),
'name':schedule.name,
})
login_testing_unauthorized(self,"secretary",url)
r = self.client.get(url)
self.assertTrue(r.status_code, 200)
r = self.client.post(url,{'save':1})
self.assertTrue(r.status_code, 302)
mtg = Meeting.objects.get(number=self.mtg.number)
self.assertEqual(mtg.agenda,schedule)
20 changes: 12 additions & 8 deletions ietf/meeting/urls.py
Expand Up @@ -12,18 +12,22 @@
]

type_ietf_only_patterns = [
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+)/edit$', views.edit_agenda),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+)/details$', views.edit_agenda_properties),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+).(?P<ext>.html)?/?$', views.agenda),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+)/permissions$', ajax.agenda_permission_api),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+)/session/(?P<assignment_id>\d+).json$', ajax.assignment_json),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+)/sessions.json$', ajax.assignments_json),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+).json$', ajax.agenda_infourl),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/edit$', views.edit_agenda),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/details$', views.edit_agenda_properties),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/delete$', views.delete_schedule),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/make_official$', views.make_schedule_official),
# The following view is broken?
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+).(?P<ext>.html)?/?$', views.agenda),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/permissions$', ajax.agenda_permission_api),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/session/(?P<assignment_id>\d+).json$', ajax.assignment_json),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/sessions.json$', ajax.assignments_json),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+).json$', ajax.agenda_infourl),
url(r'^agenda/by-room$', views.agenda_by_room),
url(r'^agenda/by-type$', views.agenda_by_type),
url(r'^agenda/by-type/(?P<type>[a-z]+)$', views.agenda_by_type),
url(r'^agenda/by-type/(?P<type>[a-z]+)/ics$', views.agenda_by_type_ics),
url(r'^agendas/edit$', views.edit_agendas),
url(r'^agendas/list$', views.list_agendas, name='meeting_list_agendas'),
url(r'^agendas/edit$', RedirectView.as_view(pattern_name='meeting_list_agendas', permanent=True)),
url(r'^timeslots/edit$', views.edit_timeslots),
url(r'^rooms$', ajax.timeslot_roomsurl),
url(r'^room/(?P<roomid>\d+).json$', ajax.timeslot_roomurl),
Expand Down
81 changes: 70 additions & 11 deletions ietf/meeting/views.py
Expand Up @@ -304,42 +304,41 @@ def edit_agenda(request, num=None, owner=None, name=None):

##############################################################################
# show the properties associated with an agenda (visible, public)
# this page uses ajax POST requests to the API
#
AgendaPropertiesForm = modelform_factory(Schedule, fields=('name','visible', 'public'))

@role_required('Area Director','Secretariat')
@ensure_csrf_cookie
def edit_agenda_properties(request, num=None, owner=None, name=None):
meeting = get_meeting(num)
person = get_person_by_email(owner)
schedule = get_schedule_by_name(meeting, person, name)
if schedule is None:
raise Http404("No meeting information for meeting %s owner %s schedule %s available" % (num, owner, name))
form = AgendaPropertiesForm(instance=schedule)

cansee, canedit, secretariat = agenda_permissions(meeting, schedule, request.user)

if not (canedit or has_role(request.user,'Secretariat')):
return HttpResponseForbidden("You may not edit this agenda")
else:
if request.method == 'POST':
form = AgendaPropertiesForm(instance=schedule,data=request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('ietf.meeting.views.list_agendas',kwargs={'num': num}))
else:
form = AgendaPropertiesForm(instance=schedule)
return render(request, "meeting/properties_edit.html",
{"schedule":schedule,
"form":form,
"meeting":meeting,
"hide_menu": True,
})

##############################################################################
# show list of agendas.
#

@role_required('Area Director','Secretariat')
@ensure_csrf_cookie
def edit_agendas(request, num=None, order=None):

#if request.method == 'POST':
# return agenda_create(request, num, owner, name)
def list_agendas(request, num=None ):

meeting = get_meeting(num)
user = request.user
Expand All @@ -350,10 +349,11 @@ def edit_agendas(request, num=None, order=None):

schedules = schedules.order_by('owner', 'name')

schedules = sorted(list(schedules),key=lambda x:not x.is_official)

return render(request, "meeting/agenda_list.html",
{"meeting": meeting,
"schedules": schedules.all(),
"hide_menu": True,
"schedules": schedules,
})

@ensure_csrf_cookie
Expand Down Expand Up @@ -927,3 +927,62 @@ def add_session_drafts(request, session_id, num):
'already_linked': session.sessionpresentation_set.filter(document__type_id='draft'),
'form': form,
})

@role_required('Secretariat')
def make_schedule_official(request, num, owner, name):

meeting = get_meeting(num)
person = get_person_by_email(owner)
schedule = get_schedule_by_name(meeting, person, name)

if schedule is None:
raise Http404

if request.method == 'POST':
if not (schedule.public and schedule.visible):
schedule.public = True
schedule.visible = True
schedule.save()
meeting.agenda = schedule
meeting.save()
return HttpResponseRedirect(reverse('ietf.meeting.views.list_agendas',kwargs={'num':num}))

if not schedule.public:
messages.warning(request,"This schedule will be made public as it is made official.")

if not schedule.visible:
messages.warning(request,"This schedule will be made visible as it is made official.")

return render(request, "meeting/make_schedule_official.html",
{ 'schedule' : schedule,
'meeting' : meeting,
}
)


@role_required('Secretariat','Area Director')
def delete_schedule(request, num, owner, name):

meeting = get_meeting(num)
person = get_person_by_email(owner)
schedule = get_schedule_by_name(meeting, person, name)

if schedule.name=='Empty-Schedule':
return HttpResponseForbidden('You may not delete the default empty schedule')

if schedule == meeting.agenda:
return HttpResponseForbidden('You may not delete the official agenda for %s'%meeting)

if not ( has_role(request.user, 'Secretariat') or person.user == request.user ):
return HttpResponseForbidden("You may not delete other user's schedules")

if request.method == 'POST':
schedule.delete()
return HttpResponseRedirect(reverse('ietf.meeting.views.list_agendas',kwargs={'num':num}))

return render(request, "meeting/delete_schedule.html",
{ 'schedule' : schedule,
'meeting' : meeting,
}
)

0 comments on commit f34ae9c

Please sign in to comment.