Merged in [12748] from rcross@amsl.com:

Fixes #2172.  Add Requested Resources and People who must be there, to email notifications of session requests.
 - Legacy-Id: 12757
Note: SVN reference [12748] has been migrated to Git commit eeb35e997d
This commit is contained in:
Henrik Levkowetz 2017-01-30 23:22:45 +00:00
commit 55b430b525
6 changed files with 68 additions and 19 deletions

View file

@ -1,5 +1,7 @@
from django import forms
import debug # pyflakes:ignore
from ietf.group.models import Group
from ietf.meeting.models import ResourceAssociation
from ietf.person.fields import SearchablePersonsField
@ -66,7 +68,7 @@ class SessionForm(forms.Form):
wg_selector2 = forms.ChoiceField(choices=WG_CHOICES,required=False)
wg_selector3 = forms.ChoiceField(choices=WG_CHOICES,required=False)
third_session = forms.BooleanField(required=False)
resources = forms.MultipleChoiceField(choices=[(x.pk,x.desc) for x in ResourceAssociation.objects.all()], widget=forms.CheckboxSelectMultiple,required=False)
resources = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,required=False)
bethere = SearchablePersonsField(label="Must be present", required=False)
def __init__(self, *args, **kwargs):
@ -82,7 +84,8 @@ class SessionForm(forms.Form):
self.fields['wg_selector3'].widget.attrs['onChange'] = "document.form_post.conflict3.value=document.form_post.conflict3.value + ' ' + this.options[this.selectedIndex].value; return handleconflictfield(3);"
self.fields['wg_selector3'].widget.attrs['onClick'] = "return check_prior_conflict(3);"
self.fields['third_session'].widget.attrs['onClick'] = "if (document.form_post.num_session.selectedIndex < 2) { alert('Cannot use this field - Number of Session is not set to 2'); return false; } else { if (this.checked==true) { document.form_post.length_session3.disabled=false; } else { document.form_post.length_session3.value=0;document.form_post.length_session3.disabled=true; } }"
self.fields["resources"].choices = [(x.pk,x.desc) for x in ResourceAssociation.objects.all() ]
# check third_session checkbox if instance and length_session3
# assert False, (self.instance, self.fields['length_session3'].initial)
if self.initial and 'length_session3' in self.initial:

View file

