Skip to content

Commit 2ff7900

Browse files
committed
fix various issues with recent changes
- Legacy-Id: 7559
1 parent 0fafe56 commit 2ff7900

10 files changed

Lines changed: 206 additions & 59 deletions

File tree

ietf/secr/meetings/forms.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,6 @@ class Meta:
111111
model = Room
112112
fields = '__all__'
113113

114-
class ExtraSessionForm(forms.Form):
115-
no_notify = forms.BooleanField(required=False, label="Do NOT notify this action")
116-
117114
class NewSessionForm(forms.Form):
118115
day = forms.ChoiceField(choices=SESSION_DAYS)
119116
time = TimeChoiceField()

ietf/secr/meetings/tests.py

Lines changed: 167 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
1+
from django.conf import settings
12
from django.core.urlresolvers import reverse
23
from ietf.utils import TestCase
34

4-
from ietf.meeting.models import Meeting, Schedule
5+
from ietf.person.models import Person
6+
from ietf.group.models import Group, GroupEvent
7+
from ietf.meeting.models import Meeting, Schedule, Room, TimeSlot, ScheduledSession
58
from ietf.utils.test_data import make_test_data
9+
from ietf.utils.mail import outbox
10+
from ietf.meeting.test_data import make_meeting_test_data
611

712
from pyquery import PyQuery
13+
from pprint import pprint
14+
15+
import datetime
16+
import os
17+
import shutil
818

919
SECR_USER='secretary'
1020

1121
class MainTestCase(TestCase):
22+
def setUp(self):
23+
self.bluesheet_dir = os.path.abspath("tmp-bluesheet-dir")
24+
self.bluesheet_path = os.path.join(self.bluesheet_dir,'blue_sheet.rtf')
25+
os.mkdir(self.bluesheet_dir)
26+
settings.SECR_BLUE_SHEET_PATH = self.bluesheet_path
27+
28+
def tearDown(self):
29+
shutil.rmtree(self.bluesheet_dir)
30+
1231
def test_main(self):
1332
"Main Test"
1433
url = reverse('meetings')
@@ -17,19 +36,161 @@ def test_main(self):
1736

