fix various issues with recent changes

- Legacy-Id: 7559
This commit is contained in:
Ryan Cross 2014-04-01 18:09:11 +00:00
parent 0fafe56381
commit 2ff7900326
10 changed files with 207 additions and 60 deletions

View file

@ -111,9 +111,6 @@ class MeetingRoomForm(forms.ModelForm):
model = Room
fields = '__all__'
class ExtraSessionForm(forms.Form):
no_notify = forms.BooleanField(required=False, label="Do NOT notify this action")
class NewSessionForm(forms.Form):
day = forms.ChoiceField(choices=SESSION_DAYS)
time = TimeChoiceField()

View file

@ -1,14 +1,33 @@
from django.conf import settings
from django.core.urlresolvers import reverse
from ietf.utils import TestCase
from ietf.meeting.models import Meeting, Schedule
from ietf.person.models import Person
from ietf.group.models import Group, GroupEvent
from ietf.meeting.models import Meeting, Schedule, Room, TimeSlot, ScheduledSession
from ietf.utils.test_data import make_test_data
from ietf.utils.mail import outbox
from ietf.meeting.test_data import make_meeting_test_data
from pyquery import PyQuery
from pprint import pprint
import datetime
import os
import shutil
SECR_USER='secretary'
class MainTestCase(TestCase):
def setUp(self):
self.bluesheet_dir = os.path.abspath("tmp-bluesheet-dir")
self.bluesheet_path = os.path.join(self.bluesheet_dir,'blue_sheet.rtf')
os.mkdir(self.bluesheet_dir)
settings.SECR_BLUE_SHEET_PATH = self.bluesheet_path
def tearDown(self):
shutil.rmtree(self.bluesheet_dir)
def test_main(self):
"Main Test"
url = reverse('meetings')
@ -17,19 +36,161 @@ class MainTestCase(TestCase):
def test_view(self):
"View Test"
draft = make_test_data()
meeting = Meeting.objects.all()[0]
meeting = make_meeting_test_data()
url = reverse('meetings_view', kwargs={'meeting_id':meeting.number})
response = self.client.get(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertEqual(len(q('#id_schedule_selector option')),2)
def test_add_meeting(self):
"Add Meeting"
url = reverse('meetings_add')
post_data = dict(number=1,city='Seattle',date='2014-07-20',country='US',
time_zone='America/Los_Angeles',venue_name='Hilton',
post_data = dict(number=1,city='Toronto',date='2014-07-20',country='CA',
time_zone='America/New_York',venue_name='Hilton',
venue_addr='100 First Ave')
response = self.client.post(url, post_data,follow=True,REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 200)
self.assertEqual(Meeting.objects.count(),1)
self.assertEqual(Schedule.objects.count(),1)
def test_edit_meeting(self):
"Edit Meeting"
Meeting.objects.create(number=1,
type_id='ietf',
date=datetime.datetime(2014,7,20))
url = reverse('meetings_edit_meeting',kwargs={'meeting_id':1})
post_data = dict(number='1',date='2014-07-20',city='Toronto')
response = self.client.post(url, post_data,follow=True,REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 200)
meeting = Meeting.objects.get(number=1)
self.assertEqual(meeting.city,'Toronto')
def test_blue_sheets(self):
"Test Bluesheets"
meeting = make_meeting_test_data()
url = reverse('meetings_blue_sheet',kwargs={'meeting_id':meeting.number})
response = self.client.get(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 200)
url = reverse('meetings_blue_sheet_generate',kwargs={'meeting_id':meeting.number})
response = self.client.get(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 302)
self.assertTrue(os.path.exists(self.bluesheet_path))
def test_notifications(self):
"Test Notifications"
meeting = make_meeting_test_data()
url = reverse('meetings_notifications',kwargs={'meeting_id':42})
response = self.client.get(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertEqual(q('#id_notification_list').html(),'ames,mars')
# test that only changes since last notification show up
mars_group = Group.objects.get(acronym='mars')
ames_group = Group.objects.get(acronym='ames')
now = datetime.datetime.now()
then = datetime.datetime.now()+datetime.timedelta(hours=1)
person = Person.objects.get(name="(System)")
GroupEvent.objects.create(group=mars_group,time=now,type='sent_notification',
by=person,desc='sent scheduled notification for %s' % meeting)
ss = meeting.agenda.scheduledsession_set.get(session__group=ames_group)
ss.modified = then
ss.save()
response = self.client.get(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertEqual(q('#id_notification_list').html(),'ames')
# test that email goes out
mailbox_before = len(outbox)
response = self.client.post(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 302)
self.assertEqual(len(outbox), mailbox_before + 1)
def test_meetings_select(self):
meeting = make_meeting_test_data()
url = reverse('meetings_select',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
response = self.client.get(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 200)
def test_meetings_rooms(self):
meeting = make_meeting_test_data()
url = reverse('meetings_rooms',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
response = self.client.get(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertEqual(len(q("#id_rooms_table tr")),2)
# test delete
# first unschedule sessions so we can delete
ScheduledSession.objects.filter(schedule=meeting.agenda).delete()
response = self.client.post(url, {
'room-TOTAL_FORMS': q('input[name="room-TOTAL_FORMS"]').val(),
'room-INITIAL_FORMS': q('input[name="room-INITIAL_FORMS"]').val(),
'room-0-meeting': q('input[name="room-0-meeting"]').val(),
'room-0-id': q('input[name="room-0-id"]').val(),
'room-0-name': q('input[name="room-0-name"]').val(),
'room-0-capacity': q('input[name="room-0-capacity"]').val(),
'room-0-DELETE': 'on'
}, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 302)
self.assertEqual(Room.objects.filter(meeting=meeting).count(),0)
def test_meetings_times(self):
meeting = make_meeting_test_data()
url = reverse('meetings_times',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
response = self.client.get(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 200)
def test_meetings_times_delete(self):
meeting = make_meeting_test_data()
qs = TimeSlot.objects.filter(meeting=meeting,type='session')
before = qs.count()
url = reverse('meetings_times_delete',kwargs={
'meeting_id':42,
'schedule_name':'test-agenda',
'time':qs.first().time.strftime("%Y:%m:%d:%H:%M")
})
response = self.client.get(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 302)
pprint(response.content)
after = TimeSlot.objects.filter(meeting=meeting,type='session').count()
self.assertEqual(after,before - (Room.objects.filter(meeting=meeting).count()))
def test_meetings_times_edit(self):
meeting = make_meeting_test_data()
timeslot = TimeSlot.objects.filter(meeting=meeting,type='session').first()
url = reverse('meetings_times_edit',kwargs={
'meeting_id':42,
'schedule_name':'test-agenda',
'time':timeslot.time.strftime("%Y:%m:%d:%H:%M")
})
response = self.client.post(url, {
'day':'1',
'time':'08:00',
'duration_hours':'1',
'duration_minutes':'0',
'name':'Testing'
},REMOTE_USER=SECR_USER)
pprint(response.content)
self.assertEqual(response.status_code, 302)
self.assertTrue(TimeSlot.objects.filter(meeting=meeting,name='Testing'))
def test_meetings_nonsession(self):
meeting = make_meeting_test_data()
url = reverse('meetings_non_session',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
response = self.client.get(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 200)
def test_meetings_select_group(self):
meeting = make_meeting_test_data()
url = reverse('meetings_select_group',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
response = self.client.get(url, REMOTE_USER=SECR_USER)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertEqual(len(q("#id_scheduled_sessions")),1)
# def test_meetings_schedule():

View file

@ -93,6 +93,9 @@ def build_nonsession(meeting):
for a new meeting, based on the last meeting
'''
last_meeting = get_last_meeting(meeting)
if not last_meeting:
return None
delta = meeting.date - last_meeting.date
system = Person.objects.get(name='(system)')
schedule = get_schedule(meeting)
@ -121,8 +124,11 @@ def build_nonsession(meeting):
def get_last_meeting(meeting):
last_number = int(meeting.number) - 1
return Meeting.objects.get(number=last_number)
try:
return Meeting.objects.get(number=last_number)
except Meeting.DoesNotExist:
return None
def is_combined(session,meeting,schedule=None):
'''
Check to see if this session is using two combined timeslots
@ -204,11 +210,13 @@ def send_notifications(meeting, groups, person):
GroupEvent.objects.create(group=group,time=now,type='sent_notification',
by=person,desc='sent scheduled notification for %s' % meeting)
def sort_groups(meeting):
def sort_groups(meeting,schedule=None):
'''
Similar to sreq.views.sort_groups
Takes a Meeting object and returns a tuple scheduled_groups, unscheduled groups.
'''
if not schedule:
schedule = meeting.agenda
scheduled_groups = []
unscheduled_groups = []
#sessions = Session.objects.filter(meeting=meeting,status__in=('schedw','apprw','appr','sched','notmeet','canceled'))
@ -216,7 +224,7 @@ def sort_groups(meeting):
groups_with_sessions = [ s.group for s in sessions ]
gset = set(groups_with_sessions)
sorted_groups_with_sessions = sorted(gset, key = lambda instance: instance.acronym)
scheduled_sessions = ScheduledSession.objects.filter(schedule=meeting.agenda,session__isnull=False)
scheduled_sessions = ScheduledSession.objects.filter(schedule=schedule,session__isnull=False)
groups_with_timeslots = [ x.session.group for x in scheduled_sessions ]
for group in sorted_groups_with_sessions:
if group in groups_with_timeslots:
@ -358,15 +366,15 @@ def edit_meeting(request, meeting_id):
if request.method == 'POST':
button_text = request.POST.get('submit','')
if button_text == 'Save':
form = MeetingModelForm(request.POST, instance=meeting)
if form.is_valid():
form.save()
messages.success(request,'The meeting entry was changed successfully')
return redirect('meetings_view', meeting_id=meeting_id)
else:
if button_text == 'Cancel':
return redirect('meetings_view', meeting_id=meeting_id)
form = MeetingModelForm(request.POST, instance=meeting)
if form.is_valid():
form.save()
messages.success(request,'The meeting entry was changed successfully')
return redirect('meetings_view', meeting_id=meeting_id)
else:
form = MeetingModelForm(instance=meeting)
@ -559,7 +567,7 @@ def notifications(request, meeting_id):
return render_to_response('meetings/notifications.html', {
'meeting': meeting,
'groups': groups,
'groups': sorted(groups, key=lambda a: a.acronym),
'last_notice': last_notice },
RequestContext(request, {}),
)
@ -671,9 +679,8 @@ def schedule(request, meeting_id, schedule_name, acronym):
return redirect('meetings_select_group', meeting_id=meeting_id,schedule_name=schedule_name)
formset = NewSessionFormset(request.POST,initial=initial)
extra_form = ExtraSessionForm(request.POST)
if formset.is_valid() and extra_form.is_valid():
if formset.is_valid():
# TODO formsets don't have has_changed until Django 1.3
has_changed = False
for form in formset.forms:
@ -728,28 +735,15 @@ def schedule(request, meeting_id, schedule_name, acronym):
assign(session,next_slot,meeting,schedule=schedule)
# ---------------------------------------
# notify. dont send if Tutorial, BOF or indicated on form
#notification_message = "No notification has been sent to anyone for this session."
#if (has_changed
# and not extra_form.cleaned_data.get('no_notify',False)
# and group.state.slug != 'bof'
# and get_timeslot(session,schedule=schedule)): # and the session is scheduled, else skip
# send_notification(request, sessions)
# notification_message = "Notification sent."
if has_changed:
messages.success(request, 'Session(s) Scheduled for %s. %s' % (group.acronym, notification_message))
messages.success(request, 'Session(s) Scheduled for %s.' % group.acronym )
return redirect('meetings_select_group', meeting_id=meeting_id,schedule_name=schedule_name)
else:
formset = NewSessionFormset(initial=initial)
extra_form = ExtraSessionForm()
return render_to_response('meetings/schedule.html', {
'extra_form': extra_form,
'group': group,
'meeting': meeting,
'schedule': schedule,
@ -785,15 +779,15 @@ def select_group(request, meeting_id, schedule_name):
if request.method == 'POST':
group = request.POST.get('group',None)
if group:
redirect_url = reverse('meetings_schedule', kwargs={'meeting_id':meeting_id,'acronym':group})
redirect_url = reverse('meetings_schedule', kwargs={'meeting_id':meeting_id,'acronym':group,'schedule_name':schedule_name})
else:
redirect_url = reverse('meetings_select_group',kwargs={'meeting_id':meeting_id})
redirect_url = reverse('meetings_select_group',kwargs={'meeting_id':meeting_id,'schedule_name':schedule_name})
messages.error(request, 'No group selected')
return HttpResponseRedirect(redirect_url)
# split groups into scheduled / unscheduled
scheduled_groups, unscheduled_groups = sort_groups(meeting)
scheduled_groups, unscheduled_groups = sort_groups(meeting,schedule)
# prep group form
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):
parts = [ int(x) for x in time.split(':') ]
dtime = datetime.datetime(*parts)
qs = meeting.agenda.scheduledsession_set.filter(timeslot__time=dtime,
session__isnull=False)
# qs = meeting.agenda.scheduledsession_set.filter(timeslot__time=dtime,
# session__isnull=False)
if qs:
messages.error(request, 'ERROR deleting timeslot. There is one or more sessions scheduled for this timeslot.')
return redirect('meetings_times', meeting_id=meeting_id,schedule_name=schedule_name)
#if qs:
# messages.error(request, 'ERROR deleting timeslot. There is one or more sessions scheduled for this timeslot.')
# return redirect('meetings_times', meeting_id=meeting_id,schedule_name=schedule_name)
TimeSlot.objects.filter(meeting=meeting,time=dtime).delete()

View file

@ -19,7 +19,7 @@
<form id="id_notification_form" action="." method="post">{% csrf_token %}
<p>Send email notifications to all groups that have been scheduled since the last
notification went out on {{ last_notice.time|date:"Y-m-d" }}:</p>
<p>{% if not groups %}(none){% endif %}{% for group in groups %}{{ group.acronym }}{% if not forloop.last %},{% endif %}{% endfor %}<p>
<p id="id_notification_list">{% if not groups %}(none){% endif %}{% for group in groups %}{{ group.acronym }}{% if not forloop.last %},{% endif %}{% endfor %}<p>
<input type="submit" value="Send Now" name="submit" onclick="return window.confirm('Are you sure you want to send notifications?');">
</form>

View file

@ -10,7 +10,7 @@
<form id="meetings-meta-rooms" action="" method="post">{% csrf_token %}
{{ formset.management_form }}
{{ formset.non_form_errors }}
<table class="full-width">
<table id="id_rooms_table" class="full-width">
<thead>
<tr>
{% for field in formset.forms.0.visible_fields %}

View file

@ -35,8 +35,8 @@
{% endblock %}
{% block breadcrumbs %}{{ block.super }}
&raquo; <a href="../../">Meetings</a>
&raquo; <a href="{% url "meetings_view" meeting_id=meeting.number %}">{{ meeting }}</a>
&raquo; <a href="{% url "meetings" %}">Meetings</a>
&raquo; <a href="{% url "meetings_view" meeting_id=meeting.number %}">{{ meeting.number }}</a>
&raquo; <a href="{% url "meetings_select" meeting_id=meeting.number schedule_name=schedule.name %}">{{ schedule.name }}</a>
&raquo; <a href="{% url "meetings_select_group" meeting_id=meeting.number schedule_name=schedule.name %}">Select</a>
&raquo; {{ group.acronym }}
@ -67,11 +67,6 @@
{% endfor %}
</div> <!-- inline-group -->
<table class="full-width amstable">
<col width="200">
{{ extra_form }}
</table>
<div class="button-group">
<ul>
<li><button type="submit" name="submit" value="Save">Save</button></li>

View file

@ -48,7 +48,7 @@
<div class="inline-related">
<h2>Scheduled Sessions</h2>
<ul>
<ul id="id_scheduled_sessions">
{% for group in scheduled_groups %}
<li><a href="{% url "meetings_schedule" meeting_id=meeting.number schedule_name=schedule.name acronym=group.acronym %}">{{ group.acronym }}</a></li>
{% endfor %}

View file

@ -23,7 +23,7 @@
<td>{{ item.time|date:"H:i" }} - {{ item.end_time|date:"H:i" }}</td>
<td>{{ item.name }}</td>
<td><a href="{% url "meetings_times_edit" meeting_id=meeting.number schedule_name=schedule.name time=item.time|date:"Y:m:d:H:i" %}">Edit</a></td>
<td><a href="{% url "meetings_times_delete" meeting_id=meeting.number schedule_name=schedule.name time=item.time|date:"Y:m:d:H:i" %}">Delete</a></td>
<td><a href="{% url "meetings_times_delete" meeting_id=meeting.number schedule_name=schedule.name time=item.time|date:"Y:m:d:H:i" %}" onclick="return window.confirm('Are you sure you want to delete this timeslot? Any sessions assigned to this timeslot will be unscheduled.');">Delete</a></td>
</tr>
{% endfor %}
</tbody>

View file

@ -36,10 +36,10 @@
<li><button onclick="window.location='{% url "meetings_edit_meeting" meeting_id=meeting.number %}'">Edit</button></li>
<li><button onclick="window.location='{% url "meetings_notifications" meeting_id=meeting.number %}'">Notifications</button></li>
<li><button onclick="window.location='{% url "meetings_blue_sheet" meeting_id=meeting.number %}'">Blue Sheets</button></li>
<li><form id="schedule-selector">
<li><form id="id_schedule_selector">
<select name="forma" onchange="location = this.options[this.selectedIndex].value;">
<option value="">Select a schedule...</option>
{% for sched in meeting.schedule_set.all %}
<option value="">Select a schedule...</option>
<option value="{{ sched.name }}">{{ sched.name }}</option>
{% endfor %}
</select>

View file

@ -490,7 +490,7 @@ tr.break td {
border-top: 2px solid black;
}
#schedule-selector {
#id_schedule_selector {
display: inline;
}