@ -1,11 +1,13 @@
from django.core.urlresolvers import reverse
import debug # pyflakes:ignore
from ietf.utils.test_utils import TestCase, unicontent
from ietf.group.models import Group
#from ietf.meeting.models import Session
#from ietf.utils.test_data import make_test_data
from ietf.meeting.test_data import make_meeting_test_data as make_test_data
from ietf.meeting.models import Meeting, Session, ResourceAssociation
from ietf.meeting.test_data import make_meeting_test_data
from ietf.utils.mail import outbox, empty_outbox
from ietf.utils.test_data import make_test_data
from pyquery import PyQuery
@ -13,7 +15,7 @@ SECR_USER='secretary'
class SreqUrlTests(TestCase):
def test_urls(self):
make_test_data()
make_meeting_test_data()
self.client.login(username="secretary", password="secretary+password")
@ -29,7 +31,7 @@ class SreqUrlTests(TestCase):
class SessionRequestTestCase(TestCase):
def test_main(self):
make_test_data()
make_meeting_test_data()
url = reverse('sessions')
self.client.login(username="secretary", password="secretary+password")
r = self.client.get(url)
@ -42,8 +44,8 @@ class SessionRequestTestCase(TestCase):
class SubmitRequestCase(TestCase):
def test_submit_request(self):
make_test_data()
acronym = Group.objects.all()[0].acronym
url = reverse('sessions_new',kwargs={'acronym':acronym})
group = Group.objects.get(acronym='mars')
url = reverse('sessions_new',kwargs={'acronym':group.acronym})
post_data = {'num_session':'1',
'length_session1':'3600',
'attendees':'10',
@ -51,11 +53,11 @@ class SubmitRequestCase(TestCase):
'comments':'need projector'}
self.client.login(username="secretary", password="secretary+password")
r = self.client.post(url,post_data)
self.assertEqual(r.status_code, 302)
self.assertRedirects(r, reverse('sessions_confirm', kwargs={'acronym':group.acronym}))
def test_submit_request_invalid(self):
make_test_data()
group = Group.objects.filter(type='wg').first()
group = Group.objects.get(acronym='mars')
url = reverse('sessions_new',kwargs={'acronym':group.acronym})
post_data = {'num_session':'2',
'length_session1':'3600',
@ -69,9 +71,42 @@ class SubmitRequestCase(TestCase):
self.assertEqual(len(q('#session-request-form')),1)
self.assertTrue('You must enter a length for all sessions' in unicontent(r))
def test_request_notification(self):
make_test_data()
meeting = Meeting.objects.filter(type='ietf').first()
group = Group.objects.get(acronym='ames')
ad = group.parent.role_set.filter(name='ad').first().person
resource = ResourceAssociation.objects.first()
url = reverse('ietf.secr.sreq.views.new',kwargs={'acronym':group.acronym})
confirm_url = reverse('sessions_confirm',kwargs={'acronym':group.acronym})
len_before = len(outbox)
post_data = {'num_session':'1',
'length_session1':'3600',
'attendees':'10',
'bethere':str(ad.pk),
'conflict1':'',
'comments':'',
'resources': resource.pk}
self.client.login(username="ameschairman", password="ameschairman+password")
# submit
r = self.client.post(url,post_data)
self.assertRedirects(r, confirm_url)
# confirm
r = self.client.post(confirm_url,{'submit':'Submit'})
self.assertRedirects(r, reverse('sessions'))
self.assertEqual(len(outbox),len_before+1)
notification = outbox[-1]
notification_payload = unicode(notification.get_payload(decode=True),"utf-8","replace")
session = Session.objects.get(meeting=meeting,group=group)
self.assertEqual(session.resources.count(),1)
self.assertEqual(session.people_constraints.count(),1)
resource = session.resources.first()
self.assertTrue(resource.desc in notification_payload)
self.assertTrue(ad.ascii_name() in notification_payload)
class LockAppTestCase(TestCase):
def test_edit_request(self):
meeting = make_test_data()
meeting = make_meeting_test_data()
meeting.session_request_lock_message='locked'
meeting.save()
group = Group.objects.get(acronym='mars')
@ -83,7 +118,7 @@ class LockAppTestCase(TestCase):
self.assertEqual(len(q(':disabled[name="submit"]')), 1)
def test_view_request(self):
meeting = make_test_data()
meeting = make_meeting_test_data()
meeting.session_request_lock_message='locked'
meeting.save()
group = Group.objects.get(acronym='mars')
@ -95,7 +130,7 @@ class LockAppTestCase(TestCase):
self.assertEqual(len(q(':disabled[name="edit"]')), 1)
def test_new_request(self):
meeting = make_test_data()
meeting = make_meeting_test_data()
meeting.session_request_lock_message='locked'
meeting.save()
group = Group.objects.get(acronym='mars')
@ -121,8 +156,7 @@ class EditRequestCase(TestCase):
class NotMeetingCase(TestCase):
def test_not_meeting(self):
make_test_data()
make_meeting_test_data()
group = Group.objects.get(acronym='mars')
url = reverse('sessions_no_session',kwargs={'acronym':group.acronym})
self.client.login(username="secretary", password="secretary+password")

View file

@ -6,6 +6,8 @@ from django.http import Http404
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.template import RequestContext
import debug # pyflakes:ignore
from ietf.group.models import Group
from ietf.ietfauth.utils import has_role, role_required
from ietf.meeting.models import Meeting, Session, Constraint, ResourceAssociation

View file

@ -13,6 +13,12 @@ Conflicts to Avoid:
{% if session.conflict3 %} Third Priority: {{ session.conflict3 }}{% endif %}
People who must be present:
{% for person in session.bethere %} {{ person.ascii_name }}
{% endfor %}
Resources Requested:
{% for resource in session.resources %} {{ resource.desc }}
{% endfor %}
Special Requests:
{{ session.comments }}
---------------------------------------------------------

View file

@ -53,7 +53,7 @@
</tr>
<tr class="bg2"><td>Resources requested:</td>
<td>
{{ form.resources }}
{{ form.resources.errors }} {{ form.resources }}
</td>
</tr>
<tr class="bg1">

View file

@ -10,8 +10,8 @@ from ietf.doc.models import Document, DocAlias, State, DocumentAuthor, BallotTyp
from ietf.group.models import Group, GroupHistory, Role, RoleHistory
from ietf.iesg.models import TelechatDate
from ietf.ipr.models import HolderIprDisclosure, IprDocRel, IprDisclosureStateName, IprLicenseTypeName
from ietf.meeting.models import Meeting
from ietf.name.models import StreamName, DocRelationshipName
from ietf.meeting.models import Meeting, ResourceAssociation
from ietf.name.models import StreamName, DocRelationshipName, RoomResourceName
from ietf.person.models import Person, Email
from ietf.group.utils import setup_default_community_list_for_group
from ietf.review.models import (ReviewRequest, ReviewerSettings, ReviewResultName, ReviewTypeName, ReviewTeamSettings )
@ -377,6 +377,10 @@ def make_test_data():
rfc_for_status_change_test_factory('draft-ietf-random-otherthing',9998,'inf')
rfc_for_status_change_test_factory('draft-was-never-issued',14,'unkn')
# Session Request ResourceAssociation
name = RoomResourceName.objects.get(slug='project')
ResourceAssociation.objects.create(name=name,icon='projector.png',desc='Projector in room')
# Instances of the remaining document types
# (Except liaison, liai-att, and recording which the code in ietf.doc does not use...)
# Meeting-related documents are created in make_meeting_test_data, and