1837
def test_view(self):
1938
"View Test"
20-
draft = make_test_data()
21-
meeting = Meeting.objects.all()[0]
39+
meeting = make_meeting_test_data()
2240
url = reverse('meetings_view', kwargs={'meeting_id':meeting.number})
2341
response = self.client.get(url, REMOTE_USER=SECR_USER)
2442
self.assertEqual(response.status_code, 200)
25-
43+
q = PyQuery(response.content)
44+
self.assertEqual(len(q('#id_schedule_selector option')),2)
45+
2646
def test_add_meeting(self):
2747
"Add Meeting"
2848
url = reverse('meetings_add')
29-
post_data = dict(number=1,city='Seattle',date='2014-07-20',country='US',
30-
time_zone='America/Los_Angeles',venue_name='Hilton',
49+
post_data = dict(number=1,city='Toronto',date='2014-07-20',country='CA',
50+
time_zone='America/New_York',venue_name='Hilton',
3151
venue_addr='100 First Ave')
3252
response = self.client.post(url, post_data,follow=True,REMOTE_USER=SECR_USER)
3353
self.assertEqual(response.status_code, 200)
3454
self.assertEqual(Meeting.objects.count(),1)
3555
self.assertEqual(Schedule.objects.count(),1)
56+
57+
def test_edit_meeting(self):
58+
"Edit Meeting"
59+
Meeting.objects.create(number=1,
60+
type_id='ietf',
61+
date=datetime.datetime(2014,7,20))
62+
url = reverse('meetings_edit_meeting',kwargs={'meeting_id':1})
63+
post_data = dict(number='1',date='2014-07-20',city='Toronto')
64+
response = self.client.post(url, post_data,follow=True,REMOTE_USER=SECR_USER)
65+
self.assertEqual(response.status_code, 200)
66+
meeting = Meeting.objects.get(number=1)
67+
self.assertEqual(meeting.city,'Toronto')
68+
69+
def test_blue_sheets(self):
70+
"Test Bluesheets"
71+
meeting = make_meeting_test_data()
72+
url = reverse('meetings_blue_sheet',kwargs={'meeting_id':meeting.number})
73+
response = self.client.get(url, REMOTE_USER=SECR_USER)
74+
self.assertEqual(response.status_code, 200)
75+
76+
url = reverse('meetings_blue_sheet_generate',kwargs={'meeting_id':meeting.number})
77+
response = self.client.get(url, REMOTE_USER=SECR_USER)
78+
self.assertEqual(response.status_code, 302)
79+
self.assertTrue(os.path.exists(self.bluesheet_path))
80+
81+
def test_notifications(self):
82+
"Test Notifications"
83+
meeting = make_meeting_test_data()
84+
url = reverse('meetings_notifications',kwargs={'meeting_id':42})
85+
response = self.client.get(url, REMOTE_USER=SECR_USER)
86+
self.assertEqual(response.status_code, 200)
87+
q = PyQuery(response.content)
88+
self.assertEqual(q('#id_notification_list').html(),'ames,mars')
89+
90+
# test that only changes since last notification show up
91+
mars_group = Group.objects.get(acronym='mars')
92+
ames_group = Group.objects.get(acronym='ames')
93+
now = datetime.datetime.now()
94+
then = datetime.datetime.now()+datetime.timedelta(hours=1)
95+
person = Person.objects.get(name="(System)")
96+
GroupEvent.objects.create(group=mars_group,time=now,type='sent_notification',
97+
by=person,desc='sent scheduled notification for %s' % meeting)
98+
ss = meeting.agenda.scheduledsession_set.get(session__group=ames_group)
99+
ss.modified = then
100+
ss.save()
101+
response = self.client.get(url, REMOTE_USER=SECR_USER)
102+
self.assertEqual(response.status_code, 200)
103+
q = PyQuery(response.content)
104+
self.assertEqual(q('#id_notification_list').html(),'ames')
105+
106+
# test that email goes out
107+
mailbox_before = len(outbox)
108+
response = self.client.post(url, REMOTE_USER=SECR_USER)
109+
self.assertEqual(response.status_code, 302)
110+
self.assertEqual(len(outbox), mailbox_before + 1)
111+
112+
def test_meetings_select(self):
113+
meeting = make_meeting_test_data()
114+
url = reverse('meetings_select',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
115+
response = self.client.get(url, REMOTE_USER=SECR_USER)
116+
self.assertEqual(response.status_code, 200)
117+
118+
def test_meetings_rooms(self):
119+
meeting = make_meeting_test_data()
120+
url = reverse('meetings_rooms',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
121+
response = self.client.get(url, REMOTE_USER=SECR_USER)
122+
self.assertEqual(response.status_code, 200)
123+
q = PyQuery(response.content)
124+
self.assertEqual(len(q("#id_rooms_table tr")),2)
125+
126+
# test delete
127+
# first unschedule sessions so we can delete
128+
ScheduledSession.objects.filter(schedule=meeting.agenda).delete()
129+
response = self.client.post(url, {
130+
'room-TOTAL_FORMS': q('input[name="room-TOTAL_FORMS"]').val(),
131+
'room-INITIAL_FORMS': q('input[name="room-INITIAL_FORMS"]').val(),
132+
'room-0-meeting': q('input[name="room-0-meeting"]').val(),
133+
'room-0-id': q('input[name="room-0-id"]').val(),
134+
'room-0-name': q('input[name="room-0-name"]').val(),
135+
'room-0-capacity': q('input[name="room-0-capacity"]').val(),
136+
'room-0-DELETE': 'on'
137+
}, REMOTE_USER=SECR_USER)
138+
self.assertEqual(response.status_code, 302)
139+
self.assertEqual(Room.objects.filter(meeting=meeting).count(),0)
140+
141+
def test_meetings_times(self):
142+
meeting = make_meeting_test_data()
143+
url = reverse('meetings_times',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
144+
response = self.client.get(url, REMOTE_USER=SECR_USER)
145+
self.assertEqual(response.status_code, 200)
146+
147+
def test_meetings_times_delete(self):
148+
meeting = make_meeting_test_data()
149+
qs = TimeSlot.objects.filter(meeting=meeting,type='session')
150+
before = qs.count()
151+
url = reverse('meetings_times_delete',kwargs={
152+
'meeting_id':42,
153+
'schedule_name':'test-agenda',
154+
'time':qs.first().time.strftime("%Y:%m:%d:%H:%M")
155+
})
156+
response = self.client.get(url, REMOTE_USER=SECR_USER)
157+
self.assertEqual(response.status_code, 302)
158+
pprint(response.content)
159+
after = TimeSlot.objects.filter(meeting=meeting,type='session').count()
160+
self.assertEqual(after,before - (Room.objects.filter(meeting=meeting).count()))
161+
162+
def test_meetings_times_edit(self):
163+
meeting = make_meeting_test_data()
164+
timeslot = TimeSlot.objects.filter(meeting=meeting,type='session').first()
165+
url = reverse('meetings_times_edit',kwargs={
166+
'meeting_id':42,
167+
'schedule_name':'test-agenda',
168+
'time':timeslot.time.strftime("%Y:%m:%d:%H:%M")
169+
})
170+
response = self.client.post(url, {
171+
'day':'1',
172+
'time':'08:00',
173+
'duration_hours':'1',
174+
'duration_minutes':'0',
175+
'name':'Testing'
176+
},REMOTE_USER=SECR_USER)
177+
pprint(response.content)
178+
self.assertEqual(response.status_code, 302)
179+
self.assertTrue(TimeSlot.objects.filter(meeting=meeting,name='Testing'))
180+
181+
def test_meetings_nonsession(self):
182+
meeting = make_meeting_test_data()
183+
url = reverse('meetings_non_session',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
184+
response = self.client.get(url, REMOTE_USER=SECR_USER)
185+
self.assertEqual(response.status_code, 200)
186+
187+
def test_meetings_select_group(self):
188+
meeting = make_meeting_test_data()
189+
url = reverse('meetings_select_group',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
190+
response = self.client.get(url, REMOTE_USER=SECR_USER)
191+
self.assertEqual(response.status_code, 200)
192+
q = PyQuery(response.content)
193+
self.assertEqual(len(q("#id_scheduled_sessions")),1)
194+
195+
# def test_meetings_schedule():
196+

ietf/secr/meetings/views.py

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ def build_nonsession(meeting):
9393
for a new meeting, based on the last meeting
9494
'''
9595
last_meeting = get_last_meeting(meeting)
96+
if not last_meeting:
97+
return None
98+
9699
delta = meeting.date - last_meeting.date
97100
system = Person.objects.get(name='(system)')
98101
schedule = get_schedule(meeting)
@@ -121,8 +124,11 @@ def build_nonsession(meeting):
121124

122125
def get_last_meeting(meeting):
123126
last_number = int(meeting.number) - 1
124-
return Meeting.objects.get(number=last_number)
125-
127+
try:
128+
return Meeting.objects.get(number=last_number)
129+
except Meeting.DoesNotExist:
130+
return None
131+
126132
def is_combined(session,meeting,schedule=None):
127133
'''
128134
Check to see if this session is using two combined timeslots
@@ -204,19 +210,21 @@ def send_notifications(meeting, groups, person):
204210
GroupEvent.objects.create(group=group,time=now,type='sent_notification',
205211
by=person,desc='sent scheduled notification for %s' % meeting)
206212

207-
def sort_groups(meeting):
213+
def sort_groups(meeting,schedule=None):
208214
'''
209215
Similar to sreq.views.sort_groups
210216
Takes a Meeting object and returns a tuple scheduled_groups, unscheduled groups.
211217
'''
218+
if not schedule:
219+
schedule = meeting.agenda
212220
scheduled_groups = []
213221
unscheduled_groups = []
214222
#sessions = Session.objects.filter(meeting=meeting,status__in=('schedw','apprw','appr','sched','notmeet','canceled'))
215223
sessions = Session.objects.filter(meeting=meeting,status__in=('schedw','apprw','appr','sched','canceled'))
216224
groups_with_sessions = [ s.group for s in sessions ]
217225
gset = set(groups_with_sessions)
218226
sorted_groups_with_sessions = sorted(gset, key = lambda instance: instance.acronym)
219-
scheduled_sessions = ScheduledSession.objects.filter(schedule=meeting.agenda,session__isnull=False)
227+
scheduled_sessions = ScheduledSession.objects.filter(schedule=schedule,session__isnull=False)
220228
groups_with_timeslots = [ x.session.group for x in scheduled_sessions ]
221229
for group in sorted_groups_with_sessions:
222230
if group in groups_with_timeslots:
@@ -358,15 +366,15 @@ def edit_meeting(request, meeting_id):
358366

359367
if request.method == 'POST':
360368
button_text = request.POST.get('submit','')
361-
if button_text == 'Save':
362-
form = MeetingModelForm(request.POST, instance=meeting)
363-
if form.is_valid():
364-
form.save()
365-
messages.success(request,'The meeting entry was changed successfully')
366-
return redirect('meetings_view', meeting_id=meeting_id)
369+
if button_text == 'Cancel':
370+
return redirect('meetings_view', meeting_id=meeting_id)
367371

368-
else:
372+
form = MeetingModelForm(request.POST, instance=meeting)
373+
if form.is_valid():
374+
form.save()
375+
messages.success(request,'The meeting entry was changed successfully')
369376
return redirect('meetings_view', meeting_id=meeting_id)
377+
370378
else:
371379
form = MeetingModelForm(instance=meeting)
372380

@@ -559,7 +567,7 @@ def notifications(request, meeting_id):
559567

560568
return render_to_response('meetings/notifications.html', {
561569
'meeting': meeting,
562-
'groups': groups,
570+
'groups': sorted(groups, key=lambda a: a.acronym),
563571
'last_notice': last_notice },
564572
RequestContext(request, {}),
565573
)
@@ -671,9 +679,8 @@ def schedule(request, meeting_id, schedule_name, acronym):
671679
return redirect('meetings_select_group', meeting_id=meeting_id,schedule_name=schedule_name)
672680

673681
formset = NewSessionFormset(request.POST,initial=initial)
674-
extra_form = ExtraSessionForm(request.POST)
675682

676-
if formset.is_valid() and extra_form.is_valid():
683+
if formset.is_valid():
677684
# TODO formsets don't have has_changed until Django 1.3
678685
has_changed = False
679686
for form in formset.forms:
@@ -728,28 +735,15 @@ def schedule(request, meeting_id, schedule_name, acronym):
728735
assign(session,next_slot,meeting,schedule=schedule)
729736
# ---------------------------------------
730737

731-
# notify. dont send if Tutorial, BOF or indicated on form
732-
#notification_message = "No notification has been sent to anyone for this session."
733-
#if (has_changed
734-
# and not extra_form.cleaned_data.get('no_notify',False)
735-
# and group.state.slug != 'bof'
736-
# and get_timeslot(session,schedule=schedule)): # and the session is scheduled, else skip
737-
738-
# send_notification(request, sessions)
739-
# notification_message = "Notification sent."
740-
741738
if has_changed:
742-
messages.success(request, 'Session(s) Scheduled for %s. %s' % (group.acronym, notification_message))
739+
messages.success(request, 'Session(s) Scheduled for %s.' % group.acronym )
743740

744741
return redirect('meetings_select_group', meeting_id=meeting_id,schedule_name=schedule_name)
745742

746-
747743
else:
748744
formset = NewSessionFormset(initial=initial)
749-
extra_form = ExtraSessionForm()
750745

751746
return render_to_response('meetings/schedule.html', {
752-
'extra_form': extra_form,
753747
'group': group,
754748
'meeting': meeting,
755749
'schedule': schedule,
@@ -785,15 +779,15 @@ def select_group(request, meeting_id, schedule_name):
785779
if request.method == 'POST':
786780
group = request.POST.get('group',None)
787781
if group:
788-
redirect_url = reverse('meetings_schedule', kwargs={'meeting_id':meeting_id,'acronym':group})
782+
redirect_url = reverse('meetings_schedule', kwargs={'meeting_id':meeting_id,'acronym':group,'schedule_name':schedule_name})
789783
else:
790-
redirect_url = reverse('meetings_select_group',kwargs={'meeting_id':meeting_id})
784+
redirect_url = reverse('meetings_select_group',kwargs={'meeting_id':meeting_id,'schedule_name':schedule_name})
791785
messages.error(request, 'No group selected')
792786

793787
return HttpResponseRedirect(redirect_url)
794788

795789
# split groups into scheduled / unscheduled
796-
scheduled_groups, unscheduled_groups = sort_groups(meeting)
790+
scheduled_groups, unscheduled_groups = sort_groups(meeting,schedule)
797791

798792
# prep group form
799793
wgs = filter(lambda a: a.type_id in ('wg','ag') and a.state_id=='active', unscheduled_groups)
@@ -947,12 +941,12 @@ def times_delete(request, meeting_id, schedule_name, time):
947941
parts = [ int(x) for x in time.split(':') ]
948942
dtime = datetime.datetime(*parts)
949943

950-
qs = meeting.agenda.scheduledsession_set.filter(timeslot__time=dtime,
951-
session__isnull=False)
944+
# qs = meeting.agenda.scheduledsession_set.filter(timeslot__time=dtime,
945+
# session__isnull=False)
952946

953-
if qs:
954-
messages.error(request, 'ERROR deleting timeslot. There is one or more sessions scheduled for this timeslot.')
955-
return redirect('meetings_times', meeting_id=meeting_id,schedule_name=schedule_name)
947+
#if qs:
948+
# messages.error(request, 'ERROR deleting timeslot. There is one or more sessions scheduled for this timeslot.')
949+
# return redirect('meetings_times', meeting_id=meeting_id,schedule_name=schedule_name)
956950

957951
TimeSlot.objects.filter(meeting=meeting,time=dtime).delete()
958952

ietf/secr/templates/meetings/notifications.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ <h2>IETF {{ meeting.number }} - Send Notifications</h2>
1919
<form id="id_notification_form" action="." method="post">{% csrf_token %}
2020
<p>Send email notifications to all groups that have been scheduled since the last
2121
notification went out on {{ last_notice.time|date:"Y-m-d" }}:</p>
22-
<p>{% if not groups %}(none){% endif %}{% for group in groups %}{{ group.acronym }}{% if not forloop.last %},{% endif %}{% endfor %}<p>
22+
<p id="id_notification_list">{% if not groups %}(none){% endif %}{% for group in groups %}{{ group.acronym }}{% if not forloop.last %},{% endif %}{% endfor %}<p>
2323
<input type="submit" value="Send Now" name="submit" onclick="return window.confirm('Are you sure you want to send notifications?');">
2424
</form>
2525

ietf/secr/templates/meetings/rooms.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ <h2>Rooms</h2>
1010
<form id="meetings-meta-rooms" action="" method="post">{% csrf_token %}
1111
{{ formset.management_form }}
1212
{{ formset.non_form_errors }}
13-
<table class="full-width">
13+
<table id="id_rooms_table" class="full-width">
1414
<thead>
1515
<tr>
1616
{% for field in formset.forms.0.visible_fields %}

0 commit comments

Comments
 (0)